;;; TOOL: run-interp
;;; ARGS*: --enable-exceptions
(module
  (tag $e1)
  (tag $e2)
  (tag $e3 (param i32))
  (func (export "throw-uncaught")
    (throw $e1))
  (func (export "throw-uncaught-2")
    (try
      (do
        (throw $e1))))
  (func (export "try-catch") (result i32)
    (try (result i32)
      (do
        (throw $e1))
      (catch $e1
        (i32.const 1))))
  (func (export "try-catch-all") (result i32)
    (try (result i32)
      (do
        (throw $e1))
      (catch_all
        (i32.const 1))))
  (func (export "try-catch-all-2")
    (try
      (do
        (i32.const 1)
        (throw $e3))
      (catch_all)))
  (func (export "try-catch-payload") (result i32)
    (try (result i32)
      (do
        (i32.const 42)
        (throw $e3))
      (catch $e3)))
  (func (export "try-catch-multi") (result i32)
    (try (result i32)
      (do
        (throw $e2))
      (catch $e1
        (i32.const 1))
      (catch $e2
        (i32.const 2))))
  (func (export "try-catch-nested") (result i32)
    (try (result i32)
      (do
        (try (result i32)
          (do (throw $e2))
          (catch $e1
            (i32.const 1))))
      (catch $e2
        (i32.const 2))))
  (func (export "try-catch-nested-2") (result i32)
    (try (result i32)
      (do
        (try (result i32)
          (do (throw $e1))
          (catch $e1
            (i32.const 1))))
      (catch $e1
        (i32.const 2))))
  (func (export "try-catch-nested-3") (result i32)
    (try (result i32)
      (do
        (try (result i32)
          (do
            (try (result i32)
              (do (throw $e2))
              (catch $e1
                (i32.const 1))))
          (catch $e2
            (i32.const 2))))
      (catch_all
        (i32.const 3))))
  (func (export "try-catch-nested-4") (result i32)
    (try (result i32)
      (do
        (try (result i32)
          (do
            (throw $e1))
          (catch $e1
            (try (do (throw $e2)))
            (i32.const 0))
          (catch $e2
            (i32.const 0))))
      (catch $e2
        (i32.const 1))))
  (func (export "try-catch-nested-5") (result i32)
    (try (result i32)
      (do
        (try (result i32)
          (do
            (throw $e1))
          (catch $e1
            (try (do (throw $e2)))
            (i32.const 0))
          (catch_all
            (i32.const 0))))
      (catch $e2
        (i32.const 1))))
  (func (export "try-catch-uncaught") (result i32)
    (try (result i32)
      (do
        (throw $e1))
      (catch $e2
        (i32.const 1))))
  (func (export "try-catch-stack-size") (result i32)
    (i32.const 1)
    (try
      (do
        (i32.const 0)
        (throw $e1))
      (catch $e1))
    ;; here the value stack should have just 1
    )
  (func $helper
    (try
      (do
        (i32.const 0)
        (throw $e1))
      (catch $e1)))
  (func (export "try-catch-stack-size-2") (result i32)
    (i32.const 1)
    (call $helper)))
(;; STDOUT ;;;
throw-uncaught() => error: uncaught exception
throw-uncaught-2() => error: uncaught exception
try-catch() => i32:1
try-catch-all() => i32:1
try-catch-all-2() =>
try-catch-payload() => i32:42
try-catch-multi() => i32:2
try-catch-nested() => i32:2
try-catch-nested-2() => i32:1
try-catch-nested-3() => i32:2
try-catch-nested-4() => i32:1
try-catch-nested-5() => i32:1
try-catch-uncaught() => error: uncaught exception
try-catch-stack-size() => i32:1
try-catch-stack-size-2() => i32:1
;;; STDOUT ;;)