reinterpret and select builtins

This commit is contained in:
dcodeIO 2017-12-04 22:47:08 +01:00
parent df3e34f2aa
commit b7030d4dea
19 changed files with 374 additions and 140 deletions

18
assembly.d.ts vendored
View File

@ -39,7 +39,6 @@ declare function popcnt<T = i32 | i64>(value: T): T;
declare function rotl<T = i32 | i64>(value: T, shift: T): T; declare function rotl<T = i32 | i64>(value: T, shift: T): T;
/** Performs the sign-agnostic rotate right operation on a 32-bit or 64-bit integer. */ /** Performs the sign-agnostic rotate right operation on a 32-bit or 64-bit integer. */
declare function rotr<T = i32 | i64>(value: T, shift: T): T; declare function rotr<T = i32 | i64>(value: T, shift: T): T;
/** Computes the absolute value of a 32-bit or 64-bit float. */ /** Computes the absolute value of a 32-bit or 64-bit float. */
declare function abs<T = f32 | f64>(value: T): T; declare function abs<T = f32 | f64>(value: T): T;
/** Performs the ceiling operation on a 32-bit or 64-bit float. */ /** Performs the ceiling operation on a 32-bit or 64-bit float. */
@ -56,11 +55,16 @@ declare function min<T = f32 | f64>(left: T, right: T): T;
declare function nearest<T = f32 | f64>(value: T): T; declare function nearest<T = f32 | f64>(value: T): T;
/** Reinterprets the bits of a value of type `T1` as type `T2`. Valid reinterpretations are i32 to/from f32 and i64 to/from f64. */ /** Reinterprets the bits of a value of type `T1` as type `T2`. Valid reinterpretations are i32 to/from f32 and i64 to/from f64. */
declare function reinterpret<T1 = i32 | i64 | f32 | f64, T2 = i32 | i64 | f32 | f64>(value: T1): T2; declare function reinterpret<T1 = i32 | i64 | f32 | f64, T2 = i32 | i64 | f32 | f64>(value: T1): T2;
/** Selects one of two pre-evaluated values depending on the condition. */
declare function select<T>(ifTrue: T, ifFalse: T, condition: bool): T;
/** Calculates the square root of a 32-bit or 64-bit float. */ /** Calculates the square root of a 32-bit or 64-bit float. */
declare function sqrt<T = f32 | f64>(value: T): T; declare function sqrt<T = f32 | f64>(value: T): T;
/** Rounds to the nearest integer towards zero of a 32-bit or 64-bit float. */ /** Rounds to the nearest integer towards zero of a 32-bit or 64-bit float. */
declare function trunc<T = f32 | f64>(value: T): T; declare function trunc<T = f32 | f64>(value: T): T;
/** Loads a value of the specified type from memory. */
declare function load<T>(offset: usize): T;
/** Stores a value of the specified type to memory. */
declare function store<T>(offset: usize, value: T): void;
/** Returns the current memory size in units of pages. One page is 64kb. */ /** Returns the current memory size in units of pages. One page is 64kb. */
declare function current_memory(): i32; declare function current_memory(): i32;
/** Grows linear memory by a given unsigned delta of pages. One page is 64kb. Returns the previous memory size in units of pages or `-1` on failure. */ /** Grows linear memory by a given unsigned delta of pages. One page is 64kb. Returns the previous memory size in units of pages or `-1` on failure. */
@ -68,18 +72,12 @@ declare function grow_memory(value: i32): i32;
/** Emits an unreachable operation that results in a runtime error when executed. */ /** Emits an unreachable operation that results in a runtime error when executed. */
declare function unreachable(): any; // sic declare function unreachable(): any; // sic
/** Loads a value of the specified type from memory. */
declare function load<T>(offset: usize): T;
/** Stores a value of the specified type to memory. */
declare function store<T>(offset: usize, value: T): void;
/** Determines the byte size of the specified core or class type. Compiles to a constant. */
declare function sizeof<T>(): usize;
/** NaN (not a number) as a 32-bit or 64-bit float depending on context. */ /** NaN (not a number) as a 32-bit or 64-bit float depending on context. */
declare const NaN: f32 | f64; declare const NaN: f32 | f64;
/** Positive infinity as a 32-bit or 64-bit float depending on context. */ /** Positive infinity as a 32-bit or 64-bit float depending on context. */
declare const Infinity: f32 | f64; declare const Infinity: f32 | f64;
/** Determines the byte size of the specified core or class type. Compiles to a constant. */
declare function sizeof<T>(): usize;
/** Tests if a 32-bit or 64-bit float is NaN. */ /** Tests if a 32-bit or 64-bit float is NaN. */
declare function isNaN<T = f32 | f64>(value: T): bool; declare function isNaN<T = f32 | f64>(value: T): bool;
/** Tests if a 32-bit or 64-bit float is finite, that is not NaN or +/-Infinity. */ /** Tests if a 32-bit or 64-bit float is finite, that is not NaN or +/-Infinity. */

