memory.js (2818B)
1 // Ensure memory operations work after a throw coming from a function call. 2 // These are also testing that the InstanceReg/HeapReg are set correctly after 3 // catching an exception. There are some variations to the kind of calls here; 4 // we test for direct/indirect calls of local/imported functions, and the 5 // indirect calls may come from a local table or an imported table. 6 7 // Throw from a direct/indirect call of a local/imported function. 8 { 9 let exports = wasmEvalText( 10 `(module $m 11 (memory $mem (data "bar")) 12 (tag $exn (export "exn")) 13 (tag $dummyExn (export "dummyExn")) 14 (func $throwsExn (export "throwsExn") 15 (throw $exn)) 16 (func $anotherThrowsExn 17 (throw $exn)) 18 (func $throwsDummyExn (export "throwsDummyExn") 19 (throw $dummyExn)) 20 (table (export "tab") funcref (elem $anotherThrowsExn $throwsDummyExn)))` 21 ).exports; 22 23 function testMemoryAfterCall(callInstruction) { 24 assertEq( 25 wasmEvalText( 26 `(module 27 (import "m" "exn" (tag $exn)) 28 (tag $localExn (param i32)) 29 (type $t (func)) 30 (import "m" "tab" (table $importTable 2 funcref)) 31 (import "m" "throwsExn" (func $importFuncThrowsExn)) 32 (memory $mem (data "foo")) 33 (func $localFuncThrowsExn 34 (throw $exn)) 35 (table $localTable funcref 36 (elem $localFuncThrowsExn $importFuncThrowsExn)) 37 (func $anotherLocalFuncThrowsExn 38 (throw $exn)) 39 (func $throwsLocalExn 40 (throw $localExn 41 (i32.const 9))) 42 (func (export "testFunc") (result i32) 43 try (result i32) 44 ${callInstruction} 45 ;; All the rest should not be reachable. 46 (call $anotherLocalFuncThrowsExn) 47 (throw $exn) 48 (call $throwsLocalExn) 49 unreachable 50 catch $localExn 51 catch $exn 52 (i32.load8_u 53 (i32.const 0)) 54 catch $exn 55 ;; This should be ignored. 56 unreachable 57 end))`, 58 { m: exports } 59 ).exports.testFunc(), 60 'foo'.charCodeAt(0) 61 ); 62 }; 63 64 // Run test for various calls. 65 let callInstructions = 66 ["(call $anotherLocalFuncThrowsExn)", 67 "(call $importFuncThrowsExn)", 68 // Calls $localFuncThrowsExn. 69 "(call_indirect $localTable (type $t) (i32.const 0))", 70 // Calls $importFuncThrowsExn. 71 "(call_indirect $localTable (type $t) (i32.const 1))", 72 // Calls non exported function of the exports module $anotherThrowsExn. 73 "(call_indirect $importTable (type $t) (i32.const 0))"]; 74 75 for (let callInstruction of callInstructions) { 76 testMemoryAfterCall(callInstruction); 77 } 78 }