mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-26 07:22:21 +00:00
Built-in abs/min/max for integers; For-loop fixes
This commit is contained in:
parent
81844a1fe7
commit
f045975a4b
4
assembly.d.ts
vendored
4
assembly.d.ts
vendored
@ -87,11 +87,9 @@ declare function assert(isTrue: bool): void;
|
|||||||
|
|
||||||
// internal decorators
|
// internal decorators
|
||||||
|
|
||||||
/** A decorator marking a function or class as global. */
|
|
||||||
declare function global(name?: string): any;
|
declare function global(name?: string): any;
|
||||||
/** A decorator marking a function as ideally being inlined. */
|
declare function struct(): any
|
||||||
declare function inline(): any;
|
declare function inline(): any;
|
||||||
/** A decorator marking a class that manually manages its memory. */
|
|
||||||
declare function allocates(): any;
|
declare function allocates(): any;
|
||||||
declare function operator(token: string, fn: any): any;
|
declare function operator(token: string, fn: any): any;
|
||||||
|
|
||||||
|
115
src/builtins.ts
115
src/builtins.ts
@ -53,7 +53,9 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
|||||||
arg1: ExpressionRef,
|
arg1: ExpressionRef,
|
||||||
arg2: ExpressionRef;
|
arg2: ExpressionRef;
|
||||||
|
|
||||||
let tempLocal: Local;
|
let tempLocal0: Local;
|
||||||
|
let tempLocal1: Local;
|
||||||
|
let nativeType: NativeType;
|
||||||
|
|
||||||
switch (internalName) {
|
switch (internalName) {
|
||||||
|
|
||||||
@ -149,7 +151,34 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
|||||||
? compiler.module.createUnary(UnaryOp.AbsF32, arg0)
|
? compiler.module.createUnary(UnaryOp.AbsF32, arg0)
|
||||||
: compiler.module.createUnary(UnaryOp.AbsF64, arg0);
|
: compiler.module.createUnary(UnaryOp.AbsF64, arg0);
|
||||||
if (typeArguments[0].isAnyInteger) {
|
if (typeArguments[0].isAnyInteger) {
|
||||||
// TODO: ternaries for integers
|
if (typeArguments[0].isSignedInteger) {
|
||||||
|
tempLocal0 = compiler.currentFunction.addLocal(typeArguments[0]);
|
||||||
|
if (typeArguments[0].isLongInteger)
|
||||||
|
return compiler.module.createSelect(
|
||||||
|
compiler.module.createBinary(BinaryOp.SubI64,
|
||||||
|
compiler.module.createI64(0, 0),
|
||||||
|
compiler.module.createTeeLocal(tempLocal0.index, arg0)
|
||||||
|
),
|
||||||
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.I64),
|
||||||
|
compiler.module.createBinary(BinaryOp.LtI64,
|
||||||
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.I64),
|
||||||
|
compiler.module.createI64(0, 0)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
else
|
||||||
|
return compiler.module.createSelect(
|
||||||
|
compiler.module.createBinary(BinaryOp.SubI32,
|
||||||
|
compiler.module.createI32(0),
|
||||||
|
compiler.module.createTeeLocal(tempLocal0.index, arg0)
|
||||||
|
),
|
||||||
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.I32),
|
||||||
|
compiler.module.createBinary(BinaryOp.LtI32,
|
||||||
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.I32),
|
||||||
|
compiler.module.createI32(0)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else
|
||||||
|
return arg0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -165,7 +194,26 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
|||||||
? compiler.module.createBinary(BinaryOp.MaxF32, arg0, arg1)
|
? compiler.module.createBinary(BinaryOp.MaxF32, arg0, arg1)
|
||||||
: compiler.module.createBinary(BinaryOp.MaxF64, arg0, arg1);
|
: compiler.module.createBinary(BinaryOp.MaxF64, arg0, arg1);
|
||||||
if (typeArguments[0].isAnyInteger) {
|
if (typeArguments[0].isAnyInteger) {
|
||||||
// TODO: ternaries for integers
|
tempLocal0 = compiler.currentFunction.addLocal(typeArguments[0]);
|
||||||
|
tempLocal1 = compiler.currentFunction.addLocal(typeArguments[0]);
|
||||||
|
if (typeArguments[0].isLongInteger)
|
||||||
|
return compiler.module.createSelect(
|
||||||
|
compiler.module.createTeeLocal(tempLocal0.index, arg0),
|
||||||
|
compiler.module.createTeeLocal(tempLocal1.index, arg1),
|
||||||
|
compiler.module.createBinary(typeArguments[0].isSignedInteger ? BinaryOp.GtI64 : BinaryOp.GtU64,
|
||||||
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.I64),
|
||||||
|
compiler.module.createGetLocal(tempLocal1.index, NativeType.I64)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
else
|
||||||
|
return compiler.module.createSelect(
|
||||||
|
compiler.module.createTeeLocal(tempLocal0.index, arg0),
|
||||||
|
compiler.module.createTeeLocal(tempLocal1.index, arg1),
|
||||||
|
compiler.module.createBinary(typeArguments[0].isSignedInteger ? BinaryOp.GtI32 : BinaryOp.GtU32,
|
||||||
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.I32),
|
||||||
|
compiler.module.createGetLocal(tempLocal1.index, NativeType.I32)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -181,7 +229,26 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
|||||||
? compiler.module.createBinary(BinaryOp.MinF32, arg0, arg1)
|
? compiler.module.createBinary(BinaryOp.MinF32, arg0, arg1)
|
||||||
: compiler.module.createBinary(BinaryOp.MinF64, arg0, arg1);
|
: compiler.module.createBinary(BinaryOp.MinF64, arg0, arg1);
|
||||||
if (typeArguments[0].isAnyInteger) {
|
if (typeArguments[0].isAnyInteger) {
|
||||||
// TODO: ternaries for integers
|
tempLocal0 = compiler.currentFunction.addLocal(typeArguments[0]);
|
||||||
|
tempLocal1 = compiler.currentFunction.addLocal(typeArguments[0]);
|
||||||
|
if (typeArguments[0].isLongInteger)
|
||||||
|
return compiler.module.createSelect(
|
||||||
|
compiler.module.createTeeLocal(tempLocal0.index, arg0),
|
||||||
|
compiler.module.createTeeLocal(tempLocal1.index, arg1),
|
||||||
|
compiler.module.createBinary(typeArguments[0].isSignedInteger ? BinaryOp.LtI64 : BinaryOp.LtU64,
|
||||||
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.I64),
|
||||||
|
compiler.module.createGetLocal(tempLocal1.index, NativeType.I64)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
else
|
||||||
|
return compiler.module.createSelect(
|
||||||
|
compiler.module.createTeeLocal(tempLocal0.index, arg0),
|
||||||
|
compiler.module.createTeeLocal(tempLocal1.index, arg1),
|
||||||
|
compiler.module.createBinary(typeArguments[0].isSignedInteger ? BinaryOp.LtI32 : BinaryOp.LtU32,
|
||||||
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.I32),
|
||||||
|
compiler.module.createGetLocal(tempLocal1.index, NativeType.I32)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -220,7 +287,7 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "nearest":
|
case "nearest": // nearest<T>(value: T) -> T
|
||||||
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
||||||
return compiler.module.createUnreachable();
|
return compiler.module.createUnreachable();
|
||||||
if ((compiler.currentType = typeArguments[0]).isAnyFloat) {
|
if ((compiler.currentType = typeArguments[0]).isAnyFloat) {
|
||||||
@ -231,7 +298,7 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "sqrt":
|
case "sqrt": // sqrt<T>(value: T) -> T
|
||||||
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
||||||
return compiler.module.createUnreachable();
|
return compiler.module.createUnreachable();
|
||||||
if ((compiler.currentType = typeArguments[0]).isAnyFloat) {
|
if ((compiler.currentType = typeArguments[0]).isAnyFloat) {
|
||||||
@ -242,7 +309,7 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "trunc":
|
case "trunc": // trunc<T>(value: T) -> T
|
||||||
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
||||||
return compiler.module.createUnreachable();
|
return compiler.module.createUnreachable();
|
||||||
if ((compiler.currentType = typeArguments[0]).isAnyFloat) {
|
if ((compiler.currentType = typeArguments[0]).isAnyFloat) {
|
||||||
@ -336,7 +403,7 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
|||||||
validateCall(compiler, typeArguments, 0, operands, 0, reportNode);
|
validateCall(compiler, typeArguments, 0, operands, 0, reportNode);
|
||||||
return compiler.module.createUnreachable();
|
return compiler.module.createUnreachable();
|
||||||
|
|
||||||
case "isNaN":
|
case "isNaN": // isNaN<T>(value: T) -> bool
|
||||||
compiler.currentType = Type.bool;
|
compiler.currentType = Type.bool;
|
||||||
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
||||||
return compiler.module.createUnreachable();
|
return compiler.module.createUnreachable();
|
||||||
@ -346,22 +413,22 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
|||||||
arg0 = compiler.compileExpression(operands[0], typeArguments[0]); // reports
|
arg0 = compiler.compileExpression(operands[0], typeArguments[0]); // reports
|
||||||
compiler.currentType = Type.bool;
|
compiler.currentType = Type.bool;
|
||||||
if (typeArguments[0] == Type.f32) {
|
if (typeArguments[0] == Type.f32) {
|
||||||
tempLocal = compiler.currentFunction.addLocal(Type.f32);
|
tempLocal0 = compiler.currentFunction.addLocal(Type.f32);
|
||||||
return compiler.module.createBinary(BinaryOp.NeF32,
|
return compiler.module.createBinary(BinaryOp.NeF32,
|
||||||
compiler.module.createTeeLocal(tempLocal.index, arg0),
|
compiler.module.createTeeLocal(tempLocal0.index, arg0),
|
||||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F32)
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.F32)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
tempLocal = compiler.currentFunction.addLocal(Type.f64);
|
tempLocal0 = compiler.currentFunction.addLocal(Type.f64);
|
||||||
return compiler.module.createBinary(BinaryOp.NeF64,
|
return compiler.module.createBinary(BinaryOp.NeF64,
|
||||||
compiler.module.createTeeLocal(tempLocal.index, arg0),
|
compiler.module.createTeeLocal(tempLocal0.index, arg0),
|
||||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F64)
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.F64)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "isFinite":
|
case "isFinite": // isFinite<T>(value: T) -> bool
|
||||||
compiler.currentType = Type.bool;
|
compiler.currentType = Type.bool;
|
||||||
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
||||||
return compiler.module.createUnreachable();
|
return compiler.module.createUnreachable();
|
||||||
@ -371,40 +438,40 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
|||||||
arg0 = compiler.compileExpression(operands[0], typeArguments[0]); // reports
|
arg0 = compiler.compileExpression(operands[0], typeArguments[0]); // reports
|
||||||
compiler.currentType = Type.bool;
|
compiler.currentType = Type.bool;
|
||||||
if (typeArguments[0] == Type.f32) {
|
if (typeArguments[0] == Type.f32) {
|
||||||
tempLocal = compiler.currentFunction.addLocal(Type.f32);
|
tempLocal0 = compiler.currentFunction.addLocal(Type.f32);
|
||||||
return compiler.module.createSelect(
|
return compiler.module.createSelect(
|
||||||
compiler.module.createBinary(BinaryOp.NeF32,
|
compiler.module.createBinary(BinaryOp.NeF32,
|
||||||
compiler.module.createUnary(UnaryOp.AbsF32,
|
compiler.module.createUnary(UnaryOp.AbsF32,
|
||||||
compiler.module.createTeeLocal(tempLocal.index, arg0)
|
compiler.module.createTeeLocal(tempLocal0.index, arg0)
|
||||||
),
|
),
|
||||||
compiler.module.createF32(Infinity)
|
compiler.module.createF32(Infinity)
|
||||||
),
|
),
|
||||||
compiler.module.createI32(0),
|
compiler.module.createI32(0),
|
||||||
compiler.module.createBinary(BinaryOp.EqF32,
|
compiler.module.createBinary(BinaryOp.EqF32,
|
||||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F32),
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.F32),
|
||||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F32)
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.F32)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
tempLocal = compiler.currentFunction.addLocal(Type.f64);
|
tempLocal0 = compiler.currentFunction.addLocal(Type.f64);
|
||||||
return compiler.module.createSelect(
|
return compiler.module.createSelect(
|
||||||
compiler.module.createBinary(BinaryOp.NeF64,
|
compiler.module.createBinary(BinaryOp.NeF64,
|
||||||
compiler.module.createUnary(UnaryOp.AbsF64,
|
compiler.module.createUnary(UnaryOp.AbsF64,
|
||||||
compiler.module.createTeeLocal(tempLocal.index, arg0)
|
compiler.module.createTeeLocal(tempLocal0.index, arg0)
|
||||||
),
|
),
|
||||||
compiler.module.createF64(Infinity)
|
compiler.module.createF64(Infinity)
|
||||||
),
|
),
|
||||||
compiler.module.createI32(0),
|
compiler.module.createI32(0),
|
||||||
compiler.module.createBinary(BinaryOp.EqF64,
|
compiler.module.createBinary(BinaryOp.EqF64,
|
||||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F64),
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.F64),
|
||||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F64)
|
compiler.module.createGetLocal(tempLocal0.index, NativeType.F64)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "assert":
|
case "assert": // assert(isTrue: bool) -> void
|
||||||
compiler.currentType = Type.void;
|
compiler.currentType = Type.void;
|
||||||
if (!validateCall(compiler, typeArguments, 0, operands, 1, reportNode))
|
if (!validateCall(compiler, typeArguments, 0, operands, 1, reportNode))
|
||||||
return compiler.module.createUnreachable();
|
return compiler.module.createUnreachable();
|
||||||
|
@ -122,6 +122,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
currentFunction: Function;
|
currentFunction: Function;
|
||||||
/** Marker indicating whether continue statements are allowed in the current break context. */
|
/** Marker indicating whether continue statements are allowed in the current break context. */
|
||||||
disallowContinue: bool = true;
|
disallowContinue: bool = true;
|
||||||
|
/** Marker indicating that a new variable, if present, is always a local. Used to distinguish locals from globals in the start function. */
|
||||||
|
variableIsLocal: bool = false;
|
||||||
|
|
||||||
/** Counting memory offset. */
|
/** Counting memory offset. */
|
||||||
memoryOffset: U64 = new U64(8, 0); // leave space for (any size of) NULL
|
memoryOffset: U64 = new U64(8, 0); // leave space for (any size of) NULL
|
||||||
@ -757,7 +759,11 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
compileForStatement(statement: ForStatement): ExpressionRef {
|
compileForStatement(statement: ForStatement): ExpressionRef {
|
||||||
const context: string = this.currentFunction.enterBreakContext();
|
const context: string = this.currentFunction.enterBreakContext();
|
||||||
|
const variableWasLocal: bool = this.variableIsLocal;
|
||||||
|
if (this.currentFunction == this.startFunction)
|
||||||
|
this.variableIsLocal = true;
|
||||||
const initializer: ExpressionRef = statement.initializer ? this.compileStatement(<Statement>statement.initializer) : this.module.createNop();
|
const initializer: ExpressionRef = statement.initializer ? this.compileStatement(<Statement>statement.initializer) : this.module.createNop();
|
||||||
|
this.variableIsLocal = variableWasLocal;
|
||||||
const condition: ExpressionRef = statement.condition ? this.compileExpression(<Expression>statement.condition, Type.i32) : this.module.createI32(1);
|
const condition: ExpressionRef = statement.condition ? this.compileExpression(<Expression>statement.condition, Type.i32) : this.module.createI32(1);
|
||||||
const incrementor: ExpressionRef = statement.incrementor ? this.compileExpression(<Expression>statement.incrementor, Type.void) : this.module.createNop();
|
const incrementor: ExpressionRef = statement.incrementor ? this.compileExpression(<Expression>statement.incrementor, Type.void) : this.module.createNop();
|
||||||
const body: ExpressionRef = this.compileStatement(statement.statement);
|
const body: ExpressionRef = this.compileStatement(statement.statement);
|
||||||
@ -860,7 +866,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
const declarations: VariableDeclaration[] = statement.declarations;
|
const declarations: VariableDeclaration[] = statement.declarations;
|
||||||
|
|
||||||
// top-level variables become globals
|
// top-level variables become globals
|
||||||
if (this.currentFunction == this.startFunction) {
|
if (this.currentFunction == this.startFunction && !this.variableIsLocal) {
|
||||||
const isConst: bool = hasModifier(ModifierKind.CONST, statement.modifiers);
|
const isConst: bool = hasModifier(ModifierKind.CONST, statement.modifiers);
|
||||||
for (let i: i32 = 0, k: i32 = declarations.length; i < k; ++i)
|
for (let i: i32 = 0, k: i32 = declarations.length; i < k; ++i)
|
||||||
this.compileGlobalDeclaration(declarations[i], isConst);
|
this.compileGlobalDeclaration(declarations[i], isConst);
|
||||||
|
@ -981,9 +981,9 @@ export class Function extends Element {
|
|||||||
|
|
||||||
/** Leaves the current break context. */
|
/** Leaves the current break context. */
|
||||||
leaveBreakContext(): void {
|
leaveBreakContext(): void {
|
||||||
if (--this.breakMinor < 0)
|
if (this.breakMinor < 1)
|
||||||
throw new Error("unexpected unbalanced break context");
|
throw new Error("unexpected unbalanced break context");
|
||||||
if (this.breakMinor == 0 && !--this.breakMajor)
|
if (--this.breakMinor == 0)
|
||||||
this.breakContext = null;
|
this.breakContext = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
tests/compiler/assert.optimized.wast
Normal file
10
tests/compiler/assert.optimized.wast
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
(module
|
||||||
|
(type $v (func))
|
||||||
|
(memory $0 1)
|
||||||
|
(data (i32.const 4) "\08")
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(start $start)
|
||||||
|
(func $start (; 0 ;) (type $v)
|
||||||
|
(nop)
|
||||||
|
)
|
||||||
|
)
|
1
tests/compiler/assert.ts
Normal file
1
tests/compiler/assert.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
assert(true);
|
45
tests/compiler/assert.wast
Normal file
45
tests/compiler/assert.wast
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
(module
|
||||||
|
(type $v (func))
|
||||||
|
(memory $0 1)
|
||||||
|
(data (i32.const 4) "\08\00\00\00")
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(start $start)
|
||||||
|
(func $start (; 0 ;) (type $v)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(;
|
||||||
|
[program.elements]
|
||||||
|
clz
|
||||||
|
ctz
|
||||||
|
popcnt
|
||||||
|
rotl
|
||||||
|
rotr
|
||||||
|
abs
|
||||||
|
ceil
|
||||||
|
copysign
|
||||||
|
floor
|
||||||
|
max
|
||||||
|
min
|
||||||
|
nearest
|
||||||
|
sqrt
|
||||||
|
trunc
|
||||||
|
current_memory
|
||||||
|
grow_memory
|
||||||
|
unreachable
|
||||||
|
load
|
||||||
|
store
|
||||||
|
reinterpret
|
||||||
|
select
|
||||||
|
sizeof
|
||||||
|
isNaN
|
||||||
|
isFinite
|
||||||
|
assert
|
||||||
|
[program.exports]
|
||||||
|
|
||||||
|
;)
|
@ -13,6 +13,38 @@
|
|||||||
(func $start (; 0 ;) (type $v)
|
(func $start (; 0 ;) (type $v)
|
||||||
(local $0 f32)
|
(local $0 f32)
|
||||||
(local $1 f64)
|
(local $1 f64)
|
||||||
|
(local $2 i32)
|
||||||
|
(local $3 i32)
|
||||||
|
(local $4 i64)
|
||||||
|
(local $5 i64)
|
||||||
|
(drop
|
||||||
|
(select
|
||||||
|
(tee_local $2
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(tee_local $3
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(i32.gt_s
|
||||||
|
(get_local $2)
|
||||||
|
(get_local $3)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(select
|
||||||
|
(tee_local $2
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(tee_local $3
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(i32.lt_s
|
||||||
|
(get_local $2)
|
||||||
|
(get_local $3)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
(set_global $builtins/i
|
(set_global $builtins/i
|
||||||
(i32.const 31)
|
(i32.const 31)
|
||||||
)
|
)
|
||||||
@ -28,6 +60,70 @@
|
|||||||
(set_global $builtins/i
|
(set_global $builtins/i
|
||||||
(i32.const -2147483648)
|
(i32.const -2147483648)
|
||||||
)
|
)
|
||||||
|
(set_global $builtins/i
|
||||||
|
(select
|
||||||
|
(i32.sub
|
||||||
|
(i32.const 0)
|
||||||
|
(tee_local $2
|
||||||
|
(i32.const -42)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_local $2)
|
||||||
|
(i32.lt_s
|
||||||
|
(get_local $2)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.ne
|
||||||
|
(get_global $builtins/i)
|
||||||
|
(i32.const 42)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(set_global $builtins/i
|
||||||
|
(select
|
||||||
|
(tee_local $2
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(tee_local $3
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(i32.gt_s
|
||||||
|
(get_local $2)
|
||||||
|
(get_local $3)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.ne
|
||||||
|
(get_global $builtins/i)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(set_global $builtins/i
|
||||||
|
(select
|
||||||
|
(tee_local $2
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(tee_local $3
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(i32.lt_s
|
||||||
|
(get_local $2)
|
||||||
|
(get_local $3)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.ne
|
||||||
|
(get_global $builtins/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
(set_global $builtins/I
|
(set_global $builtins/I
|
||||||
(i64.const 63)
|
(i64.const 63)
|
||||||
)
|
)
|
||||||
@ -43,6 +139,70 @@
|
|||||||
(set_global $builtins/I
|
(set_global $builtins/I
|
||||||
(i64.const -9223372036854775808)
|
(i64.const -9223372036854775808)
|
||||||
)
|
)
|
||||||
|
(set_global $builtins/I
|
||||||
|
(select
|
||||||
|
(i64.sub
|
||||||
|
(i64.const 0)
|
||||||
|
(tee_local $4
|
||||||
|
(i64.const -42)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_local $4)
|
||||||
|
(i64.lt_s
|
||||||
|
(get_local $4)
|
||||||
|
(i64.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i64.ne
|
||||||
|
(get_global $builtins/I)
|
||||||
|
(i64.const 42)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(set_global $builtins/I
|
||||||
|
(select
|
||||||
|
(tee_local $4
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
(tee_local $5
|
||||||
|
(i64.const 2)
|
||||||
|
)
|
||||||
|
(i64.gt_s
|
||||||
|
(get_local $4)
|
||||||
|
(get_local $5)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i64.ne
|
||||||
|
(get_global $builtins/I)
|
||||||
|
(i64.const 2)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(set_global $builtins/I
|
||||||
|
(select
|
||||||
|
(tee_local $4
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
(tee_local $5
|
||||||
|
(i64.const 2)
|
||||||
|
)
|
||||||
|
(i64.lt_s
|
||||||
|
(get_local $4)
|
||||||
|
(get_local $5)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.ne
|
||||||
|
(get_global $builtins/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
(set_global $builtins/f
|
(set_global $builtins/f
|
||||||
(f32.const nan:0x400000)
|
(f32.const nan:0x400000)
|
||||||
)
|
)
|
||||||
@ -168,6 +328,12 @@
|
|||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(get_global $builtins/i)
|
(get_global $builtins/i)
|
||||||
)
|
)
|
||||||
|
(i32.store
|
||||||
|
(i32.const 8)
|
||||||
|
(i32.load
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
)
|
||||||
(set_global $builtins/I
|
(set_global $builtins/I
|
||||||
(i64.load
|
(i64.load
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -177,6 +343,12 @@
|
|||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(get_global $builtins/I)
|
(get_global $builtins/I)
|
||||||
)
|
)
|
||||||
|
(i64.store
|
||||||
|
(i32.const 8)
|
||||||
|
(i64.load
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
)
|
||||||
(set_global $builtins/f
|
(set_global $builtins/f
|
||||||
(f32.load
|
(f32.load
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -186,6 +358,12 @@
|
|||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(get_global $builtins/f)
|
(get_global $builtins/f)
|
||||||
)
|
)
|
||||||
|
(f32.store
|
||||||
|
(i32.const 8)
|
||||||
|
(f32.load
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
)
|
||||||
(set_global $builtins/F
|
(set_global $builtins/F
|
||||||
(f64.load
|
(f64.load
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -195,6 +373,12 @@
|
|||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(get_global $builtins/F)
|
(get_global $builtins/F)
|
||||||
)
|
)
|
||||||
|
(f64.store
|
||||||
|
(i32.const 8)
|
||||||
|
(f64.load
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
)
|
||||||
(set_global $builtins/i
|
(set_global $builtins/i
|
||||||
(i32.const 1067450368)
|
(i32.const 1067450368)
|
||||||
)
|
)
|
||||||
@ -244,6 +428,15 @@
|
|||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
|
(if
|
||||||
|
(f64.eq
|
||||||
|
(tee_local $1
|
||||||
|
(f64.const nan:0x8000000000000)
|
||||||
|
)
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
(if
|
(if
|
||||||
(select
|
(select
|
||||||
(f32.ne
|
(f32.ne
|
||||||
@ -280,6 +473,62 @@
|
|||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
|
(if
|
||||||
|
(select
|
||||||
|
(f64.ne
|
||||||
|
(f64.abs
|
||||||
|
(tee_local $1
|
||||||
|
(f64.const nan:0x8000000000000)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(f64.const inf)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
(f64.eq
|
||||||
|
(get_local $1)
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(select
|
||||||
|
(f64.ne
|
||||||
|
(f64.abs
|
||||||
|
(tee_local $1
|
||||||
|
(f64.const inf)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(f64.const inf)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
(f64.eq
|
||||||
|
(get_local $1)
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(select
|
||||||
|
(f32.ne
|
||||||
|
(f32.abs
|
||||||
|
(tee_local $0
|
||||||
|
(f32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(f32.const inf)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
(f32.eq
|
||||||
|
(get_local $0)
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
(if
|
(if
|
||||||
(i32.eqz
|
(i32.eqz
|
||||||
(select
|
(select
|
||||||
|
@ -9,12 +9,18 @@ ctz<i32>(1);
|
|||||||
popcnt<i32>(1);
|
popcnt<i32>(1);
|
||||||
rotl<i32>(1, 1);
|
rotl<i32>(1, 1);
|
||||||
rotr<i32>(1, 1);
|
rotr<i32>(1, 1);
|
||||||
|
abs<i32>(-42);
|
||||||
|
max<i32>(1, 2);
|
||||||
|
min<i32>(1, 2);
|
||||||
|
|
||||||
i = clz<i32>(1);
|
i = clz<i32>(1);
|
||||||
i = ctz<i32>(1);
|
i = ctz<i32>(1);
|
||||||
i = popcnt<i32>(1);
|
i = popcnt<i32>(1);
|
||||||
i = rotl<i32>(1, 1);
|
i = rotl<i32>(1, 1);
|
||||||
i = rotr<i32>(1, 1);
|
i = rotr<i32>(1, 1);
|
||||||
|
i = abs<i32>(-42); assert(i == 42);
|
||||||
|
i = max<i32>(1, 2); assert(i == 2);
|
||||||
|
i = min<i32>(1, 2); assert(i == 1);
|
||||||
|
|
||||||
let I: i64;
|
let I: i64;
|
||||||
|
|
||||||
@ -23,12 +29,16 @@ ctz<i64>(1);
|
|||||||
popcnt<i64>(1);
|
popcnt<i64>(1);
|
||||||
rotl<i64>(1, 1);
|
rotl<i64>(1, 1);
|
||||||
rotr<i64>(1, 1);
|
rotr<i64>(1, 1);
|
||||||
|
abs<i64>(-42);
|
||||||
|
|
||||||
I = clz<i64>(1);
|
I = clz<i64>(1);
|
||||||
I = ctz<i64>(1);
|
I = ctz<i64>(1);
|
||||||
I = popcnt<i64>(1);
|
I = popcnt<i64>(1);
|
||||||
I = rotl<i64>(1, 1);
|
I = rotl<i64>(1, 1);
|
||||||
I = rotr<i64>(1, 1);
|
I = rotr<i64>(1, 1);
|
||||||
|
I = abs<i64>(-42); assert(I == 42);
|
||||||
|
I = max<i64>(1, 2); assert(I == 2);
|
||||||
|
I = min<i64>(1, 2); assert(i == 1);
|
||||||
|
|
||||||
// floating point builtins
|
// floating point builtins
|
||||||
|
|
||||||
@ -96,14 +106,14 @@ b = isFinite<f64>(1.25);
|
|||||||
|
|
||||||
// load and store builtins
|
// load and store builtins
|
||||||
|
|
||||||
i = load<i32>(8);
|
i = load<i32>(8); store<i32>(8, i);
|
||||||
store<i32>(8, i);
|
store<i32>(8, load<i32>(8));
|
||||||
I = load<i64>(8);
|
I = load<i64>(8); store<i64>(8, I);
|
||||||
store<i64>(8, I);
|
store<i64>(8, load<i64>(8));
|
||||||
f = load<f32>(8);
|
f = load<f32>(8); store<f32>(8, f);
|
||||||
store<f32>(8, f);
|
store<f32>(8, load<f32>(8));
|
||||||
F = load<f64>(8);
|
F = load<f64>(8); store<f64>(8, F);
|
||||||
store<f64>(8, F);
|
store<f64>(8, load<f64>(8));
|
||||||
|
|
||||||
// reinterpretation builtins
|
// reinterpretation builtins
|
||||||
|
|
||||||
@ -143,8 +153,6 @@ if (0) unreachable();
|
|||||||
|
|
||||||
// AS specific builtins
|
// AS specific builtins
|
||||||
|
|
||||||
assert(true);
|
|
||||||
|
|
||||||
sizeof<u8>();
|
sizeof<u8>();
|
||||||
sizeof<u16>();
|
sizeof<u16>();
|
||||||
sizeof<u32>();
|
sizeof<u32>();
|
||||||
@ -159,13 +167,12 @@ sizeof<isize>();
|
|||||||
sizeof<f32>();
|
sizeof<f32>();
|
||||||
sizeof<f64>();
|
sizeof<f64>();
|
||||||
|
|
||||||
if (NaN == NaN)
|
assert(NaN != NaN);
|
||||||
unreachable();
|
assert(isNaN<f32>(NaN));
|
||||||
if (!isNaN<f32>(NaN))
|
assert(isNaN<f64>(NaN));
|
||||||
unreachable();
|
assert(!isFinite<f32>(NaN));
|
||||||
if (isFinite<f32>(NaN))
|
assert(!isFinite<f32>(Infinity));
|
||||||
unreachable();
|
assert(!isFinite<f64>(NaN));
|
||||||
if (isFinite<f32>(Infinity))
|
assert(!isFinite<f64>(Infinity));
|
||||||
unreachable();
|
assert(isFinite<f32>(0));
|
||||||
if (!isFinite<f64>(0))
|
assert(isFinite<f64>(0));
|
||||||
unreachable();
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,7 @@
|
|||||||
(export "memory" (memory $0))
|
(export "memory" (memory $0))
|
||||||
(start $start)
|
(start $start)
|
||||||
(func $start (; 0 ;) (type $v)
|
(func $start (; 0 ;) (type $v)
|
||||||
|
(local $0 i32)
|
||||||
(set_global $for/i
|
(set_global $for/i
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
@ -33,5 +34,74 @@
|
|||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
|
(set_local $0
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(loop $continue$2.1
|
||||||
|
(if
|
||||||
|
(i32.lt_s
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 10)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(set_local $0
|
||||||
|
(i32.add
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br $continue$2.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(loop $continue$3.1
|
||||||
|
(if
|
||||||
|
(i32.gt_s
|
||||||
|
(get_global $for/i)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(set_global $for/i
|
||||||
|
(i32.sub
|
||||||
|
(get_global $for/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br $continue$3.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(get_global $for/i)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(block $break$4.1
|
||||||
|
(loop $continue$4.1
|
||||||
|
(br_if $break$4.1
|
||||||
|
(i32.eq
|
||||||
|
(get_global $for/i)
|
||||||
|
(i32.const 10)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $for/i
|
||||||
|
(i32.add
|
||||||
|
(get_global $for/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br $continue$4.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(loop $continue$5.1
|
||||||
|
(set_global $for/i
|
||||||
|
(i32.sub
|
||||||
|
(get_global $for/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br_if $continue$5.1
|
||||||
|
(get_global $for/i)
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -2,5 +2,19 @@ let i: i32;
|
|||||||
for (i = 0; i < 10; ++i) {
|
for (i = 0; i < 10; ++i) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
if (i != 10)
|
assert(i == 10);
|
||||||
unreachable();
|
|
||||||
|
for (let j: i32 = 0; j < 10; ++j) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i > 0; --i);
|
||||||
|
assert(i == 0);
|
||||||
|
|
||||||
|
for (;; ++i)
|
||||||
|
if (i == 10)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
if (--i == 0)
|
||||||
|
break;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
(export "memory" (memory $0))
|
(export "memory" (memory $0))
|
||||||
(start $start)
|
(start $start)
|
||||||
(func $start (; 0 ;) (type $v)
|
(func $start (; 0 ;) (type $v)
|
||||||
|
(local $0 i32)
|
||||||
(block $break$1.1
|
(block $break$1.1
|
||||||
(set_global $for/i
|
(set_global $for/i
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
@ -30,12 +31,120 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(if
|
(if
|
||||||
(i32.ne
|
(i32.eqz
|
||||||
|
(i32.eq
|
||||||
(get_global $for/i)
|
(get_global $for/i)
|
||||||
(i32.const 10)
|
(i32.const 10)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
|
(block $break$2.1
|
||||||
|
(block
|
||||||
|
(set_local $0
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(loop $continue$2.1
|
||||||
|
(if
|
||||||
|
(i32.lt_s
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 10)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(nop)
|
||||||
|
(set_local $0
|
||||||
|
(i32.add
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br $continue$2.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block $break$3.1
|
||||||
|
(nop)
|
||||||
|
(loop $continue$3.1
|
||||||
|
(if
|
||||||
|
(i32.gt_s
|
||||||
|
(get_global $for/i)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(nop)
|
||||||
|
(set_global $for/i
|
||||||
|
(i32.sub
|
||||||
|
(get_global $for/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br $continue$3.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(i32.eq
|
||||||
|
(get_global $for/i)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(block $break$4.1
|
||||||
|
(nop)
|
||||||
|
(loop $continue$4.1
|
||||||
|
(if
|
||||||
|
(i32.const 1)
|
||||||
|
(block
|
||||||
|
(if
|
||||||
|
(i32.eq
|
||||||
|
(get_global $for/i)
|
||||||
|
(i32.const 10)
|
||||||
|
)
|
||||||
|
(br $break$4.1)
|
||||||
|
)
|
||||||
|
(set_global $for/i
|
||||||
|
(i32.add
|
||||||
|
(get_global $for/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br $continue$4.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block $break$5.1
|
||||||
|
(nop)
|
||||||
|
(loop $continue$5.1
|
||||||
|
(if
|
||||||
|
(i32.const 1)
|
||||||
|
(block
|
||||||
|
(if
|
||||||
|
(i32.eq
|
||||||
|
(block (result i32)
|
||||||
|
(set_global $for/i
|
||||||
|
(i32.sub
|
||||||
|
(get_global $for/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_global $for/i)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(br $break$5.1)
|
||||||
|
)
|
||||||
|
(nop)
|
||||||
|
(br $continue$5.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(;
|
(;
|
||||||
|
@ -9,39 +9,31 @@
|
|||||||
let i: i32;
|
let i: i32;
|
||||||
|
|
||||||
i = 1 && 2;
|
i = 1 && 2;
|
||||||
if (i != 2)
|
assert(i == 2);
|
||||||
unreachable();
|
|
||||||
|
|
||||||
i = 0 || 1;
|
i = 0 || 1;
|
||||||
if (i != 1)
|
assert(i == 1);
|
||||||
unreachable();
|
|
||||||
|
|
||||||
let I: i64;
|
let I: i64;
|
||||||
|
|
||||||
I = 1 && 2;
|
I = 1 && 2;
|
||||||
if (I != 2)
|
assert(I == 2);
|
||||||
unreachable();
|
|
||||||
|
|
||||||
I = 0 || 1;
|
I = 0 || 1;
|
||||||
if (I != 1)
|
assert(I == 1);
|
||||||
unreachable();
|
|
||||||
|
|
||||||
let f: f32;
|
let f: f32;
|
||||||
|
|
||||||
f = 1.0 && 2.0;
|
f = 1.0 && 2.0;
|
||||||
if (f != 2.0)
|
assert(f == 2.0);
|
||||||
unreachable();
|
|
||||||
|
|
||||||
f = 0.0 || 1.0;
|
f = 0.0 || 1.0;
|
||||||
if (f != 1.0)
|
assert(f == 1.0);
|
||||||
unreachable();
|
|
||||||
|
|
||||||
let F: f64;
|
let F: f64;
|
||||||
|
|
||||||
F = 1.0 && 2.0;
|
F = 1.0 && 2.0;
|
||||||
if (F != 2.0)
|
assert(F == 2.0);
|
||||||
unreachable();
|
|
||||||
|
|
||||||
F = 0.0 || 1.0;
|
F = 0.0 || 1.0;
|
||||||
if (F != 1.0)
|
assert(F == 1.0);
|
||||||
unreachable();
|
|
||||||
|
@ -113,10 +113,12 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(if
|
(if
|
||||||
(i32.ne
|
(i32.eqz
|
||||||
|
(i32.eq
|
||||||
(get_global $logical/i)
|
(get_global $logical/i)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
(set_global $logical/i
|
(set_global $logical/i
|
||||||
@ -129,10 +131,12 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(if
|
(if
|
||||||
(i32.ne
|
(i32.eqz
|
||||||
|
(i32.eq
|
||||||
(get_global $logical/i)
|
(get_global $logical/i)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
(set_global $logical/I
|
(set_global $logical/I
|
||||||
@ -148,10 +152,12 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(if
|
(if
|
||||||
(i64.ne
|
(i32.eqz
|
||||||
|
(i64.eq
|
||||||
(get_global $logical/I)
|
(get_global $logical/I)
|
||||||
(i64.const 2)
|
(i64.const 2)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
(set_global $logical/I
|
(set_global $logical/I
|
||||||
@ -167,10 +173,12 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(if
|
(if
|
||||||
(i64.ne
|
(i32.eqz
|
||||||
|
(i64.eq
|
||||||
(get_global $logical/I)
|
(get_global $logical/I)
|
||||||
(i64.const 1)
|
(i64.const 1)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
(set_global $logical/f
|
(set_global $logical/f
|
||||||
@ -186,10 +194,12 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(if
|
(if
|
||||||
(f32.ne
|
(i32.eqz
|
||||||
|
(f32.eq
|
||||||
(get_global $logical/f)
|
(get_global $logical/f)
|
||||||
(f32.const 2)
|
(f32.const 2)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
(set_global $logical/f
|
(set_global $logical/f
|
||||||
@ -205,10 +215,12 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(if
|
(if
|
||||||
(f32.ne
|
(i32.eqz
|
||||||
|
(f32.eq
|
||||||
(get_global $logical/f)
|
(get_global $logical/f)
|
||||||
(f32.const 1)
|
(f32.const 1)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
(set_global $logical/F
|
(set_global $logical/F
|
||||||
@ -224,10 +236,12 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(if
|
(if
|
||||||
(f64.ne
|
(i32.eqz
|
||||||
|
(f64.eq
|
||||||
(get_global $logical/F)
|
(get_global $logical/F)
|
||||||
(f64.const 2)
|
(f64.const 2)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
(set_global $logical/F
|
(set_global $logical/F
|
||||||
@ -243,10 +257,12 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(if
|
(if
|
||||||
(f64.ne
|
(i32.eqz
|
||||||
|
(f64.eq
|
||||||
(get_global $logical/F)
|
(get_global $logical/F)
|
||||||
(f64.const 1)
|
(f64.const 1)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -7,37 +7,16 @@
|
|||||||
(export "doSwitchDefaultOmitted" (func $switch/doSwitchDefaultOmitted))
|
(export "doSwitchDefaultOmitted" (func $switch/doSwitchDefaultOmitted))
|
||||||
(export "memory" (memory $0))
|
(export "memory" (memory $0))
|
||||||
(func $switch/doSwitch (; 0 ;) (type $ii) (param $0 i32) (result i32)
|
(func $switch/doSwitch (; 0 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
(local $1 i32)
|
|
||||||
(block $case4$1.1
|
(block $case4$1.1
|
||||||
(block $case2$1.1
|
(block $case2$1.1
|
||||||
(if
|
(block $case0$1.1
|
||||||
(i32.ne
|
(block $tablify|0
|
||||||
(tee_local $1
|
(br_table $case2$1.1 $case0$1.1 $case4$1.1 $case4$1.1 $tablify|0
|
||||||
(get_local $0)
|
(get_local $0)
|
||||||
)
|
)
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(br_if $case2$1.1
|
|
||||||
(i32.eqz
|
|
||||||
(get_local $1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(br_if $case4$1.1
|
|
||||||
(i32.eq
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(br_if $case4$1.1
|
|
||||||
(i32.eq
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 3)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
(br $case2$1.1)
|
(br $case2$1.1)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
(return
|
(return
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
@ -49,33 +28,20 @@
|
|||||||
(i32.const 23)
|
(i32.const 23)
|
||||||
)
|
)
|
||||||
(func $switch/doSwitchDefaultFirst (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
(func $switch/doSwitchDefaultFirst (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
(local $1 i32)
|
|
||||||
(block $case3$1.1
|
(block $case3$1.1
|
||||||
(if
|
(block $case1$1.1
|
||||||
(i32.ne
|
(block $tablify|0
|
||||||
(tee_local $1
|
(br_table $case1$1.1 $case3$1.1 $case3$1.1 $tablify|0
|
||||||
|
(i32.sub
|
||||||
(get_local $0)
|
(get_local $0)
|
||||||
)
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
(block
|
|
||||||
(br_if $case3$1.1
|
|
||||||
(i32.eq
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(br_if $case3$1.1
|
|
||||||
(i32.eq
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 3)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(return
|
(return
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
(return
|
(return
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
@ -83,32 +49,19 @@
|
|||||||
(i32.const 23)
|
(i32.const 23)
|
||||||
)
|
)
|
||||||
(func $switch/doSwitchDefaultOmitted (; 2 ;) (type $ii) (param $0 i32) (result i32)
|
(func $switch/doSwitchDefaultOmitted (; 2 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
(local $1 i32)
|
|
||||||
(block $break$1.1
|
(block $break$1.1
|
||||||
(block $case2$1.1
|
(block $case2$1.1
|
||||||
(if
|
(block $case0$1.1
|
||||||
(i32.ne
|
(block $tablify|0
|
||||||
(tee_local $1
|
(br_table $case0$1.1 $case2$1.1 $case2$1.1 $tablify|0
|
||||||
|
(i32.sub
|
||||||
(get_local $0)
|
(get_local $0)
|
||||||
)
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
(block
|
|
||||||
(br_if $case2$1.1
|
|
||||||
(i32.eq
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(br_if $case2$1.1
|
|
||||||
(i32.eq
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 3)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(br $break$1.1)
|
(br $break$1.1)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
(return
|
(return
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user