mirror of
https://github.com/servo/servo.git
synced 2025-09-03 19:48:21 +01:00
Update web-platform-tests to revision 2b7dace05fc1869398ee24f84fda4c0e4c0455ae
This commit is contained in:
parent
b23125d590
commit
6c901de216
844 changed files with 19802 additions and 3093 deletions
|
@ -0,0 +1,121 @@
|
|||
// META: global=jsshell
|
||||
// META: script=/wasm/jsapi/assertions.js
|
||||
|
||||
function assert_Global(actual, expected) {
|
||||
assert_equals(Object.getPrototypeOf(actual), WebAssembly.Global.prototype,
|
||||
"prototype");
|
||||
assert_true(Object.isExtensible(actual), "extensible");
|
||||
|
||||
assert_equals(actual.value, expected, "value");
|
||||
assert_equals(actual.valueOf(), expected, "valueOf");
|
||||
}
|
||||
|
||||
test(() => {
|
||||
assert_function_name(WebAssembly.Global, "Global", "WebAssembly.Global");
|
||||
}, "name");
|
||||
|
||||
test(() => {
|
||||
assert_function_length(WebAssembly.Global, 1, "WebAssembly.Global");
|
||||
}, "length");
|
||||
|
||||
test(() => {
|
||||
assert_throws(new TypeError(), () => new WebAssembly.Global());
|
||||
}, "No arguments");
|
||||
|
||||
test(() => {
|
||||
const argument = { "value": "i32" };
|
||||
assert_throws(new TypeError(), () => WebAssembly.Global(argument));
|
||||
}, "Calling");
|
||||
|
||||
test(() => {
|
||||
const order = [];
|
||||
|
||||
new WebAssembly.Global({
|
||||
get value() {
|
||||
order.push("descriptor value");
|
||||
return {
|
||||
toString() {
|
||||
order.push("descriptor value toString");
|
||||
return "f64";
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
get mutable() {
|
||||
order.push("descriptor mutable");
|
||||
return false;
|
||||
},
|
||||
}, {
|
||||
valueOf() {
|
||||
order.push("value valueOf()");
|
||||
}
|
||||
});
|
||||
|
||||
assert_array_equals(order, [
|
||||
"descriptor mutable",
|
||||
"descriptor value",
|
||||
"descriptor value toString",
|
||||
"value valueOf()",
|
||||
]);
|
||||
}, "Order of evaluation");
|
||||
|
||||
test(() => {
|
||||
const invalidArguments = [
|
||||
undefined,
|
||||
null,
|
||||
false,
|
||||
true,
|
||||
"",
|
||||
"test",
|
||||
Symbol(),
|
||||
1,
|
||||
NaN,
|
||||
{},
|
||||
];
|
||||
for (const invalidArgument of invalidArguments) {
|
||||
assert_throws(new TypeError(),
|
||||
() => new WebAssembly.Global(invalidArgument),
|
||||
`new Global(${format_value(invalidArgument)})`);
|
||||
}
|
||||
}, "Invalid descriptor argument");
|
||||
|
||||
test(() => {
|
||||
const invalidTypes = ["i16", "i128", "f16", "f128", "u32", "u64", "i32\0"];
|
||||
for (const value of invalidTypes) {
|
||||
const argument = { value };
|
||||
assert_throws(new TypeError(), () => new WebAssembly.Global(argument));
|
||||
}
|
||||
}, "Invalid type argument");
|
||||
|
||||
test(() => {
|
||||
const argument = { "value": "i64" };
|
||||
const global = new WebAssembly.Global(argument);
|
||||
assert_throws(new TypeError(), () => global.value);
|
||||
assert_throws(new TypeError(), () => global.valueOf());
|
||||
}, "i64 with default");
|
||||
|
||||
for (const type of ["i32", "f32", "f64"]) {
|
||||
test(() => {
|
||||
const argument = { "value": type };
|
||||
const global = new WebAssembly.Global(argument);
|
||||
assert_Global(global, 0);
|
||||
}, `Default value for type ${type}`);
|
||||
|
||||
const valueArguments = [
|
||||
[undefined, 0],
|
||||
[null, 0],
|
||||
[true, 1],
|
||||
[false, 0],
|
||||
[2, 2],
|
||||
["3", 3],
|
||||
[{ toString() { return "5" } }, 5, "object with toString"],
|
||||
[{ valueOf() { return "8" } }, 8, "object with valueOf"],
|
||||
];
|
||||
for (const [value, expected, name = format_value(value)] of valueArguments) {
|
||||
test(() => {
|
||||
const argument = { "value": type };
|
||||
const global = new WebAssembly.Global(argument, value);
|
||||
assert_Global(global, expected);
|
||||
}, `Explicit value ${name} for type ${type}`);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
// META: global=jsshell
|
||||
|
||||
test(() => {
|
||||
const argument = { "value": "i32" };
|
||||
const global = new WebAssembly.Global(argument);
|
||||
assert_class_string(global, "WebAssembly.Global");
|
||||
}, "Object.prototype.toString on an Global");
|
|
@ -0,0 +1,94 @@
|
|||
// META: global=jsshell
|
||||
|
||||
test(() => {
|
||||
const thisValues = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Global,
|
||||
WebAssembly.Global.prototype,
|
||||
];
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value");
|
||||
assert_equals(typeof desc, "object");
|
||||
|
||||
const getter = desc.get;
|
||||
assert_equals(typeof getter, "function");
|
||||
|
||||
const setter = desc.set;
|
||||
assert_equals(typeof setter, "function");
|
||||
|
||||
for (const thisValue of thisValues) {
|
||||
assert_throws(new TypeError(), () => getter.call(thisValue), `getter with this=${format_value(thisValue)}`);
|
||||
assert_throws(new TypeError(), () => setter.call(thisValue, 1), `setter with this=${format_value(thisValue)}`);
|
||||
}
|
||||
}, "Branding");
|
||||
|
||||
for (const type of ["i32", "f32", "f64"]) {
|
||||
const immutableOptions = [
|
||||
[{}, "missing"],
|
||||
[{ "mutable": undefined }, "undefined"],
|
||||
[{ "mutable": null }, "null"],
|
||||
[{ "mutable": false }, "false"],
|
||||
[{ "mutable": "" }, "empty string"],
|
||||
[{ "mutable": 0 }, "zero"],
|
||||
];
|
||||
for (const [opts, name] of immutableOptions) {
|
||||
test(() => {
|
||||
opts.value = type;
|
||||
const global = new WebAssembly.Global(opts);
|
||||
assert_equals(global.value, 0, "initial value");
|
||||
assert_equals(global.valueOf(), 0, "initial valueOf");
|
||||
|
||||
assert_throws(new TypeError(), () => global.value = 1);
|
||||
|
||||
assert_equals(global.value, 0, "post-set value");
|
||||
assert_equals(global.valueOf(), 0, "post-set valueOf");
|
||||
}, `Immutable ${type} (${name})`);
|
||||
}
|
||||
|
||||
const mutableOptions = [
|
||||
[{ "mutable": true }, "true"],
|
||||
[{ "mutable": 1 }, "one"],
|
||||
[{ "mutable": "x" }, "string"],
|
||||
[Object.create({ "mutable": true }), "true on prototype"],
|
||||
];
|
||||
for (const [opts, name] of mutableOptions) {
|
||||
test(() => {
|
||||
opts.value = type;
|
||||
const global = new WebAssembly.Global(opts);
|
||||
assert_equals(global.value, 0, "initial value");
|
||||
assert_equals(global.valueOf(), 0, "initial valueOf");
|
||||
|
||||
global.value = 1;
|
||||
|
||||
assert_equals(global.value, 1, "post-set value");
|
||||
assert_equals(global.valueOf(), 1, "post-set valueOf");
|
||||
}, `Mutable ${type} (${name})`);
|
||||
}
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const argument = { "value": "i64", "mutable": true };
|
||||
const global = new WebAssembly.Global(argument);
|
||||
assert_throws(new TypeError(), () => global.value);
|
||||
assert_throws(new TypeError(), () => global.value = 0);
|
||||
assert_throws(new TypeError(), () => global.valueOf());
|
||||
}, "i64 with default");
|
||||
|
||||
|
||||
test(() => {
|
||||
const argument = { "value": "i32", "mutable": true };
|
||||
const global = new WebAssembly.Global(argument);
|
||||
const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value");
|
||||
assert_equals(typeof desc, "object");
|
||||
|
||||
const setter = desc.set;
|
||||
assert_equals(typeof setter, "function");
|
||||
|
||||
assert_throws(new TypeError(), () => setter.call(global));
|
||||
}, "Calling setter without argument");
|
|
@ -0,0 +1,22 @@
|
|||
// META: global=jsshell
|
||||
|
||||
test(() => {
|
||||
const argument = { "value": "i32" };
|
||||
const thisValues = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Global,
|
||||
WebAssembly.Global.prototype,
|
||||
];
|
||||
|
||||
const fn = WebAssembly.Global.prototype.valueOf;
|
||||
|
||||
for (const thisValue of thisValues) {
|
||||
assert_throws(new TypeError(), () => fn.call(thisValue), `this=${format_value(thisValue)}`);
|
||||
}
|
||||
}, "Branding");
|
|
@ -28,6 +28,7 @@ function assert_Instance(instance, expected_exports) {
|
|||
assert_true(property.enumerable, `${key}: enumerable`);
|
||||
assert_false(property.configurable, `${key}: configurable`);
|
||||
const actual = property.value;
|
||||
assert_true(Object.isExtensible(actual), `${key}: extensible`);
|
||||
|
||||
switch (expected.kind) {
|
||||
case "function":
|
||||
|
@ -75,6 +76,39 @@ test(() => {
|
|||
assert_throws(new TypeError(), () => new WebAssembly.Instance());
|
||||
}, "No arguments");
|
||||
|
||||
test(() => {
|
||||
const invalidArguments = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Module,
|
||||
WebAssembly.Module.prototype,
|
||||
];
|
||||
for (const argument of invalidArguments) {
|
||||
assert_throws(new TypeError(), () => new WebAssembly.Instance(argument),
|
||||
`new Instance(${format_value(argument)})`);
|
||||
}
|
||||
}, "Non-Module arguments");
|
||||
|
||||
test(() => {
|
||||
const module = new WebAssembly.Module(emptyModuleBinary);
|
||||
const invalidArguments = [
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
];
|
||||
for (const argument of invalidArguments) {
|
||||
assert_throws(new TypeError(), () => new WebAssembly.Instance(module, argument),
|
||||
`new Instance(module, ${format_value(argument)})`);
|
||||
}
|
||||
}, "Non-object imports");
|
||||
|
||||
test(() => {
|
||||
const module = new WebAssembly.Module(emptyModuleBinary);
|
||||
assert_throws(new TypeError(), () => WebAssembly.Instance(module));
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
// META: global=jsshell
|
||||
// META: script=/wasm/jsapi/wasm-constants.js
|
||||
// META: script=/wasm/jsapi/wasm-module-builder.js
|
||||
|
||||
let emptyModuleBinary;
|
||||
setup(() => {
|
||||
emptyModuleBinary = new WasmModuleBuilder().toBuffer();
|
||||
});
|
||||
|
||||
test(() => {
|
||||
const thisValues = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Instance,
|
||||
WebAssembly.Instance.prototype,
|
||||
];
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor(WebAssembly.Instance.prototype, "exports");
|
||||
assert_equals(typeof desc, "object");
|
||||
|
||||
const getter = desc.get;
|
||||
assert_equals(typeof getter, "function");
|
||||
|
||||
assert_equals(typeof desc.set, "undefined");
|
||||
|
||||
for (const thisValue of thisValues) {
|
||||
assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`);
|
||||
}
|
||||
}, "Branding");
|
||||
|
||||
test(() => {
|
||||
const module = new WebAssembly.Module(emptyModuleBinary);
|
||||
const instance = new WebAssembly.Instance(module);
|
||||
const exports = instance.exports;
|
||||
instance.exports = {};
|
||||
assert_equals(instance.exports, exports, "Should not change the exports");
|
||||
}, "Setting (sloppy mode)");
|
||||
|
||||
test(() => {
|
||||
const module = new WebAssembly.Module(emptyModuleBinary);
|
||||
const instance = new WebAssembly.Instance(module);
|
||||
const exports = instance.exports;
|
||||
assert_throws(new TypeError(), () => {
|
||||
"use strict";
|
||||
instance.exports = {};
|
||||
});
|
||||
assert_equals(instance.exports, exports, "Should not change the exports");
|
||||
}, "Setting (strict mode)");
|
|
@ -0,0 +1,10 @@
|
|||
// META: global=jsshell
|
||||
// META: script=/wasm/jsapi/wasm-constants.js
|
||||
// META: script=/wasm/jsapi/wasm-module-builder.js
|
||||
|
||||
test(() => {
|
||||
const emptyModuleBinary = new WasmModuleBuilder().toBuffer();
|
||||
const module = new WebAssembly.Module(emptyModuleBinary);
|
||||
const instance = new WebAssembly.Instance(module);
|
||||
assert_class_string(instance, "WebAssembly.Instance");
|
||||
}, "Object.prototype.toString on an Instance");
|
|
@ -62,6 +62,10 @@ test(() => {
|
|||
assert_equals(propdesc.value, this.WebAssembly);
|
||||
}, "WebAssembly: property descriptor");
|
||||
|
||||
test(() => {
|
||||
assert_throws(new TypeError(), () => WebAssembly());
|
||||
}, "WebAssembly: calling");
|
||||
|
||||
test(() => {
|
||||
assert_throws(new TypeError(), () => new WebAssembly());
|
||||
}, "WebAssembly: constructing");
|
||||
|
@ -87,6 +91,15 @@ for (const name of interfaces) {
|
|||
assert_equals(propdesc.value, WebAssembly[name]);
|
||||
}, `WebAssembly.${name}: property descriptor`);
|
||||
|
||||
test(() => {
|
||||
const interface_object = WebAssembly[name];
|
||||
const propdesc = Object.getOwnPropertyDescriptor(interface_object, "prototype");
|
||||
assert_equals(typeof propdesc, "object");
|
||||
assert_false(propdesc.writable, "writable");
|
||||
assert_false(propdesc.enumerable, "enumerable");
|
||||
assert_false(propdesc.configurable, "configurable");
|
||||
}, `WebAssembly.${name}: prototype`);
|
||||
|
||||
test(() => {
|
||||
const interface_object = WebAssembly[name];
|
||||
const interface_prototype_object = interface_object.prototype;
|
||||
|
@ -96,7 +109,7 @@ for (const name of interfaces) {
|
|||
assert_false(propdesc.enumerable, "enumerable");
|
||||
assert_true(propdesc.configurable, "configurable");
|
||||
assert_equals(propdesc.value, interface_object);
|
||||
}, `WebAssembly.${name}: prototype`);
|
||||
}, `WebAssembly.${name}: prototype.constructor`);
|
||||
}
|
||||
|
||||
test_operations(WebAssembly, "WebAssembly", [
|
||||
|
|
50
tests/wpt/web-platform-tests/wasm/jsapi/memory/buffer.any.js
Normal file
50
tests/wpt/web-platform-tests/wasm/jsapi/memory/buffer.any.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
// META: global=jsshell
|
||||
|
||||
test(() => {
|
||||
const thisValues = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Memory,
|
||||
WebAssembly.Memory.prototype,
|
||||
];
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor(WebAssembly.Memory.prototype, "buffer");
|
||||
assert_equals(typeof desc, "object");
|
||||
|
||||
const getter = desc.get;
|
||||
assert_equals(typeof getter, "function");
|
||||
|
||||
assert_equals(typeof desc.set, "undefined");
|
||||
|
||||
for (const thisValue of thisValues) {
|
||||
assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`);
|
||||
}
|
||||
}, "Branding");
|
||||
|
||||
test(() => {
|
||||
const argument = { "initial": 0 };
|
||||
const memory = new WebAssembly.Memory(argument);
|
||||
const memory2 = new WebAssembly.Memory(argument);
|
||||
const buffer = memory.buffer;
|
||||
assert_not_equals(buffer, memory2.buffer, "Need two distinct buffers");
|
||||
memory.buffer = memory2.buffer;
|
||||
assert_equals(memory.buffer, buffer, "Should not change the buffer");
|
||||
}, "Setting (sloppy mode)");
|
||||
|
||||
test(() => {
|
||||
const argument = { "initial": 0 };
|
||||
const memory = new WebAssembly.Memory(argument);
|
||||
const memory2 = new WebAssembly.Memory(argument);
|
||||
const buffer = memory.buffer;
|
||||
assert_not_equals(buffer, memory2.buffer, "Need two distinct buffers");
|
||||
assert_throws(new TypeError(), () => {
|
||||
"use strict";
|
||||
memory.buffer = memory2.buffer;
|
||||
});
|
||||
assert_equals(memory.buffer, buffer, "Should not change the buffer");
|
||||
}, "Setting (strict mode)");
|
|
@ -1,12 +1,23 @@
|
|||
// META: global=jsshell
|
||||
// META: script=/wasm/jsapi/wasm-constants.js
|
||||
// META: script=/wasm/jsapi/wasm-module-builder.js
|
||||
// META: script=/wasm/jsapi/assertions.js
|
||||
|
||||
let emptyModuleBinary;
|
||||
setup(() => {
|
||||
emptyModuleBinary = new WasmModuleBuilder().toBuffer();
|
||||
});
|
||||
function assert_Memory(memory, expected) {
|
||||
assert_equals(Object.getPrototypeOf(memory), WebAssembly.Memory.prototype,
|
||||
"prototype");
|
||||
assert_true(Object.isExtensible(memory), "extensible");
|
||||
|
||||
// https://github.com/WebAssembly/spec/issues/840
|
||||
assert_equals(memory.buffer, memory.buffer, "buffer should be idempotent");
|
||||
assert_equals(Object.getPrototypeOf(memory.buffer), ArrayBuffer.prototype,
|
||||
"prototype of buffer");
|
||||
assert_true(Object.isExtensible(memory.buffer), "buffer extensibility");
|
||||
assert_equals(memory.buffer.byteLength, 0x10000 * expected.size, "size of buffer");
|
||||
if (expected.size > 0) {
|
||||
const array = new Uint8Array(memory.buffer);
|
||||
assert_equals(array[0], 0, "first element of buffer");
|
||||
assert_equals(array[array.byteLength - 1], 0, "last element of buffer");
|
||||
}
|
||||
}
|
||||
|
||||
test(() => {
|
||||
assert_function_name(WebAssembly.Memory, "Memory", "WebAssembly.Memory");
|
||||
|
@ -26,8 +37,24 @@ test(() => {
|
|||
}, "Calling");
|
||||
|
||||
test(() => {
|
||||
assert_throws(new TypeError(), () => new WebAssembly.Memory({}));
|
||||
}, "Empty descriptor");
|
||||
const invalidArguments = [
|
||||
undefined,
|
||||
null,
|
||||
false,
|
||||
true,
|
||||
"",
|
||||
"test",
|
||||
Symbol(),
|
||||
1,
|
||||
NaN,
|
||||
{},
|
||||
];
|
||||
for (const invalidArgument of invalidArguments) {
|
||||
assert_throws(new TypeError(),
|
||||
() => new WebAssembly.Memory(invalidArgument),
|
||||
`new Memory(${format_value(invalidArgument)})`);
|
||||
}
|
||||
}, "Invalid descriptor argument");
|
||||
|
||||
test(() => {
|
||||
assert_throws(new TypeError(), () => new WebAssembly.Memory({ "initial": undefined }));
|
||||
|
@ -64,8 +91,47 @@ test(() => {
|
|||
new WebAssembly.Memory(proxy);
|
||||
}, "Proxy descriptor");
|
||||
|
||||
test(() => {
|
||||
const order = [];
|
||||
|
||||
new WebAssembly.Memory({
|
||||
get maximum() {
|
||||
order.push("maximum");
|
||||
return {
|
||||
valueOf() {
|
||||
order.push("maximum valueOf");
|
||||
return 1;
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
get initial() {
|
||||
order.push("initial");
|
||||
return {
|
||||
valueOf() {
|
||||
order.push("initial valueOf");
|
||||
return 1;
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
assert_array_equals(order, [
|
||||
"initial",
|
||||
"initial valueOf",
|
||||
"maximum",
|
||||
"maximum valueOf",
|
||||
]);
|
||||
}, "Order of evaluation for descriptor");
|
||||
|
||||
test(() => {
|
||||
const argument = { "initial": 0 };
|
||||
const memory = new WebAssembly.Memory(argument);
|
||||
assert_equals(Object.getPrototypeOf(memory), WebAssembly.Memory.prototype);
|
||||
}, "Prototype");
|
||||
assert_Memory(memory, { "size": 0 });
|
||||
}, "Zero initial");
|
||||
|
||||
test(() => {
|
||||
const argument = { "initial": 4 };
|
||||
const memory = new WebAssembly.Memory(argument);
|
||||
assert_Memory(memory, { "size": 4 });
|
||||
}, "Non-zero initial");
|
||||
|
|
170
tests/wpt/web-platform-tests/wasm/jsapi/memory/grow.any.js
Normal file
170
tests/wpt/web-platform-tests/wasm/jsapi/memory/grow.any.js
Normal file
|
@ -0,0 +1,170 @@
|
|||
// META: global=jsshell
|
||||
|
||||
function assert_ArrayBuffer(actual, expected, message) {
|
||||
// https://github.com/WebAssembly/spec/issues/840
|
||||
assert_equals(Object.getPrototypeOf(actual), ArrayBuffer.prototype,
|
||||
`${message}: prototype`);
|
||||
if (expected.detached) {
|
||||
// https://github.com/tc39/ecma262/issues/678
|
||||
let byteLength;
|
||||
try {
|
||||
byteLength = actual.byteLength;
|
||||
} catch (e) {
|
||||
byteLength = 0;
|
||||
}
|
||||
assert_equals(byteLength, 0, `${message}: detached size`);
|
||||
} else {
|
||||
assert_equals(actual.byteLength, 0x10000 * expected.size, `${message}: size`);
|
||||
if (expected.size > 0) {
|
||||
const array = new Uint8Array(actual);
|
||||
assert_equals(array[0], 0, `${message}: first element`);
|
||||
assert_equals(array[array.byteLength - 1], 0, `${message}: last element`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const argument = { "initial": 0 };
|
||||
const memory = new WebAssembly.Memory(argument);
|
||||
assert_throws(new 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(new 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(new 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(new TypeError(), () => memory.grow(value));
|
||||
}, `Out-of-range argument: ${format_value(value)}`);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
// META: global=jsshell
|
||||
|
||||
test(() => {
|
||||
const argument = { "initial": 0 };
|
||||
const memory = new WebAssembly.Memory(argument);
|
||||
assert_class_string(memory, "WebAssembly.Memory");
|
||||
}, "Object.prototype.toString on an Memory");
|
|
@ -24,6 +24,26 @@ test(() => {
|
|||
assert_throws(new TypeError(), () => WebAssembly.Module(emptyModuleBinary));
|
||||
}, "Calling");
|
||||
|
||||
test(() => {
|
||||
const invalidArguments = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"test",
|
||||
Symbol(),
|
||||
7,
|
||||
NaN,
|
||||
{},
|
||||
ArrayBuffer,
|
||||
ArrayBuffer.prototype,
|
||||
Array.from(emptyModuleBinary),
|
||||
];
|
||||
for (const argument of invalidArguments) {
|
||||
assert_throws(new TypeError(), () => new WebAssembly.Module(argument),
|
||||
`new Module(${format_value(argument)})`);
|
||||
}
|
||||
}, "Invalid arguments");
|
||||
|
||||
test(() => {
|
||||
const buffer = new Uint8Array();
|
||||
assert_throws(new WebAssembly.CompileError(), () => new WebAssembly.Module(buffer));
|
||||
|
@ -33,3 +53,8 @@ test(() => {
|
|||
const module = new WebAssembly.Module(emptyModuleBinary);
|
||||
assert_equals(Object.getPrototypeOf(module), WebAssembly.Module.prototype);
|
||||
}, "Prototype");
|
||||
|
||||
test(() => {
|
||||
const module = new WebAssembly.Module(emptyModuleBinary);
|
||||
assert_true(Object.isExtensible(module));
|
||||
}, "Extensibility");
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
|
||||
function assert_ArrayBuffer(buffer, expected) {
|
||||
assert_equals(Object.getPrototypeOf(buffer), ArrayBuffer.prototype, "Prototype");
|
||||
assert_true(Object.isExtensible(buffer), "isExtensible");
|
||||
assert_array_equals(new Uint8Array(buffer), expected);
|
||||
}
|
||||
|
||||
function assert_sections(sections, expected) {
|
||||
assert_true(Array.isArray(sections), "Should be array");
|
||||
assert_equals(Object.getPrototypeOf(sections), Array.prototype, "Prototype");
|
||||
assert_true(Object.isExtensible(sections), "isExtensible");
|
||||
|
||||
assert_equals(sections.length, expected.length);
|
||||
for (let i = 0; i < expected.length; ++i) {
|
||||
|
@ -29,10 +31,21 @@ test(() => {
|
|||
}, "Missing arguments");
|
||||
|
||||
test(() => {
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.customSections({}, ""));
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.customSections("", ""));
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.customSections(undefined, ""));
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.customSections(null, ""));
|
||||
const invalidArguments = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Module,
|
||||
WebAssembly.Module.prototype,
|
||||
];
|
||||
for (const argument of invalidArguments) {
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.customSections(argument, ""),
|
||||
`customSections(${format_value(argument)})`);
|
||||
}
|
||||
}, "Non-Module arguments");
|
||||
|
||||
test(() => {
|
||||
|
@ -102,3 +115,48 @@ test(() => {
|
|||
assert_sections(WebAssembly.Module.customSections(module, "name\0"), [])
|
||||
assert_sections(WebAssembly.Module.customSections(module, "foo\0"), [])
|
||||
}, "Custom sections");
|
||||
|
||||
test(() => {
|
||||
const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
|
||||
const name = "yee\uD801\uDC37eey"
|
||||
|
||||
const binary = new Binary;
|
||||
binary.emit_section(kUnknownSectionCode, section => {
|
||||
section.emit_string(name);
|
||||
section.emit_bytes(bytes);
|
||||
});
|
||||
|
||||
const builder = new WasmModuleBuilder();
|
||||
builder.addExplicitSection(binary);
|
||||
const buffer = builder.toBuffer();
|
||||
const module = new WebAssembly.Module(buffer);
|
||||
|
||||
assert_sections(WebAssembly.Module.customSections(module, name), [
|
||||
bytes,
|
||||
]);
|
||||
assert_sections(WebAssembly.Module.customSections(module, "yee\uFFFDeey"), []);
|
||||
assert_sections(WebAssembly.Module.customSections(module, "yee\uFFFD\uFFFDeey"), []);
|
||||
}, "Custom sections with surrogate pairs");
|
||||
|
||||
test(() => {
|
||||
const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
|
||||
|
||||
const binary = new Binary;
|
||||
binary.emit_section(kUnknownSectionCode, section => {
|
||||
section.emit_string("na\uFFFDme");
|
||||
section.emit_bytes(bytes);
|
||||
});
|
||||
|
||||
const builder = new WasmModuleBuilder();
|
||||
builder.addExplicitSection(binary);
|
||||
const buffer = builder.toBuffer();
|
||||
const module = new WebAssembly.Module(buffer);
|
||||
|
||||
assert_sections(WebAssembly.Module.customSections(module, "name"), []);
|
||||
assert_sections(WebAssembly.Module.customSections(module, "na\uFFFDme"), [
|
||||
bytes,
|
||||
]);
|
||||
assert_sections(WebAssembly.Module.customSections(module, "na\uDC01me"), [
|
||||
bytes,
|
||||
]);
|
||||
}, "Custom sections with U+FFFD");
|
||||
|
|
|
@ -7,15 +7,54 @@ setup(() => {
|
|||
emptyModuleBinary = new WasmModuleBuilder().toBuffer();
|
||||
});
|
||||
|
||||
function assert_ModuleExportDescriptor(export_, expected) {
|
||||
assert_equals(Object.getPrototypeOf(export_), Object.prototype, "Prototype");
|
||||
assert_true(Object.isExtensible(export_), "isExtensible");
|
||||
|
||||
const name = Object.getOwnPropertyDescriptor(export_, "name");
|
||||
assert_true(name.writable, "name: writable");
|
||||
assert_true(name.enumerable, "name: enumerable");
|
||||
assert_true(name.configurable, "name: configurable");
|
||||
assert_equals(name.value, expected.name);
|
||||
|
||||
const kind = Object.getOwnPropertyDescriptor(export_, "kind");
|
||||
assert_true(kind.writable, "kind: writable");
|
||||
assert_true(kind.enumerable, "kind: enumerable");
|
||||
assert_true(kind.configurable, "kind: configurable");
|
||||
assert_equals(kind.value, expected.kind);
|
||||
}
|
||||
|
||||
function assert_exports(exports, expected) {
|
||||
assert_true(Array.isArray(exports), "Should be array");
|
||||
assert_equals(Object.getPrototypeOf(exports), Array.prototype, "Prototype");
|
||||
assert_true(Object.isExtensible(exports), "isExtensible");
|
||||
|
||||
assert_equals(exports.length, expected.length);
|
||||
for (let i = 0; i < expected.length; ++i) {
|
||||
assert_ModuleExportDescriptor(exports[i], expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
test(() => {
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.exports());
|
||||
}, "Missing arguments");
|
||||
|
||||
test(() => {
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.exports({}));
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.exports(""));
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.exports(undefined));
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.exports(null));
|
||||
const invalidArguments = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Module,
|
||||
WebAssembly.Module.prototype,
|
||||
];
|
||||
for (const argument of invalidArguments) {
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.exports(argument),
|
||||
`exports(${format_value(argument)})`);
|
||||
}
|
||||
}, "Non-Module arguments");
|
||||
|
||||
test(() => {
|
||||
|
@ -40,15 +79,7 @@ test(() => {
|
|||
test(() => {
|
||||
const module = new WebAssembly.Module(emptyModuleBinary);
|
||||
const exports = WebAssembly.Module.exports(module);
|
||||
assert_true(Array.isArray(exports));
|
||||
}, "Return type");
|
||||
|
||||
test(() => {
|
||||
const module = new WebAssembly.Module(emptyModuleBinary);
|
||||
const exports = WebAssembly.Module.exports(module);
|
||||
assert_true(Array.isArray(exports), "Should be array");
|
||||
assert_equals(Object.getPrototypeOf(exports), Array.prototype, "Prototype");
|
||||
assert_array_equals(exports, []);
|
||||
assert_exports(exports, []);
|
||||
}, "Empty module");
|
||||
|
||||
test(() => {
|
||||
|
@ -56,22 +87,6 @@ test(() => {
|
|||
assert_not_equals(WebAssembly.Module.exports(module), WebAssembly.Module.exports(module));
|
||||
}, "Empty module: array caching");
|
||||
|
||||
function assert_ModuleExportDescriptor(export_, expected) {
|
||||
assert_equals(Object.getPrototypeOf(export_), Object.prototype, "Prototype");
|
||||
|
||||
const name = Object.getOwnPropertyDescriptor(export_, "name");
|
||||
assert_true(name.writable, "name: writable");
|
||||
assert_true(name.enumerable, "name: enumerable");
|
||||
assert_true(name.configurable, "name: configurable");
|
||||
assert_equals(name.value, expected.name);
|
||||
|
||||
const kind = Object.getOwnPropertyDescriptor(export_, "kind");
|
||||
assert_true(kind.writable, "kind: writable");
|
||||
assert_true(kind.enumerable, "kind: enumerable");
|
||||
assert_true(kind.configurable, "kind: configurable");
|
||||
assert_equals(kind.value, expected.kind);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const builder = new WasmModuleBuilder();
|
||||
|
||||
|
@ -103,9 +118,6 @@ test(() => {
|
|||
const buffer = builder.toBuffer()
|
||||
const module = new WebAssembly.Module(buffer);
|
||||
const exports = WebAssembly.Module.exports(module);
|
||||
assert_true(Array.isArray(exports), "Should be array");
|
||||
assert_equals(Object.getPrototypeOf(exports), Array.prototype, "Prototype");
|
||||
|
||||
const expected = [
|
||||
{ "kind": "function", "name": "fn" },
|
||||
{ "kind": "function", "name": "fn2" },
|
||||
|
@ -114,8 +126,5 @@ test(() => {
|
|||
{ "kind": "global", "name": "global2" },
|
||||
{ "kind": "memory", "name": "memory" },
|
||||
];
|
||||
assert_equals(exports.length, expected.length);
|
||||
for (let i = 0; i < expected.length; ++i) {
|
||||
assert_ModuleExportDescriptor(exports[i], expected[i]);
|
||||
}
|
||||
assert_exports(exports, expected);
|
||||
}, "exports");
|
||||
|
|
|
@ -2,6 +2,40 @@
|
|||
// META: script=/wasm/jsapi/wasm-constants.js
|
||||
// META: script=/wasm/jsapi/wasm-module-builder.js
|
||||
|
||||
function assert_ModuleImportDescriptor(import_, expected) {
|
||||
assert_equals(Object.getPrototypeOf(import_), Object.prototype, "Prototype");
|
||||
assert_true(Object.isExtensible(import_), "isExtensible");
|
||||
|
||||
const module = Object.getOwnPropertyDescriptor(import_, "module");
|
||||
assert_true(module.writable, "module: writable");
|
||||
assert_true(module.enumerable, "module: enumerable");
|
||||
assert_true(module.configurable, "module: configurable");
|
||||
assert_equals(module.value, expected.module);
|
||||
|
||||
const name = Object.getOwnPropertyDescriptor(import_, "name");
|
||||
assert_true(name.writable, "name: writable");
|
||||
assert_true(name.enumerable, "name: enumerable");
|
||||
assert_true(name.configurable, "name: configurable");
|
||||
assert_equals(name.value, expected.name);
|
||||
|
||||
const kind = Object.getOwnPropertyDescriptor(import_, "kind");
|
||||
assert_true(kind.writable, "kind: writable");
|
||||
assert_true(kind.enumerable, "kind: enumerable");
|
||||
assert_true(kind.configurable, "kind: configurable");
|
||||
assert_equals(kind.value, expected.kind);
|
||||
}
|
||||
|
||||
function assert_imports(imports, expected) {
|
||||
assert_true(Array.isArray(imports), "Should be array");
|
||||
assert_equals(Object.getPrototypeOf(imports), Array.prototype, "Prototype");
|
||||
assert_true(Object.isExtensible(imports), "isExtensible");
|
||||
|
||||
assert_equals(imports.length, expected.length);
|
||||
for (let i = 0; i < expected.length; ++i) {
|
||||
assert_ModuleImportDescriptor(imports[i], expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
let emptyModuleBinary;
|
||||
setup(() => {
|
||||
emptyModuleBinary = new WasmModuleBuilder().toBuffer();
|
||||
|
@ -12,10 +46,21 @@ test(() => {
|
|||
}, "Missing arguments");
|
||||
|
||||
test(() => {
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.imports({}));
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.imports(""));
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.imports(undefined));
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.imports(null));
|
||||
const invalidArguments = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Module,
|
||||
WebAssembly.Module.prototype,
|
||||
];
|
||||
for (const argument of invalidArguments) {
|
||||
assert_throws(new TypeError(), () => WebAssembly.Module.imports(argument),
|
||||
`imports(${format_value(argument)})`);
|
||||
}
|
||||
}, "Non-Module arguments");
|
||||
|
||||
test(() => {
|
||||
|
@ -46,9 +91,7 @@ test(() => {
|
|||
test(() => {
|
||||
const module = new WebAssembly.Module(emptyModuleBinary);
|
||||
const imports = WebAssembly.Module.imports(module);
|
||||
assert_true(Array.isArray(imports), "Should be array");
|
||||
assert_equals(Object.getPrototypeOf(imports), Array.prototype, "Prototype");
|
||||
assert_array_equals(imports, []);
|
||||
assert_imports(imports, []);
|
||||
}, "Empty module");
|
||||
|
||||
test(() => {
|
||||
|
@ -56,28 +99,6 @@ test(() => {
|
|||
assert_not_equals(WebAssembly.Module.imports(module), WebAssembly.Module.imports(module));
|
||||
}, "Empty module: array caching");
|
||||
|
||||
function assert_ModuleImportDescriptor(import_, expected) {
|
||||
assert_equals(Object.getPrototypeOf(import_), Object.prototype, "Prototype");
|
||||
|
||||
const module = Object.getOwnPropertyDescriptor(import_, "module");
|
||||
assert_true(module.writable, "module: writable");
|
||||
assert_true(module.enumerable, "module: enumerable");
|
||||
assert_true(module.configurable, "module: configurable");
|
||||
assert_equals(module.value, expected.module);
|
||||
|
||||
const name = Object.getOwnPropertyDescriptor(import_, "name");
|
||||
assert_true(name.writable, "name: writable");
|
||||
assert_true(name.enumerable, "name: enumerable");
|
||||
assert_true(name.configurable, "name: configurable");
|
||||
assert_equals(name.value, expected.name);
|
||||
|
||||
const kind = Object.getOwnPropertyDescriptor(import_, "kind");
|
||||
assert_true(kind.writable, "kind: writable");
|
||||
assert_true(kind.enumerable, "kind: enumerable");
|
||||
assert_true(kind.configurable, "kind: configurable");
|
||||
assert_equals(kind.value, expected.kind);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const builder = new WasmModuleBuilder();
|
||||
|
||||
|
@ -89,17 +110,11 @@ test(() => {
|
|||
const buffer = builder.toBuffer()
|
||||
const module = new WebAssembly.Module(buffer);
|
||||
const imports = WebAssembly.Module.imports(module);
|
||||
assert_true(Array.isArray(imports), "Should be array");
|
||||
assert_equals(Object.getPrototypeOf(imports), Array.prototype, "Prototype");
|
||||
|
||||
const expected = [
|
||||
{ "module": "module", "kind": "function", "name": "fn" },
|
||||
{ "module": "module", "kind": "global", "name": "global" },
|
||||
{ "module": "module", "kind": "memory", "name": "memory" },
|
||||
{ "module": "module", "kind": "table", "name": "table" },
|
||||
];
|
||||
assert_equals(imports.length, expected.length);
|
||||
for (let i = 0; i < expected.length; ++i) {
|
||||
assert_ModuleImportDescriptor(imports[i], expected[i]);
|
||||
}
|
||||
assert_imports(imports, expected);
|
||||
}, "imports");
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// META: global=jsshell
|
||||
// META: script=/wasm/jsapi/wasm-constants.js
|
||||
// META: script=/wasm/jsapi/wasm-module-builder.js
|
||||
|
||||
test(() => {
|
||||
const emptyModuleBinary = new WasmModuleBuilder().toBuffer();
|
||||
const module = new WebAssembly.Module(emptyModuleBinary);
|
||||
assert_class_string(module, "WebAssembly.Module");
|
||||
}, "Object.prototype.toString on an Module");
|
11
tests/wpt/web-platform-tests/wasm/jsapi/table/assertions.js
Normal file
11
tests/wpt/web-platform-tests/wasm/jsapi/table/assertions.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
function assert_equal_to_array(table, expected, message) {
|
||||
assert_equals(table.length, expected.length, `${message}: length`);
|
||||
assert_throws(new RangeError(), () => table.get(-1), `${message}: table.get(-1)`);
|
||||
for (let i = 0; i < expected.length; ++i) {
|
||||
assert_equals(table.get(i), expected[i], `${message}: table.get(${i} of ${expected.length})`);
|
||||
}
|
||||
assert_throws(new RangeError(), () => table.get(expected.length),
|
||||
`${message}: table.get(${expected.length} of ${expected.length})`);
|
||||
assert_throws(new RangeError(), () => table.get(expected.length + 1),
|
||||
`${message}: table.get(${expected.length + 1} of ${expected.length})`);
|
||||
}
|
|
@ -1,12 +1,16 @@
|
|||
// META: global=jsshell
|
||||
// META: script=/wasm/jsapi/wasm-constants.js
|
||||
// META: script=/wasm/jsapi/wasm-module-builder.js
|
||||
// META: script=/wasm/jsapi/assertions.js
|
||||
|
||||
let emptyModuleBinary;
|
||||
setup(() => {
|
||||
emptyModuleBinary = new WasmModuleBuilder().toBuffer();
|
||||
});
|
||||
function assert_Table(actual, expected) {
|
||||
assert_equals(Object.getPrototypeOf(actual), WebAssembly.Table.prototype,
|
||||
"prototype");
|
||||
assert_true(Object.isExtensible(actual), "extensible");
|
||||
|
||||
assert_equals(actual.length, expected.length, "length");
|
||||
for (let i = 0; i < expected.length; ++i) {
|
||||
assert_equals(actual.get(i), null, `actual.get(${i})`);
|
||||
}
|
||||
}
|
||||
|
||||
test(() => {
|
||||
assert_function_name(WebAssembly.Table, "Table", "WebAssembly.Table");
|
||||
|
@ -21,7 +25,7 @@ test(() => {
|
|||
}, "No arguments");
|
||||
|
||||
test(() => {
|
||||
const argument = { "initial": 0 };
|
||||
const argument = { "element": "anyfunc", "initial": 0 };
|
||||
assert_throws(new TypeError(), () => WebAssembly.Table(argument));
|
||||
}, "Calling");
|
||||
|
||||
|
@ -29,6 +33,26 @@ test(() => {
|
|||
assert_throws(new TypeError(), () => new WebAssembly.Table({}));
|
||||
}, "Empty descriptor");
|
||||
|
||||
test(() => {
|
||||
const invalidArguments = [
|
||||
undefined,
|
||||
null,
|
||||
false,
|
||||
true,
|
||||
"",
|
||||
"test",
|
||||
Symbol(),
|
||||
1,
|
||||
NaN,
|
||||
{},
|
||||
];
|
||||
for (const invalidArgument of invalidArguments) {
|
||||
assert_throws(new TypeError(),
|
||||
() => new WebAssembly.Table(invalidArgument),
|
||||
`new Table(${format_value(invalidArgument)})`);
|
||||
}
|
||||
}, "Invalid descriptor argument");
|
||||
|
||||
test(() => {
|
||||
assert_throws(new TypeError(), () => new WebAssembly.Table({ "element": "anyfunc", "initial": undefined }));
|
||||
}, "Undefined initial value in descriptor");
|
||||
|
@ -56,6 +80,22 @@ for (const value of outOfRangeValues) {
|
|||
}, `Out-of-range maximum value in descriptor: ${format_value(value)}`);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
assert_throws(new RangeError(), () => new WebAssembly.Table({ "element": "anyfunc", "initial": 10, "maximum": 9 }));
|
||||
}, "Initial value exceeds maximum");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 0 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_Table(table, { "length": 0 });
|
||||
}, "Basic (zero)");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 5 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_Table(table, { "length": 5 });
|
||||
}, "Basic (non-zero)");
|
||||
|
||||
test(() => {
|
||||
const proxy = new Proxy({}, {
|
||||
has(o, x) {
|
||||
|
@ -73,11 +113,61 @@ test(() => {
|
|||
}
|
||||
},
|
||||
});
|
||||
new WebAssembly.Table(proxy);
|
||||
const table = new WebAssembly.Table(proxy);
|
||||
assert_Table(table, { "length": 0 });
|
||||
}, "Proxy descriptor");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 0 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equals(Object.getPrototypeOf(table), WebAssembly.Table.prototype);
|
||||
}, "Prototype");
|
||||
const table = new WebAssembly.Table({
|
||||
"element": {
|
||||
toString() { return "anyfunc"; },
|
||||
},
|
||||
"initial": 1,
|
||||
});
|
||||
assert_Table(table, { "length": 1 });
|
||||
}, "Type conversion for descriptor.element");
|
||||
|
||||
test(() => {
|
||||
const order = [];
|
||||
|
||||
new WebAssembly.Table({
|
||||
get maximum() {
|
||||
order.push("maximum");
|
||||
return {
|
||||
valueOf() {
|
||||
order.push("maximum valueOf");
|
||||
return 1;
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
get initial() {
|
||||
order.push("initial");
|
||||
return {
|
||||
valueOf() {
|
||||
order.push("initial valueOf");
|
||||
return 1;
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
get element() {
|
||||
order.push("element");
|
||||
return {
|
||||
toString() {
|
||||
order.push("element toString");
|
||||
return "anyfunc";
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
assert_array_equals(order, [
|
||||
"element",
|
||||
"element toString",
|
||||
"initial",
|
||||
"initial valueOf",
|
||||
"maximum",
|
||||
"maximum valueOf",
|
||||
]);
|
||||
}, "Order of evaluation for descriptor");
|
||||
|
|
220
tests/wpt/web-platform-tests/wasm/jsapi/table/get-set.any.js
Normal file
220
tests/wpt/web-platform-tests/wasm/jsapi/table/get-set.any.js
Normal file
|
@ -0,0 +1,220 @@
|
|||
// META: global=jsshell
|
||||
// META: script=/wasm/jsapi/wasm-constants.js
|
||||
// META: script=/wasm/jsapi/wasm-module-builder.js
|
||||
// META: script=assertions.js
|
||||
|
||||
let functions;
|
||||
setup(() => {
|
||||
const builder = new WasmModuleBuilder();
|
||||
|
||||
builder
|
||||
.addFunction("fn", kSig_v_d)
|
||||
.addBody([
|
||||
kExprEnd
|
||||
])
|
||||
.exportFunc();
|
||||
builder
|
||||
.addFunction("fn2", kSig_v_v)
|
||||
.addBody([
|
||||
kExprEnd
|
||||
])
|
||||
.exportFunc();
|
||||
|
||||
const buffer = builder.toBuffer()
|
||||
const module = new WebAssembly.Module(buffer);
|
||||
const instance = new WebAssembly.Instance(module, {});
|
||||
functions = instance.exports;
|
||||
});
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 5 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_throws(new TypeError(), () => table.get());
|
||||
}, "Missing arguments: get");
|
||||
|
||||
test(t => {
|
||||
const thisValues = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Table,
|
||||
WebAssembly.Table.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.Table.prototype.get;
|
||||
|
||||
for (const thisValue of thisValues) {
|
||||
assert_throws(new TypeError(), () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`);
|
||||
}
|
||||
}, "Branding: get");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 5 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_throws(new TypeError(), () => table.set());
|
||||
assert_throws(new TypeError(), () => table.set(0));
|
||||
}, "Missing arguments: set");
|
||||
|
||||
test(t => {
|
||||
const thisValues = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Table,
|
||||
WebAssembly.Table.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.Table.prototype.set;
|
||||
|
||||
for (const thisValue of thisValues) {
|
||||
assert_throws(new TypeError(), () => fn.call(thisValue, argument, null), `this=${format_value(thisValue)}`);
|
||||
}
|
||||
}, "Branding: set");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 5 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equal_to_array(table, [null, null, null, null, null]);
|
||||
|
||||
const {fn, fn2} = functions;
|
||||
|
||||
assert_equals(table.set(0, fn), undefined, "set() returns undefined.");
|
||||
table.set(2, fn2);
|
||||
table.set(4, fn);
|
||||
|
||||
assert_equal_to_array(table, [fn, null, fn2, null, fn]);
|
||||
|
||||
table.set(0, null);
|
||||
assert_equal_to_array(table, [null, null, fn2, null, fn]);
|
||||
}, "Basic");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 5 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equal_to_array(table, [null, null, null, null, null]);
|
||||
|
||||
const {fn, fn2} = functions;
|
||||
|
||||
table.set(0, fn);
|
||||
table.set(2, fn2);
|
||||
table.set(4, fn);
|
||||
|
||||
assert_equal_to_array(table, [fn, null, fn2, null, fn]);
|
||||
|
||||
table.grow(4);
|
||||
|
||||
assert_equal_to_array(table, [fn, null, fn2, null, fn, null, null, null, null]);
|
||||
}, "Growing");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 5 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equal_to_array(table, [null, null, null, null, null]);
|
||||
|
||||
const {fn} = functions;
|
||||
|
||||
assert_throws(new RangeError(), () => table.set(-1, fn));
|
||||
assert_throws(new RangeError(), () => table.set(5, fn));
|
||||
assert_equal_to_array(table, [null, null, null, null, null]);
|
||||
}, "Setting out-of-bounds");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 1 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equal_to_array(table, [null]);
|
||||
|
||||
const invalidArguments = [
|
||||
undefined,
|
||||
true,
|
||||
false,
|
||||
"test",
|
||||
Symbol(),
|
||||
7,
|
||||
NaN,
|
||||
{},
|
||||
];
|
||||
for (const argument of invalidArguments) {
|
||||
assert_throws(new TypeError(), () => table.set(0, argument),
|
||||
`set(${format_value(argument)})`);
|
||||
}
|
||||
assert_equal_to_array(table, [null]);
|
||||
}, "Setting non-function");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 1 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equal_to_array(table, [null]);
|
||||
|
||||
const fn = function() {};
|
||||
assert_throws(new TypeError(), () => table.set(0, fn));
|
||||
assert_equal_to_array(table, [null]);
|
||||
}, "Setting non-wasm function");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 1 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equal_to_array(table, [null]);
|
||||
|
||||
const fn = () => {};
|
||||
assert_throws(new TypeError(), () => table.set(0, fn));
|
||||
assert_equal_to_array(table, [null]);
|
||||
}, "Setting non-wasm arrow function");
|
||||
|
||||
const outOfRangeValues = [
|
||||
undefined,
|
||||
NaN,
|
||||
Infinity,
|
||||
-Infinity,
|
||||
-1,
|
||||
0x100000000,
|
||||
0x1000000000,
|
||||
"0x100000000",
|
||||
{ valueOf() { return 0x100000000; } },
|
||||
];
|
||||
|
||||
for (const value of outOfRangeValues) {
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 1 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_throws(new TypeError(), () => table.get(value));
|
||||
}, `Getting out-of-range argument: ${format_value(value)}`);
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 1 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_throws(new TypeError(), () => table.set(value, null));
|
||||
}, `Setting out-of-range argument: ${format_value(value)}`);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 1 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
let called = 0;
|
||||
const value = {
|
||||
valueOf() {
|
||||
called++;
|
||||
return 0;
|
||||
},
|
||||
};
|
||||
assert_throws(new TypeError(), () => table.set(value, {}));
|
||||
assert_equals(called, 1);
|
||||
}, "Order of argument conversion");
|
||||
|
86
tests/wpt/web-platform-tests/wasm/jsapi/table/grow.any.js
Normal file
86
tests/wpt/web-platform-tests/wasm/jsapi/table/grow.any.js
Normal file
|
@ -0,0 +1,86 @@
|
|||
// META: global=jsshell
|
||||
// META: script=assertions.js
|
||||
|
||||
function nulls(n) {
|
||||
return Array(n).fill(null);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 5 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_throws(new TypeError(), () => table.grow());
|
||||
}, "Missing arguments");
|
||||
|
||||
test(t => {
|
||||
const thisValues = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Table,
|
||||
WebAssembly.Table.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.Table.prototype.grow;
|
||||
|
||||
for (const thisValue of thisValues) {
|
||||
assert_throws(new TypeError(), () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`);
|
||||
}
|
||||
}, "Branding");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 5 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equal_to_array(table, nulls(5), "before");
|
||||
|
||||
const result = table.grow(3);
|
||||
assert_equals(result, 5);
|
||||
assert_equal_to_array(table, nulls(8), "after");
|
||||
}, "Basic");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 3, "maximum": 5 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equal_to_array(table, nulls(3), "before");
|
||||
|
||||
const result = table.grow(2);
|
||||
assert_equals(result, 3);
|
||||
assert_equal_to_array(table, nulls(5), "after");
|
||||
}, "Reached maximum");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 2, "maximum": 5 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equal_to_array(table, nulls(2), "before");
|
||||
|
||||
assert_throws(new RangeError(), () => table.grow(4));
|
||||
assert_equal_to_array(table, nulls(2), "after");
|
||||
}, "Exceeded maximum");
|
||||
|
||||
const outOfRangeValues = [
|
||||
undefined,
|
||||
NaN,
|
||||
Infinity,
|
||||
-Infinity,
|
||||
-1,
|
||||
0x100000000,
|
||||
0x1000000000,
|
||||
"0x100000000",
|
||||
{ valueOf() { return 0x100000000; } },
|
||||
];
|
||||
|
||||
for (const value of outOfRangeValues) {
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 1 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_throws(new TypeError(), () => table.grow(value));
|
||||
}, `Out-of-range argument: ${format_value(value)}`);
|
||||
}
|
46
tests/wpt/web-platform-tests/wasm/jsapi/table/length.any.js
Normal file
46
tests/wpt/web-platform-tests/wasm/jsapi/table/length.any.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
// META: global=jsshell
|
||||
|
||||
test(() => {
|
||||
const thisValues = [
|
||||
undefined,
|
||||
null,
|
||||
true,
|
||||
"",
|
||||
Symbol(),
|
||||
1,
|
||||
{},
|
||||
WebAssembly.Table,
|
||||
WebAssembly.Table.prototype,
|
||||
];
|
||||
|
||||
const desc = Object.getOwnPropertyDescriptor(WebAssembly.Table.prototype, "length");
|
||||
assert_equals(typeof desc, "object");
|
||||
|
||||
const getter = desc.get;
|
||||
assert_equals(typeof getter, "function");
|
||||
|
||||
assert_equals(typeof desc.set, "undefined");
|
||||
|
||||
for (const thisValue of thisValues) {
|
||||
assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`);
|
||||
}
|
||||
}, "Branding");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 2 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equals(table.length, 2, "Initial length");
|
||||
table.length = 4;
|
||||
assert_equals(table.length, 2, "Should not change the length");
|
||||
}, "Setting (sloppy mode)");
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 2 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_equals(table.length, 2, "Initial length");
|
||||
assert_throws(new TypeError(), () => {
|
||||
"use strict";
|
||||
table.length = 4;
|
||||
});
|
||||
assert_equals(table.length, 2, "Should not change the length");
|
||||
}, "Setting (strict mode)");
|
|
@ -0,0 +1,7 @@
|
|||
// META: global=jsshell
|
||||
|
||||
test(() => {
|
||||
const argument = { "element": "anyfunc", "initial": 0 };
|
||||
const table = new WebAssembly.Table(argument);
|
||||
assert_class_string(table, "WebAssembly.Table");
|
||||
}, "Object.prototype.toString on an Table");
|
|
@ -1,18 +0,0 @@
|
|||
<script>
|
||||
function listener(event) {
|
||||
var mod = event.data;
|
||||
try {
|
||||
var i = new WebAssembly.Instance(mod);
|
||||
var ans = i.exports.increment(42);
|
||||
event.source.postMessage(ans, event.origin);
|
||||
} catch (e) {
|
||||
event.source.postMessage(e, event.origin);
|
||||
}
|
||||
}
|
||||
|
||||
if (window.addEventListener){
|
||||
addEventListener("message", listener, false)
|
||||
} else {
|
||||
attachEvent("onmessage", listener)
|
||||
}
|
||||
</script>
|
|
@ -1,30 +0,0 @@
|
|||
var port;
|
||||
|
||||
importScripts('load_wasm.js');
|
||||
|
||||
self.onmessage = function(e) {
|
||||
var message = e.data;
|
||||
if ('port' in message) {
|
||||
port = message.port;
|
||||
}
|
||||
};
|
||||
|
||||
// And an event listener:
|
||||
self.addEventListener('message', function(e) {
|
||||
var message = e.data;
|
||||
if ("compile" in message) {
|
||||
createWasmModule()
|
||||
.then(m => {
|
||||
try {
|
||||
port.postMessage({type:"OK", module:m});
|
||||
} catch (e) {
|
||||
port.postMessage({type:"SEND ERROR"});
|
||||
}
|
||||
})
|
||||
.catch(e => port.postMessage({type:"OTHER ERROR"}));
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener('messageerror', function(e) {
|
||||
port.postMessage({type:"RECEIVE ERROR"});
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
<!doctype html>
|
||||
<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ -->
|
||||
<title>WebAssembly.Module cannot cross agent clusters, BroadcastChannel edition</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/test-incrementer.js"></script>
|
||||
<script>
|
||||
async_test(t => {
|
||||
const channel = new BroadcastChannel("anne was here"),
|
||||
dw = new Worker("resources/broadcastchannel-worker.js"),
|
||||
sw = new SharedWorker("resources/broadcastchannel-sharedworker.js");
|
||||
let startCounter = 0,
|
||||
dwStatus = "unknown",
|
||||
swStatus = "unknown";
|
||||
|
||||
channel.onmessage = t.step_func(({ data }) => {
|
||||
if(data === "hi") {
|
||||
startCounter++;
|
||||
if(startCounter === 2) {
|
||||
createWasmModule().then(module => {
|
||||
channel.postMessage(module);
|
||||
});
|
||||
} else if(startCounter > 2) {
|
||||
assert_unreached();
|
||||
}
|
||||
} else if(data === "dw-success") {
|
||||
dwStatus = "success";
|
||||
} else if(data === "sw-success") {
|
||||
swStatus = "success";
|
||||
} else {
|
||||
assert_unreached();
|
||||
}
|
||||
if(dwStatus === "success" && swStatus === "success") {
|
||||
t.done();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ -->
|
||||
<meta charset="utf-8">
|
||||
<title>Structured cloning of WebAssembly.Module: BroadcastChannel within the same agent cluster</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/test-incrementer.js"></script>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
promise_test(t => {
|
||||
return createWasmModule().then(module => {
|
||||
let loadedIframes = 0;
|
||||
return Promise.all([
|
||||
createIFrame("resources/broadcastchannel-iframe.html"),
|
||||
createIFrame("resources/broadcastchannel-iframe.html"),
|
||||
createIFrame("resources/broadcastchannel-iframe.html")
|
||||
]).then(() => {
|
||||
const thisIframe = loadedIframes++;
|
||||
const channel = new BroadcastChannel("channel name");
|
||||
|
||||
return new Promise(resolve => {
|
||||
let soFar = 0;
|
||||
channel.onmessage = t.step_func(msg => {
|
||||
if (msg.module) {
|
||||
// We only care about "broadcasts" from the workers.
|
||||
return;
|
||||
}
|
||||
|
||||
let {i, result} = msg;
|
||||
|
||||
assert_in_array(i, [0, 1, 2], "Any message events must come from expected sources");
|
||||
assert_equals(result, i + 1, `iframe ${i} must return ${i+1}`);
|
||||
++soFar;
|
||||
|
||||
if (soFar === 3) {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
channel.postMessage({ module, i: thisIframe });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createIFrame(src) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = src;
|
||||
iframe.onload = () => resolve(iframe);
|
||||
iframe.onerror = () => reject(`iframe with URL ${src} failed to load`);
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,66 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ -->
|
||||
<meta charset="utf-8">
|
||||
<title>WebAssembly.Modules, when cloned, do not give back the same object</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/test-incrementer.js"></script>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
async_test(t => {
|
||||
createWasmModule().then(module => {
|
||||
window.addEventListener("message", t.step_func(({ data }) => {
|
||||
if (data.testId !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert_not_equals(data.module, module);
|
||||
|
||||
t.done();
|
||||
}));
|
||||
|
||||
window.postMessage({ module, testId: 1 }, "*");
|
||||
});
|
||||
}, "postMessaging to this window does not give back the same WebAssembly.Module");
|
||||
|
||||
async_test(t => {
|
||||
createWasmModule().then(module => {
|
||||
const worker = new Worker("resources/echo-worker.js");
|
||||
|
||||
worker.addEventListener("message", t.step_func(({ data }) => {
|
||||
if (data.testId !== 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert_not_equals(data.module, module);
|
||||
t.done();
|
||||
}));
|
||||
|
||||
worker.postMessage({ testId: 2, module });
|
||||
});
|
||||
}, "postMessaging to a worker and back does not give back the same WebAssembly.Module");
|
||||
|
||||
async_test(t => {
|
||||
createWasmModule().then(module => {
|
||||
window.addEventListener("message", t.step_func(({ data }) => {
|
||||
if (data.testId !== 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert_not_equals(data.module, module);
|
||||
t.done();
|
||||
}));
|
||||
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.onload = t.step_func(() => {
|
||||
iframe.contentWindow.postMessage({ testId: 3, module }, "*");
|
||||
});
|
||||
iframe.src = "resources/echo-iframe.html";
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
}, "postMessaging to an iframe and back does not give back the same WebAssembly.Module");
|
||||
</script>
|
|
@ -0,0 +1,9 @@
|
|||
// META: global=!default,dedicatedworker,sharedworker
|
||||
// META: script=resources/test-incrementer.js
|
||||
"use strict";
|
||||
|
||||
promise_test(t => {
|
||||
const worker = new Worker("resources/incrementer-worker.js");
|
||||
|
||||
return testSharingViaIncrementerScript(t, worker, "parent worker", worker, "sub-worker");
|
||||
}, "postMessaging to a dedicated sub-worker allows them to see each others' modifications");
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ -->
|
||||
<meta charset="utf-8">
|
||||
<title>WebAssembly.Modules cannot be transferred</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/create-empty-wasm-module.js"></script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
test(() => {
|
||||
const module = createEmptyWasmModule();
|
||||
assert_throws("DataCloneError", () => window.postMessage(module, "*", [module]));
|
||||
assert_throws("DataCloneError", () => window.postMessage("test", "*", [module]));
|
||||
}, "Trying to transfer a WebAssembly.Module to this window throws");
|
||||
|
||||
test(() => {
|
||||
const module = createEmptyWasmModule();
|
||||
const worker = new Worker("resources/echo-worker.js");
|
||||
assert_throws("DataCloneError", () => worker.postMessage(module, [module]));
|
||||
assert_throws("DataCloneError", () => worker.postMessage("test", [module]));
|
||||
}, "Trying to transfer a WebAssembly.Module to a worker throws");
|
||||
|
||||
test(() => {
|
||||
const module = createEmptyWasmModule();
|
||||
const channel = new MessageChannel();
|
||||
assert_throws("DataCloneError", () => channel.port1.postMessage(module, [module]));
|
||||
assert_throws("DataCloneError", () => channel.port1.postMessage("test", [module]));
|
||||
}, "Trying to transfer a WebAssembly.Module through a MessagePort throws");
|
||||
</script>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>A test page that uses a given WebAssembly.Module sent from a BroadcastChannel</title>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
const channel = new BroadcastChannel("channel name");
|
||||
|
||||
channel.onmessage = ({ data: { module, i }, source }) => {
|
||||
if (!module) {
|
||||
// We only care about "broadcasts" from the window
|
||||
return;
|
||||
}
|
||||
|
||||
let instance = new WebAssembly.Instance(module);
|
||||
let increment = instance.exports["increment"];
|
||||
let result = increment(i);
|
||||
channel.postMessage({i, result});
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,7 @@
|
|||
const channel = new BroadcastChannel("anne was here");
|
||||
channel.onmessageerror = ({ data }) => {
|
||||
if(data === null) {
|
||||
channel.postMessage("sw-success");
|
||||
}
|
||||
}
|
||||
channel.postMessage("hi");
|
|
@ -0,0 +1,9 @@
|
|||
const channel = new BroadcastChannel("anne was here");
|
||||
channel.onmessage = ({ data }) => {
|
||||
if(data === "hi" || data === "sw-success") {
|
||||
return;
|
||||
} else if(data instanceof WebAssembly.Module) {
|
||||
channel.postMessage("dw-success");
|
||||
}
|
||||
}
|
||||
channel.postMessage("hi");
|
|
@ -0,0 +1,4 @@
|
|||
function createEmptyWasmModule() {
|
||||
return new WebAssembly.Module(
|
||||
new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]));
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>A test page that echos back anything postMessaged to it to its parent</title>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
window.onmessage = ({ data }) => {
|
||||
parent.postMessage(data, "*");
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
self.onmessage = ({ data }) => {
|
||||
self.postMessage(data);
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>A test page that is sent a WebAssembly Module</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="test-incrementer.js"></script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
document.domain = "{{host}}";
|
||||
setupDestinationIncrementer(self, parent, "*");
|
||||
</script>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>A test page that is sent a WebAssembly Module</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="test-incrementer.js"></script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
setupDestinationIncrementer(self, parent, "*");
|
||||
</script>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>A test page that is sent a WebAssembly Module</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="test-incrementer.js"></script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
setupDestinationIncrementer(self, opener, "*");
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
"use strict";
|
||||
importScripts("/resources/testharness.js");
|
||||
importScripts("./test-incrementer.js");
|
||||
|
||||
self.onmessage = ({ data }) => {
|
||||
// data will be a MessagePort
|
||||
setupDestinationIncrementer(data, data);
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
"use strict";
|
||||
importScripts("/resources/testharness.js");
|
||||
importScripts("./test-incrementer.js");
|
||||
|
||||
setupDestinationIncrementer(self, self);
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Nesting level 1</title>
|
||||
|
||||
<iframe src="nested-iframe-2.html"></iframe>
|
|
@ -0,0 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Nesting level 2</title>
|
||||
|
||||
<iframe src="nested-iframe-3.html"></iframe>
|
|
@ -0,0 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Nesting level 3</title>
|
||||
|
||||
<iframe src="nested-iframe-4-incrementer.html"></iframe>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>A test page that is sent a WebAssembly Module, nested 4 levels deep in iframes</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="test-incrementer.js"></script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
setupDestinationIncrementer(self, parent.parent.parent.parent.parent, "*");
|
||||
</script>
|
|
@ -0,0 +1,34 @@
|
|||
// Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/.
|
||||
"use strict";
|
||||
self.importScripts("/resources/testharness.js");
|
||||
self.importScripts("./create-empty-wasm-module.js");
|
||||
|
||||
let state = "start in worker";
|
||||
|
||||
self.onmessage = e => {
|
||||
if (e.data === "start in window") {
|
||||
assert_equals(state, "start in worker");
|
||||
e.source.postMessage(state);
|
||||
state = "we are expecting a messageerror due to the window sending us a WebAssembly.Module";
|
||||
} else if (e.data === "we are expecting a messageerror due to the worker sending us a WebAssembly.Module") {
|
||||
assert_equals(state, "onmessageerror was received in worker");
|
||||
e.source.postMessage(createEmptyWasmModule());
|
||||
state = "done in worker";
|
||||
} else {
|
||||
e.source.postMessage(`worker onmessage was reached when in state "${state}" and data ${e.data}`);
|
||||
}
|
||||
};
|
||||
|
||||
self.onmessageerror = e => {
|
||||
if (state === "we are expecting a messageerror due to the window sending us a WebAssembly.Module") {
|
||||
assert_equals(e.data, null, "data");
|
||||
assert_equals(e.origin, self.origin, "origin");
|
||||
assert_not_equals(e.source, null, "source");
|
||||
assert_equals(e.ports.length, 0, "ports length");
|
||||
|
||||
state = "onmessageerror was received in worker";
|
||||
e.source.postMessage(state);
|
||||
} else {
|
||||
e.source.postMessage(`worker onmessageerror was reached when in state "${state}" and data ${e.data}`);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
importScripts("./test-incrementer.js");
|
||||
importScripts("./create-empty-wasm-module.js");
|
||||
|
||||
let state = "send-sw-failure"
|
||||
onconnect = initialE => {
|
||||
let port = initialE.source;
|
||||
port.postMessage(state)
|
||||
port.onmessage = e => {
|
||||
if(state === "" && e.data === "send-window-failure") {
|
||||
port.postMessage(createEmptyWasmModule())
|
||||
} else {
|
||||
port.postMessage("failure")
|
||||
}
|
||||
}
|
||||
port.onmessageerror = e => {
|
||||
if(state === "send-sw-failure") {
|
||||
port.postMessage("send-sw-failure-success")
|
||||
state = ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
// Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/.
|
||||
//
|
||||
// This file is simplified from the one there, because it only tests that the
|
||||
// module can be passed and that functions can be run. The SharedArrayBuffer
|
||||
// version also tests that the memory is shared between the agents.
|
||||
|
||||
"use strict";
|
||||
|
||||
function createWasmModule() {
|
||||
return fetch('incrementer.wasm')
|
||||
.then(response => {
|
||||
if (!response.ok)
|
||||
throw new Error(response.statusText);
|
||||
return response.arrayBuffer();
|
||||
})
|
||||
.then(WebAssembly.compile);
|
||||
}
|
||||
|
||||
function testModule(module) {
|
||||
let instance = new WebAssembly.Instance(module);
|
||||
let increment = instance.exports["increment"];
|
||||
assert_equals(typeof increment, "function", `The type of the increment export should be "function", got ${typeof increment}`);
|
||||
let result = increment(42);
|
||||
assert_equals(result, 43, `increment(42) should be 43, got ${result}`);
|
||||
}
|
||||
|
||||
self.testSharingViaIncrementerScript = (t, whereToListen, whereToListenLabel, whereToSend, whereToSendLabel, origin) => {
|
||||
return createWasmModule().then(module => {
|
||||
return new Promise(resolve => {
|
||||
|
||||
whereToListen.onmessage = t.step_func(({ data }) => {
|
||||
switch (data.message) {
|
||||
case "module received": {
|
||||
testModule(data.module);
|
||||
resolve();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
whereToSend.postMessage({ message: "send module", module }, origin);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
self.setupDestinationIncrementer = (whereToListen, whereToSendBackTo, origin) => {
|
||||
whereToListen.onmessage = ({ data }) => {
|
||||
switch (data.message) {
|
||||
case "send module": {
|
||||
let module = data.module;
|
||||
testModule(data.module);
|
||||
whereToSendBackTo.postMessage({ message: "module received", module }, origin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ -->
|
||||
<meta charset="utf-8">
|
||||
<title>WebAssembly.Module cloning via history's methods invoking StructuredSerializeForStorage</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/create-empty-wasm-module.js"></script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
for (const method of ["pushState", "replaceState"]) {
|
||||
test(() => {
|
||||
assert_throws("DataCloneError", () => {
|
||||
history[method](createEmptyWasmModule(), "dummy title");
|
||||
});
|
||||
}, `history.${method}(): simple case`);
|
||||
|
||||
test(() => {
|
||||
let getter1Called = false;
|
||||
let getter2Called = false;
|
||||
assert_throws("DataCloneError", () => {
|
||||
history[method]([
|
||||
{ get x() { getter1Called = true; return 5; } },
|
||||
createEmptyWasmModule(),
|
||||
{ get x() { getter2Called = true; return 5; } }
|
||||
], "dummy title");
|
||||
});
|
||||
|
||||
assert_true(getter1Called, "The getter before the WebAssembly.Module must have been called");
|
||||
assert_false(getter2Called, "The getter after the WebAssembly.Module must not have been called");
|
||||
}, `history.${method}(): is interleaved correctly`);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,45 @@
|
|||
// META: script=/IndexedDB/support.js
|
||||
"use strict";
|
||||
|
||||
function createEmptyWasmModule() {
|
||||
return new WebAssembly.Module(
|
||||
new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]));
|
||||
}
|
||||
|
||||
async_test(t => {
|
||||
const openReq = createdb(t);
|
||||
|
||||
openReq.onupgradeneeded = e => {
|
||||
const db = e.target.result;
|
||||
const store = db.createObjectStore("store", { keyPath: "key" });
|
||||
|
||||
assert_throws("DataCloneError", () => {
|
||||
store.put({ key: 1, property: createEmptyWasmModule() });
|
||||
});
|
||||
t.done();
|
||||
};
|
||||
}, "WebAssembly.Module cloning via IndexedDB: basic case");
|
||||
|
||||
async_test(t => {
|
||||
const openReq = createdb(t);
|
||||
|
||||
openReq.onupgradeneeded = e => {
|
||||
const db = e.target.result;
|
||||
const store = db.createObjectStore("store", { keyPath: "key" });
|
||||
|
||||
let getter1Called = false;
|
||||
let getter2Called = false;
|
||||
|
||||
assert_throws("DataCloneError", () => {
|
||||
store.put({ key: 1, property: [
|
||||
{ get x() { getter1Called = true; return 5; } },
|
||||
createEmptyWasmModule(),
|
||||
{ get x() { getter2Called = true; return 5; } }
|
||||
]});
|
||||
});
|
||||
|
||||
assert_true(getter1Called, "The getter before the WebAssembly.Module must have been called");
|
||||
assert_false(getter2Called, "The getter after the WebAssembly.Module must not have been called");
|
||||
t.done();
|
||||
};
|
||||
}, "WebAssembly.Module cloning via the IndexedDB: is interleaved correctly");
|
|
@ -0,0 +1,28 @@
|
|||
"use strict";
|
||||
|
||||
function createEmptyWasmModule() {
|
||||
return new WebAssembly.Module(
|
||||
new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]));
|
||||
}
|
||||
|
||||
test(() => {
|
||||
assert_throws("DataCloneError", () => {
|
||||
new Notification("Bob: Hi", { data: createEmptyWasmModule() });
|
||||
})
|
||||
}, "WebAssembly.Module cloning via the Notifications API's data member: basic case");
|
||||
|
||||
test(() => {
|
||||
let getter1Called = false;
|
||||
let getter2Called = false;
|
||||
|
||||
assert_throws("DataCloneError", () => {
|
||||
new Notification("Bob: Hi", { data: [
|
||||
{ get x() { getter1Called = true; return 5; } },
|
||||
createEmptyWasmModule(),
|
||||
{ get x() { getter2Called = true; return 5; } }
|
||||
]});
|
||||
});
|
||||
|
||||
assert_true(getter1Called, "The getter before the SAB must have been called");
|
||||
assert_false(getter2Called, "The getter after the SAB must not have been called");
|
||||
}, "WebAssembly.Module cloning via the Notifications API's data member: is interleaved correctly");
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ -->
|
||||
<meta charset="utf-8">
|
||||
<title>Structured cloning of WebAssembly.Module into same-origin-domain windows</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/test-incrementer.js"></script>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
document.domain = "{{host}}";
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise(resolve => {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.onload = t.step_func(() => {
|
||||
resolve(testSharingViaIncrementerScript(t, window, "window", iframe.contentWindow, "iframe", "*"));
|
||||
});
|
||||
iframe.src = "//{{domains[www1]}}:{{location[port]}}/wasm/serialization/resources/incrementer-iframe-domain.sub.html";
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
}, "postMessaging to a same-origin-domain (but not same-origin) iframe allows them to instantiate");
|
||||
|
||||
</script>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ -->
|
||||
<meta charset="utf-8">
|
||||
<title>Structured cloning of WebAssembly.Module using MessageChannel</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/test-incrementer.js"></script>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
promise_test(t => {
|
||||
const worker = new Worker("resources/incrementer-worker-with-channel.js");
|
||||
const channel = new MessageChannel();
|
||||
worker.postMessage(channel.port2, [channel.port2]);
|
||||
|
||||
return testSharingViaIncrementerScript(t, channel.port1, "window", channel.port1, "worker");
|
||||
}, "postMessaging to a dedicated worker via MessageChannel allows them to instantiate");
|
||||
</script>
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ -->
|
||||
<title>WebAssembly.Module cannot cross agent clusters, service worker edition</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||
<script src="./resources/create-empty-wasm-module.js"></script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
promise_test(t => {
|
||||
const scope = "resources/blank.html";
|
||||
return service_worker_unregister_and_register(t, "resources/serviceworker-failure.js", scope).then(reg => {
|
||||
return wait_for_state(t, reg.installing, "activated");
|
||||
})
|
||||
.then(() => {
|
||||
return with_iframe(scope);
|
||||
}).then(iframe => {
|
||||
const sw = iframe.contentWindow.navigator.serviceWorker;
|
||||
let state = "start in window";
|
||||
|
||||
return new Promise(resolve => {
|
||||
sw.onmessage = t.step_func(e => {
|
||||
if (e.data === "start in worker") {
|
||||
assert_equals(state, "start in window");
|
||||
sw.controller.postMessage(createEmptyWasmModule());
|
||||
state = "we are expecting confirmation of an onmessageerror in the worker";
|
||||
} else if (e.data === "onmessageerror was received in worker") {
|
||||
assert_equals(state, "we are expecting confirmation of an onmessageerror in the worker");
|
||||
state = "we are expecting a messageerror due to the worker sending us a WebAssembly.Module";
|
||||
sw.controller.postMessage(state);
|
||||
} else {
|
||||
assert_unreached("Got an unexpected message from the service worker: " + e.data);
|
||||
}
|
||||
});
|
||||
|
||||
sw.onmessageerror = t.step_func(e => {
|
||||
assert_equals(state, "we are expecting a messageerror due to the worker sending us a WebAssembly.Module");
|
||||
|
||||
assert_equals(e.data, null, "data");
|
||||
assert_equals(e.origin, self.origin, "origin");
|
||||
assert_equals(e.source, null, "source");
|
||||
assert_equals(e.ports.length, 0, "ports length");
|
||||
|
||||
state = "done in window";
|
||||
resolve();
|
||||
});
|
||||
|
||||
sw.controller.postMessage(state);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,33 @@
|
|||
<!doctype html>
|
||||
<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ -->
|
||||
<title>WebAssembly.Modules cannot cross agent clusters, shared worker edition</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/create-empty-wasm-module.js"></script>
|
||||
<script>
|
||||
async_test(t => {
|
||||
const sw = new SharedWorker("resources/sharedworker-failure.js")
|
||||
let state = ""
|
||||
sw.port.onmessage = t.step_func(e => {
|
||||
if(e.data === "send-sw-failure") {
|
||||
sw.port.postMessage(createEmptyWasmModule())
|
||||
} else if(e.data === "send-sw-failure-success") {
|
||||
state = "send-window-failure"
|
||||
sw.port.postMessage(state)
|
||||
} else {
|
||||
assert_unreached()
|
||||
}
|
||||
})
|
||||
sw.port.onmessageerror = t.step_func(e => {
|
||||
if(state === "send-window-failure") {
|
||||
assert_equals(e.data, null, "data")
|
||||
assert_equals(e.origin, "", "origin")
|
||||
assert_equals(e.source, null, "source")
|
||||
assert_equals(e.ports.length, 0, "ports length")
|
||||
t.done()
|
||||
} else {
|
||||
assert_unreached()
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ -->
|
||||
<meta charset="utf-8">
|
||||
<title>Structured cloning of WebAssembly.Module to similar-origin, but not same-origin, windows</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/test-incrementer.js"></script>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
document.domain = "{{host}}";
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise(resolve => {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.onload = t.step_func(() => {
|
||||
resolve(testSharingViaIncrementerScript(t, window, "window", iframe.contentWindow, "iframe", "*"));
|
||||
});
|
||||
iframe.src = "//{{domains[www1]}}:{{location[port]}}/wasm/serialization/resources/incrementer-iframe.html";
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
}, "postMessaging to a not same-origin-domain, but similar origin, iframe allows them to instantiate");
|
||||
</script>
|
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- Based on similar tests in html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/ -->
|
||||
<meta charset="utf-8">
|
||||
<title>Structured cloning of WebAssembly.Module: simple success cases that don't need dedicated files</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/test-incrementer.js"></script>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
promise_test(t => {
|
||||
const worker = new Worker("resources/incrementer-worker.js");
|
||||
|
||||
return testSharingViaIncrementerScript(t, worker, "window", worker, "worker", undefined);
|
||||
}, "postMessaging to a dedicated worker allows them to instantiate");
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise(resolve => {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.onload = t.step_func(() => {
|
||||
resolve(testSharingViaIncrementerScript(t, window, "window", iframe.contentWindow, "iframe", "*"));
|
||||
});
|
||||
iframe.src = "resources/incrementer-iframe.html";
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
}, "postMessaging to a same-origin iframe allows them to instantiate");
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise(resolve => {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.onload = t.step_func(() => {
|
||||
const level1 = iframe.contentWindow;
|
||||
const level2 = level1.frames[0];
|
||||
const level3 = level2.frames[0];
|
||||
const targetWindow = level3.frames[0];
|
||||
resolve(testSharingViaIncrementerScript(t, window, "window", targetWindow, "nested iframe", "*"));
|
||||
});
|
||||
iframe.src = "resources/nested-iframe-1.html";
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
}, "postMessaging to a same-origin deeply-nested iframe allows them to instantiate");
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise(resolve => {
|
||||
const w = window.open("resources/incrementer-popup.html");
|
||||
w.onload = t.step_func(() => {
|
||||
resolve(testSharingViaIncrementerScript(t, window, "window", w, "popup window", "*").then(() => {
|
||||
w.close();
|
||||
}));
|
||||
});
|
||||
});
|
||||
}, "postMessaging to a same-origin opened window allows them to instantiate");
|
||||
|
||||
</script>
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/load_wasm.js"></script>
|
||||
<script>
|
||||
function runTests(iframe) {
|
||||
iframe = iframe.contentWindow;
|
||||
promise_test(async function() {
|
||||
var mod = await createWasmModule();
|
||||
assert_true(mod instanceof WebAssembly.Module);
|
||||
var ans = await new Promise((resolve, reject) => {
|
||||
iframe.postMessage(mod, '*');
|
||||
window.addEventListener("message", (reply) => resolve(reply.data), false);
|
||||
});
|
||||
assert_equals(ans, 43);
|
||||
}, "send wasm module to iframe");
|
||||
}
|
||||
</script>
|
||||
<iframe src="resources/frame.html" onload="runTests(this)"></iframe>
|
|
@ -1,8 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/load_wasm.js"></script>
|
||||
<script src="wasm_serialization_tests.js"></script>
|
||||
<script>
|
||||
promise_test(TestInstantiateInWorker, "serialize wasm to worker");
|
||||
</script>
|
|
@ -1,18 +0,0 @@
|
|||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
function TestInstantiateInWorker() {
|
||||
return createWasmModule()
|
||||
.then((mod) => {
|
||||
var worker = new Worker("wasm_serialization_worker.js");
|
||||
return new Promise((resolve, reject) => {
|
||||
worker.postMessage(mod);
|
||||
worker.onmessage = function(event) {
|
||||
resolve(event.data);
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(data => assert_equals(data, 43))
|
||||
.catch(error => assert_unreached(error));
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
onmessage = function(e) {
|
||||
var compiled_module = e.data;
|
||||
var instance = new WebAssembly.Instance(compiled_module);
|
||||
if (instance === undefined) {
|
||||
postMessage("error!");
|
||||
return;
|
||||
}
|
||||
var entrypoint = instance.exports["increment"];
|
||||
|
||||
if (typeof entrypoint !== "function") {
|
||||
postMessage("error!");
|
||||
return;
|
||||
}
|
||||
|
||||
var ret = entrypoint(42);
|
||||
postMessage(ret);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: postMessage with wasm</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/get-host-info.sub.js"></script>
|
||||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
promise_test(async test => {
|
||||
var registration = await service_worker_unregister_and_register(
|
||||
test, 'resources/service-worker.js', 'resources/blank.html');
|
||||
add_completion_callback(() => registration.unregister());
|
||||
var worker = registration.installing;
|
||||
var event = await new Promise((resolve, reject) => {
|
||||
var messageChannel = new MessageChannel();
|
||||
worker.postMessage({port: messageChannel.port2}, [messageChannel.port2]);
|
||||
worker.postMessage({compile: true});
|
||||
messageChannel.port1.onmessage = event => reject(event);
|
||||
messageChannel.port1.onmessageerror = event => resolve(event);
|
||||
});
|
||||
assert_equals(event.type, "messageerror");
|
||||
assert_equals(event.data, null);
|
||||
}, 'postMessaging wasm from a service worker should fail');
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue