179e4fe975cdaae90852bd221ca7f7dcbd034fe6
[WebKit-https.git] / JSTests / wasm / spec-tests / jsapi.js
1 /*
2  * Copyright 2017 WebAssembly Community Group participants
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17 (function testJSAPI() {
18
19 const WasmPage = 64 * 1024;
20
21 const emptyModuleBinary = new WasmModuleBuilder().toBuffer();
22
23 const importingModuleBinary = (() => {
24     let builder = new WasmModuleBuilder();
25
26     builder.addImport('', 'f', kSig_v_v);
27
28     return builder.toBuffer();
29 })();
30
31 const complexImportingModuleBinary = (() => {
32     let builder = new WasmModuleBuilder();
33
34     builder.addImport('a', 'b', kSig_v_v);
35     builder.addImportedMemory('c', 'd', 1);
36     builder.addImportedTable('e', 'f', 1);
37     builder.addImportedGlobal('g', '⚡', kWasmI32);
38
39     return builder.toBuffer();
40 })();
41
42 const exportingModuleBinary = (() => {
43     let builder = new WasmModuleBuilder();
44
45     builder
46         .addFunction('f', kSig_i_v)
47         .addBody([
48             kExprI32Const,
49             42
50         ])
51         .exportFunc();
52
53     return builder.toBuffer();
54 })();
55
56 const complexExportingModuleBinary = (() => {
57     let builder = new WasmModuleBuilder();
58
59     builder
60         .addFunction('a', kSig_v_v)
61         .addBody([])
62         .exportFunc();
63
64     builder.addMemory(1, 1, /* exported */ false);
65     builder.exportMemoryAs('b');
66
67     builder.setFunctionTableLength(1);
68     builder.addExportOfKind('c', kExternalTable, 0);
69
70     // Default init for global values is 0. Keep that.
71     builder.addGlobal(kWasmI32, /* mutable */ false)
72         .exportAs("⚡");
73
74     return builder.toBuffer();
75 })();
76
77 const moduleBinaryImporting2Memories = (() => {
78     var builder = new WasmModuleBuilder();
79     builder.addImportedMemory("", "memory1");
80     builder.addImportedMemory("", "memory2");
81     return builder.toBuffer();
82 })();
83
84 const moduleBinaryWithMemSectionAndMemImport = (() => {
85     var builder = new WasmModuleBuilder();
86     builder.addMemory(1, 1, false);
87     builder.addImportedMemory("", "memory1");
88     return builder.toBuffer();
89 })();
90
91 let Module;
92 let Instance;
93 let CompileError;
94 let LinkError;
95 let RuntimeError;
96 let Memory;
97 let instanceProto;
98 let memoryProto;
99 let mem1;
100 let Table;
101 let tbl1;
102 let tableProto;
103
104 let emptyModule;
105 let exportingModule;
106 let exportingInstance;
107 let exportsObj;
108 let importingModule;
109
110 // Start of tests.
111
112 test(() => {
113     const wasmDesc = Object.getOwnPropertyDescriptor(this, 'WebAssembly');
114     assert_equals(typeof wasmDesc.value, "object");
115     assert_true(wasmDesc.writable);
116     assert_false(wasmDesc.enumerable);
117     assert_true(wasmDesc.configurable);
118 }, "'WebAssembly' data property on global object");
119
120 test(() => {
121     const wasmDesc = Object.getOwnPropertyDescriptor(this, 'WebAssembly');
122     assert_equals(WebAssembly, wasmDesc.value);
123     assert_equals(String(WebAssembly), "[object WebAssembly]");
124 }, "'WebAssembly' object");
125
126 test(() => {
127     const compileErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'CompileError');
128     const linkErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'LinkError');
129     const runtimeErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'RuntimeError');
130     assert_equals(typeof compileErrorDesc.value, "function");
131     assert_equals(typeof linkErrorDesc.value, "function");
132     assert_equals(typeof runtimeErrorDesc.value, "function");
133     assert_equals(compileErrorDesc.writable, true);
134     assert_equals(linkErrorDesc.writable, true);
135     assert_equals(runtimeErrorDesc.writable, true);
136     assert_equals(compileErrorDesc.enumerable, false);
137     assert_equals(linkErrorDesc.enumerable, false);
138     assert_equals(runtimeErrorDesc.enumerable, false);
139     assert_equals(compileErrorDesc.configurable, true);
140     assert_equals(linkErrorDesc.configurable, true);
141     assert_equals(runtimeErrorDesc.configurable, true);
142
143     CompileError = WebAssembly.CompileError;
144     LinkError = WebAssembly.LinkError;
145     RuntimeError = WebAssembly.RuntimeError;
146 }, "'WebAssembly.(Compile|Link|Runtime)Error' data property");
147
148 test(() => {
149     const compileErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'CompileError');
150     const linkErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'LinkError');
151     const runtimeErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'RuntimeError');
152     assert_equals(CompileError, compileErrorDesc.value);
153     assert_equals(LinkError, linkErrorDesc.value);
154     assert_equals(RuntimeError, runtimeErrorDesc.value);
155     assert_equals(CompileError.length, 1);
156     assert_equals(LinkError.length, 1);
157     assert_equals(RuntimeError.length, 1);
158     assert_equals(CompileError.name, "CompileError");
159     assert_equals(LinkError.name, "LinkError");
160     assert_equals(RuntimeError.name, "RuntimeError");
161 }, "'WebAssembly.(Compile|Runtime)Error' constructor function");
162
163 test(() => {
164     const compileError = new CompileError;
165     const runtimeError = new RuntimeError;
166     assert_equals(compileError instanceof CompileError, true);
167     assert_equals(runtimeError instanceof RuntimeError, true);
168     assert_equals(compileError instanceof Error, true);
169     assert_equals(runtimeError instanceof Error, true);
170     assert_equals(compileError instanceof TypeError, false);
171     assert_equals(runtimeError instanceof TypeError, false);
172     assert_equals(compileError.message, "");
173     assert_equals(runtimeError.message, "");
174 // FIXME https://bugs.webkit.org/show_bug.cgi?id=173159    assert_equals(new CompileError("hi").message, "hi");
175 // FIXME https://bugs.webkit.org/show_bug.cgi?id=173159    assert_equals(new RuntimeError("hi").message, "hi");
176 }, "'WebAssembly.(Compile|Runtime)Error' instance objects");
177
178 test(() => {
179     const moduleDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Module');
180     assert_equals(typeof moduleDesc.value, "function");
181     assert_equals(moduleDesc.writable, true);
182     assert_equals(moduleDesc.enumerable, false);
183     assert_equals(moduleDesc.configurable, true);
184     Module = WebAssembly.Module;
185 }, "'WebAssembly.Module' data property");
186
187 test(() => {
188     const moduleDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Module');
189     assert_equals(Module, moduleDesc.value);
190     assert_equals(Module.length, 1);
191     assert_equals(Module.name, "Module");
192     assertThrows(() => Module(), TypeError);
193     assertThrows(() => new Module(), TypeError);
194     assertThrows(() => new Module(undefined), TypeError);
195     assertThrows(() => new Module(1), TypeError);
196     assertThrows(() => new Module({}), TypeError);
197     assertThrows(() => new Module(new Uint8Array()), CompileError);
198     assertThrows(() => new Module(new ArrayBuffer()), CompileError);
199     assert_equals(new Module(emptyModuleBinary) instanceof Module, true);
200     assert_equals(new Module(new Uint8Array(emptyModuleBinary)) instanceof Module, true);
201 }, "'WebAssembly.Module' constructor function");
202
203 test(() => {
204     const moduleProtoDesc = Object.getOwnPropertyDescriptor(Module, 'prototype');
205     assert_equals(typeof moduleProtoDesc.value, "object");
206     assert_equals(moduleProtoDesc.writable, false);
207     assert_equals(moduleProtoDesc.enumerable, false);
208     assert_equals(moduleProtoDesc.configurable, false);
209 }, "'WebAssembly.Module.prototype' data property");
210
211 test(() => {
212     const moduleProtoDesc = Object.getOwnPropertyDescriptor(Module, 'prototype');
213     const moduleProto = Module.prototype;
214     assert_equals(moduleProto, moduleProtoDesc.value);
215     assert_equals(String(moduleProto), "[object WebAssembly.Module]");
216     assert_equals(Object.getPrototypeOf(moduleProto), Object.prototype);
217 }, "'WebAssembly.Module.prototype' object");
218
219 test(() => {
220     const moduleProto = Module.prototype;
221     emptyModule = new Module(emptyModuleBinary);
222     exportingModule = new Module(exportingModuleBinary);
223     importingModule = new Module(importingModuleBinary);
224     assert_equals(typeof emptyModule, "object");
225     assert_equals(String(emptyModule), "[object WebAssembly.Module]");
226     assert_equals(Object.getPrototypeOf(emptyModule), moduleProto);
227 }, "'WebAssembly.Module' instance objects");
228
229 test(() => {
230     const moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports');
231     assert_equals(typeof moduleImportsDesc.value, "function");
232     assert_equals(moduleImportsDesc.writable, true);
233     assert_equals(moduleImportsDesc.enumerable, false);
234     assert_equals(moduleImportsDesc.configurable, true);
235 }, "'WebAssembly.Module.imports' data property");
236
237 test(() => {
238     const moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports');
239     const moduleImports = moduleImportsDesc.value;
240     assert_equals(moduleImports.length, 1);
241     assertThrows(() => moduleImports(), TypeError);
242     assertThrows(() => moduleImports(undefined), TypeError);
243     assertThrows(() => moduleImports({}), TypeError);
244     var arr = moduleImports(emptyModule);
245     assert_equals(arr instanceof Array, true);
246     assert_equals(arr.length, 0);
247     var arr = moduleImports(new Module(complexImportingModuleBinary));
248     assert_equals(arr instanceof Array, true);
249     assert_equals(arr.length, 4);
250     assert_equals(arr[0].kind, "function");
251     assert_equals(arr[0].module, "a");
252     assert_equals(arr[0].name, "b");
253     assert_equals(arr[1].kind, "memory");
254     assert_equals(arr[1].module, "c");
255     assert_equals(arr[1].name, "d");
256     assert_equals(arr[2].kind, "table");
257     assert_equals(arr[2].module, "e");
258     assert_equals(arr[2].name, "f");
259     assert_equals(arr[3].kind, "global");
260     assert_equals(arr[3].module, "g");
261     assert_equals(arr[3].name, "⚡");
262 }, "'WebAssembly.Module.imports' method");
263
264 test(() => {
265     const moduleExportsDesc = Object.getOwnPropertyDescriptor(Module, 'exports');
266     assert_equals(typeof moduleExportsDesc.value, "function");
267     assert_equals(moduleExportsDesc.writable, true);
268     assert_equals(moduleExportsDesc.enumerable, false);
269     assert_equals(moduleExportsDesc.configurable, true);
270 }, "'WebAssembly.Module.exports' data property");
271
272 test(() => {
273     const moduleExportsDesc = Object.getOwnPropertyDescriptor(Module, 'exports');
274     const moduleExports = moduleExportsDesc.value;
275     assert_equals(moduleExports.length, 1);
276     assertThrows(() => moduleExports(), TypeError);
277     assertThrows(() => moduleExports(undefined), TypeError);
278     assertThrows(() => moduleExports({}), TypeError);
279     var arr = moduleExports(emptyModule);
280     assert_equals(arr instanceof Array, true);
281     assert_equals(arr.length, 0);
282     var arr = moduleExports(new Module(complexExportingModuleBinary));
283     assert_equals(arr instanceof Array, true);
284     assert_equals(arr.length, 4);
285     assert_equals(arr[0].kind, "function");
286     assert_equals(arr[0].name, "a");
287     assert_equals(arr[1].kind, "memory");
288     assert_equals(arr[1].name, "b");
289     assert_equals(arr[2].kind, "table");
290     assert_equals(arr[2].name, "c");
291     assert_equals(arr[3].kind, "global");
292     assert_equals(arr[3].name, "⚡");
293 }, "'WebAssembly.Module.exports' method");
294
295 test(() => {
296     const customSectionsDesc = Object.getOwnPropertyDescriptor(Module, 'customSections');
297     assert_equals(typeof customSectionsDesc.value, "function");
298     assert_equals(customSectionsDesc.writable, true);
299     assert_equals(customSectionsDesc.enumerable, false);
300     assert_equals(customSectionsDesc.configurable, true);
301 }, "'WebAssembly.Module.customSections' data property");
302
303 test(() => {
304     const customSectionsDesc = Object.getOwnPropertyDescriptor(Module, 'customSections');
305     const moduleCustomSections = customSectionsDesc.value;
306     assert_equals(moduleCustomSections.length, 2);
307     assertThrows(() => moduleCustomSections(), TypeError);
308     assertThrows(() => moduleCustomSections(undefined), TypeError);
309     assertThrows(() => moduleCustomSections({}), TypeError);
310     var arr = moduleCustomSections(emptyModule);
311     assert_equals(arr instanceof Array, true);
312     assert_equals(arr.length, 0);
313 }, "'WebAssembly.Module.customSections' method");
314
315 test(() => {
316     const instanceDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Instance');
317     assert_equals(typeof instanceDesc.value, "function");
318     assert_equals(instanceDesc.writable, true);
319     assert_equals(instanceDesc.enumerable, false);
320     assert_equals(instanceDesc.configurable, true);
321     Instance = WebAssembly.Instance;
322 }, "'WebAssembly.Instance' data property");
323
324 test(() => {
325     const instanceDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Instance');
326     assert_equals(Instance, instanceDesc.value);
327     assert_equals(Instance.length, 1);
328     assert_equals(Instance.name, "Instance");
329     assertThrows(() => Instance(), TypeError);
330     assertThrows(() => new Instance(1), TypeError);
331     assertThrows(() => new Instance({}), TypeError);
332     assertThrows(() => new Instance(emptyModule, null), TypeError);
333     assertThrows(() => new Instance(importingModule, null), TypeError);
334     assertThrows(() => new Instance(importingModule, undefined), TypeError);
335     assertThrows(() => new Instance(importingModule, {}), TypeError);
336     assertThrows(() => new Instance(importingModule, {"":{g:()=>{}}}), LinkError);
337     assertThrows(() => new Instance(importingModule, {t:{f:()=>{}}}), TypeError);
338     assert_equals(new Instance(emptyModule) instanceof Instance, true);
339     assert_equals(new Instance(emptyModule, {}) instanceof Instance, true);
340 }, "'WebAssembly.Instance' constructor function");
341
342 test(() => {
343     const instanceProtoDesc = Object.getOwnPropertyDescriptor(Instance, 'prototype');
344     assert_equals(typeof instanceProtoDesc.value, "object");
345     assert_equals(instanceProtoDesc.writable, false);
346     assert_equals(instanceProtoDesc.enumerable, false);
347     assert_equals(instanceProtoDesc.configurable, false);
348 }, "'WebAssembly.Instance.prototype' data property");
349
350 test(() => {
351     instanceProto = Instance.prototype;
352     const instanceProtoDesc = Object.getOwnPropertyDescriptor(Instance, 'prototype');
353     assert_equals(instanceProto, instanceProtoDesc.value);
354     assert_equals(String(instanceProto), "[object WebAssembly.Instance]");
355     assert_equals(Object.getPrototypeOf(instanceProto), Object.prototype);
356 }, "'WebAssembly.Instance.prototype' object");
357
358 test(() => {
359     const instanceProto = Instance.prototype;
360     exportingInstance = new Instance(exportingModule);
361     assert_equals(typeof exportingInstance, "object");
362     assert_equals(String(exportingInstance), "[object WebAssembly.Instance]");
363     assert_equals(Object.getPrototypeOf(exportingInstance), instanceProto);
364 }, "'WebAssembly.Instance' instance objects");
365
366 test(() => {
367     const exportsDesc = Object.getOwnPropertyDescriptor(instanceProto, 'exports');
368     assert_equals(typeof exportsDesc.get, "function");
369     assert_equals(exportsDesc.set, undefined);
370     assert_equals(exportsDesc.enumerable, false);
371     assert_equals(exportsDesc.configurable, true);
372     const exportsGetter = exportsDesc.get;
373     assertThrows(() => exportsGetter.call(), TypeError);
374     assertThrows(() => exportsGetter.call({}), TypeError);
375     assert_equals(typeof exportsGetter.call(exportingInstance), "object");
376 }, "'WebAssembly.Instance.prototype.exports' accessor property");
377
378 test(() => {
379     exportsObj = exportingInstance.exports;
380     assert_equals(typeof exportsObj, "object");
381     assert_equals(Object.isExtensible(exportsObj), false);
382     assert_equals(Object.getPrototypeOf(exportsObj), null);
383     assert_equals(Object.keys(exportsObj).join(), "f");
384     exportsObj.g = 1;
385     assert_equals(Object.keys(exportsObj).join(), "f");
386     assertThrows(() => Object.setPrototypeOf(exportsObj, {}), TypeError);
387     assert_equals(Object.getPrototypeOf(exportsObj), null);
388     assertThrows(() => Object.defineProperty(exportsObj, 'g', {}), TypeError);
389     assert_equals(Object.keys(exportsObj).join(), "f");
390 }, "exports object");
391
392 test(() => {
393     const f = exportsObj.f;
394     assert_equals(f instanceof Function, true);
395     assert_equals(f.length, 0);
396     assert_equals('name' in f, true);
397     assert_equals(Function.prototype.call.call(f), 42);
398     assertThrows(() => new f(), TypeError);
399 }, "Exported WebAssembly functions");
400
401 test(() => {
402     const memoryDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Memory');
403     assert_equals(typeof memoryDesc.value, "function");
404     assert_equals(memoryDesc.writable, true);
405     assert_equals(memoryDesc.enumerable, false);
406     assert_equals(memoryDesc.configurable, true);
407     Memory = WebAssembly.Memory;
408 }, "'WebAssembly.Memory' data property");
409
410 test(() => {
411     const memoryDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Memory');
412     assert_equals(Memory, memoryDesc.value);
413     assert_equals(Memory.length, 1);
414     assert_equals(Memory.name, "Memory");
415     assertThrows(() => Memory(), TypeError);
416     assertThrows(() => new Memory(1), TypeError);
417     assertThrows(() => new Memory({initial:{valueOf() { throw new Error("here")}}}), Error);
418     assertThrows(() => new Memory({initial:-1}), RangeError);
419     assertThrows(() => new Memory({initial:Math.pow(2,32)}), RangeError);
420     assertThrows(() => new Memory({initial:1, maximum: Math.pow(2,32)/Math.pow(2,14) }), RangeError);
421     assertThrows(() => new Memory({initial:2, maximum:1 }), RangeError);
422     assertThrows(() => new Memory({maximum: -1 }), RangeError);
423     assert_equals(new Memory({initial:1}) instanceof Memory, true);
424     assert_equals(new Memory({initial:1.5}).buffer.byteLength, WasmPage);
425 }, "'WebAssembly.Memory' constructor function");
426
427 test(() => {
428     const memoryProtoDesc = Object.getOwnPropertyDescriptor(Memory, 'prototype');
429     assert_equals(typeof memoryProtoDesc.value, "object");
430     assert_equals(memoryProtoDesc.writable, false);
431     assert_equals(memoryProtoDesc.enumerable, false);
432     assert_equals(memoryProtoDesc.configurable, false);
433 }, "'WebAssembly.Memory.prototype' data property");
434
435 test(() => {
436     memoryProto = Memory.prototype;
437     const memoryProtoDesc = Object.getOwnPropertyDescriptor(Memory, 'prototype');
438     assert_equals(memoryProto, memoryProtoDesc.value);
439     assert_equals(String(memoryProto), "[object WebAssembly.Memory]");
440     assert_equals(Object.getPrototypeOf(memoryProto), Object.prototype);
441 }, "'WebAssembly.Memory.prototype' object");
442
443 test(() => {
444     mem1 = new Memory({initial:1});
445     assert_equals(typeof mem1, "object");
446     assert_equals(String(mem1), "[object WebAssembly.Memory]");
447     assert_equals(Object.getPrototypeOf(mem1), memoryProto);
448 }, "'WebAssembly.Memory' instance objects");
449
450 test(() => {
451     const bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer');
452     assert_equals(typeof bufferDesc.get, "function");
453     assert_equals(bufferDesc.set, undefined);
454     assert_equals(bufferDesc.enumerable, false);
455     assert_equals(bufferDesc.configurable, true);
456 }, "'WebAssembly.Memory.prototype.buffer' accessor property");
457
458 test(() => {
459     const bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer');
460     const bufferGetter = bufferDesc.get;
461     assertThrows(() => bufferGetter.call(), TypeError);
462     assertThrows(() => bufferGetter.call({}), TypeError);
463     assert_equals(bufferGetter.call(mem1) instanceof ArrayBuffer, true);
464     assert_equals(bufferGetter.call(mem1).byteLength, WasmPage);
465 }, "'WebAssembly.Memory.prototype.buffer' getter");
466
467 test(() => {
468     const memGrowDesc = Object.getOwnPropertyDescriptor(memoryProto, 'grow');
469     assert_equals(typeof memGrowDesc.value, "function");
470     assert_equals(memGrowDesc.enumerable, false);
471     assert_equals(memGrowDesc.configurable, true);
472 }, "'WebAssembly.Memory.prototype.grow' data property");
473
474 test(() => {
475     const memGrowDesc = Object.getOwnPropertyDescriptor(memoryProto, 'grow');
476     const memGrow = memGrowDesc.value;
477     assert_equals(memGrow.length, 1);
478     assertThrows(() => memGrow.call(), TypeError);
479     assertThrows(() => memGrow.call({}), TypeError);
480     assertThrows(() => memGrow.call(mem1, -1), RangeError);
481     assertThrows(() => memGrow.call(mem1, Math.pow(2,32)), RangeError);
482     var mem = new Memory({initial:1, maximum:2});
483     var buf = mem.buffer;
484     assert_equals(buf.byteLength, WasmPage);
485     assert_equals(mem.grow(0), 1);
486     assert_equals(buf !== mem.buffer, true);
487     assert_equals(buf.byteLength, 0);
488     buf = mem.buffer;
489     assert_equals(buf.byteLength, WasmPage);
490     assert_equals(mem.grow(1), 1);
491     assert_equals(buf !== mem.buffer, true);
492     assert_equals(buf.byteLength, 0);
493     buf = mem.buffer;
494     assert_equals(buf.byteLength, 2 * WasmPage);
495     assertThrows(() => mem.grow(1), Error);
496     assert_equals(buf, mem.buffer);
497 }, "'WebAssembly.Memory.prototype.grow' method");
498
499 test(() => {
500     const tableDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Table');
501     assert_equals(typeof tableDesc.value, "function");
502     assert_equals(tableDesc.writable, true);
503     assert_equals(tableDesc.enumerable, false);
504     assert_equals(tableDesc.configurable, true);
505     Table = WebAssembly.Table;
506 }, "'WebAssembly.Table' data property");
507
508 test(() => {
509     const tableDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Table');
510     assert_equals(Table, tableDesc.value);
511     assert_equals(Table.length, 1);
512     assert_equals(Table.name, "Table");
513     assertThrows(() => Table(), TypeError);
514     assertThrows(() => new Table(1), TypeError);
515     assertThrows(() => new Table({initial:1, element:1}), TypeError);
516     assertThrows(() => new Table({initial:1, element:"any"}), TypeError);
517     assertThrows(() => new Table({initial:1, element:{valueOf() { return "anyfunc" }}}), TypeError);
518     assertThrows(() => new Table({initial:{valueOf() { throw new Error("here")}}, element:"anyfunc"}), Error);
519     assertThrows(() => new Table({initial:-1, element:"anyfunc"}), RangeError);
520     assertThrows(() => new Table({initial:Math.pow(2,32), element:"anyfunc"}), RangeError);
521     assertThrows(() => new Table({initial:2, maximum:1, element:"anyfunc"}), RangeError);
522     assertThrows(() => new Table({initial:2, maximum:Math.pow(2,32), element:"anyfunc"}), RangeError);
523     assert_equals(new Table({initial:1, element:"anyfunc"}) instanceof Table, true);
524     assert_equals(new Table({initial:1.5, element:"anyfunc"}) instanceof Table, true);
525     assert_equals(new Table({initial:1, maximum:1.5, element:"anyfunc"}) instanceof Table, true);
526     assert_equals(new Table({initial:1, maximum:Math.pow(2,32)-1, element:"anyfunc"}) instanceof Table, true);
527 }, "'WebAssembly.Table' constructor function");
528
529 test(() => {
530     const tableProtoDesc = Object.getOwnPropertyDescriptor(Table, 'prototype');
531     assert_equals(typeof tableProtoDesc.value, "object");
532     assert_equals(tableProtoDesc.writable, false);
533     assert_equals(tableProtoDesc.enumerable, false);
534     assert_equals(tableProtoDesc.configurable, false);
535 }, "'WebAssembly.Table.prototype' data property");
536
537 test(() => {
538     const tableProtoDesc = Object.getOwnPropertyDescriptor(Table, 'prototype');
539     tableProto = Table.prototype;
540     assert_equals(tableProto, tableProtoDesc.value);
541     assert_equals(String(tableProto), "[object WebAssembly.Table]");
542     assert_equals(Object.getPrototypeOf(tableProto), Object.prototype);
543 }, "'WebAssembly.Table.prototype' object");
544
545 test(() => {
546     tbl1 = new Table({initial:2, element:"anyfunc"});
547     assert_equals(typeof tbl1, "object");
548     assert_equals(String(tbl1), "[object WebAssembly.Table]");
549     assert_equals(Object.getPrototypeOf(tbl1), tableProto);
550 }, "'WebAssembly.Table' instance objects");
551
552 test(() => {
553     const lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length');
554     assert_equals(typeof lengthDesc.get, "function");
555     assert_equals(lengthDesc.set, undefined);
556     assert_equals(lengthDesc.enumerable, false);
557     assert_equals(lengthDesc.configurable, true);
558 }, "'WebAssembly.Table.prototype.length' accessor data property");
559
560 test(() => {
561     const lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length');
562     const lengthGetter = lengthDesc.get;
563     assert_equals(lengthGetter.length, 0);
564     assertThrows(() => lengthGetter.call(), TypeError);
565     assertThrows(() => lengthGetter.call({}), TypeError);
566     assert_equals(typeof lengthGetter.call(tbl1), "number");
567     assert_equals(lengthGetter.call(tbl1), 2);
568 }, "'WebAssembly.Table.prototype.length' getter");
569
570 test(() => {
571     const getDesc = Object.getOwnPropertyDescriptor(tableProto, 'get');
572     assert_equals(typeof getDesc.value, "function");
573     assert_equals(getDesc.enumerable, false);
574     assert_equals(getDesc.configurable, true);
575 }, "'WebAssembly.Table.prototype.get' data property");
576
577 test(() => {
578     const getDesc = Object.getOwnPropertyDescriptor(tableProto, 'get');
579     const get = getDesc.value;
580     assert_equals(get.length, 1);
581     assertThrows(() => get.call(), TypeError);
582     assertThrows(() => get.call({}), TypeError);
583     assert_equals(get.call(tbl1, 0), null);
584     assert_equals(get.call(tbl1, 1), null);
585     assert_equals(get.call(tbl1, 1.5), null);
586     assertThrows(() => get.call(tbl1, 2), RangeError);
587     assertThrows(() => get.call(tbl1, 2.5), RangeError);
588     assertThrows(() => get.call(tbl1, -1), RangeError);
589     assertThrows(() => get.call(tbl1, Math.pow(2,33)), RangeError);
590     assertThrows(() => get.call(tbl1, {valueOf() { throw new Error("hi") }}), Error);
591 }, "'WebAssembly.Table.prototype.get' method");
592
593 test(() => {
594     const setDesc = Object.getOwnPropertyDescriptor(tableProto, 'set');
595     assert_equals(typeof setDesc.value, "function");
596     assert_equals(setDesc.enumerable, false);
597     assert_equals(setDesc.configurable, true);
598 }, "'WebAssembly.Table.prototype.set' data property");
599
600 test(() => {
601     const setDesc = Object.getOwnPropertyDescriptor(tableProto, 'set');
602     const set = setDesc.value;
603     assert_equals(set.length, 2);
604     assertThrows(() => set.call(), TypeError);
605     assertThrows(() => set.call({}), TypeError);
606     assertThrows(() => set.call(tbl1, 0), TypeError);
607     assertThrows(() => set.call(tbl1, 2, null), RangeError);
608     assertThrows(() => set.call(tbl1, -1, null), RangeError);
609     assertThrows(() => set.call(tbl1, Math.pow(2,33), null), RangeError);
610     assertThrows(() => set.call(tbl1, 0, undefined), TypeError);
611     assertThrows(() => set.call(tbl1, 0, {}), TypeError);
612     assertThrows(() => set.call(tbl1, 0, function() {}), TypeError);
613     assertThrows(() => set.call(tbl1, 0, Math.sin), TypeError);
614     assertThrows(() => set.call(tbl1, {valueOf() { throw Error("hai") }}, null), Error);
615     assert_equals(set.call(tbl1, 0, null), undefined);
616     assert_equals(set.call(tbl1, 1, null), undefined);
617 }, "'WebAssembly.Table.prototype.set' method");
618
619 test(() => {
620     const tblGrowDesc = Object.getOwnPropertyDescriptor(tableProto, 'grow');
621     assert_equals(typeof tblGrowDesc.value, "function");
622     assert_equals(tblGrowDesc.enumerable, false);
623     assert_equals(tblGrowDesc.configurable, true);
624 }, "'WebAssembly.Table.prototype.grow' data property");
625
626 test(() => {
627     const tblGrowDesc = Object.getOwnPropertyDescriptor(tableProto, 'grow');
628     const tblGrow = tblGrowDesc.value;
629     assert_equals(tblGrow.length, 1);
630     assertThrows(() => tblGrow.call(), TypeError);
631     assertThrows(() => tblGrow.call({}), TypeError);
632     assertThrows(() => tblGrow.call(tbl1, -1), RangeError);
633     assertThrows(() => tblGrow.call(tbl1, Math.pow(2,32)), RangeError);
634     var tbl = new Table({element:"anyfunc", initial:1, maximum:2});
635     assert_equals(tbl.length, 1);
636     assert_equals(tbl.grow(0), 1);
637     assert_equals(tbl.length, 1);
638     assert_equals(tbl.grow(1), 1);
639     assert_equals(tbl.length, 2);
640     assertThrows(() => tbl.grow(1), Error);
641 }, "'WebAssembly.Table.prototype.grow' method");
642
643 test(() => {
644     assertThrows(() => WebAssembly.validate(), TypeError);
645     assertThrows(() => WebAssembly.validate("hi"), TypeError);
646     assert_true(WebAssembly.validate(emptyModuleBinary));
647     assert_true(WebAssembly.validate(complexImportingModuleBinary));
648     assert_false(WebAssembly.validate(moduleBinaryImporting2Memories));
649     assert_false(WebAssembly.validate(moduleBinaryWithMemSectionAndMemImport));
650 }, "'WebAssembly.validate' method");
651
652 /* FIXME https://bugs.webkit.org/show_bug.cgi?id=173180
653 test(() => {
654     const compileDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'compile');
655     assert_equals(typeof compileDesc.value, "function");
656     assert_equals(compileDesc.writable, true);
657     assert_equals(compileDesc.enumerable, false);
658     assert_equals(compileDesc.configurable, true);
659 }, "'WebAssembly.compile' data property");
660
661 test(() => {
662     const compile = WebAssembly.compile;
663     const compileDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'compile');
664
665     assert_equals(compile, compileDesc.value);
666     assert_equals(compile.length, 1);
667     assert_equals(compile.name, "compile");
668 }, "'WebAssembly.compile' function"); */
669
670 var num_tests = 1;
671 function assertCompileError(args, err) {
672     promise_test(() => {
673         return WebAssembly.compile(...args)
674         .then(_ => {
675             throw null;
676         })
677         .catch(error => {
678             assert_equals(error instanceof err, true);
679             return Promise.resolve()
680         });
681     }, `assertCompileError ${num_tests++}`);
682 }
683
684 assertCompileError([], TypeError);
685 assertCompileError([undefined], TypeError);
686 assertCompileError([1], TypeError);
687 assertCompileError([{}], TypeError);
688 assertCompileError([new Uint8Array()], CompileError);
689 assertCompileError([new ArrayBuffer()], CompileError);
690 // FIXME: https://github.com/WebAssembly/spec/pull/503
691 //assertCompileError([new Uint8Array("hi!")], CompileError);
692 //assertCompileError([new ArrayBuffer("hi!")], CompileError);
693
694 num_tests = 1;
695 function assertCompileSuccess(bytes) {
696     promise_test(() => {
697         return WebAssembly.compile(bytes)
698         .then(module => {
699             assert_equals(module instanceof Module, true);
700         });
701     }, `assertCompileSuccess ${num_tests++}`);
702 }
703
704 assertCompileSuccess(emptyModuleBinary);
705 assertCompileSuccess(new Uint8Array(emptyModuleBinary));
706
707 /* FIXME https://bugs.webkit.org/show_bug.cgi?id=173180
708 test(() => {
709     const instantiateDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'instantiate');
710     assert_equals(typeof instantiateDesc.value, "function");
711     assert_equals(instantiateDesc.writable, true);
712     assert_equals(instantiateDesc.enumerable, false);
713     assert_equals(instantiateDesc.configurable, true);
714 }, "'WebAssembly.instantiate' data property");*/
715
716 test(() => {
717     const instantiateDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'instantiate');
718     const instantiate = WebAssembly.instantiate;
719 /* FIXME https://bugs.webkit.org/show_bug.cgi?id=173180
720     assert_equals(instantiate, instantiateDesc.value);
721     assert_equals(instantiate.length, 1);
722     assert_equals(instantiate.name, "instantiate");*/
723     function assertInstantiateError(args, err) {
724         promise_test(() => {
725             return instantiate(...args)
726                 .then(m => {
727                     throw null;
728                 })
729                 .catch(error => {
730                     assert_equals(error instanceof err, true);
731                 })
732         }, 'unexpected success in assertInstantiateError');
733     }
734     var scratch_memory = new WebAssembly.Memory({initial:1});
735     var scratch_table = new WebAssembly.Table({element:"anyfunc", initial:1, maximum:1});
736     assertInstantiateError([], TypeError);
737     assertInstantiateError([undefined], TypeError);
738     assertInstantiateError([1], TypeError);
739     assertInstantiateError([{}], TypeError);
740     assertInstantiateError([new Uint8Array()], CompileError);
741     assertInstantiateError([new ArrayBuffer()], CompileError);
742 // FIXME: https://github.com/WebAssembly/spec/pull/503
743 //    assertInstantiateError([new Uint8Array("hi!")], CompileError);
744 //    assertInstantiateError([new ArrayBuffer("hi!")], CompileError);
745     assertInstantiateError([importingModule], TypeError);
746     assertInstantiateError([importingModule, null], TypeError);
747     assertInstantiateError([importingModuleBinary, null], TypeError);
748     assertInstantiateError([emptyModule, null], TypeError);
749     assertInstantiateError([importingModuleBinary, null], TypeError);
750     assertInstantiateError([importingModuleBinary, undefined], TypeError);
751     assertInstantiateError([importingModuleBinary, {}], TypeError);
752     assertInstantiateError([importingModuleBinary, {"":{g:()=>{}}}], LinkError);
753     assertInstantiateError([importingModuleBinary, {t:{f:()=>{}}}], TypeError);
754     assertInstantiateError([complexImportingModuleBinary, null], TypeError);
755     assertInstantiateError([complexImportingModuleBinary, undefined], TypeError);
756     assertInstantiateError([complexImportingModuleBinary, {}], TypeError);
757     assertInstantiateError([complexImportingModuleBinary, {"c": {"d": scratch_memory}}], TypeError);
758
759     function assertInstantiateSuccess(module, imports) {
760         promise_test(()=> {
761             return instantiate(module, imports)
762                 .then(result => {
763                     if (module instanceof Module) {
764                         assert_equals(result instanceof Instance, true);
765                     } else {
766                         assert_equals(result.module instanceof Module, true);
767                         assert_equals(result.instance instanceof Instance, true);
768                         var desc = Object.getOwnPropertyDescriptor(result, 'module');
769                         assert_equals(desc.writable, true);
770                         assert_equals(desc.enumerable, true);
771                         assert_equals(desc.configurable, true);
772                         desc = Object.getOwnPropertyDescriptor(result, 'instance');
773                         assert_equals(desc.writable, true);
774                         assert_equals(desc.enumerable, true);
775                         assert_equals(desc.configurable, true);
776                     }
777                 })}, 'unexpected failure in assertInstantiateSuccess');
778     }
779     assertInstantiateSuccess(emptyModule);
780     assertInstantiateSuccess(emptyModuleBinary);
781     assertInstantiateSuccess(new Uint8Array(emptyModuleBinary));
782     assertInstantiateSuccess(importingModule, {"":{f:()=>{}}});
783     assertInstantiateSuccess(importingModuleBinary, {"":{f:()=>{}}});
784     assertInstantiateSuccess(new Uint8Array(importingModuleBinary), {"":{f:()=>{}}});
785     assertInstantiateSuccess(complexImportingModuleBinary, {
786         a:{b:()=>{}},
787         c:{d:scratch_memory},
788         e:{f:scratch_table},
789         g:{'⚡':1}});
790 }, "'WebAssembly.instantiate' function");
791
792 })();