1# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+exception-handling < %s | FileCheck %s 2# Check that it converts to .o without errors, but don't check any output: 3# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+exception-handling -o %t.o < %s 4 5 .tagtype __cpp_exception i32 6 .tagtype __c_longjmp i32 7 .functype foo () -> () 8 9eh_test: 10 .functype eh_test (exnref) -> () 11 12 # try_table with all four kinds of catch clauses 13 block exnref 14 block 15 block () -> (i32, exnref) 16 block i32 17 try_table (catch __cpp_exception 0) (catch_ref __c_longjmp 1) (catch_all 2) (catch_all_ref 3) 18 i32.const 0 19 throw __cpp_exception 20 end_try_table 21 return 22 end_block 23 drop 24 return 25 end_block 26 throw_ref 27 end_block 28 return 29 end_block 30 drop 31 32 # You can use the same kind of catch clause more than once 33 block 34 block exnref 35 block 36 try_table (catch_all 0) (catch_all_ref 1) (catch_all 2) 37 call foo 38 end_try_table 39 end_block 40 return 41 end_block 42 drop 43 end_block 44 45 # Two catch clauses targeting the same block 46 block 47 try_table (catch_all 0) (catch_all 0) 48 end_try_table 49 end_block 50 51 # try_table with a return type 52 block 53 try_table f32 (catch_all 0) 54 f32.const 0.0 55 end_try_table 56 drop 57 end_block 58 59 # try_table with a multivalue type return 60 block 61 try_table () -> (i32, f32) (catch_all 0) 62 i32.const 0 63 f32.const 0.0 64 end_try_table 65 drop 66 drop 67 end_block 68 69 # catch-less try_tables 70 try_table 71 call foo 72 end_try_table 73 74 try_table i32 75 i32.const 0 76 end_try_table 77 drop 78 79 try_table () -> (i32, f32) 80 i32.const 0 81 f32.const 0.0 82 end_try_table 83 drop 84 drop 85 86 # try_table targeting loops 87 i32.const 0 88 loop (i32) -> () 89 local.get 0 90 loop (exnref) -> () 91 try_table (catch __cpp_exception 1) (catch_all_ref 0) 92 end_try_table 93 drop 94 end_loop 95 drop 96 end_loop 97 end_function 98 99eh_legacy_test: 100 .functype eh_legacy_test () -> () 101 102 # try-catch with catch, catch_all, throw, and rethrow 103 try 104 i32.const 3 105 throw __cpp_exception 106 catch __cpp_exception 107 drop 108 rethrow 0 109 catch __c_longjmp 110 drop 111 catch_all 112 rethrow 0 113 end_try 114 115 # Nested try-catch with a rethrow 116 try 117 call foo 118 catch_all 119 try 120 catch_all 121 rethrow 1 122 end_try 123 end_try 124 125 # try-catch with a single return value 126 try i32 127 i32.const 0 128 catch __cpp_exception 129 end_try 130 drop 131 132 # try-catch with a mulvivalue return 133 try () -> (i32, f32) 134 i32.const 0 135 f32.const 0.0 136 catch __cpp_exception 137 f32.const 1.0 138 end_try 139 drop 140 drop 141 142 # Catch-less try 143 try 144 call foo 145 end_try 146 end_function 147 148 149# CHECK-LABEL: eh_test: 150# CHECK: block exnref 151# CHECK-NEXT: block 152# CHECK-NEXT: block () -> (i32, exnref) 153# CHECK-NEXT: block i32 154# CHECK-NEXT: try_table (catch __cpp_exception 0) (catch_ref __c_longjmp 1) (catch_all 2) (catch_all_ref 3) 155# CHECK: i32.const 0 156# CHECK-NEXT: throw __cpp_exception 157# CHECK-NEXT: end_try_table 158# CHECK-NEXT: return 159# CHECK-NEXT: end_block 160# CHECK-NEXT: drop 161# CHECK-NEXT: return 162# CHECK-NEXT: end_block 163# CHECK-NEXT: throw_ref 164# CHECK-NEXT: end_block 165# CHECK-NEXT: return 166# CHECK-NEXT: end_block 167# CHECK-NEXT: drop 168 169# CHECK: block 170# CHECK-NEXT: block exnref 171# CHECK-NEXT: block 172# CHECK-NEXT: try_table (catch_all 0) (catch_all_ref 1) (catch_all 2) 173# CHECK: call foo 174# CHECK-NEXT: end_try_table 175# CHECK-NEXT: end_block 176# CHECK-NEXT: return 177# CHECK-NEXT: end_block 178# CHECK-NEXT: drop 179# CHECK-NEXT: end_block 180 181# CHECK: block 182# CHECK-NEXT: try_table (catch_all 0) (catch_all 0) 183# CHECK: end_try_table 184# CHECK-NEXT: end_block 185 186# CHECK: block 187# CHECK-NEXT: try_table f32 (catch_all 0) 188# CHECK: f32.const 0x0p0 189# CHECK-NEXT: end_try_table 190# CHECK-NEXT: drop 191# CHECK-NEXT: end_block 192 193# CHECK: block 194# CHECK-NEXT: try_table () -> (i32, f32) (catch_all 0) 195# CHECK: i32.const 0 196# CHECK-NEXT: f32.const 0x0p0 197# CHECK-NEXT: end_try_table 198# CHECK-NEXT: drop 199# CHECK-NEXT: drop 200# CHECK-NEXT: end_block 201 202# CHECK: try_table 203# CHECK-NEXT: call foo 204# CHECK-NEXT: end_try_table 205 206# CHECK: try_table i32 207# CHECK-NEXT: i32.const 0 208# CHECK-NEXT: end_try_table 209# CHECK-NEXT: drop 210 211# CHECK: try_table () -> (i32, f32) 212# CHECK-NEXT: i32.const 0 213# CHECK-NEXT: f32.const 0x0p0 214# CHECK-NEXT: end_try_table 215# CHECK-NEXT: drop 216# CHECK-NEXT: drop 217 218# CHECK: i32.const 0 219# CHECK-NEXT: loop (i32) -> () 220# CHECK-NEXT: local.get 0 221# CHECK-NEXT: loop (exnref) -> () 222# CHECK-NEXT: try_table (catch __cpp_exception 1) (catch_all_ref 0) 223# CHECK: end_try_table 224# CHECK-NEXT: drop 225# CHECK-NEXT: end_loop 226# CHECK-NEXT: drop 227# CHECK-NEXT: end_loop 228 229# CHECK: eh_legacy_test: 230# CHECK: try 231# CHECK-NEXT: i32.const 3 232# CHECK-NEXT: throw __cpp_exception 233# CHECK-NEXT: catch __cpp_exception 234# CHECK-NEXT: drop 235# CHECK-NEXT: rethrow 0 236# CHECK-NEXT: catch __c_longjmp 237# CHECK-NEXT: drop 238# CHECK-NEXT: catch_all 239# CHECK-NEXT: rethrow 0 240# CHECK-NEXT: end_try 241 242# CHECK: try 243# CHECK-NEXT: call foo 244# CHECK-NEXT: catch_all 245# CHECK-NEXT: try 246# CHECK-NEXT: catch_all 247# CHECK-NEXT: rethrow 1 248# CHECK-NEXT: end_try 249# CHECK-NEXT: end_try 250 251# CHECK: try i32 252# CHECK-NEXT: i32.const 0 253# CHECK-NEXT: catch __cpp_exception 254# CHECK-NEXT: end_try 255# CHECK-NEXT: drop 256 257# CHECK: try () -> (i32, f32) 258# CHECK-NEXT: i32.const 0 259# CHECK-NEXT: f32.const 0x0p0 260# CHECK-NEXT: catch __cpp_exception 261# CHECK-NEXT: f32.const 0x1p0 262# CHECK-NEXT: end_try 263# CHECK-NEXT: drop 264# CHECK-NEXT: drop 265 266# CHECK: try 267# CHECK-NEXT: call foo 268# CHECK-NEXT: end_try 269