|
946 | 946 | (local.set $i (i32.add (i32.const 1) (local.get $i)))
|
947 | 947 | (br $next)))
|
948 | 948 |
|
949 |
| - (func $sumUp (export "sumUp") (param $n i32) (result i32) |
| 949 | + (func (export "sumUp") (param $n i32) (result i32) |
950 | 950 | (local $i i32)
|
951 | 951 | (local $j i32)
|
952 | 952 | (local $k (ref $ct))
|
|
964 | 964 | )
|
965 | 965 | (return (local.get $i)))
|
966 | 966 |
|
967 |
| - (elem declare func $nats) |
| 967 | + (func $nats-bad (type $ft) |
| 968 | + (local $h (ref $ht)) |
| 969 | + (local $i i32) |
| 970 | + (local.set $h (local.get 0)) |
| 971 | + (loop $next |
| 972 | + (suspend_to $ht $yield |
| 973 | + (local.get $i) (local.get $h)) |
| 974 | + (drop) ;; drop the handle |
| 975 | + (local.set $i (i32.add (i32.const 1) (local.get $i))) |
| 976 | + (br $next))) |
| 977 | + |
| 978 | + (func (export "sumUp-bad") (param $n i32) (result i32) |
| 979 | + (local $i i32) |
| 980 | + (local $j i32) |
| 981 | + (local $k (ref $ct)) |
| 982 | + (local.set $k (cont.new $ct (ref.func $nats-bad))) |
| 983 | + (loop $next |
| 984 | + (block $on_yield (result i32 (ref $ct)) |
| 985 | + (resume_with $ct (on $yield $on_yield) (local.get $k)) |
| 986 | + (return (local.get $i)) |
| 987 | + ) ;; on_yield |
| 988 | + (local.set $k) |
| 989 | + (i32.add (local.get $i)) |
| 990 | + (local.set $i) |
| 991 | + (local.set $j (i32.add (i32.const 1) (local.get $j))) |
| 992 | + (br_if $next (i32.le_u (local.get $j) (local.get $n))) |
| 993 | + ) |
| 994 | + (return (local.get $i))) |
| 995 | + |
| 996 | + (elem declare func $nats $nats-bad) |
968 | 997 | )
|
969 | 998 | (assert_return (invoke "sumUp" (i32.const 10)) (i32.const 55))
|
| 999 | +(assert_suspension (invoke "sumUp-bad" (i32.const 10)) "unhandled tag") |
| 1000 | + |
| 1001 | +(module |
| 1002 | + (type $ht (handler)) |
| 1003 | + (type $ft (func (param (ref $ht)))) |
| 1004 | + (type $ct (cont $ft)) |
| 1005 | + |
| 1006 | + (type $ft2 (func)) |
| 1007 | + (type $ct2 (cont $ft2)) |
| 1008 | + |
| 1009 | + (global $h1 (mut (ref null $ht)) (ref.null $ht)) |
| 1010 | + (global $h2 (mut (ref null $ht)) (ref.null $ht)) |
| 1011 | + |
| 1012 | + (tag $yield) |
| 1013 | + |
| 1014 | + (func $escape (type $ft) |
| 1015 | + (global.set $h2 (local.get 0)) |
| 1016 | + (resume $ct2 (cont.new $ct2 (ref.func $do-suspend))) |
| 1017 | + (unreachable)) |
| 1018 | + |
| 1019 | + (func $do-suspend |
| 1020 | + (suspend_to $ht $yield (global.get $h1)) |
| 1021 | + (unreachable)) |
| 1022 | + |
| 1023 | + (func $generate-name (type $ft) |
| 1024 | + (global.set $h1 (local.get 0)) |
| 1025 | + (block $on_yield (result (ref $ct)) |
| 1026 | + (resume_with $ct (on $yield $on_yield) (cont.new $ct (ref.func $escape))) |
| 1027 | + (unreachable) |
| 1028 | + ) ;; on_yield [named] |
| 1029 | + (unreachable)) |
| 1030 | + |
| 1031 | + (func (export "use-escapee") |
| 1032 | + (block $on_yield (result (ref $ct)) |
| 1033 | + (resume_with $ct (on $yield $on_yield) (cont.new $ct (ref.func $generate-name))) |
| 1034 | + (unreachable) |
| 1035 | + ) ;; on_yield |
| 1036 | + (suspend_to $ht $yield (global.get $h2)) |
| 1037 | + (unreachable)) |
| 1038 | + |
| 1039 | + (elem declare func $escape $do-suspend $generate-name) |
| 1040 | +) |
| 1041 | +(assert_suspension (invoke "use-escapee") "unhandled tag") |
0 commit comments