Create catch_ret.wast
diff --git a/test/core/exceptions/catch_ret.wast b/test/core/exceptions/catch_ret.wast
new file mode 100644
index 0000000..dac0680
--- /dev/null
+++ b/test/core/exceptions/catch_ret.wast
@@ -0,0 +1,252 @@
+(module
+  (type $f1 (func))
+  (tag $t (param i32))
+  (func $throw
+    (throw $t (i32.const 47))
+  )
+  (elem declare func $throw)
+  (func (export "main") (param i32) (result i32)
+    (try_table (catch $t 0)
+      (call $throw)
+    )
+    i32.const 42 ;; unreachable
+  )
+)
+
+(assert_return (invoke "main" (i32.const 44)) (i32.const 47))
+(module
+  (type $f1 (func))
+  (tag $t (param i32))
+  (func $throw
+    (throw $t (i32.const 47))
+  )
+  (elem declare func $throw)
+  (func (export "main") (param i32) (result i32)
+    (block (result i32)
+      (try_table (catch $t 0)
+        (call $throw)
+      )
+      (i32.const 22)
+    )
+  )
+)
+
+(assert_return (invoke "main" (i32.const 44)) (i32.const 47))
+(module
+  (type $f1 (func))
+  (tag $t (param i32))
+  (func $throw
+    (throw $t (i32.const 47))
+  )
+  (elem declare func $throw)
+  (func (export "main") (param i32) (result i32)
+    (i32.const 33)
+    (block (result i32)
+      (try_table (catch $t 0)
+        (call $throw)
+      )
+      (i32.const 22)
+    )
+    return
+  )
+)
+
+(assert_return (invoke "main" (i32.const 44)) (i32.const 47))
+(module
+  (type $f1 (func))
+  (tag $t (param i32))
+  (func $throw
+    (throw $t (i32.const 47))
+  )
+  (elem declare func $throw)
+  (func (export "main") (param i32) (result i32)
+    (local f32)
+    (local f32)
+    (local f32)
+    (i32.const 33)
+    (block (result i32)
+      (try_table (catch $t 0)
+        (call $throw)
+      )
+      (i32.const 22)
+    )
+    return
+  )
+)
+
+(assert_return (invoke "main" (i32.const 44)) (i32.const 47))
+(module
+  (type $f1 (func))
+  (tag $t (param i32))
+  (func $throw
+    (throw $t (i32.const 47))
+  )
+  (elem declare func $throw)
+  (func (export "main") (param i32) (result i32)
+    (local f32)
+    (local f32)
+    (local f32)
+    (i32.const 33)
+    (block (result i32)
+      (try_table (catch $t 1)
+        (call $throw)
+      )
+      (i32.const 22)
+    )
+    return
+  )
+)
+
+(assert_return (invoke "main" (i32.const 44)) (i32.const 47))
+(module
+  (type $f1 (func))
+  (tag $t (param i32))
+  (func $throw
+    (throw $t (i32.const 47))
+  )
+  (elem declare func $throw)
+  (func (export "main") (param i32) (result i32)
+    (i32.add (i32.const 11) (call $f1 (local.get 0)))
+  )
+  (func $f1 (param i32) (result i32)
+    (local f32)
+    (local f32)
+    (local f32)
+    (i32.const 33)
+    (block (result i32)
+      (try_table (catch $t 1)
+        (call $throw)
+      )
+      (i32.const 22)
+    )
+    return
+  )
+)
+
+(assert_return (invoke "main" (i32.const 44)) (i32.const 58))
+(module
+  (type $f1 (func))
+  (tag $t (param i64))
+  (func $throw
+    (throw $t (i64.const 9999999999))
+  )
+  (elem declare func $throw)
+  (func (export "main") (param i64) (result i64)
+    (try_table (catch $t 0)
+      (call $throw)
+    )
+    i64.const 42 ;; unreachable
+  )
+)
+
+(assert_return (invoke "main" (i64.const 123)) (i64.const 9999999999))
+(module
+  (type $f1 (func))
+  (tag $t (param f32))
+  (func $throw
+    (throw $t (f32.const 3.25))
+  )
+  (elem declare func $throw)
+  (func (export "main") (param f32) (result f32)
+    (try_table (catch $t 0)
+      (call $throw)
+    )
+    f32.const 42 ;; unreachable
+  )
+)
+
+(assert_return (invoke "main" (f32.const 1.5)) (f32.const 3.25))
+(module
+  (type $f1 (func))
+  (tag $t (param f64))
+  (func $throw
+    (throw $t (f64.const 6.022e23))
+  )
+  (elem declare func $throw)
+  (func (export "main") (param f64) (result f64)
+    (try_table (catch $t 0)
+      (call $throw)
+    )
+    f64.const 42 ;; unreachable
+  )
+)
+
+(assert_return (invoke "main" (f64.const 0.0)) (f64.const 6.022e23))
+(module
+  (type $f1 (func))
+  (tag $t (param i32 f32))
+  (func $throw
+    (throw $t (i32.const 77) (f32.const 1.75))
+  )
+  (elem declare func $throw)
+  (func (export "main") (param i32) (result i32 f32)
+    (try_table (catch $t 0)
+      (call $throw)
+    )
+    i32.const 0
+    f32.const 0 ;; unreachable
+  )
+)
+
+(assert_return (invoke "main" (i32.const 11)) (i32.const 77) (f32.const 1.75))
+(module
+  (type $f1 (func))
+  (tag $t (param i32))
+  (func $throw
+    (throw $t (i32.const 99))
+  )
+  (elem declare func $throw)
+
+  (func (export "main") (param i32) (result i32)
+    (local i32 i64) ;; a couple of locals
+
+    ;; initialize locals so they’re nontrivial
+    (local.set 1 (i32.const 77777))
+    (local.set 2 (i64.const 88888))
+
+    ;; put some junk on the stack before entering try_table
+    (local.get 1)
+    (local.get 2)
+
+    (try_table (result i32) (catch $t 0)
+      ;; at this point, stack has 77777, 88888 on it
+      (call $throw)
+      ;; if throw didn’t happen, return a dummy
+      i32.const 42
+    )
+    return ;; implicit pop
+  )
+)
+
+(assert_return (invoke "main" (i32.const 44)) (i32.const 99))
+(module
+  (type $f1 (func))
+  (tag $t (param i32))
+  (func $throw
+    (throw $t (i32.const 99))
+  )
+  (elem declare func $throw)
+
+  (func (export "main") (param i32) (result i32)
+    (local i32 i64) ;; a couple of locals
+
+    ;; initialize locals so they’re nontrivial
+    (local.set 1 (i32.const 77777))
+    (local.set 2 (i64.const 88888))
+
+    ;; put some junk on the stack before entering try_table
+    (local.get 1)
+    (local.get 2)
+
+    (try_table (param i32 i64) (result i32) (catch $t 0)
+      ;; at this point, stack has 77777, 88888 on it
+      (call $throw)
+      drop
+      drop
+      ;; pop if throw didn't
+      i32.const 42
+    )
+  )
+)
+
+(assert_return (invoke "main" (i32.const 44)) (i32.const 99))