blob: 5e372105c7d1c1c165e87c6f1362440439adb63c [file] [log] [blame]
jfbastien@apple.com28721472016-10-19 22:11:11 +00001import * as assert from '../assert.js';
2import * as utilities from '../utilities.js';
jfbastien@apple.comd2c6b7a2016-10-17 21:36:05 +00003
jfbastien@apple.com5d26c892017-02-23 21:36:13 +00004const version = 0x01;
jfbastien@apple.comc4988542016-10-27 02:18:51 +00005const emptyModuleArray = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, version, 0x00, 0x00, 0x00);
6const invalidConstructorInputs = [undefined, null, "", 1, {}, []];
7const invalidInstanceImports = [null, "", 1];
jfbastien@apple.com7e51cf32016-10-25 17:23:53 +00008
jfbastien@apple.com28721472016-10-19 22:11:11 +00009const checkOwnPropertyDescriptor = (obj, prop, expect) => {
10 const descriptor = Object.getOwnPropertyDescriptor(obj, prop);
11 assert.eq(typeof descriptor.value, expect.typeofvalue);
12 assert.eq(descriptor.writable, expect.writable);
13 assert.eq(descriptor.configurable, expect.configurable);
14 assert.eq(descriptor.enumerable, expect.enumerable);
15};
jfbastien@apple.comd2c6b7a2016-10-17 21:36:05 +000016
jfbastien@apple.com71d1e862017-05-19 05:27:28 +000017const checkAccessorOwnPropertyDescriptor = (obj, prop, expect) => {
18 const descriptor = Object.getOwnPropertyDescriptor(obj, prop);
19 assert.eq(typeof descriptor.value, "undefined");
20 assert.eq(typeof descriptor.writable, "undefined");
21 assert.eq(descriptor.configurable, expect.configurable);
22 assert.eq(descriptor.enumerable, expect.enumerable);
23};
24
jfbastien@apple.com28721472016-10-19 22:11:11 +000025const functionProperties = {
26 "validate": { length: 1 },
27 "compile": { length: 1 },
28};
29const constructorProperties = {
jfbastien@apple.com7e51cf32016-10-25 17:23:53 +000030 "Module": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
31 "Instance": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
32 "Memory": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
33 "Table": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
34 "CompileError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
jfbastien@apple.com5d2a7e32016-12-20 20:20:05 +000035 "LinkError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
jfbastien@apple.com7e51cf32016-10-25 17:23:53 +000036 "RuntimeError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
jfbastien@apple.com28721472016-10-19 22:11:11 +000037};
jfbastien@apple.comd2c6b7a2016-10-17 21:36:05 +000038
jfbastien@apple.comd2c6b7a2016-10-17 21:36:05 +000039
jfbastien@apple.com97a32c12016-11-04 22:12:12 +000040assert.isNotUndef(WebAssembly);
jfbastien@apple.com28721472016-10-19 22:11:11 +000041checkOwnPropertyDescriptor(utilities.global, "WebAssembly", { typeofvalue: "object", writable: true, configurable: true, enumerable: false });
42assert.eq(String(WebAssembly), "[object WebAssembly]");
43assert.isUndef(WebAssembly.length);
jfbastien@apple.come7640f32016-10-21 01:19:24 +000044assert.eq(WebAssembly instanceof Object, true);
45assert.throws(() => WebAssembly(), TypeError, `WebAssembly is not a function. (In 'WebAssembly()', 'WebAssembly' is an instance of WebAssembly)`);
46assert.throws(() => new WebAssembly(), TypeError, `WebAssembly is not a constructor (evaluating 'new WebAssembly()')`);
jfbastien@apple.comd2c6b7a2016-10-17 21:36:05 +000047
jfbastien@apple.com28721472016-10-19 22:11:11 +000048for (const f in functionProperties) {
jfbastien@apple.com97a32c12016-11-04 22:12:12 +000049 assert.isNotUndef(WebAssembly[f]);
jfbastien@apple.com28721472016-10-19 22:11:11 +000050 assert.eq(WebAssembly[f].name, f);
51 assert.eq(WebAssembly[f].length, functionProperties[f].length);
jfbastien@apple.comd2c6b7a2016-10-17 21:36:05 +000052}
53
jfbastien@apple.com28721472016-10-19 22:11:11 +000054for (const c in constructorProperties) {
jfbastien@apple.com97a32c12016-11-04 22:12:12 +000055 assert.isNotUndef(WebAssembly[c]);
jfbastien@apple.com28721472016-10-19 22:11:11 +000056 assert.eq(WebAssembly[c].name, c);
57 assert.eq(WebAssembly[c].length, constructorProperties[c].length);
58 checkOwnPropertyDescriptor(WebAssembly, c, constructorProperties[c]);
jfbastien@apple.com28721472016-10-19 22:11:11 +000059 checkOwnPropertyDescriptor(WebAssembly[c], "prototype", { typeofvalue: "object", writable: false, configurable: false, enumerable: false });
jfbastien@apple.com7172d5d2017-03-22 17:52:55 +000060 if (["CompileError", "LinkError", "RuntimeError"].indexOf(c) >= 0)
61 WebAssembly[c](); // Per spec, the WebAssembly.*Error types match ye olden JavaScript NativeError behavior: they can be constructed without `new`.
62 else
63 assert.throws(() => WebAssembly[c](), TypeError, `calling WebAssembly.${c} constructor without new is invalid`);
jfbastien@apple.com7e51cf32016-10-25 17:23:53 +000064 switch (c) {
65 case "Module":
jfbastien@apple.comc4988542016-10-27 02:18:51 +000066 for (const invalid of invalidConstructorInputs)
sbarati@apple.com7fbb1b22016-12-19 07:22:42 +000067 assert.throws(() => new WebAssembly[c](invalid), TypeError, `first argument must be an ArrayBufferView or an ArrayBuffer (evaluating 'new WebAssembly[c](invalid)')`);
jfbastien@apple.com7e51cf32016-10-25 17:23:53 +000068 for (const buffer of [new ArrayBuffer(), new DataView(new ArrayBuffer()), new Int8Array(), new Uint8Array(), new Uint8ClampedArray(), new Int16Array(), new Uint16Array(), new Int32Array(), new Uint32Array(), new Float32Array(), new Float64Array()])
69 // FIXME the following should be WebAssembly.CompileError. https://bugs.webkit.org/show_bug.cgi?id=163768
yusukesuzuki@slowstart.org184dd1f2018-08-28 06:38:29 +000070 assert.throws(() => new WebAssembly[c](buffer), Error, `WebAssembly.Module doesn't parse at byte 0: expected a module of at least 8 bytes (evaluating 'new WebAssembly[c](buffer)')`);
jfbastien@apple.comc4988542016-10-27 02:18:51 +000071 assert.instanceof(new WebAssembly[c](emptyModuleArray), WebAssembly.Module);
jfbastien@apple.com7e51cf32016-10-25 17:23:53 +000072 break;
73 case "Instance":
jfbastien@apple.comc4988542016-10-27 02:18:51 +000074 for (const invalid of invalidConstructorInputs)
75 assert.throws(() => new WebAssembly[c](invalid), TypeError, `first argument to WebAssembly.Instance must be a WebAssembly.Module (evaluating 'new WebAssembly[c](invalid)')`);
76 const instance = new WebAssembly[c](new WebAssembly.Module(emptyModuleArray));
77 assert.instanceof(instance, WebAssembly.Instance);
78 for (const invalid of invalidInstanceImports)
79 assert.throws(() => new WebAssembly[c](new WebAssembly.Module(emptyModuleArray), invalid), TypeError, `second argument to WebAssembly.Instance must be undefined or an Object (evaluating 'new WebAssembly[c](new WebAssembly.Module(emptyModuleArray), invalid)')`);
jfbastien@apple.com97a32c12016-11-04 22:12:12 +000080 assert.isNotUndef(instance.exports);
ysuzuki@apple.com3640d4e2019-07-15 22:41:54 +000081 checkAccessorOwnPropertyDescriptor(WebAssembly.Instance.prototype, "exports", { configurable: true, enumerable: true });
jfbastien@apple.com71d1e862017-05-19 05:27:28 +000082 assert.throws(() => WebAssembly.Instance.prototype.exports = undefined, TypeError, `Attempted to assign to readonly property.`);
83 assert.throws(() => WebAssembly.Instance.prototype.exports, TypeError, `expected |this| value to be an instance of WebAssembly.Instance`);
jfbastien@apple.com0a1b73d2017-03-22 17:54:36 +000084 assert.isUndef(instance.exports.__proto__);
85 assert.eq(Reflect.isExtensible(instance.exports), false);
86 assert.eq(Symbol.iterator in instance.exports, false);
87 assert.eq(Symbol.toStringTag in instance.exports, true);
88 assert.eq(Object.getOwnPropertySymbols(instance.exports).length, 1);
89 assert.eq(Object.getOwnPropertySymbols(instance.exports)[0], Symbol.toStringTag);
90 assert.throws(() => instance.exports[Symbol.toStringTag] = 42, TypeError, `Attempted to assign to readonly property.`);
jfbastien@apple.com7e51cf32016-10-25 17:23:53 +000091 break;
92 case "Memory":
sbarati@apple.com73916bb2016-12-09 22:38:39 +000093 new WebAssembly.Memory({initial: 20});
jfbastien@apple.com7e51cf32016-10-25 17:23:53 +000094 break;
95 case "Table":
justin_michaud@apple.com44534122019-06-19 15:36:46 +000096 new WebAssembly.Table({initial: 20, element: "funcref"});
97 new WebAssembly.Table({initial: 20, maximum: 20, element: "funcref"});
98 new WebAssembly.Table({initial: 20, maximum: 25, element: "funcref"});
jfbastien@apple.com7e51cf32016-10-25 17:23:53 +000099 break;
100 case "CompileError":
jfbastien@apple.com5d2a7e32016-12-20 20:20:05 +0000101 case "LinkError":
jfbastien@apple.com7e51cf32016-10-25 17:23:53 +0000102 case "RuntimeError": {
jfbastien@apple.com7172d5d2017-03-22 17:52:55 +0000103 {
104 const e = new WebAssembly[c];
105 assert.eq(e instanceof WebAssembly[c], true);
106 assert.eq(e instanceof Error, true);
107 assert.eq(e instanceof TypeError, false);
108 assert.eq(e.message, "");
109 assert.eq(typeof e.stack, "string");
110 const sillyString = "uh-oh!";
111 const e2 = new WebAssembly[c](sillyString);
112 assert.eq(e2.message, sillyString + " (evaluating 'new WebAssembly[c](sillyString)')");
113 }
114 {
115 const e = WebAssembly[c]();
116 assert.eq(e instanceof WebAssembly[c], true);
117 assert.eq(e instanceof Error, true);
118 assert.eq(e instanceof TypeError, false);
119 assert.eq(e.message, "");
120 assert.eq(typeof e.stack, "string");
121 const sillyString = "uh-oh!";
122 const e2 = WebAssembly[c](sillyString);
123 assert.eq(e2.message, sillyString);
124 }
jfbastien@apple.com7e51cf32016-10-25 17:23:53 +0000125 } break;
126 default: throw new Error(`Implementation error: unexpected constructor property "${c}"`);
jfbastien@apple.come7640f32016-10-21 01:19:24 +0000127 }
jfbastien@apple.comd2c6b7a2016-10-17 21:36:05 +0000128}