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