|
1119 | 1119 | (local.set $i (i32.add (i32.const 1) (local.get $i)))
|
1120 | 1120 | (br $next)))
|
1121 | 1121 |
|
1122 |
| - (func $sumUp (export "sumUp") (param $n i32) (result i32) |
| 1122 | + (func (export "sumUp") (param $n i32) (result i32) |
1123 | 1123 | (local $i i32)
|
1124 | 1124 | (local $j i32)
|
1125 | 1125 | (local $k (ref $ct))
|
|
1137 | 1137 | )
|
1138 | 1138 | (return (local.get $i)))
|
1139 | 1139 |
|
1140 |
| - (elem declare func $nats) |
| 1140 | + (func $nats-bad (type $ft) |
| 1141 | + (local $h (ref $ht)) |
| 1142 | + (local $i i32) |
| 1143 | + (local.set $h (local.get 0)) |
| 1144 | + (loop $next |
| 1145 | + (suspend_to $ht $yield |
| 1146 | + (local.get $i) (local.get $h)) |
| 1147 | + (drop) ;; drop the handle |
| 1148 | + (local.set $i (i32.add (i32.const 1) (local.get $i))) |
| 1149 | + (br $next))) |
| 1150 | + |
| 1151 | + (func (export "sumUp-bad") (param $n i32) (result i32) |
| 1152 | + (local $i i32) |
| 1153 | + (local $j i32) |
| 1154 | + (local $k (ref $ct)) |
| 1155 | + (local.set $k (cont.new $ct (ref.func $nats-bad))) |
| 1156 | + (loop $next |
| 1157 | + (block $on_yield (result i32 (ref $ct)) |
| 1158 | + (resume_with $ct (on $yield $on_yield) (local.get $k)) |
| 1159 | + (return (local.get $i)) |
| 1160 | + ) ;; on_yield |
| 1161 | + (local.set $k) |
| 1162 | + (i32.add (local.get $i)) |
| 1163 | + (local.set $i) |
| 1164 | + (local.set $j (i32.add (i32.const 1) (local.get $j))) |
| 1165 | + (br_if $next (i32.le_u (local.get $j) (local.get $n))) |
| 1166 | + ) |
| 1167 | + (return (local.get $i))) |
| 1168 | + |
| 1169 | + (elem declare func $nats $nats-bad) |
1141 | 1170 | )
|
1142 | 1171 | (assert_return (invoke "sumUp" (i32.const 10)) (i32.const 55))
|
| 1172 | +(assert_suspension (invoke "sumUp-bad" (i32.const 10)) "unhandled tag") |
| 1173 | + |
| 1174 | +(module |
| 1175 | + (type $ht (handler)) |
| 1176 | + (type $ft (func (param (ref $ht)))) |
| 1177 | + (type $ct (cont $ft)) |
| 1178 | + |
| 1179 | + (type $ft2 (func)) |
| 1180 | + (type $ct2 (cont $ft2)) |
| 1181 | + |
| 1182 | + (global $h1 (mut (ref null $ht)) (ref.null $ht)) |
| 1183 | + (global $h2 (mut (ref null $ht)) (ref.null $ht)) |
| 1184 | + |
| 1185 | + (tag $yield) |
| 1186 | + |
| 1187 | + (func $escape (type $ft) |
| 1188 | + (global.set $h2 (local.get 0)) |
| 1189 | + (resume $ct2 (cont.new $ct2 (ref.func $do-suspend))) |
| 1190 | + (unreachable)) |
| 1191 | + |
| 1192 | + (func $do-suspend |
| 1193 | + (suspend_to $ht $yield (global.get $h1)) |
| 1194 | + (unreachable)) |
| 1195 | + |
| 1196 | + (func $generate-name (type $ft) |
| 1197 | + (global.set $h1 (local.get 0)) |
| 1198 | + (block $on_yield (result (ref $ct)) |
| 1199 | + (resume_with $ct (on $yield $on_yield) (cont.new $ct (ref.func $escape))) |
| 1200 | + (unreachable) |
| 1201 | + ) ;; on_yield [named] |
| 1202 | + (unreachable)) |
| 1203 | + |
| 1204 | + (func (export "use-escapee") |
| 1205 | + (block $on_yield (result (ref $ct)) |
| 1206 | + (resume_with $ct (on $yield $on_yield) (cont.new $ct (ref.func $generate-name))) |
| 1207 | + (unreachable) |
| 1208 | + ) ;; on_yield |
| 1209 | + (suspend_to $ht $yield (global.get $h2)) |
| 1210 | + (unreachable)) |
| 1211 | + |
| 1212 | + (elem declare func $escape $do-suspend $generate-name) |
| 1213 | +) |
| 1214 | +(assert_suspension (invoke "use-escapee") "unhandled tag") |
0 commit comments