|
@@ -0,0 +1,189 @@
|
|
|
+// META: global=window,dedicatedworker,jsshell,shadowrealm
|
|
|
+// META: script=/wasm/jsapi/memory/assertions.js
|
|
|
+
|
|
|
+test(() => {
|
|
|
+ const argument = { "initial": 0 };
|
|
|
+ const memory = new WebAssembly.Memory(argument);
|
|
|
+ assert_throws_js(TypeError, () => memory.grow());
|
|
|
+}, "Missing arguments");
|
|
|
+
|
|
|
+test(t => {
|
|
|
+ const thisValues = [
|
|
|
+ undefined,
|
|
|
+ null,
|
|
|
+ true,
|
|
|
+ "",
|
|
|
+ Symbol(),
|
|
|
+ 1,
|
|
|
+ {},
|
|
|
+ WebAssembly.Memory,
|
|
|
+ WebAssembly.Memory.prototype,
|
|
|
+ ];
|
|
|
+
|
|
|
+ const argument = {
|
|
|
+ valueOf: t.unreached_func("Should not touch the argument (valueOf)"),
|
|
|
+ toString: t.unreached_func("Should not touch the argument (toString)"),
|
|
|
+ };
|
|
|
+
|
|
|
+ const fn = WebAssembly.Memory.prototype.grow;
|
|
|
+
|
|
|
+ for (const thisValue of thisValues) {
|
|
|
+ assert_throws_js(TypeError, () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`);
|
|
|
+ }
|
|
|
+}, "Branding");
|
|
|
+
|
|
|
+test(() => {
|
|
|
+ const argument = { "initial": 0 };
|
|
|
+ const memory = new WebAssembly.Memory(argument);
|
|
|
+ const oldMemory = memory.buffer;
|
|
|
+ assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing");
|
|
|
+
|
|
|
+ const result = memory.grow(2);
|
|
|
+ assert_equals(result, 0);
|
|
|
+
|
|
|
+ const newMemory = memory.buffer;
|
|
|
+ assert_not_equals(oldMemory, newMemory);
|
|
|
+ assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing");
|
|
|
+ assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing");
|
|
|
+}, "Zero initial");
|
|
|
+
|
|
|
+test(() => {
|
|
|
+ const argument = { "initial": { valueOf() { return 0 } } };
|
|
|
+ const memory = new WebAssembly.Memory(argument);
|
|
|
+ const oldMemory = memory.buffer;
|
|
|
+ assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing");
|
|
|
+
|
|
|
+ const result = memory.grow({ valueOf() { return 2 } });
|
|
|
+ assert_equals(result, 0);
|
|
|
+
|
|
|
+ const newMemory = memory.buffer;
|
|
|
+ assert_not_equals(oldMemory, newMemory);
|
|
|
+ assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing");
|
|
|
+ assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing");
|
|
|
+}, "Zero initial with valueOf");
|
|
|
+
|
|
|
+test(() => {
|
|
|
+ const argument = { "initial": 3 };
|
|
|
+ const memory = new WebAssembly.Memory(argument);
|
|
|
+ const oldMemory = memory.buffer;
|
|
|
+ assert_ArrayBuffer(oldMemory, { "size": 3 }, "Buffer before growing");
|
|
|
+
|
|
|
+ const result = memory.grow(2);
|
|
|
+ assert_equals(result, 3);
|
|
|
+
|
|
|
+ const newMemory = memory.buffer;
|
|
|
+ assert_not_equals(oldMemory, newMemory);
|
|
|
+ assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing");
|
|
|
+ assert_ArrayBuffer(newMemory, { "size": 5 }, "New buffer after growing");
|
|
|
+}, "Non-zero initial");
|
|
|
+
|
|
|
+test(() => {
|
|
|
+ const argument = { "initial": 0, "maximum": 2 };
|
|
|
+ const memory = new WebAssembly.Memory(argument);
|
|
|
+ const oldMemory = memory.buffer;
|
|
|
+ assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing");
|
|
|
+
|
|
|
+ const result = memory.grow(2);
|
|
|
+ assert_equals(result, 0);
|
|
|
+
|
|
|
+ const newMemory = memory.buffer;
|
|
|
+ assert_not_equals(oldMemory, newMemory);
|
|
|
+ assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing");
|
|
|
+ assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing");
|
|
|
+}, "Zero initial with respected maximum");
|
|
|
+
|
|
|
+test(() => {
|
|
|
+ const argument = { "initial": 0, "maximum": 2 };
|
|
|
+ const memory = new WebAssembly.Memory(argument);
|
|
|
+ const oldMemory = memory.buffer;
|
|
|
+ assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing");
|
|
|
+
|
|
|
+ const result = memory.grow(1);
|
|
|
+ assert_equals(result, 0);
|
|
|
+
|
|
|
+ const newMemory = memory.buffer;
|
|
|
+ assert_not_equals(oldMemory, newMemory);
|
|
|
+ assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing once");
|
|
|
+ assert_ArrayBuffer(newMemory, { "size": 1 }, "New buffer after growing once");
|
|
|
+
|
|
|
+ const result2 = memory.grow(1);
|
|
|
+ assert_equals(result2, 1);
|
|
|
+
|
|
|
+ const newestMemory = memory.buffer;
|
|
|
+ assert_not_equals(newMemory, newestMemory);
|
|
|
+ assert_ArrayBuffer(oldMemory, { "detached": true }, "New buffer after growing twice");
|
|
|
+ assert_ArrayBuffer(newMemory, { "detached": true }, "New buffer after growing twice");
|
|
|
+ assert_ArrayBuffer(newestMemory, { "size": 2 }, "Newest buffer after growing twice");
|
|
|
+}, "Zero initial with respected maximum grown twice");
|
|
|
+
|
|
|
+test(() => {
|
|
|
+ const argument = { "initial": 1, "maximum": 2 };
|
|
|
+ const memory = new WebAssembly.Memory(argument);
|
|
|
+ const oldMemory = memory.buffer;
|
|
|
+ assert_ArrayBuffer(oldMemory, { "size": 1 }, "Buffer before growing");
|
|
|
+
|
|
|
+ assert_throws_js(RangeError, () => memory.grow(2));
|
|
|
+ assert_equals(memory.buffer, oldMemory);
|
|
|
+ assert_ArrayBuffer(memory.buffer, { "size": 1 }, "Buffer before trying to grow");
|
|
|
+}, "Zero initial growing too much");
|
|
|
+
|
|
|
+const outOfRangeValues = [
|
|
|
+ undefined,
|
|
|
+ NaN,
|
|
|
+ Infinity,
|
|
|
+ -Infinity,
|
|
|
+ -1,
|
|
|
+ 0x100000000,
|
|
|
+ 0x1000000000,
|
|
|
+ "0x100000000",
|
|
|
+ { valueOf() { return 0x100000000; } },
|
|
|
+];
|
|
|
+
|
|
|
+for (const value of outOfRangeValues) {
|
|
|
+ test(() => {
|
|
|
+ const argument = { "initial": 0 };
|
|
|
+ const memory = new WebAssembly.Memory(argument);
|
|
|
+ assert_throws_js(TypeError, () => memory.grow(value));
|
|
|
+ }, `Out-of-range argument: ${format_value(value)}`);
|
|
|
+}
|
|
|
+
|
|
|
+test(() => {
|
|
|
+ const argument = { "initial": 0 };
|
|
|
+ const memory = new WebAssembly.Memory(argument);
|
|
|
+ const oldMemory = memory.buffer;
|
|
|
+ assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing");
|
|
|
+
|
|
|
+ const result = memory.grow(2, {});
|
|
|
+ assert_equals(result, 0);
|
|
|
+
|
|
|
+ const newMemory = memory.buffer;
|
|
|
+ assert_not_equals(oldMemory, newMemory);
|
|
|
+ assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing");
|
|
|
+ assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing");
|
|
|
+}, "Stray argument");
|
|
|
+
|
|
|
+test(() => {
|
|
|
+ const argument = { "initial": 1, "maximum": 2, "shared": true };
|
|
|
+ const memory = new WebAssembly.Memory(argument);
|
|
|
+ const oldMemory = memory.buffer;
|
|
|
+ assert_ArrayBuffer(oldMemory, { "size": 1, "shared": true }, "Buffer before growing");
|
|
|
+
|
|
|
+ const result = memory.grow(1);
|
|
|
+ assert_equals(result, 1);
|
|
|
+
|
|
|
+ const newMemory = memory.buffer;
|
|
|
+ assert_not_equals(oldMemory, newMemory);
|
|
|
+ assert_ArrayBuffer(oldMemory, { "size": 1, "shared": true }, "Old buffer after growing");
|
|
|
+ assert_ArrayBuffer(newMemory, { "size": 2, "shared": true }, "New buffer after growing");
|
|
|
+
|
|
|
+ // The old and new buffers must have the same value for the
|
|
|
+ // [[ArrayBufferData]] internal slot.
|
|
|
+ const oldArray = new Uint8Array(oldMemory);
|
|
|
+ const newArray = new Uint8Array(newMemory);
|
|
|
+ assert_equals(oldArray[0], 0, "old first element");
|
|
|
+ assert_equals(newArray[0], 0, "new first element");
|
|
|
+ oldArray[0] = 1;
|
|
|
+ assert_equals(oldArray[0], 1, "old first element");
|
|
|
+ assert_equals(newArray[0], 1, "new first element");
|
|
|
+
|
|
|
+}, "Growing shared memory does not detach old buffer");
|