| import * as assert from '../assert.js'; |
| import Builder from '../Builder.js'; |
| |
| (function EmptyModule() { |
| const builder = new Builder(); |
| const bin = builder.WebAssembly().get(); |
| const module = new WebAssembly.Module(bin); |
| const instance = new WebAssembly.Instance(module); |
| assert.instanceof(instance, WebAssembly.Instance); |
| })(); |
| |
| (function ExportedAnswerI32() { |
| const builder = (new Builder()) |
| .Type().End() |
| .Function().End() |
| .Export() |
| .Function("answer") |
| .End() |
| .Code() |
| .Function("answer", { params: [], ret: "i32" }) |
| .I32Const(42) |
| .Return() |
| .End() |
| .End(); |
| const bin = builder.WebAssembly().get(); |
| const module = new WebAssembly.Module(bin); |
| const instance = new WebAssembly.Instance(module); |
| const result = instance.exports.answer(); |
| assert.isA(result, "number"); |
| assert.eq(result, 42); |
| })(); |
| |
| (function ExportedNumber() { |
| for (let i = 0; i <= 129; ++i) { |
| const name = i.toString(); |
| const builder = (new Builder()) |
| .Type().End() |
| .Function().End() |
| .Export() |
| .Function(name) |
| .End() |
| .Code() |
| .Function(name, { params: [], ret: "i32" }) |
| .I32Const(i) |
| .Return() |
| .End() |
| .End(); |
| const bin = builder.WebAssembly().get(); |
| const module = new WebAssembly.Module(bin); |
| const instance = new WebAssembly.Instance(module); |
| const result = instance.exports[name](); |
| assert.isA(result, "number"); |
| assert.eq(result, i); |
| } |
| })(); |
| |
| const wasmModuleWhichImportJS = () => { |
| const builder = (new Builder()) |
| .Type().End() |
| .Import() |
| .Function("imp", "func", { params: ["i32"] }) |
| .End() |
| .Function().End() |
| .Export() |
| .Function("changeCounter") |
| .End() |
| .Code() |
| .Function("changeCounter", { params: ["i32"] }) |
| .I32Const(42) |
| .GetLocal(0) |
| .I32Add() |
| .Call(0) // Calls func(param[0] + 42). |
| .End() |
| .End(); |
| const bin = builder.WebAssembly().get(); |
| const module = new WebAssembly.Module(bin); |
| return module; |
| }; |
| |
| (function MonomorphicImport() { |
| let counter = 0; |
| const counterSetter = v => counter = v; |
| const module = wasmModuleWhichImportJS(); |
| const instance = new WebAssembly.Instance(module, { imp: { func: counterSetter } }); |
| for (let i = 0; i < 4096; ++i) { |
| // Invoke this a bunch of times to make sure the IC in the wasm -> JS stub works correctly. |
| instance.exports.changeCounter(i); |
| assert.eq(counter, i + 42); |
| } |
| })(); |
| |
| (function Polyphic2Import() { |
| let counterA = 0; |
| let counterB = undefined; |
| const counterASetter = v => counterA = v; |
| const counterBSetter = v => counterB = { valueB: v }; |
| const module = wasmModuleWhichImportJS(); |
| const instanceA = new WebAssembly.Instance(module, { imp: { func: counterASetter } }); |
| const instanceB = new WebAssembly.Instance(module, { imp: { func: counterBSetter } }); |
| for (let i = 0; i < 2048; ++i) { |
| instanceA.exports.changeCounter(i); |
| assert.isA(counterA, "number"); |
| assert.eq(counterA, i + 42); |
| instanceB.exports.changeCounter(i); |
| assert.isA(counterB, "object"); |
| assert.eq(counterB.valueB, i + 42); |
| } |
| })(); |
| |
| (function Polyphic3Import() { |
| let counterA = 0; |
| let counterB = undefined; |
| let counterC = undefined; |
| const counterASetter = v => counterA = v; |
| const counterBSetter = v => counterB = { valueB: v }; |
| const counterCSetter = v => counterC = { valueC: v }; |
| const module = wasmModuleWhichImportJS(); |
| const instanceA = new WebAssembly.Instance(module, { imp: { func: counterASetter } }); |
| const instanceB = new WebAssembly.Instance(module, { imp: { func: counterBSetter } }); |
| const instanceC = new WebAssembly.Instance(module, { imp: { func: counterCSetter } }); |
| for (let i = 0; i < 2048; ++i) { |
| instanceA.exports.changeCounter(i); |
| assert.isA(counterA, "number"); |
| assert.eq(counterA, i + 42); |
| instanceB.exports.changeCounter(i); |
| assert.isA(counterB, "object"); |
| assert.eq(counterB.valueB, i + 42); |
| instanceC.exports.changeCounter(i); |
| assert.isA(counterC, "object"); |
| assert.eq(counterC.valueC, i + 42); |
| } |
| })(); |
| |
| (function VirtualImport() { |
| const num = 10; // It's definitely going virtual at 10! |
| let counters = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; |
| const counterSetters = [ |
| v => counters[0] = v, |
| v => counters[1] = v + 1, |
| v => counters[2] = v + 2, |
| v => counters[3] = v + 3, |
| v => counters[4] = v + 4, |
| v => counters[5] = v + 5, |
| v => counters[6] = v + 6, |
| v => counters[7] = v + 7, |
| v => counters[8] = v + 8, |
| v => counters[9] = v + 9, |
| ]; |
| assert.eq(counters.length, num); |
| assert.eq(counterSetters.length, num); |
| const module = wasmModuleWhichImportJS(); |
| let instances = []; |
| for (let i = 0; i < num; ++i) |
| instances[i] = new WebAssembly.Instance(module, { imp: { func: counterSetters[i] } }); |
| for (let i = 0; i < 2048; ++i) { |
| for (let j = 0; j < num; ++j) { |
| instances[j].exports.changeCounter(i); |
| assert.isA(counters[j], "number"); |
| assert.eq(counters[j], i + 42 + j); |
| } |
| } |
| })(); |