diff options
-rw-r--r-- | src/wasm2js.h | 17 | ||||
-rw-r--r-- | test/wasm2js/emscripten.2asm.js | 2 | ||||
-rw-r--r-- | test/wasm2js/func-ptr-offset.2asm.js | 2 | ||||
-rw-r--r-- | test/wasm2js/func-ptr-offset.2asm.js.opt | 2 | ||||
-rw-r--r-- | test/wasm2js/func_ptrs.2asm.js | 6 | ||||
-rw-r--r-- | test/wasm2js/indirect-select.2asm.js | 43 | ||||
-rw-r--r-- | test/wasm2js/indirect-select.2asm.js.opt | 43 | ||||
-rw-r--r-- | test/wasm2js/indirect-select.wast | 22 | ||||
-rw-r--r-- | test/wasm2js/left-to-right.2asm.js | 8 | ||||
-rw-r--r-- | test/wasm2js/ordering.2asm.js | 8 |
10 files changed, 135 insertions, 18 deletions
diff --git a/src/wasm2js.h b/src/wasm2js.h index 3accfad75..33f70a4fc 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -1146,6 +1146,14 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, } } } + // Ensure the function pointer is a number. In general in wasm2js we are + // ok with true/false being present, as they are immediately cast to a + // number anyhow on their use. However, FUNCTION_TABLE[true] is *not* the + // same as FUNCTION_TABLE[1], so we must cast. This is a rare exception + // because FUNCTION_TABLE is just a normal JS object, not a typed array + // or a mathematical operation (all of which coerce to a number for us). + auto target = visit(curr->target, EXPRESSION_RESULT); + target = makeAsmCoercion(target, ASM_INT); if (mustReorder) { Ref ret; ScopedTemp idx(Type::i32, parent, func); @@ -1155,7 +1163,9 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, IString temp = temps.back()->temp; sequenceAppend(ret, visitAndAssign(operand, temp)); } - sequenceAppend(ret, visitAndAssign(curr->target, idx)); + sequenceAppend(ret, + ValueBuilder::makeBinary( + ValueBuilder::makeName(idx.getName()), SET, target)); Ref theCall = ValueBuilder::makeCall(ValueBuilder::makeSub( ValueBuilder::makeName(FUNCTION_TABLE), idx.getAstName())); for (size_t i = 0; i < temps.size(); i++) { @@ -1172,9 +1182,8 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, return ret; } else { // Target has no side effects, emit simple code - Ref theCall = ValueBuilder::makeCall( - ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), - visit(curr->target, EXPRESSION_RESULT))); + Ref theCall = ValueBuilder::makeCall(ValueBuilder::makeSub( + ValueBuilder::makeName(FUNCTION_TABLE), target)); for (auto* operand : curr->operands) { theCall[2]->push_back(visit(operand, EXPRESSION_RESULT)); } diff --git a/test/wasm2js/emscripten.2asm.js b/test/wasm2js/emscripten.2asm.js index a595eb151..6f1d19bce 100644 --- a/test/wasm2js/emscripten.2asm.js +++ b/test/wasm2js/emscripten.2asm.js @@ -30,7 +30,7 @@ function asmFunc(global, env, buffer) { function main() { syscall$6(1 | 0, 2 | 0) | 0; syscall$54(3 | 0, 4 | 0) | 0; - FUNCTION_TABLE[HEAP32[(0 + 1030 | 0) >> 2] | 0](); + FUNCTION_TABLE[HEAP32[(0 + 1030 | 0) >> 2] | 0 | 0](); internal(1 | 0) | 0; tabled(1 | 0) | 0; exported(1 | 0) | 0; diff --git a/test/wasm2js/func-ptr-offset.2asm.js b/test/wasm2js/func-ptr-offset.2asm.js index 98d5f7281..ac436c6d6 100644 --- a/test/wasm2js/func-ptr-offset.2asm.js +++ b/test/wasm2js/func-ptr-offset.2asm.js @@ -34,7 +34,7 @@ function asmFunc(global, env, buffer) { function $3($0) { $0 = $0 | 0; - return FUNCTION_TABLE[$0]() | 0 | 0; + return FUNCTION_TABLE[$0 | 0]() | 0 | 0; } var FUNCTION_TABLE = [null, t1, t2, t3]; diff --git a/test/wasm2js/func-ptr-offset.2asm.js.opt b/test/wasm2js/func-ptr-offset.2asm.js.opt index 1c2457fc9..b1198607d 100644 --- a/test/wasm2js/func-ptr-offset.2asm.js.opt +++ b/test/wasm2js/func-ptr-offset.2asm.js.opt @@ -34,7 +34,7 @@ function asmFunc(global, env, buffer) { function $3($0) { $0 = $0 | 0; - return FUNCTION_TABLE[$0]() | 0; + return FUNCTION_TABLE[$0 | 0]() | 0; } var FUNCTION_TABLE = [null, t1, t2, t3]; diff --git a/test/wasm2js/func_ptrs.2asm.js b/test/wasm2js/func_ptrs.2asm.js index 45e0a8697..97ebf3cb3 100644 --- a/test/wasm2js/func_ptrs.2asm.js +++ b/test/wasm2js/func_ptrs.2asm.js @@ -100,12 +100,12 @@ function asmFunc(global, env, buffer) { function $5(i) { i = i | 0; - return FUNCTION_TABLE[i]() | 0 | 0; + return FUNCTION_TABLE[i | 0]() | 0 | 0; } function $6(i) { i = i | 0; - return FUNCTION_TABLE[i]() | 0 | 0; + return FUNCTION_TABLE[i | 0]() | 0 | 0; } var FUNCTION_TABLE = [t1, t2, t3, u1, u2, t1, t3]; @@ -151,7 +151,7 @@ function asmFunc(global, env, buffer) { function $2(i) { i = i | 0; - return FUNCTION_TABLE[i]() | 0 | 0; + return FUNCTION_TABLE[i | 0]() | 0 | 0; } var FUNCTION_TABLE = [t1, t2]; diff --git a/test/wasm2js/indirect-select.2asm.js b/test/wasm2js/indirect-select.2asm.js new file mode 100644 index 000000000..d190bb082 --- /dev/null +++ b/test/wasm2js/indirect-select.2asm.js @@ -0,0 +1,43 @@ +import { FUNCTION_TABLE } from 'env'; + +function asmFunc(global, env, buffer) { + var HEAP8 = new global.Int8Array(buffer); + var HEAP16 = new global.Int16Array(buffer); + var HEAP32 = new global.Int32Array(buffer); + var HEAPU8 = new global.Uint8Array(buffer); + var HEAPU16 = new global.Uint16Array(buffer); + var HEAPU32 = new global.Uint32Array(buffer); + var HEAPF32 = new global.Float32Array(buffer); + var HEAPF64 = new global.Float64Array(buffer); + var Math_imul = global.Math.imul; + var Math_fround = global.Math.fround; + var Math_abs = global.Math.abs; + var Math_clz32 = global.Math.clz32; + var Math_min = global.Math.min; + var Math_max = global.Math.max; + var Math_floor = global.Math.floor; + var Math_ceil = global.Math.ceil; + var Math_sqrt = global.Math.sqrt; + var abort = env.abort; + var nan = global.NaN; + var infinity = global.Infinity; + function $0(x) { + x = x | 0; + return FUNCTION_TABLE[(x ? 1 : 0) | 0]() | 0 | 0; + } + + function $1(x) { + x = x | 0; + return FUNCTION_TABLE[(x ? 0 : 1) | 0]() | 0 | 0; + } + + return { + "foo_true": $0, + "foo_false": $1 + }; +} + +var memasmFunc = new ArrayBuffer(65536); +var retasmFunc = asmFunc({Math,Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,NaN,Infinity}, {abort:function() { throw new Error('abort'); }},memasmFunc); +export var foo_true = retasmFunc.foo_true; +export var foo_false = retasmFunc.foo_false; diff --git a/test/wasm2js/indirect-select.2asm.js.opt b/test/wasm2js/indirect-select.2asm.js.opt new file mode 100644 index 000000000..424b91d4a --- /dev/null +++ b/test/wasm2js/indirect-select.2asm.js.opt @@ -0,0 +1,43 @@ +import { FUNCTION_TABLE } from 'env'; + +function asmFunc(global, env, buffer) { + var HEAP8 = new global.Int8Array(buffer); + var HEAP16 = new global.Int16Array(buffer); + var HEAP32 = new global.Int32Array(buffer); + var HEAPU8 = new global.Uint8Array(buffer); + var HEAPU16 = new global.Uint16Array(buffer); + var HEAPU32 = new global.Uint32Array(buffer); + var HEAPF32 = new global.Float32Array(buffer); + var HEAPF64 = new global.Float64Array(buffer); + var Math_imul = global.Math.imul; + var Math_fround = global.Math.fround; + var Math_abs = global.Math.abs; + var Math_clz32 = global.Math.clz32; + var Math_min = global.Math.min; + var Math_max = global.Math.max; + var Math_floor = global.Math.floor; + var Math_ceil = global.Math.ceil; + var Math_sqrt = global.Math.sqrt; + var abort = env.abort; + var nan = global.NaN; + var infinity = global.Infinity; + function $0($0_1) { + $0_1 = $0_1 | 0; + return FUNCTION_TABLE[!!$0_1 | 0]() | 0; + } + + function $1($0_1) { + $0_1 = $0_1 | 0; + return FUNCTION_TABLE[!$0_1 | 0]() | 0; + } + + return { + "foo_true": $0, + "foo_false": $1 + }; +} + +var memasmFunc = new ArrayBuffer(65536); +var retasmFunc = asmFunc({Math,Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,NaN,Infinity}, {abort:function() { throw new Error('abort'); }},memasmFunc); +export var foo_true = retasmFunc.foo_true; +export var foo_false = retasmFunc.foo_false; diff --git a/test/wasm2js/indirect-select.wast b/test/wasm2js/indirect-select.wast new file mode 100644 index 000000000..fc6f4c470 --- /dev/null +++ b/test/wasm2js/indirect-select.wast @@ -0,0 +1,22 @@ +(module + (type $none_=>_i32 (func (result i32))) + (import "env" "table" (table $timport 6 funcref)) + (func "foo-true" (param $x i32) (result i32) + (call_indirect (type $none_=>_i32) + (select + (i32.const 1) + (i32.const 0) + (local.get $x) + ) + ) + ) + (func "foo-false" (param $x i32) (result i32) + (call_indirect (type $none_=>_i32) + (select + (i32.const 0) + (i32.const 1) + (local.get $x) + ) + ) + ) +) diff --git a/test/wasm2js/left-to-right.2asm.js b/test/wasm2js/left-to-right.2asm.js index f5f19a1cd..4c595c3b0 100644 --- a/test/wasm2js/left-to-right.2asm.js +++ b/test/wasm2js/left-to-right.2asm.js @@ -408,7 +408,7 @@ function asmFunc(global, env, buffer) { function $62() { var wasm2js_i32$0 = 0, wasm2js_i32$1 = 0, wasm2js_i32$2 = 0; reset(); - ((wasm2js_i32$1 = i32_left() | 0, wasm2js_i32$2 = i32_right() | 0), wasm2js_i32$0 = i32_callee() | 0), FUNCTION_TABLE[wasm2js_i32$0](wasm2js_i32$1 | 0, wasm2js_i32$2 | 0) | 0; + ((wasm2js_i32$1 = i32_left() | 0, wasm2js_i32$2 = i32_right() | 0), wasm2js_i32$0 = i32_callee() | 0 | 0), FUNCTION_TABLE[wasm2js_i32$0](wasm2js_i32$1 | 0, wasm2js_i32$2 | 0) | 0; return get() | 0 | 0; } @@ -972,7 +972,7 @@ function asmFunc(global, env, buffer) { $1$hi = i64toi32_i32$0; i64toi32_i32$0 = $0$hi; i64toi32_i32$1 = $1$hi; - FUNCTION_TABLE[i64_callee() | 0]($0, i64toi32_i32$0, $1, i64toi32_i32$1) | 0; + FUNCTION_TABLE[i64_callee() | 0 | 0]($0, i64toi32_i32$0, $1, i64toi32_i32$1) | 0; return get() | 0 | 0; } @@ -1087,7 +1087,7 @@ function asmFunc(global, env, buffer) { function $109() { var wasm2js_i32$0 = 0, wasm2js_f32$0 = Math_fround(0), wasm2js_f32$1 = Math_fround(0); reset(); - ((wasm2js_f32$0 = Math_fround(f32_left()), wasm2js_f32$1 = Math_fround(f32_right())), wasm2js_i32$0 = f32_callee() | 0), FUNCTION_TABLE[wasm2js_i32$0](Math_fround(wasm2js_f32$0), Math_fround(wasm2js_f32$1)) | 0; + ((wasm2js_f32$0 = Math_fround(f32_left()), wasm2js_f32$1 = Math_fround(f32_right())), wasm2js_i32$0 = f32_callee() | 0 | 0), FUNCTION_TABLE[wasm2js_i32$0](Math_fround(wasm2js_f32$0), Math_fround(wasm2js_f32$1)) | 0; return get() | 0 | 0; } @@ -1216,7 +1216,7 @@ function asmFunc(global, env, buffer) { function $126() { var wasm2js_i32$0 = 0, wasm2js_f64$0 = 0.0, wasm2js_f64$1 = 0.0; reset(); - ((wasm2js_f64$0 = +f64_left(), wasm2js_f64$1 = +f64_right()), wasm2js_i32$0 = f64_callee() | 0), FUNCTION_TABLE[wasm2js_i32$0](+wasm2js_f64$0, +wasm2js_f64$1) | 0; + ((wasm2js_f64$0 = +f64_left(), wasm2js_f64$1 = +f64_right()), wasm2js_i32$0 = f64_callee() | 0 | 0), FUNCTION_TABLE[wasm2js_i32$0](+wasm2js_f64$0, +wasm2js_f64$1) | 0; return get() | 0 | 0; } diff --git a/test/wasm2js/ordering.2asm.js b/test/wasm2js/ordering.2asm.js index 1fbfd0c03..f3d879a99 100644 --- a/test/wasm2js/ordering.2asm.js +++ b/test/wasm2js/ordering.2asm.js @@ -23,10 +23,10 @@ function asmFunc(global, env, buffer) { var infinity = global.Infinity; function main() { var wasm2js_i32$0 = 0, wasm2js_i32$1 = 0, wasm2js_i32$2 = 0; - FUNCTION_TABLE[foo(2 | 0) | 0](1) | 0; - FUNCTION_TABLE[4](foo(3 | 0) | 0) | 0; - (wasm2js_i32$1 = foo(5 | 0) | 0, wasm2js_i32$0 = bar(6 | 0) | 0), FUNCTION_TABLE[wasm2js_i32$0](wasm2js_i32$1 | 0) | 0; - FUNCTION_TABLE[8](7) | 0; + FUNCTION_TABLE[foo(2 | 0) | 0 | 0](1) | 0; + FUNCTION_TABLE[4 | 0](foo(3 | 0) | 0) | 0; + (wasm2js_i32$1 = foo(5 | 0) | 0, wasm2js_i32$0 = bar(6 | 0) | 0 | 0), FUNCTION_TABLE[wasm2js_i32$0](wasm2js_i32$1 | 0) | 0; + FUNCTION_TABLE[8 | 0](7) | 0; baz((11 ? 9 : 10) | 0) | 0; baz((wasm2js_i32$0 = foo(12 | 0) | 0, wasm2js_i32$1 = 13, wasm2js_i32$2 = 14, wasm2js_i32$2 ? wasm2js_i32$0 : wasm2js_i32$1) | 0) | 0; baz((wasm2js_i32$0 = 15, wasm2js_i32$1 = foo(16 | 0) | 0, wasm2js_i32$2 = 17, wasm2js_i32$2 ? wasm2js_i32$0 : wasm2js_i32$1) | 0) | 0; |