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