|
1087 | 1087 | (local.set $i (i32.add (i32.const 1) (local.get $i)))
|
1088 | 1088 | (br $next)))
|
1089 | 1089 |
|
1090 |
| - (func $sumUp (export "sumUp") (param $n i32) (result i32) |
| 1090 | + (func (export "sumUp") (param $n i32) (result i32) |
1091 | 1091 | (local $i i32)
|
1092 | 1092 | (local $j i32)
|
1093 | 1093 | (local $k (ref $ct))
|
|
1105 | 1105 | )
|
1106 | 1106 | (return (local.get $i)))
|
1107 | 1107 |
|
1108 |
| - (elem declare func $nats) |
| 1108 | + (func $nats-bad (type $ft) |
| 1109 | + (local $h (ref $ht)) |
| 1110 | + (local $i i32) |
| 1111 | + (local.set $h (local.get 0)) |
| 1112 | + (loop $next |
| 1113 | + (suspend_to $ht $yield |
| 1114 | + (local.get $i) (local.get $h)) |
| 1115 | + (drop) ;; drop the handle |
| 1116 | + (local.set $i (i32.add (i32.const 1) (local.get $i))) |
| 1117 | + (br $next))) |
| 1118 | + |
| 1119 | + (func (export "sumUp-bad") (param $n i32) (result i32) |
| 1120 | + (local $i i32) |
| 1121 | + (local $j i32) |
| 1122 | + (local $k (ref $ct)) |
| 1123 | + (local.set $k (cont.new $ct (ref.func $nats-bad))) |
| 1124 | + (loop $next |
| 1125 | + (block $on_yield (result i32 (ref $ct)) |
| 1126 | + (resume_with $ct (on $yield $on_yield) (local.get $k)) |
| 1127 | + (return (local.get $i)) |
| 1128 | + ) ;; on_yield |
| 1129 | + (local.set $k) |
| 1130 | + (i32.add (local.get $i)) |
| 1131 | + (local.set $i) |
| 1132 | + (local.set $j (i32.add (i32.const 1) (local.get $j))) |
| 1133 | + (br_if $next (i32.le_u (local.get $j) (local.get $n))) |
| 1134 | + ) |
| 1135 | + (return (local.get $i))) |
| 1136 | + |
| 1137 | + (elem declare func $nats $nats-bad) |
1109 | 1138 | )
|
1110 | 1139 | (assert_return (invoke "sumUp" (i32.const 10)) (i32.const 55))
|
| 1140 | +(assert_suspension (invoke "sumUp-bad" (i32.const 10)) "unhandled tag") |
| 1141 | + |
| 1142 | +(module |
| 1143 | + (type $ht (handler)) |
| 1144 | + (type $ft (func (param (ref $ht)))) |
| 1145 | + (type $ct (cont $ft)) |
| 1146 | + |
| 1147 | + (type $ft2 (func)) |
| 1148 | + (type $ct2 (cont $ft2)) |
| 1149 | + |
| 1150 | + (global $h1 (mut (ref null $ht)) (ref.null $ht)) |
| 1151 | + (global $h2 (mut (ref null $ht)) (ref.null $ht)) |
| 1152 | + |
| 1153 | + (tag $yield) |
| 1154 | + |
| 1155 | + (func $escape (type $ft) |
| 1156 | + (global.set $h2 (local.get 0)) |
| 1157 | + (resume $ct2 (cont.new $ct2 (ref.func $do-suspend))) |
| 1158 | + (unreachable)) |
| 1159 | + |
| 1160 | + (func $do-suspend |
| 1161 | + (suspend_to $ht $yield (global.get $h1)) |
| 1162 | + (unreachable)) |
| 1163 | + |
| 1164 | + (func $generate-name (type $ft) |
| 1165 | + (global.set $h1 (local.get 0)) |
| 1166 | + (block $on_yield (result (ref $ct)) |
| 1167 | + (resume_with $ct (on $yield $on_yield) (cont.new $ct (ref.func $escape))) |
| 1168 | + (unreachable) |
| 1169 | + ) ;; on_yield [named] |
| 1170 | + (unreachable)) |
| 1171 | + |
| 1172 | + (func (export "use-escapee") |
| 1173 | + (block $on_yield (result (ref $ct)) |
| 1174 | + (resume_with $ct (on $yield $on_yield) (cont.new $ct (ref.func $generate-name))) |
| 1175 | + (unreachable) |
| 1176 | + ) ;; on_yield |
| 1177 | + (suspend_to $ht $yield (global.get $h2)) |
| 1178 | + (unreachable)) |
| 1179 | + |
| 1180 | + (elem declare func $escape $do-suspend $generate-name) |
| 1181 | +) |
| 1182 | +(assert_suspension (invoke "use-escapee") "unhandled tag") |
0 commit comments