bug-1744663-extended.js (8332B)
1 load(libdir + "eqArrayHelper.js"); 2 3 // These tests ensure that the gc related errors in bug 1744663 are resolved. 4 5 { 6 let catchlessTry = ` 7 try 8 (call $gc) 9 (throw $exn) 10 end`; 11 let rethrow0 = ` 12 try 13 (call $gc) 14 (throw $exn) 15 catch $exn 16 (rethrow 0) 17 end`; 18 let rethrow1 = ` 19 try 20 (throw $exn) 21 catch_all 22 try 23 (throw $exn) 24 catch $exn 25 (rethrow 1) 26 end 27 end`; 28 let delegate0 = ` 29 try 30 (call $gc) 31 (throw $exn) 32 delegate 0`; 33 let delegate1 = ` 34 (block 35 try 36 (call $gc) 37 (throw $exn) 38 delegate 1)`; 39 let delegate0InCatch = ` 40 try 41 (throw $exn) 42 catch_all 43 try 44 (call $gc) 45 (throw $exn) 46 delegate 0 47 end`; 48 let delegate1InCatch = ` 49 try 50 throw $exn 51 catch_all 52 try 53 (call $gc) 54 (throw $exn) 55 delegate 1 56 end`; 57 58 let rethrowingBodies = [catchlessTry, rethrow0, delegate0, delegate1, 59 rethrow1, delegate0InCatch, delegate1InCatch]; 60 61 function rethrowingIndirectly(rethrowingBody) { 62 let exports = wasmEvalText( 63 `(module 64 (tag $exn (export "exn")) 65 (import "js" "gc" (func $gc)) 66 (func $throwExn (export "throwExn") ${rethrowingBody}))`, 67 {js: {gc: () => { gc(); }}} 68 ).exports; 69 70 let mod = 71 `(module 72 (type $exnType (func)) 73 (type $indirectFunctype (func)) 74 (import "m" "exn" (tag $exn (type $exnType))) 75 (import "m" "throwExn" (func $throwExn (type $indirectFunctype))) 76 (table funcref (elem $throwExn)) 77 (func (export "testFunc") (result i32) 78 try (result i32) 79 (call_indirect (type $indirectFunctype) (i32.const 0)) 80 (i32.const 0) 81 catch $exn (i32.const 1) 82 end 83 ) 84 )`; 85 86 let testFunction = wasmEvalText(mod, { m : exports}).exports.testFunc; 87 assertEq(testFunction(), 1); 88 }; 89 90 for (let rethrowingBody of rethrowingBodies) { 91 //console.log("Calling rethrowingIndirectly with rethrowingBody = " + rethrowingBody); 92 rethrowingIndirectly(rethrowingBody); 93 } 94 } 95 96 // The full test case that caused the original failure. 97 98 { 99 gczeal(2,1); // Collect after every allocation. 100 101 let v128Type = " i32"; 102 let wrongV128 = "(i32.const 0)"; 103 let correctV128 = "(i32.const 1)"; 104 let checkV128Value = ""; 105 106 if (wasmSimdEnabled()) { 107 v128Type = " v128"; 108 wrongV128 = "(v128.const i32x4 11 22 33 44)"; 109 correctV128 = "(v128.const i32x4 55 66 77 88)"; 110 checkV128Value = `;; Check the V128 value 111 (v128.const i32x4 55 66 77 88) 112 (i32x4.eq) 113 (i32x4.all_true)`; 114 } 115 116 let exports = wasmEvalText( 117 `(module 118 (type $exnType (func (param i32 i64 f32 f64 externref ${v128Type}))) 119 (type $indirectFunctype (func (param i32 i64 f32 f64 externref ${v128Type}) 120 (result i32 i64 f32 f64 externref ${v128Type}))) 121 (tag $exn (export "exn") (type $exnType)) 122 (tag $emptyExn (export "emptyExn")) 123 (func $throwExn (export "throwExn") (param i32 i64 f32 f64 externref ${v128Type}) 124 (result i32 i64 f32 f64 externref ${v128Type}) 125 (local $ifPredicate i32) 126 (local.get 0) ;; i32 127 (local.get 1) ;; i64 128 (local.get 2) ;; f32 129 (local.get 3) ;; f64 130 (local.get 4) ;; ref 131 (local.get 5) ;; v128 or i32 132 try (param i32 i64 f32 f64 externref ${v128Type}) 133 (if (param i32 i64 f32 f64 externref ${v128Type}) 134 (local.get $ifPredicate) 135 (then (throw $exn)) 136 (else (throw $exn))) 137 catch $exn 138 try (param i32 i64 f32 f64 externref ${v128Type}) 139 (throw $exn) 140 catch_all (rethrow 1) 141 end 142 catch_all 143 end 144 unreachable) 145 (func $throwEmptyExn (export "throwEmptyExn") 146 (param i32 i64 f32 f64 externref ${v128Type}) 147 (result i32 i64 f32 f64 externref ${v128Type}) 148 (throw $emptyExn) 149 unreachable) 150 (func $returnArgs (export "returnArgs") 151 (param i32 i64 f32 f64 externref ${v128Type}) 152 (result i32 i64 f32 f64 externref ${v128Type}) 153 (local.get 0) ;; i32 154 (local.get 1) ;; i64 155 (local.get 2) ;; f32 156 (local.get 3) ;; f64 157 (local.get 4) ;; ref 158 (local.get 5)) 159 (table (export "tab") funcref (elem $throwExn ;; 0 160 $throwEmptyExn ;; 1 161 $returnArgs)) ;; 2 162 )`).exports; 163 164 var mod = 165 `(module 166 (type $exnType (func (param i32 i64 f32 f64 externref ${v128Type}))) 167 (type $indirectFunctype (func (param i32 i64 f32 f64 externref ${v128Type}) 168 (result i32 i64 f32 f64 externref ${v128Type}))) 169 (import "m" "exn" (tag $exn (type $exnType))) 170 (import "m" "emptyExn" (tag $emptyExn)) 171 (import "m" "throwExn" (func $throwExn (type $indirectFunctype))) 172 (import "m" "throwEmptyExn" 173 (func $throwEmptyExn (type $indirectFunctype))) 174 (import "m" "returnArgs" 175 (func $returnArgs (type $indirectFunctype))) 176 (import "m" "tab" (table 3 funcref)) 177 (func (export "testFunc") (param $correctRef externref) 178 (param $wrongRef externref) 179 ;; The last i32 result is the v128 check. 180 (result i32 i64 f32 f64 externref i32) 181 (local $ifPredicate i32) 182 try (result i32 i64 f32 f64 externref i32) 183 ;; Wrong values 184 (i32.const 5) 185 (i64.const 6) 186 (f32.const 0.1) 187 (f64.const 0.6437) 188 (local.get $wrongRef) 189 ${wrongV128} 190 ;; throwEmptyExn 191 (call_indirect (type $indirectFunctype) (i32.const 1)) 192 drop ;; Drop the last v128 value. 193 (i32.const 0) 194 catch_all 195 try (result i32 i64 f32 f64 externref ${v128Type}) 196 ;; Values to throw. 197 (i32.const 2) 198 (i64.const 3) 199 (f32.const 4) 200 (f64.const 13.37) 201 (local.get $correctRef) 202 ${correctV128} 203 (call_indirect (type $indirectFunctype) (i32.const 2)) ;; returnArgs 204 (call_indirect (type $indirectFunctype) (i32.const 0)) ;; throwExn 205 drop drop ;; Drop v128 and externref to do trivial and irrelevant ops. 206 (f64.const 5) 207 (f64.add) 208 (local.get $wrongRef) 209 ${wrongV128} 210 ;; throwEmptyExn 211 (call_indirect (type $indirectFunctype) (i32.const 1)) 212 unreachable 213 catch $emptyExn 214 ;; Wrong values 215 (i32.const 5) 216 (i64.const 6) 217 (f32.const 0.1) 218 (f64.const 0.6437) 219 (local.get $wrongRef) 220 ${wrongV128} 221 catch $exn 222 catch_all 223 ;; Wrong values 224 (i32.const 5) 225 (i64.const 6) 226 (f32.const 0.1) 227 (f64.const 0.6437) 228 (local.get $wrongRef) 229 ${wrongV128} 230 end 231 ${checkV128Value} 232 end))`; 233 234 let testAllValtypes = wasmEvalText(mod, { m : exports}).exports.testFunc; 235 assertEqArray(testAllValtypes("foo", "bar"), 236 [2, 3n, 4, 13.37, "foo", 1]); 237 }