mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 07:02:13 +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
|
||||
|
||||
/** A decorator marking a function or class as global. */
|
||||
declare function global(name?: string): any;
|
||||
/** A decorator marking a function as ideally being inlined. */
|
||||
declare function struct(): any
|
||||
declare function inline(): any;
|
||||
/** A decorator marking a class that manually manages its memory. */
|
||||
declare function allocates(): 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,
|
||||
arg2: ExpressionRef;
|
||||
|
||||
let tempLocal: Local;
|
||||
let tempLocal0: Local;
|
||||
let tempLocal1: Local;
|
||||
let nativeType: NativeType;
|
||||
|
||||
switch (internalName) {
|
||||
|
||||
@ -149,7 +151,34 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
||||
? compiler.module.createUnary(UnaryOp.AbsF32, arg0)
|
||||
: compiler.module.createUnary(UnaryOp.AbsF64, arg0);
|
||||
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;
|
||||
@ -165,7 +194,26 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
||||
? compiler.module.createBinary(BinaryOp.MaxF32, arg0, arg1)
|
||||
: compiler.module.createBinary(BinaryOp.MaxF64, arg0, arg1);
|
||||
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;
|
||||
@ -181,7 +229,26 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
||||
? compiler.module.createBinary(BinaryOp.MinF32, arg0, arg1)
|
||||
: compiler.module.createBinary(BinaryOp.MinF64, arg0, arg1);
|
||||
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;
|
||||
@ -220,7 +287,7 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
||||
}
|
||||
break;
|
||||
|
||||
case "nearest":
|
||||
case "nearest": // nearest<T>(value: T) -> T
|
||||
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
||||
return compiler.module.createUnreachable();
|
||||
if ((compiler.currentType = typeArguments[0]).isAnyFloat) {
|
||||
@ -231,7 +298,7 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
||||
}
|
||||
break;
|
||||
|
||||
case "sqrt":
|
||||
case "sqrt": // sqrt<T>(value: T) -> T
|
||||
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
||||
return compiler.module.createUnreachable();
|
||||
if ((compiler.currentType = typeArguments[0]).isAnyFloat) {
|
||||
@ -242,7 +309,7 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
||||
}
|
||||
break;
|
||||
|
||||
case "trunc":
|
||||
case "trunc": // trunc<T>(value: T) -> T
|
||||
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
||||
return compiler.module.createUnreachable();
|
||||
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);
|
||||
return compiler.module.createUnreachable();
|
||||
|
||||
case "isNaN":
|
||||
case "isNaN": // isNaN<T>(value: T) -> bool
|
||||
compiler.currentType = Type.bool;
|
||||
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
||||
return compiler.module.createUnreachable();
|
||||
@ -346,22 +413,22 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
||||
arg0 = compiler.compileExpression(operands[0], typeArguments[0]); // reports
|
||||
compiler.currentType = Type.bool;
|
||||
if (typeArguments[0] == Type.f32) {
|
||||
tempLocal = compiler.currentFunction.addLocal(Type.f32);
|
||||
tempLocal0 = compiler.currentFunction.addLocal(Type.f32);
|
||||
return compiler.module.createBinary(BinaryOp.NeF32,
|
||||
compiler.module.createTeeLocal(tempLocal.index, arg0),
|
||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F32)
|
||||
compiler.module.createTeeLocal(tempLocal0.index, arg0),
|
||||
compiler.module.createGetLocal(tempLocal0.index, NativeType.F32)
|
||||
);
|
||||
} else {
|
||||
tempLocal = compiler.currentFunction.addLocal(Type.f64);
|
||||
tempLocal0 = compiler.currentFunction.addLocal(Type.f64);
|
||||
return compiler.module.createBinary(BinaryOp.NeF64,
|
||||
compiler.module.createTeeLocal(tempLocal.index, arg0),
|
||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F64)
|
||||
compiler.module.createTeeLocal(tempLocal0.index, arg0),
|
||||
compiler.module.createGetLocal(tempLocal0.index, NativeType.F64)
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "isFinite":
|
||||
case "isFinite": // isFinite<T>(value: T) -> bool
|
||||
compiler.currentType = Type.bool;
|
||||
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
||||
return compiler.module.createUnreachable();
|
||||
@ -371,40 +438,40 @@ export function compileCall(compiler: Compiler, internalName: string, typeArgume
|
||||
arg0 = compiler.compileExpression(operands[0], typeArguments[0]); // reports
|
||||
compiler.currentType = Type.bool;
|
||||
if (typeArguments[0] == Type.f32) {
|
||||
tempLocal = compiler.currentFunction.addLocal(Type.f32);
|
||||
tempLocal0 = compiler.currentFunction.addLocal(Type.f32);
|
||||
return compiler.module.createSelect(
|
||||
compiler.module.createBinary(BinaryOp.NeF32,
|
||||
compiler.module.createUnary(UnaryOp.AbsF32,
|
||||
compiler.module.createTeeLocal(tempLocal.index, arg0)
|
||||
compiler.module.createTeeLocal(tempLocal0.index, arg0)
|
||||
),
|
||||
compiler.module.createF32(Infinity)
|
||||
),
|
||||
compiler.module.createI32(0),
|
||||
compiler.module.createBinary(BinaryOp.EqF32,
|
||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F32),
|
||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F32)
|
||||
compiler.module.createGetLocal(tempLocal0.index, NativeType.F32),
|
||||
compiler.module.createGetLocal(tempLocal0.index, NativeType.F32)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
tempLocal = compiler.currentFunction.addLocal(Type.f64);
|
||||
tempLocal0 = compiler.currentFunction.addLocal(Type.f64);
|
||||
return compiler.module.createSelect(
|
||||
compiler.module.createBinary(BinaryOp.NeF64,
|
||||
compiler.module.createUnary(UnaryOp.AbsF64,
|
||||
compiler.module.createTeeLocal(tempLocal.index, arg0)
|
||||
compiler.module.createTeeLocal(tempLocal0.index, arg0)
|
||||
),
|
||||
compiler.module.createF64(Infinity)
|
||||
),
|
||||
compiler.module.createI32(0),
|
||||
compiler.module.createBinary(BinaryOp.EqF64,
|
||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F64),
|
||||
compiler.module.createGetLocal(tempLocal.index, NativeType.F64)
|
||||
compiler.module.createGetLocal(tempLocal0.index, NativeType.F64),
|
||||
compiler.module.createGetLocal(tempLocal0.index, NativeType.F64)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "assert":
|
||||
case "assert": // assert(isTrue: bool) -> void
|
||||
compiler.currentType = Type.void;
|
||||
if (!validateCall(compiler, typeArguments, 0, operands, 1, reportNode))
|
||||
return compiler.module.createUnreachable();
|
||||
|
@ -122,6 +122,8 @@ export class Compiler extends DiagnosticEmitter {
|
||||
currentFunction: Function;
|
||||
/** Marker indicating whether continue statements are allowed in the current break context. */
|
||||
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. */
|
||||
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 {
|
||||
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();
|
||||
this.variableIsLocal = variableWasLocal;
|
||||
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 body: ExpressionRef = this.compileStatement(statement.statement);
|
||||
@ -860,7 +866,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
const declarations: VariableDeclaration[] = statement.declarations;
|
||||
|
||||
// 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);
|
||||
for (let i: i32 = 0, k: i32 = declarations.length; i < k; ++i)
|
||||
this.compileGlobalDeclaration(declarations[i], isConst);
|
||||
|
@ -981,9 +981,9 @@ export class Function extends Element {
|
||||
|
||||
/** Leaves the current break context. */
|
||||
leaveBreakContext(): void {
|
||||
if (--this.breakMinor < 0)
|
||||
if (this.breakMinor < 1)
|
||||
throw new Error("unexpected unbalanced break context");
|
||||
if (this.breakMinor == 0 && !--this.breakMajor)
|
||||
if (--this.breakMinor == 0)
|
||||
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)
|
||||
(local $0 f32)
|
||||
(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
|
||||
(i32.const 31)
|
||||
)
|
||||
@ -28,6 +60,70 @@
|
||||
(set_global $builtins/i
|
||||
(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
|
||||
(i64.const 63)
|
||||
)
|
||||
@ -43,6 +139,70 @@
|
||||
(set_global $builtins/I
|
||||
(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
|
||||
(f32.const nan:0x400000)
|
||||
)
|
||||
@ -168,6 +328,12 @@
|
||||
(i32.const 8)
|
||||
(get_global $builtins/i)
|
||||
)
|
||||
(i32.store
|
||||
(i32.const 8)
|
||||
(i32.load
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.load
|
||||
(i32.const 8)
|
||||
@ -177,6 +343,12 @@
|
||||
(i32.const 8)
|
||||
(get_global $builtins/I)
|
||||
)
|
||||
(i64.store
|
||||
(i32.const 8)
|
||||
(i64.load
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/f
|
||||
(f32.load
|
||||
(i32.const 8)
|
||||
@ -186,6 +358,12 @@
|
||||
(i32.const 8)
|
||||
(get_global $builtins/f)
|
||||
)
|
||||
(f32.store
|
||||
(i32.const 8)
|
||||
(f32.load
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/F
|
||||
(f64.load
|
||||
(i32.const 8)
|
||||
@ -195,6 +373,12 @@
|
||||
(i32.const 8)
|
||||
(get_global $builtins/F)
|
||||
)
|
||||
(f64.store
|
||||
(i32.const 8)
|
||||
(f64.load
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(i32.const 1067450368)
|
||||
)
|
||||
@ -244,6 +428,15 @@
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(if
|
||||
(f64.eq
|
||||
(tee_local $1
|
||||
(f64.const nan:0x8000000000000)
|
||||
)
|
||||
(get_local $1)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(if
|
||||
(select
|
||||
(f32.ne
|
||||
@ -280,6 +473,62 @@
|
||||
)
|
||||
(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
|
||||
(i32.eqz
|
||||
(select
|
||||
|
@ -9,12 +9,18 @@ ctz<i32>(1);
|
||||
popcnt<i32>(1);
|
||||
rotl<i32>(1, 1);
|
||||
rotr<i32>(1, 1);
|
||||
abs<i32>(-42);
|
||||
max<i32>(1, 2);
|
||||
min<i32>(1, 2);
|
||||
|
||||
i = clz<i32>(1);
|
||||
i = ctz<i32>(1);
|
||||
i = popcnt<i32>(1);
|
||||
i = rotl<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;
|
||||
|
||||
@ -23,12 +29,16 @@ ctz<i64>(1);
|
||||
popcnt<i64>(1);
|
||||
rotl<i64>(1, 1);
|
||||
rotr<i64>(1, 1);
|
||||
abs<i64>(-42);
|
||||
|
||||
I = clz<i64>(1);
|
||||
I = ctz<i64>(1);
|
||||
I = popcnt<i64>(1);
|
||||
I = rotl<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
|
||||
|
||||
@ -96,14 +106,14 @@ b = isFinite<f64>(1.25);
|
||||
|
||||
// load and store builtins
|
||||
|
||||
i = load<i32>(8);
|
||||
store<i32>(8, i);
|
||||
I = load<i64>(8);
|
||||
store<i64>(8, I);
|
||||
f = load<f32>(8);
|
||||
store<f32>(8, f);
|
||||
F = load<f64>(8);
|
||||
store<f64>(8, F);
|
||||
i = load<i32>(8); store<i32>(8, i);
|
||||
store<i32>(8, load<i32>(8));
|
||||
I = load<i64>(8); store<i64>(8, I);
|
||||
store<i64>(8, load<i64>(8));
|
||||
f = load<f32>(8); store<f32>(8, f);
|
||||
store<f32>(8, load<f32>(8));
|
||||
F = load<f64>(8); store<f64>(8, F);
|
||||
store<f64>(8, load<f64>(8));
|
||||
|
||||
// reinterpretation builtins
|
||||
|
||||
@ -143,8 +153,6 @@ if (0) unreachable();
|
||||
|
||||
// AS specific builtins
|
||||
|
||||
assert(true);
|
||||
|
||||
sizeof<u8>();
|
||||
sizeof<u16>();
|
||||
sizeof<u32>();
|
||||
@ -159,13 +167,12 @@ sizeof<isize>();
|
||||
sizeof<f32>();
|
||||
sizeof<f64>();
|
||||
|
||||
if (NaN == NaN)
|
||||
unreachable();
|
||||
if (!isNaN<f32>(NaN))
|
||||
unreachable();
|
||||
if (isFinite<f32>(NaN))
|
||||
unreachable();
|
||||
if (isFinite<f32>(Infinity))
|
||||
unreachable();
|
||||
if (!isFinite<f64>(0))
|
||||
unreachable();
|
||||
assert(NaN != NaN);
|
||||
assert(isNaN<f32>(NaN));
|
||||
assert(isNaN<f64>(NaN));
|
||||
assert(!isFinite<f32>(NaN));
|
||||
assert(!isFinite<f32>(Infinity));
|
||||
assert(!isFinite<f64>(NaN));
|
||||
assert(!isFinite<f64>(Infinity));
|
||||
assert(isFinite<f32>(0));
|
||||
assert(isFinite<f64>(0));
|
||||
|
@ -11,18 +11,38 @@
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $start (; 0 ;) (type $v)
|
||||
(local $0 f32)
|
||||
(local $1 f32)
|
||||
(local $2 f32)
|
||||
(local $3 f32)
|
||||
(local $4 f64)
|
||||
(local $5 f64)
|
||||
(local $6 f64)
|
||||
(local $7 f64)
|
||||
(local $8 f32)
|
||||
(local $9 f32)
|
||||
(local $10 f32)
|
||||
(local $11 f64)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
(local $7 i32)
|
||||
(local $8 i32)
|
||||
(local $9 i32)
|
||||
(local $10 i64)
|
||||
(local $11 i64)
|
||||
(local $12 i64)
|
||||
(local $13 i64)
|
||||
(local $14 i64)
|
||||
(local $15 i64)
|
||||
(local $16 f32)
|
||||
(local $17 f32)
|
||||
(local $18 f32)
|
||||
(local $19 f32)
|
||||
(local $20 f64)
|
||||
(local $21 f64)
|
||||
(local $22 f64)
|
||||
(local $23 f64)
|
||||
(local $24 f32)
|
||||
(local $25 f64)
|
||||
(local $26 f32)
|
||||
(local $27 f32)
|
||||
(local $28 f64)
|
||||
(local $29 f64)
|
||||
(local $30 f32)
|
||||
(local $31 f64)
|
||||
(drop
|
||||
(i32.clz
|
||||
(i32.const 1)
|
||||
@ -50,154 +70,364 @@
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(i32.clz
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(i32.ctz
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(i32.popcnt
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(i32.rotl
|
||||
(i32.const 1)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(i32.rotr
|
||||
(i32.const 1)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(i64.clz
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(i64.ctz
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(i64.popcnt
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(i64.rotl
|
||||
(i64.const 1)
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(i64.rotr
|
||||
(i64.const 1)
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.clz
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.ctz
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.popcnt
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.rotl
|
||||
(i64.const 1)
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.rotr
|
||||
(i64.const 1)
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.const nan:0x400000)
|
||||
)
|
||||
(drop
|
||||
(f32.const inf)
|
||||
)
|
||||
(drop
|
||||
(f32.abs
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.ceil
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.copysign
|
||||
(f32.const 1.25)
|
||||
(f32.const 2.5)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.floor
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.max
|
||||
(f32.const 1.25)
|
||||
(f32.const 2.5)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.min
|
||||
(f32.const 1.25)
|
||||
(f32.const 2.5)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.nearest
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.sqrt
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.trunc
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.ne
|
||||
(tee_local $0
|
||||
(f32.const 1.25)
|
||||
(select
|
||||
(i32.sub
|
||||
(i32.const 0)
|
||||
(tee_local $0
|
||||
(i32.sub
|
||||
(i32.const 0)
|
||||
(i32.const 42)
|
||||
)
|
||||
)
|
||||
)
|
||||
(get_local $0)
|
||||
(i32.lt_s
|
||||
(get_local $0)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(select
|
||||
(tee_local $1
|
||||
(i32.const 1)
|
||||
)
|
||||
(tee_local $2
|
||||
(i32.const 2)
|
||||
)
|
||||
(i32.gt_s
|
||||
(get_local $1)
|
||||
(get_local $2)
|
||||
)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(select
|
||||
(tee_local $3
|
||||
(i32.const 1)
|
||||
)
|
||||
(tee_local $4
|
||||
(i32.const 2)
|
||||
)
|
||||
(i32.lt_s
|
||||
(get_local $3)
|
||||
(get_local $4)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(i32.clz
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(i32.ctz
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(i32.popcnt
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(i32.rotl
|
||||
(i32.const 1)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(i32.rotr
|
||||
(i32.const 1)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(select
|
||||
(i32.sub
|
||||
(i32.const 0)
|
||||
(tee_local $5
|
||||
(i32.sub
|
||||
(i32.const 0)
|
||||
(i32.const 42)
|
||||
)
|
||||
)
|
||||
)
|
||||
(get_local $5)
|
||||
(i32.lt_s
|
||||
(get_local $5)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.eq
|
||||
(get_global $builtins/i)
|
||||
(i32.const 42)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(select
|
||||
(tee_local $6
|
||||
(i32.const 1)
|
||||
)
|
||||
(tee_local $7
|
||||
(i32.const 2)
|
||||
)
|
||||
(i32.gt_s
|
||||
(get_local $6)
|
||||
(get_local $7)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.eq
|
||||
(get_global $builtins/i)
|
||||
(i32.const 2)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(set_global $builtins/i
|
||||
(select
|
||||
(tee_local $8
|
||||
(i32.const 1)
|
||||
)
|
||||
(tee_local $9
|
||||
(i32.const 2)
|
||||
)
|
||||
(i32.lt_s
|
||||
(get_local $8)
|
||||
(get_local $9)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.eq
|
||||
(get_global $builtins/i)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(drop
|
||||
(i64.clz
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(i64.ctz
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(i64.popcnt
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(i64.rotl
|
||||
(i64.const 1)
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(i64.rotr
|
||||
(i64.const 1)
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(select
|
||||
(i64.sub
|
||||
(i64.const 0)
|
||||
(tee_local $10
|
||||
(i64.sub
|
||||
(i64.const 0)
|
||||
(i64.const 42)
|
||||
)
|
||||
)
|
||||
)
|
||||
(get_local $10)
|
||||
(i64.lt_s
|
||||
(get_local $10)
|
||||
(i64.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.clz
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.ctz
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.popcnt
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.rotl
|
||||
(i64.const 1)
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.rotr
|
||||
(i64.const 1)
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(select
|
||||
(i64.sub
|
||||
(i64.const 0)
|
||||
(tee_local $11
|
||||
(i64.sub
|
||||
(i64.const 0)
|
||||
(i64.const 42)
|
||||
)
|
||||
)
|
||||
)
|
||||
(get_local $11)
|
||||
(i64.lt_s
|
||||
(get_local $11)
|
||||
(i64.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i64.eq
|
||||
(get_global $builtins/I)
|
||||
(i64.const 42)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(select
|
||||
(tee_local $12
|
||||
(i64.const 1)
|
||||
)
|
||||
(tee_local $13
|
||||
(i64.const 2)
|
||||
)
|
||||
(i64.gt_s
|
||||
(get_local $12)
|
||||
(get_local $13)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i64.eq
|
||||
(get_global $builtins/I)
|
||||
(i64.const 2)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(select
|
||||
(tee_local $14
|
||||
(i64.const 1)
|
||||
)
|
||||
(tee_local $15
|
||||
(i64.const 2)
|
||||
)
|
||||
(i64.lt_s
|
||||
(get_local $14)
|
||||
(get_local $15)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.eq
|
||||
(get_global $builtins/i)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(drop
|
||||
(f32.const nan:0x400000)
|
||||
)
|
||||
(drop
|
||||
(f32.const inf)
|
||||
)
|
||||
(drop
|
||||
(f32.abs
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.ceil
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.copysign
|
||||
(f32.const 1.25)
|
||||
(f32.const 2.5)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.floor
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.max
|
||||
(f32.const 1.25)
|
||||
(f32.const 2.5)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.min
|
||||
(f32.const 1.25)
|
||||
(f32.const 2.5)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.nearest
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.sqrt
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.trunc
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(f32.ne
|
||||
(tee_local $16
|
||||
(f32.const 1.25)
|
||||
)
|
||||
(get_local $16)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(select
|
||||
(f32.ne
|
||||
(f32.abs
|
||||
(tee_local $1
|
||||
(tee_local $17
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
@ -205,8 +435,8 @@
|
||||
)
|
||||
(i32.const 0)
|
||||
(f32.eq
|
||||
(get_local $1)
|
||||
(get_local $1)
|
||||
(get_local $17)
|
||||
(get_local $17)
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -266,17 +496,17 @@
|
||||
)
|
||||
(set_global $builtins/b
|
||||
(f32.ne
|
||||
(tee_local $2
|
||||
(tee_local $18
|
||||
(f32.const 1.25)
|
||||
)
|
||||
(get_local $2)
|
||||
(get_local $18)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/b
|
||||
(select
|
||||
(f32.ne
|
||||
(f32.abs
|
||||
(tee_local $3
|
||||
(tee_local $19
|
||||
(f32.const 1.25)
|
||||
)
|
||||
)
|
||||
@ -284,8 +514,8 @@
|
||||
)
|
||||
(i32.const 0)
|
||||
(f32.eq
|
||||
(get_local $3)
|
||||
(get_local $3)
|
||||
(get_local $19)
|
||||
(get_local $19)
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -351,17 +581,17 @@
|
||||
)
|
||||
(drop
|
||||
(f64.ne
|
||||
(tee_local $4
|
||||
(tee_local $20
|
||||
(f64.const 1.25)
|
||||
)
|
||||
(get_local $4)
|
||||
(get_local $20)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(select
|
||||
(f64.ne
|
||||
(f64.abs
|
||||
(tee_local $5
|
||||
(tee_local $21
|
||||
(f64.const 1.25)
|
||||
)
|
||||
)
|
||||
@ -369,8 +599,8 @@
|
||||
)
|
||||
(i32.const 0)
|
||||
(f64.eq
|
||||
(get_local $5)
|
||||
(get_local $5)
|
||||
(get_local $21)
|
||||
(get_local $21)
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -430,17 +660,17 @@
|
||||
)
|
||||
(set_global $builtins/b
|
||||
(f64.ne
|
||||
(tee_local $6
|
||||
(tee_local $22
|
||||
(f64.const 1.25)
|
||||
)
|
||||
(get_local $6)
|
||||
(get_local $22)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/b
|
||||
(select
|
||||
(f64.ne
|
||||
(f64.abs
|
||||
(tee_local $7
|
||||
(tee_local $23
|
||||
(f64.const 1.25)
|
||||
)
|
||||
)
|
||||
@ -448,8 +678,8 @@
|
||||
)
|
||||
(i32.const 0)
|
||||
(f64.eq
|
||||
(get_local $7)
|
||||
(get_local $7)
|
||||
(get_local $23)
|
||||
(get_local $23)
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -462,6 +692,12 @@
|
||||
(i32.const 8)
|
||||
(get_global $builtins/i)
|
||||
)
|
||||
(i32.store
|
||||
(i32.const 8)
|
||||
(i32.load
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/I
|
||||
(i64.load
|
||||
(i32.const 8)
|
||||
@ -471,6 +707,12 @@
|
||||
(i32.const 8)
|
||||
(get_global $builtins/I)
|
||||
)
|
||||
(i64.store
|
||||
(i32.const 8)
|
||||
(i64.load
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/f
|
||||
(f32.load
|
||||
(i32.const 8)
|
||||
@ -480,6 +722,12 @@
|
||||
(i32.const 8)
|
||||
(get_global $builtins/f)
|
||||
)
|
||||
(f32.store
|
||||
(i32.const 8)
|
||||
(f32.load
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
(set_global $builtins/F
|
||||
(f64.load
|
||||
(i32.const 8)
|
||||
@ -489,6 +737,12 @@
|
||||
(i32.const 8)
|
||||
(get_global $builtins/F)
|
||||
)
|
||||
(f64.store
|
||||
(i32.const 8)
|
||||
(f64.load
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
(drop
|
||||
(i32.reinterpret/f32
|
||||
(f32.const 1.25)
|
||||
@ -605,101 +859,180 @@
|
||||
(i32.const 0)
|
||||
(unreachable)
|
||||
)
|
||||
(drop
|
||||
(i32.const 1)
|
||||
)
|
||||
(drop
|
||||
(i32.const 2)
|
||||
)
|
||||
(drop
|
||||
(i32.const 4)
|
||||
)
|
||||
(drop
|
||||
(i32.const 8)
|
||||
)
|
||||
(drop
|
||||
(i32.const 4)
|
||||
)
|
||||
(drop
|
||||
(i32.const 1)
|
||||
)
|
||||
(drop
|
||||
(i32.const 1)
|
||||
)
|
||||
(drop
|
||||
(i32.const 2)
|
||||
)
|
||||
(drop
|
||||
(i32.const 4)
|
||||
)
|
||||
(drop
|
||||
(i32.const 8)
|
||||
)
|
||||
(drop
|
||||
(i32.const 4)
|
||||
)
|
||||
(drop
|
||||
(i32.const 4)
|
||||
)
|
||||
(drop
|
||||
(i32.const 8)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.const 1)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(drop
|
||||
(i32.const 1)
|
||||
)
|
||||
(drop
|
||||
(i32.const 2)
|
||||
)
|
||||
(drop
|
||||
(i32.const 4)
|
||||
)
|
||||
(drop
|
||||
(i32.const 8)
|
||||
)
|
||||
(drop
|
||||
(i32.const 4)
|
||||
)
|
||||
(drop
|
||||
(i32.const 1)
|
||||
)
|
||||
(drop
|
||||
(i32.const 1)
|
||||
)
|
||||
(drop
|
||||
(i32.const 2)
|
||||
)
|
||||
(drop
|
||||
(i32.const 4)
|
||||
)
|
||||
(drop
|
||||
(i32.const 8)
|
||||
)
|
||||
(drop
|
||||
(i32.const 4)
|
||||
)
|
||||
(drop
|
||||
(i32.const 4)
|
||||
)
|
||||
(drop
|
||||
(i32.const 8)
|
||||
)
|
||||
(if
|
||||
(f64.eq
|
||||
(f64.const nan:0x8000000000000)
|
||||
(f64.const nan:0x8000000000000)
|
||||
(f64.ne
|
||||
(f64.const nan:0x8000000000000)
|
||||
(f64.const nan:0x8000000000000)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(f32.ne
|
||||
(tee_local $8
|
||||
(tee_local $24
|
||||
(f32.const nan:0x400000)
|
||||
)
|
||||
(get_local $8)
|
||||
(get_local $24)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(if
|
||||
(select
|
||||
(f32.ne
|
||||
(f32.abs
|
||||
(tee_local $9
|
||||
(f32.const nan:0x400000)
|
||||
)
|
||||
(i32.eqz
|
||||
(f64.ne
|
||||
(tee_local $25
|
||||
(f64.const nan:0x8000000000000)
|
||||
)
|
||||
(f32.const inf)
|
||||
)
|
||||
(i32.const 0)
|
||||
(f32.eq
|
||||
(get_local $9)
|
||||
(get_local $9)
|
||||
(get_local $25)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(if
|
||||
(select
|
||||
(f32.ne
|
||||
(f32.abs
|
||||
(tee_local $10
|
||||
(i32.eqz
|
||||
(i32.eqz
|
||||
(select
|
||||
(f32.ne
|
||||
(f32.abs
|
||||
(tee_local $26
|
||||
(f32.const nan:0x400000)
|
||||
)
|
||||
)
|
||||
(f32.const inf)
|
||||
)
|
||||
(i32.const 0)
|
||||
(f32.eq
|
||||
(get_local $26)
|
||||
(get_local $26)
|
||||
)
|
||||
)
|
||||
(f32.const inf)
|
||||
)
|
||||
(i32.const 0)
|
||||
(f32.eq
|
||||
(get_local $10)
|
||||
(get_local $10)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.eqz
|
||||
(select
|
||||
(f32.ne
|
||||
(f32.abs
|
||||
(tee_local $27
|
||||
(f32.const inf)
|
||||
)
|
||||
)
|
||||
(f32.const inf)
|
||||
)
|
||||
(i32.const 0)
|
||||
(f32.eq
|
||||
(get_local $27)
|
||||
(get_local $27)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.eqz
|
||||
(select
|
||||
(f64.ne
|
||||
(f64.abs
|
||||
(tee_local $28
|
||||
(f64.const nan:0x8000000000000)
|
||||
)
|
||||
)
|
||||
(f64.const inf)
|
||||
)
|
||||
(i32.const 0)
|
||||
(f64.eq
|
||||
(get_local $28)
|
||||
(get_local $28)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.eqz
|
||||
(select
|
||||
(f64.ne
|
||||
(f64.abs
|
||||
(tee_local $29
|
||||
(f64.const inf)
|
||||
)
|
||||
)
|
||||
(f64.const inf)
|
||||
)
|
||||
(i32.const 0)
|
||||
(f64.eq
|
||||
(get_local $29)
|
||||
(get_local $29)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(select
|
||||
(f32.ne
|
||||
(f32.abs
|
||||
(tee_local $30
|
||||
(f32.const 0)
|
||||
)
|
||||
)
|
||||
(f32.const inf)
|
||||
)
|
||||
(i32.const 0)
|
||||
(f32.eq
|
||||
(get_local $30)
|
||||
(get_local $30)
|
||||
)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
@ -709,7 +1042,7 @@
|
||||
(select
|
||||
(f64.ne
|
||||
(f64.abs
|
||||
(tee_local $11
|
||||
(tee_local $31
|
||||
(f64.const 0)
|
||||
)
|
||||
)
|
||||
@ -717,8 +1050,8 @@
|
||||
)
|
||||
(i32.const 0)
|
||||
(f64.eq
|
||||
(get_local $11)
|
||||
(get_local $11)
|
||||
(get_local $31)
|
||||
(get_local $31)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -6,6 +6,7 @@
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $start (; 0 ;) (type $v)
|
||||
(local $0 i32)
|
||||
(set_global $for/i
|
||||
(i32.const 0)
|
||||
)
|
||||
@ -33,5 +34,74 @@
|
||||
)
|
||||
(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) {
|
||||
;
|
||||
}
|
||||
if (i != 10)
|
||||
unreachable();
|
||||
assert(i == 10);
|
||||
|
||||
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))
|
||||
(start $start)
|
||||
(func $start (; 0 ;) (type $v)
|
||||
(local $0 i32)
|
||||
(block $break$1.1
|
||||
(set_global $for/i
|
||||
(i32.const 0)
|
||||
@ -30,12 +31,120 @@
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.ne
|
||||
(get_global $for/i)
|
||||
(i32.const 10)
|
||||
(i32.eqz
|
||||
(i32.eq
|
||||
(get_global $for/i)
|
||||
(i32.const 10)
|
||||
)
|
||||
)
|
||||
(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;
|
||||
|
||||
i = 1 && 2;
|
||||
if (i != 2)
|
||||
unreachable();
|
||||
assert(i == 2);
|
||||
|
||||
i = 0 || 1;
|
||||
if (i != 1)
|
||||
unreachable();
|
||||
assert(i == 1);
|
||||
|
||||
let I: i64;
|
||||
|
||||
I = 1 && 2;
|
||||
if (I != 2)
|
||||
unreachable();
|
||||
assert(I == 2);
|
||||
|
||||
I = 0 || 1;
|
||||
if (I != 1)
|
||||
unreachable();
|
||||
assert(I == 1);
|
||||
|
||||
let f: f32;
|
||||
|
||||
f = 1.0 && 2.0;
|
||||
if (f != 2.0)
|
||||
unreachable();
|
||||
assert(f == 2.0);
|
||||
|
||||
f = 0.0 || 1.0;
|
||||
if (f != 1.0)
|
||||
unreachable();
|
||||
assert(f == 1.0);
|
||||
|
||||
let F: f64;
|
||||
|
||||
F = 1.0 && 2.0;
|
||||
if (F != 2.0)
|
||||
unreachable();
|
||||
assert(F == 2.0);
|
||||
|
||||
F = 0.0 || 1.0;
|
||||
if (F != 1.0)
|
||||
unreachable();
|
||||
assert(F == 1.0);
|
||||
|
@ -113,9 +113,11 @@
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.ne
|
||||
(get_global $logical/i)
|
||||
(i32.const 2)
|
||||
(i32.eqz
|
||||
(i32.eq
|
||||
(get_global $logical/i)
|
||||
(i32.const 2)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
@ -129,9 +131,11 @@
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.ne
|
||||
(get_global $logical/i)
|
||||
(i32.const 1)
|
||||
(i32.eqz
|
||||
(i32.eq
|
||||
(get_global $logical/i)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
@ -148,9 +152,11 @@
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i64.ne
|
||||
(get_global $logical/I)
|
||||
(i64.const 2)
|
||||
(i32.eqz
|
||||
(i64.eq
|
||||
(get_global $logical/I)
|
||||
(i64.const 2)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
@ -167,9 +173,11 @@
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i64.ne
|
||||
(get_global $logical/I)
|
||||
(i64.const 1)
|
||||
(i32.eqz
|
||||
(i64.eq
|
||||
(get_global $logical/I)
|
||||
(i64.const 1)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
@ -186,9 +194,11 @@
|
||||
)
|
||||
)
|
||||
(if
|
||||
(f32.ne
|
||||
(get_global $logical/f)
|
||||
(f32.const 2)
|
||||
(i32.eqz
|
||||
(f32.eq
|
||||
(get_global $logical/f)
|
||||
(f32.const 2)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
@ -205,9 +215,11 @@
|
||||
)
|
||||
)
|
||||
(if
|
||||
(f32.ne
|
||||
(get_global $logical/f)
|
||||
(f32.const 1)
|
||||
(i32.eqz
|
||||
(f32.eq
|
||||
(get_global $logical/f)
|
||||
(f32.const 1)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
@ -224,9 +236,11 @@
|
||||
)
|
||||
)
|
||||
(if
|
||||
(f64.ne
|
||||
(get_global $logical/F)
|
||||
(f64.const 2)
|
||||
(i32.eqz
|
||||
(f64.eq
|
||||
(get_global $logical/F)
|
||||
(f64.const 2)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
@ -243,9 +257,11 @@
|
||||
)
|
||||
)
|
||||
(if
|
||||
(f64.ne
|
||||
(get_global $logical/F)
|
||||
(f64.const 1)
|
||||
(i32.eqz
|
||||
(f64.eq
|
||||
(get_global $logical/F)
|
||||
(f64.const 1)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
|
@ -7,36 +7,15 @@
|
||||
(export "doSwitchDefaultOmitted" (func $switch/doSwitchDefaultOmitted))
|
||||
(export "memory" (memory $0))
|
||||
(func $switch/doSwitch (; 0 ;) (type $ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(block $case4$1.1
|
||||
(block $case2$1.1
|
||||
(if
|
||||
(i32.ne
|
||||
(tee_local $1
|
||||
(block $case0$1.1
|
||||
(block $tablify|0
|
||||
(br_table $case2$1.1 $case0$1.1 $case4$1.1 $case4$1.1 $tablify|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
|
||||
(i32.const 1)
|
||||
@ -49,31 +28,18 @@
|
||||
(i32.const 23)
|
||||
)
|
||||
(func $switch/doSwitchDefaultFirst (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(block $case3$1.1
|
||||
(if
|
||||
(i32.ne
|
||||
(tee_local $1
|
||||
(get_local $0)
|
||||
(block $case1$1.1
|
||||
(block $tablify|0
|
||||
(br_table $case1$1.1 $case3$1.1 $case3$1.1 $tablify|0
|
||||
(i32.sub
|
||||
(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
|
||||
(i32.const 0)
|
||||
)
|
||||
(return
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
(return
|
||||
@ -83,31 +49,18 @@
|
||||
(i32.const 23)
|
||||
)
|
||||
(func $switch/doSwitchDefaultOmitted (; 2 ;) (type $ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
(block $break$1.1
|
||||
(block $case2$1.1
|
||||
(if
|
||||
(i32.ne
|
||||
(tee_local $1
|
||||
(get_local $0)
|
||||
)
|
||||
(i32.const 1)
|
||||
)
|
||||
(block
|
||||
(br_if $case2$1.1
|
||||
(i32.eq
|
||||
(get_local $1)
|
||||
(i32.const 2)
|
||||
(block $case0$1.1
|
||||
(block $tablify|0
|
||||
(br_table $case0$1.1 $case2$1.1 $case2$1.1 $tablify|0
|
||||
(i32.sub
|
||||
(get_local $0)
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
(br_if $case2$1.1
|
||||
(i32.eq
|
||||
(get_local $1)
|
||||
(i32.const 3)
|
||||
)
|
||||
)
|
||||
(br $break$1.1)
|
||||
)
|
||||
(br $break$1.1)
|
||||
)
|
||||
(return
|
||||
(i32.const 1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user