diff options
Diffstat (limited to 'js/src/jit-test/tests/wasm/memory-cloning.js')
-rw-r--r-- | js/src/jit-test/tests/wasm/memory-cloning.js | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/memory-cloning.js b/js/src/jit-test/tests/wasm/memory-cloning.js new file mode 100644 index 0000000000..12b05e4aab --- /dev/null +++ b/js/src/jit-test/tests/wasm/memory-cloning.js @@ -0,0 +1,103 @@ +// |jit-test| skip-if: !wasmThreadsEnabled() + +// Basic structured cloning tests (specific to SpiderMonkey shell) + +var memtypes = wasmMemory64Enabled() ? ['i32', 'i64'] : ['']; + +function makeMemoryDesc(memtype, d) { + if (memtype != '') { + d.index = memtype; + } + return d; +} + +function Zero(memtype) { + return memtype == 'i64' ? 0n : 0; +} + +// Should *not* be possible to serialize and deserialize memories that are not +// shared, whether we transfer them or not. + +for ( let memtype of memtypes ) { + let mem1 = new WebAssembly.Memory(makeMemoryDesc(memtype, {initial: 2, maximum: 4})); + assertErrorMessage(() => serialize(mem1), + TypeError, + /unsupported type for structured data/); + assertErrorMessage(() => serialize(mem1, [mem1]), + TypeError, + /invalid transferable array for structured clone/); +} + +// Should be possible to serialize and deserialize memories that are shared, and +// observe shared effects. + +for ( let memtype of memtypes ) { + let ptrtype = memtype == 'i64' ? memtype : 'i32'; + let mem1 = new WebAssembly.Memory(makeMemoryDesc(memtype, {initial: 2, maximum: 4, shared: true})); + let buf1 = mem1.buffer; + + // Serialization and deserialization of shared memories work: + + let mem2 = deserialize(serialize(mem1, [], {SharedArrayBuffer: 'allow'}), {SharedArrayBuffer: 'allow'}); + assertEq(mem2 instanceof WebAssembly.Memory, true); + let buf2 = mem2.buffer; + assertEq(buf2 instanceof SharedArrayBuffer, true); + + assertEq(buf1 !== buf2, true); + assertEq(buf1.byteLength, buf2.byteLength); + if (memtype != '' && mem2.type) { + assertEq(mem2.type().index, memtype); + } + + // Effects to one buffer must be reflected in the other: + + let v1 = new Int32Array(buf1); + let v2 = new Int32Array(buf2); + + v1[37] = 0x12345678; + assertEq(v2[37], 0x12345678); + + // Growth in a memory is reflected in its clone: + + let index = 2*65536 + 200; + let access = wasmEvalText(`(module + (memory (import "" "memory") ${memtype} 2 4 shared) + (func (export "l") (result ${ptrtype}) + (${ptrtype}.load (${ptrtype}.const ${index}))))`, + {"": {memory: mem2}}).exports.l; + + // initially mem2 cannot be accessed at index + assertErrorMessage(access, WebAssembly.RuntimeError, /out of bounds/); + + // then we grow mem1 + wasmEvalText(`(module + (memory (import "" "memory") ${memtype} 2 4 shared) + (func (export "g") (drop (memory.grow (${ptrtype}.const 1)))))`, + {"": {memory: mem1}}).exports.g(); + + // after growing mem1, mem2 can be accessed at index + assertEq(access(), Zero(memtype)); +} + +// Should not be possible to transfer a shared memory + +for ( let memtype of memtypes ) { + let mem1 = new WebAssembly.Memory(makeMemoryDesc(memtype, {initial: 2, maximum: 4, shared: true})); + assertErrorMessage(() => serialize(mem1, [mem1]), + TypeError, + /Shared memory objects must not be in the transfer list/); + +} + +// When serializing and deserializing a SAB extracted from a memory, the length +// of the SAB should not change even if the memory was grown after serialization +// and before deserialization. + +for ( let memtype of memtypes ) { + let mem = new WebAssembly.Memory(makeMemoryDesc(memtype, {initial: 2, maximum: 4, shared: true})); + let buf = mem.buffer; + let clonedbuf = serialize(buf, [], {SharedArrayBuffer: 'allow'}); + mem.grow(1); + let buf2 = deserialize(clonedbuf, {SharedArrayBuffer: 'allow'}); + assertEq(buf.byteLength, buf2.byteLength); +} |