wasm-tools 1.253.0

CLI tools for interoperating with WebAssembly files
Documentation
;; RUN: wast --assert default,no-test-folded --snapshot tests/snapshots % -f legacy-exceptions

;; Test try-delegate blocks.

(module
  (tag $e0)
  (tag $e1)

  (func (export "delegate-no-throw") (result i32)
    try (result i32)  ;; label = @1
      try (result i32)  ;; label = @2
        i32.const 1
      delegate 0
    catch 0
      i32.const 2
    end
  )

  (func $throw-if (param i32)
    (local.get 0)
    (if (then (throw $e0)) (else))
  )

  (func (export "delegate-throw") (param i32) (result i32)
    try (result i32)  ;; label = @1
      try (result i32)  ;; label = @2
        local.get 0
        call 1
        i32.const 1
      delegate 0
    catch 0
      i32.const 2
    end
  )

  (func (export "delegate-skip") (result i32)
    try (result i32)  ;; label = @1
      try (result i32)  ;; label = @2
        try (result i32)  ;; label = @3
          throw 0
          i32.const 1
        delegate 1
      catch 0
        i32.const 2
      end
    catch 0
      i32.const 3
    end
  )

  (func (export "delegate-to-block") (result i32)
    try (result i32)  ;; label = @1
      block  ;; label = @2
        try  ;; label = @3
          throw 0
        delegate 0
      end
      i32.const 0
    catch_all
      i32.const 1
    end
  )

  (func (export "delegate-to-catch") (result i32)
    try (result i32)  ;; label = @1
      try  ;; label = @2
        throw 0
      catch 0
        try  ;; label = @3
          rethrow 1 (;@2;)
        delegate 0
      end
      i32.const 0
    catch_all
      i32.const 1
    end
  )

  (func (export "delegate-to-caller-trivial")
    try  ;; label = @1
      throw 0
    delegate 0)

  (func (export "delegate-to-caller-skipping")
    try  ;; label = @1
      try  ;; label = @2
        throw 0
      delegate 1
    catch_all
    end
  )

  (func $select-tag (param i32)
    block  ;; label = @1
      block  ;; label = @2
        block  ;; label = @3
          local.get 0
          br_table 0 (;@3;) 1 (;@2;) 2 (;@1;)
        end
        return
      end
      throw 0
    end
    throw 1
  )

  (func (export "delegate-merge") (param i32 i32) (result i32)
    try (result i32)  ;; label = @1
      local.get 0
      call 8
      try (result i32)  ;; label = @2
        local.get 1
        call 8
        i32.const 1
      delegate 0
    catch 0
      i32.const 2
    end
  )

  (func (export "delegate-throw-no-catch") (result i32)
    try (result i32)  ;; label = @1
      try (result i32)  ;; label = @2
        throw 0
        i32.const 1
      delegate 0
    catch 1
      i32.const 2
    end
  )

  (func (export "delegate-correct-targets") (result i32)
    try (result i32)  ;; label = @1
      try  ;; label = @2
        try  ;; label = @3
          try  ;; label = @4
            try  ;; label = @5
              try  ;; label = @6
                throw 0
              delegate 1
            catch_all
              unreachable
            end
          delegate 1
        catch_all
          unreachable
        end
      catch_all
        try  ;; label = @3
          throw 0
        delegate 0
      end
      unreachable
    catch_all
      i32.const 1
    end)

  (func $throw-void (throw $e0))
  (func (export "return-call-in-try-delegate")
    try  ;; label = @1
      try  ;; label = @2
        return_call 12
      delegate 0
    catch 0
    end
  )

  (table funcref (elem $throw-void))
  (func (export "return-call-indirect-in-try-delegate")
    try  ;; label = @1
      try  ;; label = @2
        i32.const 0
        return_call_indirect (type 0)
      delegate 0
    catch 0
    end
  )

  (func (export "break-try-delegate")
    try  ;; label = @1
      br 0 (;@1;)
    delegate 0)

  (func (export "break-and-call-throw") (result i32)
    try (result i32)  ;; label = @1
      try (result i32)  ;; label = @2
        block  ;; label = @3
          try  ;; label = @4
            br 1 (;@3;)
          delegate 2
        end
        call 12
        i32.const 0
      catch 0
        i32.const 1
      end
    catch 0
      i32.const 2
    end
  )

  (func (export "break-and-throw") (result i32)
    try (result i32)  ;; label = @1
      try (result i32)  ;; label = @2
        block  ;; label = @3
          try  ;; label = @4
            br 1 (;@3;)
          delegate 2
        end
        throw 0
        i32.const 0
      catch 0
        i32.const 1
      end
    catch 0
      i32.const 2
    end
  )
)

(assert_return (invoke "delegate-no-throw") (i32.const 1))

(assert_return (invoke "delegate-throw" (i32.const 0)) (i32.const 1))
(assert_return (invoke "delegate-throw" (i32.const 1)) (i32.const 2))

(assert_exception (invoke "delegate-throw-no-catch"))

(assert_return (invoke "delegate-merge" (i32.const 1) (i32.const 0)) (i32.const 2))
(assert_exception (invoke "delegate-merge" (i32.const 2) (i32.const 0)))
(assert_return (invoke "delegate-merge" (i32.const 0) (i32.const 1)) (i32.const 2))
(assert_exception (invoke "delegate-merge" (i32.const 0) (i32.const 2)))
(assert_return (invoke "delegate-merge" (i32.const 0) (i32.const 0)) (i32.const 1))

(assert_return (invoke "delegate-skip") (i32.const 3))

(assert_return (invoke "delegate-to-block") (i32.const 1))
(assert_return (invoke "delegate-to-catch") (i32.const 1))

(assert_exception (invoke "delegate-to-caller-trivial"))
(assert_exception (invoke "delegate-to-caller-skipping"))

(assert_return (invoke "delegate-correct-targets") (i32.const 1))

(assert_exception (invoke "return-call-in-try-delegate"))
(assert_exception (invoke "return-call-indirect-in-try-delegate"))

(assert_return (invoke "break-try-delegate"))

(assert_return (invoke "break-and-call-throw") (i32.const 1))
(assert_return (invoke "break-and-throw") (i32.const 1))

;; Ignore per https://github.com/bytecodealliance/wasm-tools/issues/1671
;;
;; (assert_malformed
;;   (module quote "(module (func (delegate 0)))")
;;   "unexpected token"
;; )

;; (assert_malformed
;;   (module quote "(module (tag $e) (func try catch $e delegate 0))")
;;   "unexpected token"
;; )

;; (assert_malformed
;;   (module quote "(module (func try catch_all delegate 0))")
;;   "unexpected token"
;; )

;; (assert_malformed
;;   (module quote "(module (func try delegate delegate 0))")
;;   "unexpected token"
;; )

(assert_invalid
  (module (func try delegate 1))
  "unknown label"
)