diff options
author | Alon Zakai <azakai@google.com> | 2020-07-20 19:24:56 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-20 19:24:56 -0700 |
commit | 2e18aff8c9d4867d9c8e7db81948a672c028348f (patch) | |
tree | b8ef6b8ec097e8d2d5bcdc313c621b91728e26f8 | |
parent | 4b60d34d807bf803cefee8fd16b9000bcfc1bdc7 (diff) | |
download | binaryen-2e18aff8c9d4867d9c8e7db81948a672c028348f.tar.gz binaryen-2e18aff8c9d4867d9c8e7db81948a672c028348f.tar.bz2 binaryen-2e18aff8c9d4867d9c8e7db81948a672c028348f.zip |
wasm2js: Fix a bug with adjacent reinterprets (#2964)
i64 reinterprets were lowered in the i64 pass, and i32s at the very end, in
wasm2js itself. This could break since in between the i64 pass and wasm2js
we run optimizations, and the optimizer was not aware of what we lower
the i32 reinterprets to - calls to use scratch memory. Those calls have a
side effect of altering scratch memory. The optimizer just saw an i32
reinterpret, and moved it across the i64 reinterpret's scratch memory calls.
This makes 32-bit reinterprets use separate scratch memory from 64-bit ones,
which means they can never interfere with each other.
-rw-r--r-- | src/passes/wasm-intrinsics.wat | 2 | ||||
-rw-r--r-- | src/wasm2js.h | 68 | ||||
-rw-r--r-- | test/wasm2js/atomics_32.2asm.js | 2 | ||||
-rw-r--r-- | test/wasm2js/atomics_32.2asm.js.opt | 2 | ||||
-rw-r--r-- | test/wasm2js/bulk-memory.2asm.js | 8 | ||||
-rw-r--r-- | test/wasm2js/bulk-memory.2asm.js.opt | 6 | ||||
-rw-r--r-- | test/wasm2js/conversions-modified.2asm.js | 10 | ||||
-rw-r--r-- | test/wasm2js/conversions-modified.2asm.js.opt | 10 | ||||
-rw-r--r-- | test/wasm2js/endianness.2asm.js | 10 | ||||
-rw-r--r-- | test/wasm2js/float_literals-modified.2asm.js | 64 | ||||
-rw-r--r-- | test/wasm2js/float_literals-modified.2asm.js.opt | 2 | ||||
-rw-r--r-- | test/wasm2js/float_misc.2asm.js | 8 | ||||
-rw-r--r-- | test/wasm2js/left-to-right.2asm.js | 6 | ||||
-rw-r--r-- | test/wasm2js/reinterpret.2asm.js | 8 | ||||
-rw-r--r-- | test/wasm2js/reinterpret.2asm.js.opt | 8 | ||||
-rw-r--r-- | test/wasm2js/reinterpret_scratch.2asm.js | 64 | ||||
-rw-r--r-- | test/wasm2js/reinterpret_scratch.2asm.js.opt | 59 | ||||
-rw-r--r-- | test/wasm2js/reinterpret_scratch.wast | 17 | ||||
-rw-r--r-- | test/wasm2js/unaligned.2asm.js | 10 | ||||
-rw-r--r-- | test/wasm2js/unaligned.2asm.js.opt | 6 |
20 files changed, 284 insertions, 86 deletions
diff --git a/src/passes/wasm-intrinsics.wat b/src/passes/wasm-intrinsics.wat index 76e900734..17bf0d649 100644 --- a/src/passes/wasm-intrinsics.wat +++ b/src/passes/wasm-intrinsics.wat @@ -10,6 +10,7 @@ ;; add $wasm-intrinsics-temp-i64 global for that. ;; * Fix function type of __wasm_ctz_i64, which was wrong somehow, ;; i32, i32 => i32 instead of i64 => i64 +;; * Remove unnecessary memory import. ;; ;; [1]: https://gist.github.com/alexcrichton/e7ea67bcdd17ce4b6254e66f77165690 @@ -20,7 +21,6 @@ (type $3 (func (param i32) (result i32))) (type $4 (func (param i32 i32) (result i32))) (type $5 (func (param i64) (result i64))) - (import "env" "memory" (memory $0 17)) (export "__wasm_i64_sdiv" (func $__wasm_i64_sdiv)) (export "__wasm_i64_udiv" (func $__wasm_i64_udiv)) (export "__wasm_i64_srem" (func $__wasm_i64_srem)) diff --git a/src/wasm2js.h b/src/wasm2js.h index 5adcdb740..3accfad75 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -1437,8 +1437,11 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Ref store = ValueBuilder::makeCall(ABI::wasm2js::SCRATCH_STORE_F32, visit(curr->value, EXPRESSION_RESULT)); + // 32-bit scratch memory uses index 2, so that it does not + // conflict with indexes 0, 1 which are used for 64-bit, see + // comment where |scratchBuffer| is defined. Ref load = ValueBuilder::makeCall(ABI::wasm2js::SCRATCH_LOAD_I32, - ValueBuilder::makeInt(0)); + ValueBuilder::makeInt(2)); return ValueBuilder::makeSeq(store, load); } // generate (~~expr), what Emscripten does @@ -1528,9 +1531,12 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::SCRATCH_LOAD_F32); + // 32-bit scratch memory uses index 2, so that it does not + // conflict with indexes 0, 1 which are used for 64-bit, see + // comment where |scratchBuffer| is defined. Ref store = ValueBuilder::makeCall(ABI::wasm2js::SCRATCH_STORE_I32, - ValueBuilder::makeNum(0), + ValueBuilder::makeNum(2), visit(curr->value, EXPRESSION_RESULT)); Ref load = ValueBuilder::makeCall(ABI::wasm2js::SCRATCH_LOAD_F32); return ValueBuilder::makeSeq(store, load); @@ -2462,8 +2468,60 @@ void Wasm2JSGlue::emitSpecialSupport() { return; } + // Scratch memory uses 3 indexes, each referring to 4 bytes. Indexes 0, 1 are + // used for 64-bit operations, while 2 is for 32-bit. These operations need + // separate indexes because we need to handle the case where the optimizer + // reorders a 32-bit reinterpret in between a 64-bit's split-out parts. + // That situation can occur because the 64-bit reinterpret was split up into + // pieces early, in the 64-bit lowering pass, while the 32-bit reinterprets + // are lowered only at the very end, and until then the optimizer sees wasm + // reinterprets which have no side effects (but they will have the side effect + // of altering scratch memory). That is, conceptual code like this: + // + // a = reinterpret_64(b) + // x = reinterpret_32(y) + // + // turns into + // + // scratch_write(b) + // a_low = scratch_read(0) + // a_high = scratch_read(1) + // x = reinterpret_32(y) + // + // (Note how the single wasm instruction for a 64-bit reinterpret turns into + // multiple operations. We have to do such splitting, because in JS we will + // have to have separate operations to receive each 32-bit chunk anyhow. A + // *32*-bit reinterpret *could* be a single function, but given we have the + // separate functions anyhow for the 64-bit case, it's more compact to reuse + // those.) + // At this point, the scratch_* functions look like they have side effects to + // the optimizer (which is true, as they modify scratch memory), but the + // reinterpret_32 is still a normal wasm instruction without side effects, so + // the optimizer might do this: + // + // scratch_write(b) + // a_low = scratch_read(0) + // x = reinterpret_32(y) ;; this moved one line up + // a_high = scratch_read(1) + // + // When we do lower the reinterpret_32 into JS, we get: + // + // scratch_write(b) + // a_low = scratch_read(0) + // scratch_write(y) + // x = scratch_read() + // a_high = scratch_read(1) + // + // The second write occurs before the first's values have been read, so they + // interfere. + // + // There isn't a problem with reordering 32-bit reinterprets with each other + // as each is lowered into a pair of write+read in JS (after the wasm + // optimizer runs), so they are guaranteed to be adjacent (and a JS optimizer + // that runs later will handle that ok since they are calls, which can always + // have side effects). out << R"( - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -2494,13 +2552,13 @@ void Wasm2JSGlue::emitSpecialSupport() { } else if (import->base == ABI::wasm2js::SCRATCH_STORE_F32) { out << R"( function wasm2js_scratch_store_f32(value) { - f32ScratchView[0] = value; + f32ScratchView[2] = value; } )"; } else if (import->base == ABI::wasm2js::SCRATCH_LOAD_F32) { out << R"( function wasm2js_scratch_load_f32() { - return f32ScratchView[0]; + return f32ScratchView[2]; } )"; } else if (import->base == ABI::wasm2js::SCRATCH_STORE_F64) { diff --git a/test/wasm2js/atomics_32.2asm.js b/test/wasm2js/atomics_32.2asm.js index 21f280e4b..bbc599423 100644 --- a/test/wasm2js/atomics_32.2asm.js +++ b/test/wasm2js/atomics_32.2asm.js @@ -1,6 +1,6 @@ - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); diff --git a/test/wasm2js/atomics_32.2asm.js.opt b/test/wasm2js/atomics_32.2asm.js.opt index f662c0ad2..d3b9cd1bb 100644 --- a/test/wasm2js/atomics_32.2asm.js.opt +++ b/test/wasm2js/atomics_32.2asm.js.opt @@ -1,6 +1,6 @@ - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); diff --git a/test/wasm2js/bulk-memory.2asm.js b/test/wasm2js/bulk-memory.2asm.js index cea852c98..379f919fa 100644 --- a/test/wasm2js/bulk-memory.2asm.js +++ b/test/wasm2js/bulk-memory.2asm.js @@ -30,7 +30,7 @@ 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); - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -115,7 +115,7 @@ export var fill = retasmFunc.fill; export var load8_u = retasmFunc.load8_u; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -196,7 +196,7 @@ export var copy = retasmFunc.copy; export var load8_u = retasmFunc.load8_u; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -301,7 +301,7 @@ export var init = retasmFunc.init; export var load8_u = retasmFunc.load8_u; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); diff --git a/test/wasm2js/bulk-memory.2asm.js.opt b/test/wasm2js/bulk-memory.2asm.js.opt index 620a7bbc7..a4da19a5d 100644 --- a/test/wasm2js/bulk-memory.2asm.js.opt +++ b/test/wasm2js/bulk-memory.2asm.js.opt @@ -30,7 +30,7 @@ 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); - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -115,7 +115,7 @@ export var fill = retasmFunc.fill; export var load8_u = retasmFunc.load8_u; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -196,7 +196,7 @@ export var copy = retasmFunc.copy; export var load8_u = retasmFunc.load8_u; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); diff --git a/test/wasm2js/conversions-modified.2asm.js b/test/wasm2js/conversions-modified.2asm.js index 693c287fd..4829bb49f 100644 --- a/test/wasm2js/conversions-modified.2asm.js +++ b/test/wasm2js/conversions-modified.2asm.js @@ -1,7 +1,7 @@ import { setTempRet0 } from 'env'; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -23,11 +23,11 @@ import { setTempRet0 } from 'env'; } function wasm2js_scratch_load_f32() { - return f32ScratchView[0]; + return f32ScratchView[2]; } function wasm2js_scratch_store_f32(value) { - f32ScratchView[0] = value; + f32ScratchView[2] = value; } function asmFunc(global, env, buffer) { @@ -240,7 +240,7 @@ function asmFunc(global, env, buffer) { function $21(x) { x = x | 0; - return Math_fround((wasm2js_scratch_store_i32(0, x), wasm2js_scratch_load_f32())); + return Math_fround((wasm2js_scratch_store_i32(2, x), wasm2js_scratch_load_f32())); } function $22(x, x$hi) { @@ -255,7 +255,7 @@ function asmFunc(global, env, buffer) { function $23(x) { x = Math_fround(x); - return (wasm2js_scratch_store_f32(x), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(x), wasm2js_scratch_load_i32(2)) | 0; } function $24(x) { diff --git a/test/wasm2js/conversions-modified.2asm.js.opt b/test/wasm2js/conversions-modified.2asm.js.opt index b30a95a8e..5efd1966d 100644 --- a/test/wasm2js/conversions-modified.2asm.js.opt +++ b/test/wasm2js/conversions-modified.2asm.js.opt @@ -1,7 +1,7 @@ import { setTempRet0 } from 'env'; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -23,11 +23,11 @@ import { setTempRet0 } from 'env'; } function wasm2js_scratch_load_f32() { - return f32ScratchView[0]; + return f32ScratchView[2]; } function wasm2js_scratch_store_f32(value) { - f32ScratchView[0] = value; + f32ScratchView[2] = value; } function asmFunc(global, env, buffer) { @@ -117,12 +117,12 @@ function asmFunc(global, env, buffer) { function $21($0) { $0 = $0 | 0; - return Math_fround((wasm2js_scratch_store_i32(0, $0), wasm2js_scratch_load_f32())); + return Math_fround((wasm2js_scratch_store_i32(2, $0), wasm2js_scratch_load_f32())); } function $23($0) { $0 = Math_fround($0); - return (wasm2js_scratch_store_f32($0), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32($0), wasm2js_scratch_load_i32(2)) | 0; } function legalstub$0($0) { diff --git a/test/wasm2js/endianness.2asm.js b/test/wasm2js/endianness.2asm.js index 2146a9840..171af7d6c 100644 --- a/test/wasm2js/endianness.2asm.js +++ b/test/wasm2js/endianness.2asm.js @@ -1,7 +1,7 @@ import { setTempRet0 } from 'env'; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -23,11 +23,11 @@ import { setTempRet0 } from 'env'; } function wasm2js_scratch_store_f32(value) { - f32ScratchView[0] = value; + f32ScratchView[2] = value; } function wasm2js_scratch_load_f32() { - return f32ScratchView[0]; + return f32ScratchView[2]; } function asmFunc(global, env, buffer) { @@ -209,7 +209,7 @@ function asmFunc(global, env, buffer) { function $14(value) { value = Math_fround(value); - i32_store_little(0 | 0, (wasm2js_scratch_store_f32(value), wasm2js_scratch_load_i32(0)) | 0); + i32_store_little(0 | 0, (wasm2js_scratch_store_f32(value), wasm2js_scratch_load_i32(2)) | 0); return Math_fround(Math_fround(HEAPF32[0 >> 2])); } @@ -275,7 +275,7 @@ function asmFunc(global, env, buffer) { function $21(value) { value = Math_fround(value); HEAPF32[0 >> 2] = value; - return Math_fround((wasm2js_scratch_store_i32(0, i32_load_little(0 | 0) | 0), wasm2js_scratch_load_f32())); + return Math_fround((wasm2js_scratch_store_i32(2, i32_load_little(0 | 0) | 0), wasm2js_scratch_load_f32())); } function $22(value) { diff --git a/test/wasm2js/float_literals-modified.2asm.js b/test/wasm2js/float_literals-modified.2asm.js index d03cbf0b9..d75781a88 100644 --- a/test/wasm2js/float_literals-modified.2asm.js +++ b/test/wasm2js/float_literals-modified.2asm.js @@ -1,7 +1,7 @@ import { setTempRet0 } from 'env'; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -15,7 +15,7 @@ import { setTempRet0 } from 'env'; } function wasm2js_scratch_store_f32(value) { - f32ScratchView[0] = value; + f32ScratchView[2] = value; } function asmFunc(global, env, buffer) { @@ -42,123 +42,123 @@ function asmFunc(global, env, buffer) { var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0() { - return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(2)) | 0; } function $1() { - return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(2)) | 0; } function $2() { - return (wasm2js_scratch_store_f32(Math_fround(-nan)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(-nan)), wasm2js_scratch_load_i32(2)) | 0; } function $3() { - return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(2)) | 0; } function $4() { - return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(2)) | 0; } function $5() { - return (wasm2js_scratch_store_f32(Math_fround(-nan)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(-nan)), wasm2js_scratch_load_i32(2)) | 0; } function $6() { - return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(2)) | 0; } function $7() { - return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(nan)), wasm2js_scratch_load_i32(2)) | 0; } function $8() { - return (wasm2js_scratch_store_f32(Math_fround(-nan)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(-nan)), wasm2js_scratch_load_i32(2)) | 0; } function $9() { - return (wasm2js_scratch_store_f32(Math_fround(infinity)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(infinity)), wasm2js_scratch_load_i32(2)) | 0; } function $10() { - return (wasm2js_scratch_store_f32(Math_fround(infinity)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(infinity)), wasm2js_scratch_load_i32(2)) | 0; } function $11() { - return (wasm2js_scratch_store_f32(Math_fround(-infinity)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(-infinity)), wasm2js_scratch_load_i32(2)) | 0; } function $12() { - return (wasm2js_scratch_store_f32(Math_fround(0.0)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(0.0)), wasm2js_scratch_load_i32(2)) | 0; } function $13() { - return (wasm2js_scratch_store_f32(Math_fround(0.0)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(0.0)), wasm2js_scratch_load_i32(2)) | 0; } function $14() { - return (wasm2js_scratch_store_f32(Math_fround(-0.0)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(-0.0)), wasm2js_scratch_load_i32(2)) | 0; } function $15() { - return (wasm2js_scratch_store_f32(Math_fround(6.2831854820251465)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(6.2831854820251465)), wasm2js_scratch_load_i32(2)) | 0; } function $16() { - return (wasm2js_scratch_store_f32(Math_fround(1.401298464324817e-45)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(1.401298464324817e-45)), wasm2js_scratch_load_i32(2)) | 0; } function $17() { - return (wasm2js_scratch_store_f32(Math_fround(1.1754943508222875e-38)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(1.1754943508222875e-38)), wasm2js_scratch_load_i32(2)) | 0; } function $18() { - return (wasm2js_scratch_store_f32(Math_fround(3402823466385288598117041.0e14)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(3402823466385288598117041.0e14)), wasm2js_scratch_load_i32(2)) | 0; } function $19() { - return (wasm2js_scratch_store_f32(Math_fround(1.1754942106924411e-38)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(1.1754942106924411e-38)), wasm2js_scratch_load_i32(2)) | 0; } function $20() { - return (wasm2js_scratch_store_f32(Math_fround(1024.0)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(1024.0)), wasm2js_scratch_load_i32(2)) | 0; } function $21() { - return (wasm2js_scratch_store_f32(Math_fround(0.0)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(0.0)), wasm2js_scratch_load_i32(2)) | 0; } function $22() { - return (wasm2js_scratch_store_f32(Math_fround(0.0)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(0.0)), wasm2js_scratch_load_i32(2)) | 0; } function $23() { - return (wasm2js_scratch_store_f32(Math_fround(-0.0)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(-0.0)), wasm2js_scratch_load_i32(2)) | 0; } function $24() { - return (wasm2js_scratch_store_f32(Math_fround(6.2831854820251465)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(6.2831854820251465)), wasm2js_scratch_load_i32(2)) | 0; } function $25() { - return (wasm2js_scratch_store_f32(Math_fround(1.401298464324817e-45)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(1.401298464324817e-45)), wasm2js_scratch_load_i32(2)) | 0; } function $26() { - return (wasm2js_scratch_store_f32(Math_fround(1.1754943508222875e-38)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(1.1754943508222875e-38)), wasm2js_scratch_load_i32(2)) | 0; } function $27() { - return (wasm2js_scratch_store_f32(Math_fround(1.1754942106924411e-38)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(1.1754942106924411e-38)), wasm2js_scratch_load_i32(2)) | 0; } function $28() { - return (wasm2js_scratch_store_f32(Math_fround(3402823466385288598117041.0e14)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(3402823466385288598117041.0e14)), wasm2js_scratch_load_i32(2)) | 0; } function $29() { - return (wasm2js_scratch_store_f32(Math_fround(1.0e10)), wasm2js_scratch_load_i32(0)) | 0; + return (wasm2js_scratch_store_f32(Math_fround(1.0e10)), wasm2js_scratch_load_i32(2)) | 0; } function $30() { diff --git a/test/wasm2js/float_literals-modified.2asm.js.opt b/test/wasm2js/float_literals-modified.2asm.js.opt index d7aaa2a0d..b055b21f4 100644 --- a/test/wasm2js/float_literals-modified.2asm.js.opt +++ b/test/wasm2js/float_literals-modified.2asm.js.opt @@ -1,7 +1,7 @@ import { setTempRet0 } from 'env'; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); diff --git a/test/wasm2js/float_misc.2asm.js b/test/wasm2js/float_misc.2asm.js index 8c5b7b0a3..f5b768e61 100644 --- a/test/wasm2js/float_misc.2asm.js +++ b/test/wasm2js/float_misc.2asm.js @@ -1,6 +1,6 @@ - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -22,11 +22,11 @@ } function wasm2js_scratch_load_f32() { - return f32ScratchView[0]; + return f32ScratchView[2]; } function wasm2js_scratch_store_f32(value) { - f32ScratchView[0] = value; + f32ScratchView[2] = value; } function asmFunc(global, env, buffer) { @@ -92,7 +92,7 @@ function asmFunc(global, env, buffer) { function $7(x, y) { x = Math_fround(x); y = Math_fround(y); - return Math_fround((wasm2js_scratch_store_i32(0, (wasm2js_scratch_store_f32(x), wasm2js_scratch_load_i32(0)) & 2147483647 | 0 | ((wasm2js_scratch_store_f32(y), wasm2js_scratch_load_i32(0)) & -2147483648 | 0) | 0), wasm2js_scratch_load_f32())); + return Math_fround((wasm2js_scratch_store_i32(2, (wasm2js_scratch_store_f32(x), wasm2js_scratch_load_i32(2)) & 2147483647 | 0 | ((wasm2js_scratch_store_f32(y), wasm2js_scratch_load_i32(2)) & -2147483648 | 0) | 0), wasm2js_scratch_load_f32())); } function $8(x) { diff --git a/test/wasm2js/left-to-right.2asm.js b/test/wasm2js/left-to-right.2asm.js index 5a2826c59..f5f19a1cd 100644 --- a/test/wasm2js/left-to-right.2asm.js +++ b/test/wasm2js/left-to-right.2asm.js @@ -1,6 +1,6 @@ - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -22,7 +22,7 @@ } function wasm2js_scratch_store_f32(value) { - f32ScratchView[0] = value; + f32ScratchView[2] = value; } function asmFunc(global, env, buffer) { @@ -1019,7 +1019,7 @@ function asmFunc(global, env, buffer) { function $98() { reset(); - (wasm2js_scratch_store_f32(Math_fround(f32_left())), wasm2js_scratch_load_i32(0)) & 2147483647 | 0 | ((wasm2js_scratch_store_f32(Math_fround(f32_right())), wasm2js_scratch_load_i32(0)) & -2147483648 | 0) | 0; + (wasm2js_scratch_store_f32(Math_fround(f32_left())), wasm2js_scratch_load_i32(2)) & 2147483647 | 0 | ((wasm2js_scratch_store_f32(Math_fround(f32_right())), wasm2js_scratch_load_i32(2)) & -2147483648 | 0) | 0; return get() | 0 | 0; } diff --git a/test/wasm2js/reinterpret.2asm.js b/test/wasm2js/reinterpret.2asm.js index 64e9161e0..e237552df 100644 --- a/test/wasm2js/reinterpret.2asm.js +++ b/test/wasm2js/reinterpret.2asm.js @@ -1,6 +1,6 @@ - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -22,11 +22,11 @@ } function wasm2js_scratch_store_f32(value) { - f32ScratchView[0] = value; + f32ScratchView[2] = value; } function wasm2js_scratch_load_f32() { - return f32ScratchView[0]; + return f32ScratchView[2]; } function asmFunc(global, env, buffer) { @@ -52,7 +52,7 @@ function asmFunc(global, env, buffer) { var infinity = global.Infinity; function $1($0) { $0 = $0 | 0; - return ((wasm2js_scratch_store_f32((wasm2js_scratch_store_i32(0, $0), wasm2js_scratch_load_f32())), wasm2js_scratch_load_i32(0)) | 0) == ($0 | 0) | 0; + return ((wasm2js_scratch_store_f32((wasm2js_scratch_store_i32(2, $0), wasm2js_scratch_load_f32())), wasm2js_scratch_load_i32(2)) | 0) == ($0 | 0) | 0; } function $2($0, $0$hi) { diff --git a/test/wasm2js/reinterpret.2asm.js.opt b/test/wasm2js/reinterpret.2asm.js.opt index 0a8408ff2..5015533ba 100644 --- a/test/wasm2js/reinterpret.2asm.js.opt +++ b/test/wasm2js/reinterpret.2asm.js.opt @@ -1,6 +1,6 @@ - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -22,11 +22,11 @@ } function wasm2js_scratch_store_f32(value) { - f32ScratchView[0] = value; + f32ScratchView[2] = value; } function wasm2js_scratch_load_f32() { - return f32ScratchView[0]; + return f32ScratchView[2]; } function asmFunc(global, env, buffer) { @@ -52,7 +52,7 @@ function asmFunc(global, env, buffer) { var infinity = global.Infinity; function $1($0) { $0 = $0 | 0; - return ((wasm2js_scratch_store_f32((wasm2js_scratch_store_i32(0, $0), wasm2js_scratch_load_f32())), wasm2js_scratch_load_i32(0)) | 0) == ($0 | 0) | 0; + return ((wasm2js_scratch_store_f32((wasm2js_scratch_store_i32(2, $0), wasm2js_scratch_load_f32())), wasm2js_scratch_load_i32(2)) | 0) == ($0 | 0) | 0; } function $2($0, $1_1) { diff --git a/test/wasm2js/reinterpret_scratch.2asm.js b/test/wasm2js/reinterpret_scratch.2asm.js new file mode 100644 index 000000000..51c4565f5 --- /dev/null +++ b/test/wasm2js/reinterpret_scratch.2asm.js @@ -0,0 +1,64 @@ + + + var scratchBuffer = new ArrayBuffer(16); + var i32ScratchView = new Int32Array(scratchBuffer); + var f32ScratchView = new Float32Array(scratchBuffer); + var f64ScratchView = new Float64Array(scratchBuffer); + + function wasm2js_scratch_load_i32(index) { + return i32ScratchView[index]; + } + + function wasm2js_scratch_store_f64(value) { + f64ScratchView[0] = value; + } + + function wasm2js_scratch_store_f32(value) { + f32ScratchView[2] = value; + } + +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() { + var i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, $0_1 = Math_fround(0); + wasm2js_scratch_store_f64(+(305419896.0)); + i64toi32_i32$0 = wasm2js_scratch_load_i32(1 | 0) | 0; + i64toi32_i32$1 = (wasm2js_scratch_store_f32($0_1), wasm2js_scratch_load_i32(2)); + HEAP32[i64toi32_i32$1 >> 2] = wasm2js_scratch_load_i32(0 | 0) | 0; + HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; + return HEAP32[0 >> 2] | 0 | 0; + } + + var FUNCTION_TABLE = []; + function __wasm_memory_size() { + return buffer.byteLength / 65536 | 0; + } + + return { + "foo": $0 + }; +} + +var memasmFunc = new ArrayBuffer(65536); +var bufferView = new Uint8Array(memasmFunc); +var retasmFunc = asmFunc({Math,Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,NaN,Infinity}, {abort:function() { throw new Error('abort'); }},memasmFunc); +export var foo = retasmFunc.foo; diff --git a/test/wasm2js/reinterpret_scratch.2asm.js.opt b/test/wasm2js/reinterpret_scratch.2asm.js.opt new file mode 100644 index 000000000..03052fa92 --- /dev/null +++ b/test/wasm2js/reinterpret_scratch.2asm.js.opt @@ -0,0 +1,59 @@ + + + var scratchBuffer = new ArrayBuffer(16); + var i32ScratchView = new Int32Array(scratchBuffer); + var f32ScratchView = new Float32Array(scratchBuffer); + var f64ScratchView = new Float64Array(scratchBuffer); + + function wasm2js_scratch_load_i32(index) { + return i32ScratchView[index]; + } + + function wasm2js_scratch_store_f64(value) { + f64ScratchView[0] = value; + } + +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() { + var $0_1 = 0; + wasm2js_scratch_store_f64(305419896.0); + $0_1 = wasm2js_scratch_load_i32(1) | 0; + HEAP32[0] = wasm2js_scratch_load_i32(0); + HEAP32[1] = $0_1; + return HEAP32[0]; + } + + var FUNCTION_TABLE = []; + function __wasm_memory_size() { + return buffer.byteLength / 65536 | 0; + } + + return { + "foo": $0 + }; +} + +var memasmFunc = new ArrayBuffer(65536); +var bufferView = new Uint8Array(memasmFunc); +var retasmFunc = asmFunc({Math,Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,NaN,Infinity}, {abort:function() { throw new Error('abort'); }},memasmFunc); +export var foo = retasmFunc.foo; diff --git a/test/wasm2js/reinterpret_scratch.wast b/test/wasm2js/reinterpret_scratch.wast new file mode 100644 index 000000000..bfaf68380 --- /dev/null +++ b/test/wasm2js/reinterpret_scratch.wast @@ -0,0 +1,17 @@ +(module + (memory $0 1 1) + (func "foo" (result i32) + (local $0 f32) + (i64.store align=4 + (i32.reinterpret_f32 ;; i32 0 + (local.get $0) ;; f32 0 + ) + (i64.reinterpret_f64 ;; these two reinterprets must not interfere with + (f64.const 0x12345678) ;; each other, even though both use scratch memory + ) + ) + (i32.load + (i32.const 0) + ) + ) +) diff --git a/test/wasm2js/unaligned.2asm.js b/test/wasm2js/unaligned.2asm.js index 2bf7da493..7bcd22aad 100644 --- a/test/wasm2js/unaligned.2asm.js +++ b/test/wasm2js/unaligned.2asm.js @@ -1,7 +1,7 @@ import { setTempRet0 } from 'env'; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -23,11 +23,11 @@ import { setTempRet0 } from 'env'; } function wasm2js_scratch_load_f32() { - return f32ScratchView[0]; + return f32ScratchView[2]; } function wasm2js_scratch_store_f32(value) { - f32ScratchView[0] = value; + f32ScratchView[2] = value; } function asmFunc(global, env, buffer) { @@ -71,7 +71,7 @@ function asmFunc(global, env, buffer) { function $2() { var $0_1 = 0; $0_1 = 0; - return Math_fround((wasm2js_scratch_store_i32(0, HEAPU8[$0_1 >> 0] | 0 | ((HEAPU8[($0_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0 | ((HEAPU8[($0_1 + 2 | 0) >> 0] | 0) << 16 | 0 | ((HEAPU8[($0_1 + 3 | 0) >> 0] | 0) << 24 | 0) | 0) | 0), wasm2js_scratch_load_f32())); + return Math_fround((wasm2js_scratch_store_i32(2, HEAPU8[$0_1 >> 0] | 0 | ((HEAPU8[($0_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0 | ((HEAPU8[($0_1 + 2 | 0) >> 0] | 0) << 16 | 0 | ((HEAPU8[($0_1 + 3 | 0) >> 0] | 0) << 24 | 0) | 0) | 0), wasm2js_scratch_load_f32())); } function $3() { @@ -111,7 +111,7 @@ function asmFunc(global, env, buffer) { function $6() { var $0_1 = 0, $1_1 = 0; $0_1 = 0; - $1_1 = (wasm2js_scratch_store_f32(Math_fround(0.0)), wasm2js_scratch_load_i32(0)); + $1_1 = (wasm2js_scratch_store_f32(Math_fround(0.0)), wasm2js_scratch_load_i32(2)); HEAP8[$0_1 >> 0] = $1_1; HEAP8[($0_1 + 1 | 0) >> 0] = $1_1 >>> 8 | 0; HEAP8[($0_1 + 2 | 0) >> 0] = $1_1 >>> 16 | 0; diff --git a/test/wasm2js/unaligned.2asm.js.opt b/test/wasm2js/unaligned.2asm.js.opt index 8ab514e8f..45627f215 100644 --- a/test/wasm2js/unaligned.2asm.js.opt +++ b/test/wasm2js/unaligned.2asm.js.opt @@ -1,7 +1,7 @@ import { setTempRet0 } from 'env'; - var scratchBuffer = new ArrayBuffer(8); + var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer); var f32ScratchView = new Float32Array(scratchBuffer); var f64ScratchView = new Float64Array(scratchBuffer); @@ -23,7 +23,7 @@ import { setTempRet0 } from 'env'; } function wasm2js_scratch_load_f32() { - return f32ScratchView[0]; + return f32ScratchView[2]; } function asmFunc(global, env, buffer) { @@ -59,7 +59,7 @@ function asmFunc(global, env, buffer) { } function $2() { - return Math_fround((wasm2js_scratch_store_i32(0, HEAPU8[0] | HEAPU8[1] << 8 | (HEAPU8[2] << 16 | HEAPU8[3] << 24)), wasm2js_scratch_load_f32())); + return Math_fround((wasm2js_scratch_store_i32(2, HEAPU8[0] | HEAPU8[1] << 8 | (HEAPU8[2] << 16 | HEAPU8[3] << 24)), wasm2js_scratch_load_f32())); } function $3() { |