blob: fef249ddf5f69aea5b36d55d9ab11771aecfd084 (
plain)
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
|
// Ensure memory operations work after a throw coming from a function call.
// These are also testing that the InstanceReg/HeapReg are set correctly after
// catching an exception. There are some variations to the kind of calls here;
// we test for direct/indirect calls of local/imported functions, and the
// indirect calls may come from a local table or an imported table.
// Throw from a direct/indirect call of a local/imported function.
{
let exports = wasmEvalText(
`(module $m
(memory $mem (data "bar"))
(tag $exn (export "exn"))
(tag $dummyExn (export "dummyExn"))
(func $throwsExn (export "throwsExn")
(throw $exn))
(func $anotherThrowsExn
(throw $exn))
(func $throwsDummyExn (export "throwsDummyExn")
(throw $dummyExn))
(table (export "tab") funcref (elem $anotherThrowsExn $throwsDummyExn)))`
).exports;
function testMemoryAfterCall(callInstruction) {
assertEq(
wasmEvalText(
`(module
(import "m" "exn" (tag $exn))
(tag $localExn (param i32))
(type $t (func))
(import "m" "tab" (table $importTable 2 funcref))
(import "m" "throwsExn" (func $importFuncThrowsExn))
(memory $mem (data "foo"))
(func $localFuncThrowsExn
(throw $exn))
(table $localTable funcref
(elem $localFuncThrowsExn $importFuncThrowsExn))
(func $anotherLocalFuncThrowsExn
(throw $exn))
(func $throwsLocalExn
(throw $localExn
(i32.const 9)))
(func (export "testFunc") (result i32)
(try (result i32)
(do
${callInstruction}
;; All the rest should not be reachable.
(call $anotherLocalFuncThrowsExn)
(throw $exn)
(call $throwsLocalExn)
unreachable)
(catch $localExn)
(catch $exn
(i32.load8_u
(i32.const 0)))
(catch $exn
;; This should be ignored.
unreachable))))`,
{ m: exports }
).exports.testFunc(),
'foo'.charCodeAt(0)
);
};
// Run test for various calls.
let callInstructions =
["(call $anotherLocalFuncThrowsExn)",
"(call $importFuncThrowsExn)",
// Calls $localFuncThrowsExn.
"(call_indirect $localTable (type $t) (i32.const 0))",
// Calls $importFuncThrowsExn.
"(call_indirect $localTable (type $t) (i32.const 1))",
// Calls non exported function of the exports module $anotherThrowsExn.
"(call_indirect $importTable (type $t) (i32.const 0))"];
for (let callInstruction of callInstructions) {
testMemoryAfterCall(callInstruction);
}
}
|