xref: /llvm-project/llvm/test/MC/WebAssembly/eh-assembly.s (revision 991adff4628deeb3b4cb7d9df366e9f1e8b2860c)
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