Skip to content

Commit

Permalink
Extend wasm js-api tests
Browse files Browse the repository at this point in the history
bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1486000
gecko-commit: 18c0aff587fa935a8149f83d58664e77c35e598a
gecko-integration-branch: mozilla-inbound
gecko-reviewers: bbouvier
  • Loading branch information
Ms2ger authored and moz-wptsync-bot committed Aug 30, 2018
1 parent d6ab2e6 commit 9b90762
Show file tree
Hide file tree
Showing 23 changed files with 1,322 additions and 99 deletions.
121 changes: 121 additions & 0 deletions wasm/jsapi/global/constructor.any.js
Original file line number Diff line number Diff line change
@@ -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}`);
}
}
7 changes: 7 additions & 0 deletions wasm/jsapi/global/toString.any.js
Original file line number Diff line number Diff line change
@@ -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");
94 changes: 94 additions & 0 deletions wasm/jsapi/global/value-set.any.js
Original file line number Diff line number Diff line change
@@ -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");
22 changes: 22 additions & 0 deletions wasm/jsapi/global/valueOf.any.js
Original file line number Diff line number Diff line change
@@ -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");
34 changes: 34 additions & 0 deletions wasm/jsapi/instance/constructor.any.js
Original file line number Diff line number Diff line change
Expand Up @@ -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":
Expand Down Expand Up @@ -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));
Expand Down
53 changes: 53 additions & 0 deletions wasm/jsapi/instance/exports.any.js
Original file line number Diff line number Diff line change
@@ -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)");
10 changes: 10 additions & 0 deletions wasm/jsapi/instance/toString.any.js
Original file line number Diff line number Diff line change
@@ -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");
15 changes: 14 additions & 1 deletion wasm/jsapi/interface.any.js
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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;
Expand All @@ -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", [
Expand Down
Loading

0 comments on commit 9b90762

Please sign in to comment.