Bug 1412852 - Test cases for structured cloning of wasm memory objects. r=luke
authorLars T Hansen <lhansen@mozilla.com>
Tue, 31 Oct 2017 16:36:05 +0100
changeset 701933 a2f237ccf5bf2ac923bbf8d2cb1b175a50e3f532
parent 701932 e8fb22afd5aaad1bd5b4b36725e4856b4557843e
child 701934 bb88efd97a282d4ec1c517903a684360497d848f
push id90308
push userbmo:lhansen@mozilla.com
push dateWed, 22 Nov 2017 12:45:04 +0000
reviewersluke
bugs1412852
milestone59.0a1
Bug 1412852 - Test cases for structured cloning of wasm memory objects. r=luke
js/src/jit-test/tests/wasm/memory-cloning.js
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/memory-cloning.js
@@ -0,0 +1,87 @@
+// Basic structured cloning tests (specific to SpiderMonkey shell)
+
+if (!wasmThreadsSupported())
+    quit(0);
+
+// Should *not* be possible to serialize and deserialize memories that are not
+// shared, whether we transfer them or not.
+
+{
+    let mem1 = new WebAssembly.Memory({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.
+
+{
+    let mem1 = new WebAssembly.Memory({initial: 2, maximum: 4, shared: true});
+    let buf1 = mem1.buffer;
+
+    // Serialization and deserialization of shared memories work:
+
+    let mem2 = deserialize(serialize(mem1));
+    assertEq(mem2 instanceof WebAssembly.Memory, true);
+    let buf2 = mem2.buffer;
+    assertEq(buf2 instanceof SharedArrayBuffer, true);
+
+    assertEq(buf1 !== buf2, true);
+    assertEq(buf1.byteLength, buf2.byteLength);
+
+    // 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") 2 4 shared)
+				(func (export "l") (result i32)
+				 (i32.load (i32.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") 2 4 shared)
+		   (func (export "g") (drop (grow_memory (i32.const 1)))))`,
+		 {"": {memory: mem1}}).exports.g();
+
+    // after growing mem1, mem2 can be accessed at index
+    assertEq(access(), 0);
+}
+
+// Should not be possible to transfer a shared memory
+
+{
+    let mem1 = new WebAssembly.Memory({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.
+
+{
+    let mem = new WebAssembly.Memory({initial: 2, maximum: 4, shared: true});
+    let buf = mem.buffer;
+    let clonedbuf = serialize(buf);
+    mem.grow(1);
+    let buf2 = deserialize(clonedbuf);
+    assertEq(buf.byteLength, buf2.byteLength);
+}