| # Verify stacky EH binary can be parsed correctly. |
| # |
| # stacky-eh.test.wasm contains below: |
| # try |
| # nop |
| # catch 0 # tag type i32 |
| # i32.const 3 |
| # local.set 1 |
| # local.set 2 |
| # |
| # (This binary was generated by |
| # 'wasm-opt --optimize-level=3 --generate-stack-ir -optimize-stack-ir') |
| # |
| # This code is 'stacky' in Binaryen parlance. In the binary reader, Binaryen has |
| # a special routine of creating a block and a local.get/local.set to read stacky |
| # code into Binaryen AST. So if we don't do any post-fixup, the 'catch' block |
| # becomes: |
| # (catch $e-i32 |
| # (local.set 2 |
| # (block (result i32) |
| # (local.set $new |
| # (pop i32) |
| # ) |
| # (local.set 1 |
| # (i32.const 3) |
| # ) |
| # (local.get $new) |
| # ) |
| # ) |
| # ) |
| # Here the 'block' and `local $new' are newly created to read the stacky code. |
| # But now the 'pop' ends up nested within the 'block', which is invalid. This |
| # test tests if this invalid code is correctly fixed up in the binary reader. |
| # The fixup will hoist the 'pop' and create another local to store it right |
| # after 'catch'. |
| |
| RUN: wasm-opt -all %s.wasm --print | filecheck %s |
| |
| # CHECK: (func $0 |
| # CHECK-NEXT: (local $0 i32) |
| # CHECK-NEXT: (local $1 i32) |
| # CHECK-NEXT: (local $2 i32) |
| # CHECK-NEXT: (local $3 i32) |
| # CHECK-NEXT: (local $4 i32) |
| # CHECK-NEXT: (try $label$3 |
| # CHECK-NEXT: (do |
| # CHECK-NEXT: (nop) |
| # CHECK-NEXT: ) |
| # CHECK-NEXT: (catch $tag$0 |
| # CHECK-NEXT: (local.set $4 |
| # CHECK-NEXT: (pop i32) |
| # CHECK-NEXT: ) |
| # CHECK-NEXT: (local.set $2 |
| # CHECK-NEXT: (block (result i32) |
| # CHECK-NEXT: (local.set $3 |
| # CHECK-NEXT: (local.get $4) |
| # CHECK-NEXT: ) |
| # CHECK-NEXT: (local.set $1 |
| # CHECK-NEXT: (i32.const 3) |
| # CHECK-NEXT: ) |
| # CHECK-NEXT: (local.get $3) |
| # CHECK-NEXT: ) |
| # CHECK-NEXT: ) |
| # CHECK-NEXT: ) |
| # CHECK-NEXT: ) |
| # CHECK-NEXT: ) |