View File

@ -1466,7 +1466,7 @@ export class Compiler extends DiagnosticEmitter {
functionInstance = <Function | null>functionPrototype.instances.get(sb.join(",")); functionInstance = <Function | null>functionPrototype.instances.get(sb.join(","));
if (!functionInstance) { if (!functionInstance) {
let arg0: ExpressionRef, arg1: ExpressionRef; let arg0: ExpressionRef, arg1: ExpressionRef, arg2: ExpressionRef;
if (functionPrototype.internalName == "sizeof") { // no parameters if (functionPrototype.internalName == "sizeof") { // no parameters
this.currentType = this.options.target == Target.WASM64 ? Type.usize64 : Type.usize32; this.currentType = this.options.target == Target.WASM64 ? Type.usize64 : Type.usize32;
@ -1483,11 +1483,11 @@ export class Compiler extends DiagnosticEmitter {
: this.module.createI32(resolvedTypeArguments[0].byteSize); : this.module.createI32(resolvedTypeArguments[0].byteSize);
} else if (functionPrototype.internalName == "load") { } else if (functionPrototype.internalName == "load") {
this.currentType = resolvedTypeArguments[0];
if (k != 1) { if (k != 1) {
this.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, expression.range, "1", k.toString()); this.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, expression.range, "1", k.toString());
return this.module.createUnreachable(); return this.module.createUnreachable();
} }
this.currentType = resolvedTypeArguments[0];
if (expression.arguments.length != 1) { if (expression.arguments.length != 1) {
this.error(DiagnosticCode.Expected_0_arguments_but_got_1, expression.range, "1", expression.arguments.length.toString()); this.error(DiagnosticCode.Expected_0_arguments_but_got_1, expression.range, "1", expression.arguments.length.toString());
return this.module.createUnreachable(); return this.module.createUnreachable();
@ -1517,6 +1517,60 @@ export class Compiler extends DiagnosticEmitter {
if (!arg1) if (!arg1)
return this.module.createUnreachable(); return this.module.createUnreachable();
return this.module.createStore(resolvedTypeArguments[0].byteSize, arg0, arg1, typeToNativeType(resolvedTypeArguments[0])); return this.module.createStore(resolvedTypeArguments[0].byteSize, arg0, arg1, typeToNativeType(resolvedTypeArguments[0]));
} else if (functionPrototype.internalName == "reinterpret") {
if (k != 2) {
this.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, expression.range, "2", k.toString());
return this.module.createUnreachable();
}
this.currentType = resolvedTypeArguments[1];
if (expression.arguments.length != 1) {
this.error(DiagnosticCode.Expected_0_arguments_but_got_1, expression.range, "1", expression.arguments.length.toString());
return this.module.createUnreachable();
}
if (this.currentType == Type.f64) {
arg0 = this.compileExpression(expression.arguments[0], Type.i64); // reports
this.currentType = Type.f64;
return this.module.createUnary(UnaryOp.ReinterpretI64, arg0);
}
if (this.currentType == Type.f32) {
arg0 = this.compileExpression(expression.arguments[0], Type.i32); // reports
this.currentType = Type.f32;
return this.module.createUnary(UnaryOp.ReinterpretI32, arg0);
}
if (this.currentType.isLongInteger) {
arg0 = this.compileExpression(expression.arguments[0], Type.f64); // reports
this.currentType = Type.i64;
return this.module.createUnary(UnaryOp.ReinterpretF64, arg0);
}
if (this.currentType.isAnyInteger) {
arg0 = this.compileExpression(expression.arguments[0], Type.f32); // reports
this.currentType = Type.i32;
return this.module.createUnary(UnaryOp.ReinterpretF32, arg0);
}
} else if (functionPrototype.internalName == "select") {
if (k != 1) {
this.error(DiagnosticCode.Expected_0_type_arguments_but_got_1, expression.range, "1", k.toString());
return this.module.createUnreachable();
}
this.currentType = resolvedTypeArguments[0];
if (expression.arguments.length != 3) {
this.error(DiagnosticCode.Expected_0_arguments_but_got_1, expression.range, "3", expression.arguments.length.toString());
return this.module.createUnreachable();
}
arg0 = this.compileExpression(expression.arguments[0], this.currentType); // reports
if (!arg0)
return this.module.createUnreachable();
arg1 = this.compileExpression(expression.arguments[1], this.currentType); // reports
if (!arg1)
return this.module.createUnreachable();
arg2 = this.compileExpression(expression.arguments[2], Type.i32); // reports
this.currentType = resolvedTypeArguments[0];
if (!arg2)
return this.module.createUnreachable();
return this.module.createSelect(arg0, arg1, arg2);
} }
this.error(DiagnosticCode.Operation_not_supported, expression.range); this.error(DiagnosticCode.Operation_not_supported, expression.range);
return this.module.createUnreachable(); return this.module.createUnreachable();

View File

@ -1111,6 +1111,9 @@ export class Interface extends Class {
} }
} }
const builtinIntTypes: Type[] = [ Type.i32, Type.i64 ];
const builtinFloatTypes: Type[] = [ Type.f32, Type.f64 ];
function initializeBuiltins(program: Program): void { function initializeBuiltins(program: Program): void {
// types // types
@ -1134,37 +1137,37 @@ function initializeBuiltins(program: Program): void {
// functions // functions
const genericInt: Type[] = [ Type.i32, Type.i64 ];
const genericFloat: Type[] = [ Type.f32, Type.f64 ];
const usize: Type = program.target == Target.WASM64 ? Type.usize64 : Type.usize32; const usize: Type = program.target == Target.WASM64 ? Type.usize64 : Type.usize32;
addGenericUnaryBuiltin(program, "clz", genericInt); addGenericUnaryBuiltin(program, "clz", builtinIntTypes);
addGenericUnaryBuiltin(program, "ctz", genericInt); addGenericUnaryBuiltin(program, "ctz", builtinIntTypes);
addGenericUnaryBuiltin(program, "popcnt", genericInt); addGenericUnaryBuiltin(program, "popcnt", builtinIntTypes);
addGenericBinaryBuiltin(program, "rotl", genericInt); addGenericBinaryBuiltin(program, "rotl", builtinIntTypes);
addGenericBinaryBuiltin(program, "rotr", genericInt); addGenericBinaryBuiltin(program, "rotr", builtinIntTypes);
addGenericUnaryBuiltin(program, "abs", genericFloat); addGenericUnaryBuiltin(program, "abs", builtinFloatTypes);
addGenericUnaryBuiltin(program, "ceil", genericFloat); addGenericUnaryBuiltin(program, "ceil", builtinFloatTypes);
addGenericBinaryBuiltin(program, "copysign", genericFloat); addGenericBinaryBuiltin(program, "copysign", builtinFloatTypes);
addGenericUnaryBuiltin(program, "floor", genericFloat); addGenericUnaryBuiltin(program, "floor", builtinFloatTypes);
addGenericBinaryBuiltin(program, "max", genericFloat); addGenericBinaryBuiltin(program, "max", builtinFloatTypes);
addGenericBinaryBuiltin(program, "min", genericFloat); addGenericBinaryBuiltin(program, "min", builtinFloatTypes);
addGenericUnaryBuiltin(program, "nearest", genericFloat); addGenericUnaryBuiltin(program, "nearest", builtinFloatTypes);
addGenericUnaryBuiltin(program, "sqrt", genericFloat); addGenericUnaryBuiltin(program, "sqrt", builtinFloatTypes);
addGenericUnaryBuiltin(program, "trunc", genericFloat); addGenericUnaryBuiltin(program, "trunc", builtinFloatTypes);
addSimpleBuiltin(program, "current_memory", [], usize); addSimpleBuiltin(program, "current_memory", [], usize);
addSimpleBuiltin(program, "grow_memory", [ usize ], usize); addSimpleBuiltin(program, "grow_memory", [ usize ], usize);
addSimpleBuiltin(program, "unreachable", [], Type.void); addSimpleBuiltin(program, "unreachable", [], Type.void);
addGenericUnaryTestBuiltin(program, "isNaN", genericFloat);
addGenericUnaryTestBuiltin(program, "isFinite", genericFloat);
addSimpleBuiltin(program, "assert", [ Type.bool ], Type.void);
addGenericAnyBuiltin(program, "sizeof");
addGenericAnyBuiltin(program, "load"); addGenericAnyBuiltin(program, "load");
addGenericAnyBuiltin(program, "store"); addGenericAnyBuiltin(program, "store");
addGenericAnyBuiltin(program, "reinterpret");
addGenericAnyBuiltin(program, "select");
addGenericAnyBuiltin(program, "sizeof");
addGenericUnaryTestBuiltin(program, "isNaN", builtinFloatTypes);
addGenericUnaryTestBuiltin(program, "isFinite", builtinFloatTypes);
addSimpleBuiltin(program, "assert", [ Type.bool ], Type.void);
} }
/** Adds a simple (non-generic) builtin. */ /** Adds a simple (non-generic) builtin. */

View File

@ -835,12 +835,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
binary/b binary/b
binary/i binary/i
binary/I binary/I

View File

@ -159,22 +159,6 @@
) )
) )
) )
(drop
(current_memory)
)
(drop
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/s
(current_memory)
)
(set_global $builtins/s
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/i (set_global $builtins/i
(i32.load (i32.load
(i32.const 8) (i32.const 8)
@ -211,6 +195,46 @@
(i32.const 8) (i32.const 8)
(get_global $builtins/F) (get_global $builtins/F)
) )
(set_global $builtins/i
(i32.const 1067450368)
)
(set_global $builtins/f
(f32.const 3.5032461608120427e-44)
)
(set_global $builtins/I
(i64.const 4608308318706860032)
)
(set_global $builtins/F
(f64.const 1.24e-322)
)
(drop
(current_memory)
)
(drop
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/s
(current_memory)
)
(set_global $builtins/s
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/i
(i32.const 10)
)
(set_global $builtins/I
(i64.const 200)
)
(set_global $builtins/f
(f32.const 1.25)
)
(set_global $builtins/F
(f64.const 25)
)
(if (if
(f32.eq (f32.eq
(tee_local $0 (tee_local $0

View File

@ -1,5 +1,7 @@
let b: bool; let b: bool;
// integer builtins
let i: i32; let i: i32;
clz<i32>(1); clz<i32>(1);
@ -28,6 +30,8 @@ I = popcnt<i64>(1);
I = rotl<i64>(1, 1); I = rotl<i64>(1, 1);
I = rotr<i64>(1, 1); I = rotr<i64>(1, 1);
// floating point builtins
let f: f32; let f: f32;
<f32>NaN; <f32>NaN;
@ -39,7 +43,6 @@ floor<f32>(1.25);
max<f32>(1.25, 2.5); max<f32>(1.25, 2.5);
min<f32>(1.25, 2.5); min<f32>(1.25, 2.5);
nearest<f32>(1.25); nearest<f32>(1.25);
// reinterpret
sqrt<f32>(1.25); sqrt<f32>(1.25);
trunc<f32>(1.25); trunc<f32>(1.25);
isNaN<f32>(1.25); isNaN<f32>(1.25);
@ -54,7 +57,6 @@ f = floor<f32>(1.25);
f = max<f32>(1.25, 2.5); f = max<f32>(1.25, 2.5);
f = min<f32>(1.25, 2.5); f = min<f32>(1.25, 2.5);
f = nearest<f32>(1.25); f = nearest<f32>(1.25);
// reinterpret
f = sqrt<f32>(1.25); f = sqrt<f32>(1.25);
f = trunc<f32>(1.25); f = trunc<f32>(1.25);
b = isNaN<f32>(1.25); b = isNaN<f32>(1.25);
@ -73,7 +75,6 @@ floor<f64>(1.25);
max<f64>(1.25, 2.5); max<f64>(1.25, 2.5);
min<f64>(1.25, 2.5); min<f64>(1.25, 2.5);
nearest<f64>(1.25); nearest<f64>(1.25);
// reinterpret
sqrt<f64>(1.25); sqrt<f64>(1.25);
trunc<f64>(1.25); trunc<f64>(1.25);
isNaN<f64>(1.25); isNaN<f64>(1.25);
@ -88,12 +89,36 @@ F = floor<f64>(1.25);
F = max<f64>(1.25, 2.5); F = max<f64>(1.25, 2.5);
F = min<f64>(1.25, 2.5); F = min<f64>(1.25, 2.5);
F = nearest<f64>(1.25); F = nearest<f64>(1.25);
// reinterpret
F = sqrt<f64>(1.25); F = sqrt<f64>(1.25);
F = trunc<f64>(1.25); F = trunc<f64>(1.25);
b = isNaN<f64>(1.25); b = isNaN<f64>(1.25);
b = isFinite<f64>(1.25); 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);
// reinterpretation builtins
reinterpret<f32,i32>(1.25);
reinterpret<i32,f32>(25);
reinterpret<f64,i64>(1.25);
reinterpret<i64,f64>(25);
i = reinterpret<f32,i32>(1.25);
f = reinterpret<i32,f32>(25);
I = reinterpret<f64,i64>(1.25);
F = reinterpret<i64,f64>(25);
// host builtins
let s: usize; let s: usize;
current_memory(); current_memory();
@ -101,8 +126,23 @@ grow_memory(1);
s = current_memory(); s = current_memory();
s = grow_memory(1); s = grow_memory(1);
// other builtins
select<i32>(10, 20, true);
select<i64>(100, 200, false);
select<f32>(1.25, 2.5, true);
select<f64>(12.5, 25.0, false);
i = select<i32>(10, 20, true);
I = select<i64>(100, 200, false);
f = select<f32>(1.25, 2.5, true);
F = select<f64>(12.5, 25.0, false);
if (0) unreachable(); if (0) unreachable();
// AS specific builtins
assert(true); assert(true);
sizeof<u8>(); sizeof<u8>();
@ -119,15 +159,6 @@ sizeof<isize>();
sizeof<f32>(); sizeof<f32>();
sizeof<f64>(); sizeof<f64>();
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);
if (NaN == NaN) if (NaN == NaN)
unreachable(); unreachable();
if (!isNaN<f32>(NaN)) if (!isNaN<f32>(NaN))

View File

@ -453,6 +453,82 @@
) )
) )
) )
(set_global $builtins/i
(i32.load
(i32.const 8)
)
)
(i32.store
(i32.const 8)
(get_global $builtins/i)
)
(set_global $builtins/I
(i64.load
(i32.const 8)
)
)
(i64.store
(i32.const 8)
(get_global $builtins/I)
)
(set_global $builtins/f
(f32.load
(i32.const 8)
)
)
(f32.store
(i32.const 8)
(get_global $builtins/f)
)
(set_global $builtins/F
(f64.load
(i32.const 8)
)
)
(f64.store
(i32.const 8)
(get_global $builtins/F)
)
(drop
(i32.reinterpret/f32
(f32.const 1.25)
)
)
(drop
(f32.reinterpret/i32
(i32.const 25)
)
)
(drop
(i64.reinterpret/f64
(f64.const 1.25)
)
)
(drop
(f64.reinterpret/i64
(i64.const 25)
)
)
(set_global $builtins/i
(i32.reinterpret/f32
(f32.const 1.25)
)
)
(set_global $builtins/f
(f32.reinterpret/i32
(i32.const 25)
)
)
(set_global $builtins/I
(i64.reinterpret/f64
(f64.const 1.25)
)
)
(set_global $builtins/F
(f64.reinterpret/i64
(i64.const 25)
)
)
(drop (drop
(current_memory) (current_memory)
) )
@ -469,6 +545,62 @@
(i32.const 1) (i32.const 1)
) )
) )
(drop
(select
(i32.const 10)
(i32.const 20)
(i32.const 1)
)
)
(drop
(select
(i64.const 100)
(i64.const 200)
(i32.const 0)
)
)
(drop
(select
(f32.const 1.25)
(f32.const 2.5)
(i32.const 1)
)
)
(drop
(select
(f64.const 12.5)
(f64.const 25)
(i32.const 0)
)
)
(set_global $builtins/i
(select
(i32.const 10)
(i32.const 20)
(i32.const 1)
)
)
(set_global $builtins/I
(select
(i64.const 100)
(i64.const 200)
(i32.const 0)
)
)
(set_global $builtins/f
(select
(f32.const 1.25)
(f32.const 2.5)
(i32.const 1)
)
)
(set_global $builtins/F
(select
(f64.const 12.5)
(f64.const 25)
(i32.const 0)
)
)
(if (if
(i32.const 0) (i32.const 0)
(unreachable) (unreachable)
@ -518,42 +650,6 @@
(drop (drop
(i32.const 8) (i32.const 8)
) )
(set_global $builtins/i
(i32.load
(i32.const 8)
)
)
(i32.store
(i32.const 8)
(get_global $builtins/i)
)
(set_global $builtins/I
(i64.load
(i32.const 8)
)
)
(i64.store
(i32.const 8)
(get_global $builtins/I)
)
(set_global $builtins/f
(f32.load
(i32.const 8)
)
)
(f32.store
(i32.const 8)
(get_global $builtins/f)
)
(set_global $builtins/F
(f64.load
(i32.const 8)
)
)
(f64.store
(i32.const 8)
(get_global $builtins/F)
)
(if (if
(f64.eq (f64.eq
(f64.const nan:0x8000000000000) (f64.const nan:0x8000000000000)
@ -649,12 +745,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
builtins/b builtins/b
builtins/i builtins/i
builtins/I builtins/I

View File

@ -25,12 +25,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
declare/external declare/external
[program.exports] [program.exports]
declare/external declare/external

View File

@ -74,12 +74,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
do/loopDo do/loopDo
do/loopDoInDo do/loopDoInDo
[program.exports] [program.exports]

View File

@ -43,12 +43,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
export/add export/add
export/sub export/sub
export/a export/a

View File

@ -65,12 +65,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
if/ifThenElse if/ifThenElse
if/ifThen if/ifThen
if/ifThenElseBlock if/ifThenElseBlock

View File

@ -57,12 +57,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
export/add export/add
export/sub export/sub
export/a export/a

View File

@ -158,12 +158,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
[program.exports] [program.exports]
;) ;)

View File

@ -270,12 +270,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
logical/i logical/i
logical/I logical/I
logical/f logical/f

View File

@ -59,12 +59,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
export/add export/add
export/sub export/sub
export/a export/a

View File

@ -164,12 +164,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
switch/doSwitch switch/doSwitch
switch/doSwitchDefaultFirst switch/doSwitchDefaultFirst
switch/doSwitchDefaultOmitted switch/doSwitchDefaultOmitted

View File

@ -52,12 +52,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
ternary/a ternary/a
[program.exports] [program.exports]

View File

@ -652,12 +652,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
unary/i unary/i
unary/I unary/I
unary/f unary/f

View File

@ -83,12 +83,14 @@
current_memory current_memory
grow_memory grow_memory
unreachable unreachable
load
store
reinterpret
select
sizeof
isNaN isNaN
isFinite isFinite
assert assert
sizeof
load
store
while/loopWhile while/loopWhile
while/loopWhileInWhile while/loopWhileInWhile
[program.exports] [program.exports]