WebAssembly JS API: implement more sections
[WebKit-https.git] / JSTests / wasm / js-api / test_basic_api.js
1 import * as assert from '../assert.js';
2 import * as utilities from '../utilities.js';
3
4 const version = 0xC;
5 const emptyModuleArray = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, version, 0x00, 0x00, 0x00);
6 const invalidConstructorInputs = [undefined, null, "", 1, {}, []];
7 const invalidInstanceImports = [null, "", 1];
8
9 const 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 };
16
17 const functionProperties = {
18     "validate": { length: 1 },
19     "compile":  { length: 1 },
20 };
21 const constructorProperties = {
22     "Module":       { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
23     "Instance":     { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
24     "Memory":       { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
25     "Table":        { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
26     "CompileError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
27     "RuntimeError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
28 };
29
30
31 assert.isNotUndef(WebAssembly);
32 checkOwnPropertyDescriptor(utilities.global, "WebAssembly", { typeofvalue: "object", writable: true, configurable: true, enumerable: false });
33 assert.eq(String(WebAssembly), "[object WebAssembly]");
34 assert.isUndef(WebAssembly.length);
35 assert.eq(WebAssembly instanceof Object, true);
36 assert.throws(() => WebAssembly(), TypeError, `WebAssembly is not a function. (In 'WebAssembly()', 'WebAssembly' is an instance of WebAssembly)`);
37 assert.throws(() => new WebAssembly(), TypeError, `WebAssembly is not a constructor (evaluating 'new WebAssembly()')`);
38
39 for (const f in functionProperties) {
40     assert.isNotUndef(WebAssembly[f]);
41     assert.eq(WebAssembly[f].name, f);
42     assert.eq(WebAssembly[f].length, functionProperties[f].length);
43 }
44
45 for (const c in constructorProperties) {
46     assert.isNotUndef(WebAssembly[c]);
47     assert.eq(WebAssembly[c].name, c);
48     assert.eq(WebAssembly[c].length, constructorProperties[c].length);
49     checkOwnPropertyDescriptor(WebAssembly, c, constructorProperties[c]);
50     checkOwnPropertyDescriptor(WebAssembly[c], "prototype", { typeofvalue: "object", writable: false, configurable: false, enumerable: false });
51     assert.throws(() => WebAssembly[c](), TypeError, `calling WebAssembly.${c} constructor without new is invalid`);
52     switch (c) {
53     case "Module":
54         for (const invalid of invalidConstructorInputs)
55             assert.throws(() => new WebAssembly[c](invalid), TypeError, `first argument to WebAssembly.Module must be an ArrayBufferView or an ArrayBuffer (evaluating 'new WebAssembly[c](invalid)')`);
56         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()])
57             // FIXME the following should be WebAssembly.CompileError. https://bugs.webkit.org/show_bug.cgi?id=163768
58             assert.throws(() => new WebAssembly[c](buffer), Error, `Module is 0 bytes, expected at least 8 bytes (evaluating 'new WebAssembly[c](buffer)')`);
59         assert.instanceof(new WebAssembly[c](emptyModuleArray), WebAssembly.Module);
60         // FIXME test neutered TypedArray and TypedArrayView. https://bugs.webkit.org/show_bug.cgi?id=163899
61         break;
62     case "Instance":
63         for (const invalid of invalidConstructorInputs)
64             assert.throws(() => new WebAssembly[c](invalid), TypeError, `first argument to WebAssembly.Instance must be a WebAssembly.Module (evaluating 'new WebAssembly[c](invalid)')`);
65         const instance = new WebAssembly[c](new WebAssembly.Module(emptyModuleArray));
66         assert.instanceof(instance, WebAssembly.Instance);
67         for (const invalid of invalidInstanceImports)
68             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)')`);
69         assert.isNotUndef(instance.exports);
70         checkOwnPropertyDescriptor(instance, "exports", { typeofvalue: "object", writable: true, configurable: true, enumerable: true });
71         assert.isUndef(instance.exports.__proto__);
72         assert.eq(Reflect.isExtensible(instance.exports), false);
73         assert.eq(Symbol.iterator in instance.exports, true);
74         assert.eq(Symbol.toStringTag in instance.exports, true);
75         break;
76     case "Memory":
77         // FIXME Implement and test these APIs further. For now they just throw. https://bugs.webkit.org/show_bug.cgi?id=159775
78         assert.throws(() => new WebAssembly[c](), Error, `WebAssembly doesn't yet implement the ${c} constructor property`);
79         break;
80     case "Table":
81         // FIXME Implement and test these APIs further. For now they just throw. https://bugs.webkit.org/show_bug.cgi?id=159775
82         assert.throws(() => new WebAssembly[c](), Error, `WebAssembly doesn't yet implement the ${c} constructor property`);
83         break;
84     case "CompileError":
85     case "RuntimeError": {
86         const e = new WebAssembly[c];
87         assert.eq(e instanceof WebAssembly[c], true);
88         assert.eq(e instanceof Error, true);
89         assert.eq(e instanceof TypeError, false);
90         assert.eq(e.message, "");
91         assert.eq(typeof e.stack, "string");
92         const sillyString = "uh-oh!";
93         const e2 = new WebAssembly[c](sillyString);
94         assert.eq(e2.message, sillyString);
95     } break;
96     default: throw new Error(`Implementation error: unexpected constructor property "${c}"`);
97     }
98 }
99
100 // FIXME Implement and test these APIs further. For now they just throw. https://bugs.webkit.org/show_bug.cgi?id=159775
101 for (const f in functionProperties) {
102     assert.throws(() => WebAssembly[f](), Error, `WebAssembly doesn't yet implement the ${f} function property`);
103 }