1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
let counter;
function resetCounter() { counter = 0; }
function boxNextInt() { return {val: counter++}; }
function unboxInt(box) { return box.val; }
function boxNextThreeInts() {
return [boxNextInt(), boxNextInt(), boxNextInt()];
}
function unboxThreeInts(x, y, z) {
return [unboxInt(x), unboxInt(y), unboxInt(z)];
}
function testAddNextThreeIntsInner(addNextThreeInts) {
resetCounter();
for (let n = 0; n < 100000; n += 3) {
assertEq(addNextThreeInts(), n * 3 + 3);
}
}
function testAddNextThreeInts(text, imports) {
let i = new WebAssembly.Instance(
new WebAssembly.Module(wasmTextToBinary(text)), { imports });
testAddNextThreeIntsInner(() => i.exports.addNextThreeInts());
}
testAddNextThreeInts(`
(module
(func $boxNextInt (import "imports" "boxNextInt")
(result externref))
(func $unboxInt (import "imports" "unboxInt")
(param externref) (result i32))
(func $boxNextThreeInts (result externref externref externref)
call $boxNextInt
call $boxNextInt
call $boxNextInt)
(func $unboxThreeInts (param externref externref externref) (result i32 i32 i32)
local.get 0
call $unboxInt
local.get 1
call $unboxInt
local.get 2
call $unboxInt)
(func $addNextThreeInts (export "addNextThreeInts") (result i32)
call $boxNextThreeInts
call $unboxThreeInts
i32.add
i32.add))`,
{boxNextInt, unboxInt});
testAddNextThreeInts(`
(module
(func $boxNextThreeInts (import "imports" "boxNextThreeInts")
(result externref externref externref))
(func $unboxThreeInts (import "imports" "unboxThreeInts")
(param externref externref externref) (result i32 i32 i32))
(func $addNextThreeInts (export "addNextThreeInts") (result i32)
call $boxNextThreeInts
call $unboxThreeInts
i32.add
i32.add))`,
{boxNextThreeInts, unboxThreeInts});
{
let i = wasmEvalText(`
(module
(func $boxNextThreeInts (import "imports" "boxNextThreeInts")
(result externref externref externref))
(func (export "boxNextThreeInts") (result externref externref externref)
call $boxNextThreeInts))`,
{imports: {boxNextThreeInts}});
testAddNextThreeIntsInner(() => {
let [a, b, c] = i.exports.boxNextThreeInts();
return unboxInt(a) + unboxInt(b) + unboxInt(c);
});
}
|