memory-cloning.js (3708B)
1 // |jit-test| skip-if: !wasmThreadsEnabled() 2 3 // Basic structured cloning tests (specific to SpiderMonkey shell) 4 5 var memtypes = ['i32', 'i64']; 6 7 function makeMemoryDesc(memtype, d) { 8 if (memtype != '') { 9 d.address = memtype; 10 } 11 return d; 12 } 13 14 function Idx(memtype, v) { 15 return memtype == 'i64' ? BigInt(v) : v; 16 } 17 18 function Zero(memtype) { 19 return memtype == 'i64' ? 0n : 0; 20 } 21 22 // Should *not* be possible to serialize and deserialize memories that are not 23 // shared, whether we transfer them or not. 24 25 for ( let memtype of memtypes ) { 26 let mem1 = new WebAssembly.Memory(makeMemoryDesc(memtype, {initial: Idx(memtype, 2), maximum: Idx(memtype, 4)})); 27 assertErrorMessage(() => serialize(mem1), 28 TypeError, 29 /unsupported type for structured data/); 30 assertErrorMessage(() => serialize(mem1, [mem1]), 31 TypeError, 32 /invalid transferable array for structured clone/); 33 } 34 35 // Should be possible to serialize and deserialize memories that are shared, and 36 // observe shared effects. 37 38 for ( let memtype of memtypes ) { 39 let ptrtype = memtype == 'i64' ? memtype : 'i32'; 40 let mem1 = new WebAssembly.Memory(makeMemoryDesc(memtype, {initial: Idx(memtype, 2), maximum: Idx(memtype, 4), shared: true})); 41 let buf1 = mem1.buffer; 42 43 // Serialization and deserialization of shared memories work: 44 45 let mem2 = deserialize(serialize(mem1, [], {SharedArrayBuffer: 'allow'}), {SharedArrayBuffer: 'allow'}); 46 assertEq(mem2 instanceof WebAssembly.Memory, true); 47 let buf2 = mem2.buffer; 48 assertEq(buf2 instanceof SharedArrayBuffer, true); 49 50 assertEq(buf1 !== buf2, true); 51 assertEq(buf1.byteLength, buf2.byteLength); 52 if (memtype != '' && mem2.type) { 53 assertEq(mem2.type().address, memtype); 54 } 55 56 // Effects to one buffer must be reflected in the other: 57 58 let v1 = new Int32Array(buf1); 59 let v2 = new Int32Array(buf2); 60 61 v1[37] = 0x12345678; 62 assertEq(v2[37], 0x12345678); 63 64 // Growth in a memory is reflected in its clone: 65 66 let index = 2*65536 + 200; 67 let access = wasmEvalText(`(module 68 (memory (import "" "memory") ${memtype} 2 4 shared) 69 (func (export "l") (result ${ptrtype}) 70 (${ptrtype}.load (${ptrtype}.const ${index}))))`, 71 {"": {memory: mem2}}).exports.l; 72 73 // initially mem2 cannot be accessed at index 74 assertErrorMessage(access, WebAssembly.RuntimeError, /out of bounds/); 75 76 // then we grow mem1 77 wasmEvalText(`(module 78 (memory (import "" "memory") ${memtype} 2 4 shared) 79 (func (export "g") (drop (memory.grow (${ptrtype}.const 1)))))`, 80 {"": {memory: mem1}}).exports.g(); 81 82 // after growing mem1, mem2 can be accessed at index 83 assertEq(access(), Zero(memtype)); 84 } 85 86 // Should not be possible to transfer a shared memory 87 88 for ( let memtype of memtypes ) { 89 let mem1 = new WebAssembly.Memory(makeMemoryDesc(memtype, {initial: Idx(memtype, 2), maximum: Idx(memtype, 4), shared: true})); 90 assertErrorMessage(() => serialize(mem1, [mem1]), 91 TypeError, 92 /Shared memory objects must not be in the transfer list/); 93 94 } 95 96 // When serializing and deserializing a SAB extracted from a memory, the length 97 // of the SAB should not change even if the memory was grown after serialization 98 // and before deserialization. 99 100 for ( let memtype of memtypes ) { 101 let mem = new WebAssembly.Memory(makeMemoryDesc(memtype, {initial: Idx(memtype, 2), maximum: Idx(memtype, 4), shared: true})); 102 let buf = mem.buffer; 103 let clonedbuf = serialize(buf, [], {SharedArrayBuffer: 'allow'}); 104 mem.grow(Idx(memtype, 1)); 105 let buf2 = deserialize(clonedbuf, {SharedArrayBuffer: 'allow'}); 106 assertEq(buf.byteLength, buf2.byteLength); 107 }