1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
// META: global=window,dedicatedworker,jsshell,shadowrealm
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_js(TypeError, () => getter.call(thisValue), `getter with this=${format_value(thisValue)}`);
assert_throws_js(TypeError, () => setter.call(thisValue, 1), `setter with this=${format_value(thisValue)}`);
}
}, "Branding");
for (const type of ["i32", "i64", "f32", "f64"]) {
const [initial, value, invalid] = type === "i64" ? [0n, 1n, 2] : [0, 1, 2n];
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, initial, "initial value");
assert_equals(global.valueOf(), initial, "initial valueOf");
assert_throws_js(TypeError, () => global.value = value);
assert_equals(global.value, initial, "post-set value");
assert_equals(global.valueOf(), initial, "post-set valueOf");
}, `Immutable ${type} (${name})`);
test(t => {
opts.value = type;
const global = new WebAssembly.Global(opts);
assert_equals(global.value, initial, "initial value");
assert_equals(global.valueOf(), initial, "initial valueOf");
const value = {
valueOf: t.unreached_func("should not call valueOf"),
toString: t.unreached_func("should not call toString"),
};
assert_throws_js(TypeError, () => global.value = value);
assert_equals(global.value, initial, "post-set value");
assert_equals(global.valueOf(), initial, "post-set valueOf");
}, `Immutable ${type} with ToNumber side-effects (${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, initial, "initial value");
assert_equals(global.valueOf(), initial, "initial valueOf");
global.value = value;
assert_throws_js(TypeError, () => global.value = invalid);
assert_equals(global.value, value, "post-set value");
assert_equals(global.valueOf(), value, "post-set valueOf");
}, `Mutable ${type} (${name})`);
}
}
test(() => {
const argument = { "value": "i64", "mutable": true };
const global = new WebAssembly.Global(argument);
assert_equals(global.value, 0n, "initial value using ToJSValue");
const valid = [
[123n, 123n],
[2n ** 63n, - (2n ** 63n)],
[true, 1n],
[false, 0n],
["456", 456n],
];
for (const [input, output] of valid) {
global.value = input;
assert_equals(global.valueOf(), output, "post-set valueOf");
}
const invalid = [
undefined,
null,
0,
1,
4.2,
Symbol(),
];
for (const input of invalid) {
assert_throws_js(TypeError, () => global.value = input);
}
}, "i64 mutability");
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_js(TypeError, () => setter.call(global));
}, "Calling setter without argument");
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 getter = desc.get;
assert_equals(typeof getter, "function");
const setter = desc.set;
assert_equals(typeof setter, "function");
assert_equals(getter.call(global, {}), 0);
assert_equals(setter.call(global, 1, {}), undefined);
assert_equals(global.value, 1);
}, "Stray argument");
|