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
|
// Test importing callable object types other than plain functions.
// Wasm function equivalent to: function run(x) { return timesSeven(x) + 3; }
let bytes = wasmTextToBinary(`
(module
(func $timesSeven (import "imports" "timesSeven")
(param i32) (result i32))
(func $run (export "run") (param i32) (result i32)
local.get 0
call $timesSeven
i32.const 3
i32.add))`);
let mod = new WebAssembly.Module(bytes);
function test(timesSeven) {
let inst = new WebAssembly.Instance(mod, {imports: {timesSeven}});
return inst.exports.run(1) + inst.exports.run(3);
}
// Various supported callables.
let timesSeven = x => x * 7;
assertEq(test(timesSeven), 34);
assertEq(test(timesSeven.bind(null)), 34);
assertEq(test(timesSeven.bind(null, 4)), 62);
assertEq(test(new Proxy(timesSeven, {})), 34);
assertEq(test(wrapWithProto(timesSeven, null)), 34);
// Test proxy `apply` trap.
let traps = [];
assertEq(test(new Proxy(timesSeven, {apply(target, thisArg, args) {
traps.push(arguments);
return 5;
}})), 16);
assertEq(traps.length, 2);
for (let trap of traps) {
assertEq(trap[0], timesSeven); // target
assertEq(trap[1], undefined); // thisArg
assertEq(trap[2].length, 1); // args
}
function testThrowsLinkError(f) {
assertErrorMessage(() => test(f), WebAssembly.LinkError, /is not a Function/);
}
// Non-callables.
testThrowsLinkError({});
testThrowsLinkError(null);
testThrowsLinkError(this);
testThrowsLinkError(new Proxy({}, {}));
testThrowsLinkError(wrapWithProto({}, null));
// Cross-compartment wrappers are currently not supported.
let g = newGlobal({newCompartment: true});
g.evaluate(`function timesSeven(x) { return x * 7; }`);
testThrowsLinkError(g.timesSeven);
|