• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1const instanceTestFactory = [
2  [
3    "Empty module without imports argument",
4    function() {
5      return {
6        buffer: emptyModuleBinary,
7        args: [],
8        exports: {},
9        verify: () => {},
10      };
11    }
12  ],
13
14  [
15    "Empty module with undefined imports argument",
16    function() {
17      return {
18        buffer: emptyModuleBinary,
19        args: [undefined],
20        exports: {},
21        verify: () => {},
22      };
23    }
24  ],
25
26  [
27    "Empty module with empty imports argument",
28    function() {
29      return {
30        buffer: emptyModuleBinary,
31        args: [{}],
32        exports: {},
33        verify: () => {},
34      };
35    }
36  ],
37
38  [
39    "getter order for imports object",
40    function() {
41      const builder = new WasmModuleBuilder();
42      builder.addImportedGlobal("module", "global1", kWasmI32);
43      builder.addImportedGlobal("module2", "global3", kWasmI32);
44      builder.addImportedMemory("module", "memory", 0, 128);
45      builder.addImportedGlobal("module", "global2", kWasmI32);
46      const buffer = builder.toBuffer();
47      const order = [];
48
49      const imports = {
50        get module() {
51          order.push("module getter");
52          return {
53            get global1() {
54              order.push("global1 getter");
55              return 0;
56            },
57            get global2() {
58              order.push("global2 getter");
59              return 0;
60            },
61            get memory() {
62              order.push("memory getter");
63              return new WebAssembly.Memory({ "initial": 64, maximum: 128 });
64            },
65          }
66        },
67        get module2() {
68          order.push("module2 getter");
69          return {
70            get global3() {
71              order.push("global3 getter");
72              return 0;
73            },
74          }
75        },
76      };
77
78      const expected = [
79        "module getter",
80        "global1 getter",
81        "module2 getter",
82        "global3 getter",
83        "module getter",
84        "memory getter",
85        "module getter",
86        "global2 getter",
87      ];
88      return {
89        buffer,
90        args: [imports],
91        exports: {},
92        verify: () => assert_array_equals(order, expected),
93      };
94    }
95  ],
96
97  [
98    "imports",
99    function() {
100      const builder = new WasmModuleBuilder();
101
102      builder.addImport("module", "fn", kSig_v_v);
103      builder.addImportedGlobal("module", "global", kWasmI32);
104      builder.addImportedMemory("module", "memory", 0, 128);
105      builder.addImportedTable("module", "table", 0, 128);
106
107      const buffer = builder.toBuffer();
108      const imports = {
109        "module": {
110          "fn": function() {},
111          "global": 0,
112          "memory": new WebAssembly.Memory({ "initial": 64, maximum: 128 }),
113          "table": new WebAssembly.Table({ "element": "anyfunc", "initial": 64, maximum: 128 }),
114        },
115        get "module2"() {
116          assert_unreached("Should not get modules that are not imported");
117        },
118      };
119
120      return {
121        buffer,
122        args: [imports],
123        exports: {},
124        verify: () => {},
125      };
126    }
127  ],
128
129  [
130    "imports with empty module names",
131    function() {
132      const builder = new WasmModuleBuilder();
133
134      builder.addImport("", "fn", kSig_v_v);
135      builder.addImportedGlobal("", "global", kWasmI32);
136      builder.addImportedMemory("", "memory", 0, 128);
137      builder.addImportedTable("", "table", 0, 128);
138
139      const buffer = builder.toBuffer();
140      const imports = {
141        "": {
142          "fn": function() {},
143          "global": 0,
144          "memory": new WebAssembly.Memory({ "initial": 64, maximum: 128 }),
145          "table": new WebAssembly.Table({ "element": "anyfunc", "initial": 64, maximum: 128 }),
146        },
147      };
148
149      return {
150        buffer,
151        args: [imports],
152        exports: {},
153        verify: () => {},
154      };
155    }
156  ],
157
158  [
159    "imports with empty names",
160    function() {
161      const builder = new WasmModuleBuilder();
162
163      builder.addImport("a", "", kSig_v_v);
164      builder.addImportedGlobal("b", "", kWasmI32);
165      builder.addImportedMemory("c", "", 0, 128);
166      builder.addImportedTable("d", "", 0, 128);
167
168      const buffer = builder.toBuffer();
169      const imports = {
170        "a": { "": function() {} },
171        "b": { "": 0 },
172        "c": { "": new WebAssembly.Memory({ "initial": 64, maximum: 128 }) },
173        "d": { "": new WebAssembly.Table({ "element": "anyfunc", "initial": 64, maximum: 128 }) },
174      };
175
176      return {
177        buffer,
178        args: [imports],
179        exports: {},
180        verify: () => {},
181      };
182    }
183  ],
184
185  [
186    "exports with empty name: function",
187    function() {
188      const builder = new WasmModuleBuilder();
189
190      builder
191        .addFunction("", kSig_v_d)
192        .addBody([])
193        .exportFunc();
194
195      const buffer = builder.toBuffer();
196
197      const exports = {
198        "": { "kind": "function", "name": "0", "length": 1 },
199      };
200
201      return {
202        buffer,
203        args: [],
204        exports,
205        verify: () => {},
206      };
207    }
208  ],
209
210  [
211    "exports with empty name: table",
212    function() {
213      const builder = new WasmModuleBuilder();
214
215      builder.setTableBounds(1);
216      builder.addExportOfKind("", kExternalTable, 0);
217
218      const buffer = builder.toBuffer();
219
220      const exports = {
221        "": { "kind": "table", "length": 1 },
222      };
223
224      return {
225        buffer,
226        args: [],
227        exports,
228        verify: () => {},
229      };
230    }
231  ],
232
233  [
234    "exports with empty name: global",
235    function() {
236      const builder = new WasmModuleBuilder();
237
238      builder.addGlobal(kWasmI32, true)
239        .exportAs("")
240        .init = 7;
241
242      const buffer = builder.toBuffer();
243
244      const exports = {
245        "": { "kind": "global", "value": 7 },
246      };
247
248      return {
249        buffer,
250        args: [],
251        exports,
252        verify: () => {},
253      };
254    }
255  ],
256
257  [
258    "No imports",
259    function() {
260      const builder = new WasmModuleBuilder();
261
262      builder
263        .addFunction("fn", kSig_v_d)
264        .addBody([])
265        .exportFunc();
266      builder
267        .addFunction("fn2", kSig_v_v)
268        .addBody([])
269        .exportFunc();
270
271      builder.setTableBounds(1);
272      builder.addExportOfKind("table", kExternalTable, 0);
273
274      builder.addGlobal(kWasmI32, true)
275        .exportAs("global")
276        .init = 7;
277      builder.addGlobal(kWasmF64, true)
278        .exportAs("global2")
279        .init = 1.2;
280
281      builder.addMemory(4, 8, true);
282
283      const buffer = builder.toBuffer();
284
285      const exports = {
286        "fn": { "kind": "function", "name": "0", "length": 1 },
287        "fn2": { "kind": "function", "name": "1", "length": 0 },
288        "table": { "kind": "table", "length": 1 },
289        "global": { "kind": "global", "value": 7 },
290        "global2": { "kind": "global", "value": 1.2 },
291        "memory": { "kind": "memory", "size": 4 },
292      };
293
294      return {
295        buffer,
296        args: [],
297        exports,
298        verify: () => {},
299      };
300    }
301  ],
302
303  [
304    "exports and imports",
305    function() {
306      const value = 102;
307
308      const builder = new WasmModuleBuilder();
309
310      const index = builder.addImportedGlobal("module", "global", kWasmI32);
311      builder
312        .addFunction("fn", kSig_i_v)
313        .addBody([
314            kExprGlobalGet,
315            index,
316            kExprReturn,
317        ])
318        .exportFunc();
319
320      const buffer = builder.toBuffer();
321
322      const imports = {
323        "module": {
324          "global": value,
325        },
326      };
327
328      const exports = {
329        "fn": { "kind": "function", "name": "0", "length": 0 },
330      };
331
332      return {
333        buffer,
334        args: [imports],
335        exports,
336        verify: instance => assert_equals(instance.exports.fn(), value)
337      };
338    }
339  ],
340
341  [
342    "i64 exports and imports",
343    function() {
344      const value = 102n;
345
346      const builder = new WasmModuleBuilder();
347
348      const index = builder.addImportedGlobal("module", "global", kWasmI64);
349      builder
350        .addFunction("fn", kSig_l_v)
351        .addBody([
352            kExprGlobalGet,
353            index,
354            kExprReturn,
355        ])
356        .exportFunc();
357
358      const index2 = builder.addImportedGlobal("module", "global2", kWasmI64);
359      builder.addExportOfKind("global", kExternalGlobal, index2);
360
361      const buffer = builder.toBuffer();
362
363      const imports = {
364        "module": {
365          "global": value,
366          "global2": 2n ** 63n,
367        },
368      };
369
370      const exports = {
371        "fn": { "kind": "function", "name": "0", "length": 0 },
372        "global": { "kind": "global", "value": -(2n ** 63n) },
373      };
374
375      return {
376        buffer,
377        args: [imports],
378        exports,
379        verify: instance => assert_equals(instance.exports.fn(), value)
380      };
381    }
382  ],
383
384  [
385    "import with i32-returning function",
386    function() {
387      const builder = new WasmModuleBuilder();
388
389      const fnIndex = builder.addImport("module", "fn", kSig_i_v);
390      const fn2 = builder
391        .addFunction("fn2", kSig_v_v)
392        .addBody([
393            kExprCallFunction,
394            fnIndex,
395            kExprReturn,
396        ])
397        .exportFunc();
398
399      const buffer = builder.toBuffer();
400
401      let called = false;
402      const imports = {
403        "module": {
404          "fn": function() {
405            called = true;
406            return 6n;
407          },
408        },
409      };
410
411      return {
412        buffer,
413        args: [imports],
414        exports: {
415          "fn2": { "kind": "function", "name": String(fn2.index), "length": 0 },
416        },
417        verify: instance => {
418          assert_throws_js(TypeError, () => instance.exports.fn2());
419          assert_true(called, "Should have called into JS");
420        }
421      };
422    }
423  ],
424
425  [
426    "import with function that takes and returns i32",
427    function() {
428      const builder = new WasmModuleBuilder();
429
430      const fnIndex = builder.addImport("module", "fn", kSig_i_i);
431      const fn2 = builder
432        .addFunction("fn2", kSig_i_v)
433        .addBody([
434            kExprI32Const, 0x66,
435            kExprCallFunction,
436            fnIndex,
437            kExprReturn,
438        ])
439        .exportFunc();
440
441      const buffer = builder.toBuffer();
442
443      let called = false;
444      const imports = {
445        "module": {
446          "fn": function(n) {
447            called = true;
448            assert_equals(n, -26);
449            return { valueOf() { return 6; } };
450          },
451        },
452      };
453
454      return {
455        buffer,
456        args: [imports],
457        exports: {
458          "fn2": { "kind": "function", "name": String(fn2.index), "length": 0 },
459        },
460        verify: instance => {
461          assert_equals(instance.exports.fn2(), 6);
462          assert_true(called, "Should have called into JS");
463        }
464      };
465    }
466  ],
467
468  [
469    "import with i64-returning function",
470    function() {
471      const builder = new WasmModuleBuilder();
472
473      const fnIndex = builder.addImport("module", "fn", kSig_l_v);
474      const fn2 = builder
475        .addFunction("fn2", kSig_v_v)
476        .addBody([
477            kExprCallFunction,
478            fnIndex,
479            kExprReturn,
480        ])
481        .exportFunc();
482
483      const buffer = builder.toBuffer();
484
485      let called = false;
486      const imports = {
487        "module": {
488          "fn": function() {
489            called = true;
490            return 6;
491          },
492        },
493      };
494
495      return {
496        buffer,
497        args: [imports],
498        exports: {
499          "fn2": { "kind": "function", "name": String(fn2.index), "length": 0 },
500        },
501        verify: instance => {
502          assert_throws_js(TypeError, () => instance.exports.fn2());
503          assert_true(called, "Should have called into JS");
504        }
505      };
506    }
507  ],
508
509  [
510    "import with function that takes and returns i64",
511    function() {
512      const builder = new WasmModuleBuilder();
513
514      const fnIndex = builder.addImport("module", "fn", kSig_l_l);
515      const fn2 = builder
516        .addFunction("fn2", kSig_l_v)
517        .addBody([
518            kExprI64Const, 0x66,
519            kExprCallFunction,
520            fnIndex,
521            kExprReturn,
522        ])
523        .exportFunc();
524
525      const buffer = builder.toBuffer();
526
527      let called = false;
528      const imports = {
529        "module": {
530          "fn": function(n) {
531            called = true;
532            assert_equals(n, -26n);
533            return { valueOf() { return 6n; } };
534          },
535        },
536      };
537
538      return {
539        buffer,
540        args: [imports],
541        exports: {
542          "fn2": { "kind": "function", "name": String(fn2.index), "length": 0 },
543        },
544        verify: instance => {
545          assert_equals(instance.exports.fn2(), 6n);
546          assert_true(called, "Should have called into JS");
547        }
548      };
549    }
550  ],
551
552  [
553    "import with i32-taking function",
554    function() {
555      const builder = new WasmModuleBuilder();
556
557      const fn = builder
558        .addFunction("fn", kSig_v_i)
559        .addBody([
560            kExprReturn,
561        ])
562        .exportFunc();
563
564      const buffer = builder.toBuffer();
565
566      return {
567        buffer,
568        args: [],
569        exports: {
570          "fn": { "kind": "function", "name": String(fn.index), "length": 1 },
571        },
572        verify: instance => assert_throws_js(TypeError, () => instance.exports.fn(6n))
573      };
574    }
575  ],
576
577  [
578    "import with i64-taking function",
579    function() {
580      const builder = new WasmModuleBuilder();
581
582      const fn = builder
583        .addFunction("fn", kSig_v_l)
584        .addBody([
585            kExprReturn,
586        ])
587        .exportFunc();
588
589      const buffer = builder.toBuffer();
590
591      return {
592        buffer,
593        args: [],
594        exports: {
595          "fn": { "kind": "function", "name": String(fn.index), "length": 1 },
596        },
597        verify: instance => assert_throws_js(TypeError, () => instance.exports.fn(6))
598      };
599    }
600  ],
601
602  [
603    "export i64-returning function",
604    function() {
605      const builder = new WasmModuleBuilder();
606
607      const fn = builder
608        .addFunction("fn", kSig_l_v)
609        .addBody([
610            kExprI64Const, 0x66,
611            kExprReturn,
612        ])
613        .exportFunc();
614
615      const buffer = builder.toBuffer();
616
617      return {
618        buffer,
619        args: [],
620        exports: {
621          "fn": { "kind": "function", "name": String(fn.index), "length": 0 },
622        },
623        verify: instance => assert_equals(instance.exports.fn(), -26n)
624      };
625    }
626  ],
627
628  [
629    "i32 mutable WebAssembly.Global import",
630    function() {
631      const initial = 102;
632      const value = new WebAssembly.Global({ "value": "i32", "mutable": true }, initial);
633
634      const builder = new WasmModuleBuilder();
635
636      const index = builder.addImportedGlobal("module", "global", kWasmI32, true);
637      const fn = builder
638        .addFunction("fn", kSig_i_v)
639        .addBody([
640            kExprGlobalGet,
641            index,
642            kExprReturn,
643        ])
644        .exportFunc();
645
646      const buffer = builder.toBuffer();
647
648      const imports = {
649        "module": {
650          "global": value,
651        },
652      };
653
654      const exports = {
655        "fn": { "kind": "function", "name": String(fn.index), "length": 0 },
656      };
657
658      return {
659        buffer,
660        args: [imports],
661        exports,
662        verify: instance => {
663          assert_equals(instance.exports.fn(), initial);
664          const after = 201;
665          value.value = after;
666          assert_equals(instance.exports.fn(), after);
667        }
668      };
669    }
670  ],
671
672  [
673    "i64 mutable WebAssembly.Global import",
674    function() {
675      const initial = 102n;
676      const value = new WebAssembly.Global({ "value": "i64", "mutable": true }, initial);
677
678      const builder = new WasmModuleBuilder();
679
680      const index = builder.addImportedGlobal("module", "global", kWasmI64, true);
681      const fn = builder
682        .addFunction("fn", kSig_l_v)
683        .addBody([
684            kExprGlobalGet,
685            index,
686            kExprReturn,
687        ])
688        .exportFunc();
689
690      const buffer = builder.toBuffer();
691
692      const imports = {
693        "module": {
694          "global": value,
695        },
696      };
697
698      const exports = {
699        "fn": { "kind": "function", "name": String(fn.index), "length": 0 },
700      };
701
702      return {
703        buffer,
704        args: [imports],
705        exports,
706        verify: instance => {
707          assert_equals(instance.exports.fn(), initial);
708          const after = 201n;
709          value.value = after;
710          assert_equals(instance.exports.fn(), after);
711        }
712      };
713    }
714  ],
715
716  [
717    "Multiple i64 arguments",
718    function() {
719      const builder = new WasmModuleBuilder();
720
721      const fn = builder
722          .addFunction("fn", kSig_l_ll)
723          .addBody([
724              kExprLocalGet, 1,
725          ])
726          .exportFunc();
727
728      const buffer = builder.toBuffer();
729
730      const exports = {
731        "fn": { "kind": "function", "name": String(fn.index), "length": 2 },
732      };
733
734      return {
735        buffer,
736        args: [],
737        exports,
738        verify: instance => {
739          const fn = instance.exports.fn;
740          assert_equals(fn(1n, 0n), 0n);
741          assert_equals(fn(1n, 123n), 123n);
742          assert_equals(fn(1n, -123n), -123n);
743          assert_equals(fn(1n, "5"), 5n);
744          assert_throws_js(TypeError, () => fn(1n, 5));
745        }
746      };
747    }
748  ],
749
750  [
751    "stray argument",
752    function() {
753      return {
754        buffer: emptyModuleBinary,
755        args: [{}, {}],
756        exports: {},
757        verify: () => {}
758      };
759    }
760  ],
761];
762