diff options
Diffstat (limited to '')
-rw-r--r-- | js/src/jit-test/tests/wasm/regress/current-memory-tls.js | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/regress/current-memory-tls.js b/js/src/jit-test/tests/wasm/regress/current-memory-tls.js new file mode 100644 index 0000000000..6bd46b2b5f --- /dev/null +++ b/js/src/jit-test/tests/wasm/regress/current-memory-tls.js @@ -0,0 +1,95 @@ +// Bug 1341650: +// - when compiled with Ion, pass the TLS register to memory.size; +// - when compiled with Baseline, don't clobber the last stack slot when +// calling into memory.size/memory.grow; + +// This toy module starts with an empty memory, then tries to set values at different +// indexes, automatically growing memory when that would trigger an out of +// bounds access, for the exact right amount of pages. Note it's not made for +// efficiency, but optimizing it doesn't trigger the bugs mentioned above. + +let i = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` +(module + (memory $mem (export "mem") 0 65535) + + (func (export "cur_mem") (result i32) (memory.size)) + + (func $maybeGrow (param $i i32) (local $smem i32) + ;; get memory.size in number of bytes, not pages. + memory.size + i64.extend_u/i32 + i64.const 65536 + i64.mul + + ;; get the last byte index accessed by an int32 access. + local.get $i + i32.const 3 + i32.add + tee_local $i + i64.extend_u/i32 + + ;; if the memory is too small, grow it. + i64.le_u + if + ;; get the floor of the accessed *page* index. + local.get $i + i64.extend_u/i32 + i64.const 65536 + i64.div_u + + ;; subtract to that the size of the current memory in pages; + ;; that's the amount of pages we want to grow, minus one. + memory.size + i64.extend_u/i32 + + i64.sub + + ;; add 1 to that amount. + i64.const 1 + i64.add + + ;; get back to i32 and grow memory. + i32.wrap/i64 + memory.grow + drop + end + ) + + (func (export "set") (param $i i32) (param $v i32) + local.get $i + call $maybeGrow + local.get $i + local.get $v + i32.store + ) + + (func (export "get") (param $i i32) (result i32) + local.get $i + i32.load + ) +) +`))).exports; + +assertEq(i.cur_mem(), 0); + +i.set(0, 1); +assertEq(i.get(0), 1); + +assertEq(i.cur_mem(), 1); + +i.set(1234, 1); +assertEq(i.get(1234), 1); + +assertEq(i.cur_mem(), 1); + +i.set(65532, 1); +assertEq(i.get(65532), 1); + +assertErrorMessage(() => i.get(65533), WebAssembly.RuntimeError, /index out of bounds/); + +assertEq(i.cur_mem(), 1); + +i.set(65533, 1); +assertEq(i.get(65533), 1); + +assertEq(i.cur_mem(), 2); |