@@ -58,6 +58,7 @@ type frame =
58
58
}
59
59
60
60
type code = value stack * admin_instr list
61
+ and handler_name = exn
61
62
62
63
and admin_instr = admin_instr' phrase
63
64
and admin_instr' =
@@ -72,25 +73,28 @@ and admin_instr' =
72
73
| Label of int * instr list * code
73
74
| Frame of int * frame * code
74
75
| Handler of int * catch list * code
75
- | Handle of handle_table option * code
76
- | Suspending of tag_inst * value stack * ref_ option * ctxt
76
+ | Handle of handler_name option * handle_table option * code
77
+ | Suspending of tag_inst * value stack * ref_ option * ref_ option * ctxt
77
78
78
79
and ctxt = code -> code
79
80
and handle_table = (tag_inst * idx) list * tag_inst list
80
81
81
82
type cont = int32 * ctxt (* TODO: represent type properly *)
82
83
type ref_ + = ContRef of cont option ref
84
+ type ref_ + = HandlerRef of handler_name option ref
83
85
84
86
let () =
85
87
let type_of_ref' = ! Value. type_of_ref' in
86
88
Value. type_of_ref' := function
87
89
| ContRef _ -> ContHT
90
+ | HandlerRef _ -> HandlerHT
88
91
| r -> type_of_ref' r
89
92
90
93
let () =
91
94
let string_of_ref' = ! Value. string_of_ref' in
92
95
Value. string_of_ref' := function
93
96
| ContRef _ -> " cont"
97
+ | HandlerRef _ -> " handler"
94
98
| r -> string_of_ref' r
95
99
96
100
let plain e = Plain e.it @@ e.at
@@ -377,7 +381,18 @@ let rec step (c : config) : config =
377
381
let tagt = tag c.frame.inst x in
378
382
let FuncT (ts, _) = func_type_of_tag_type c.frame.inst (Tag. type_of tagt) in
379
383
let args, vs' = i32_split (Lib.List32. length ts) vs e.at in
380
- vs', [Suspending (tagt, args, None , fun code -> code) @@ e.at]
384
+ vs', [Suspending (tagt, args, None , None , fun code -> code) @@ e.at]
385
+
386
+ | SuspendTo (x , y ), vs ->
387
+ let tagt = tag c.frame.inst y in
388
+ let FuncT (ts, _) = func_type_of_tag_type c.frame.inst (Tag. type_of tagt) in
389
+ let args, vs' = i32_split (Lib.List32. length ts) vs e.at in
390
+ let args, href =
391
+ match Lib.List. lead args, Lib.List. last args with
392
+ | args , Ref r -> args, r
393
+ | _ -> Crash. error e.at " type mismatch at suspend to"
394
+ in
395
+ vs', [Suspending (tagt, args, None , Some href, fun code -> code) @@ e.at]
381
396
382
397
| Resume (x , xls ), Ref (NullRef _ ) :: vs ->
383
398
vs, [Trapping " null continuation reference" @@ e.at]
@@ -389,7 +404,7 @@ let rec step (c : config) : config =
389
404
let hs = handle_table c xls in
390
405
let args, vs' = i32_split n vs e.at in
391
406
cont := None ;
392
- vs', [Handle (Some hs, ctxt (args, [] )) @@ e.at]
407
+ vs', [Handle (None , Some hs, ctxt (args, [] )) @@ e.at]
393
408
394
409
| ResumeThrow (x , y , xls ), Ref (NullRef _ ) :: vs ->
395
410
vs, [Trapping " null continuation reference" @@ e.at]
@@ -403,7 +418,24 @@ let rec step (c : config) : config =
403
418
let hs = handle_table c xls in
404
419
let args, vs' = i32_split (Lib.List32. length ts) vs e.at in
405
420
cont := None ;
406
- vs', [Handle (Some hs, ctxt (args, [Plain (Throw x) @@ e.at])) @@ e.at]
421
+ vs', [Handle (None , Some hs, ctxt (args, [Plain (Throw x) @@ e.at])) @@ e.at]
422
+
423
+ | ResumeWith (x , xls ), Ref (NullRef _ ) :: vs ->
424
+ vs, [Trapping " null continuation reference" @@ e.at]
425
+
426
+ | ResumeWith (x , xls ), Ref (ContRef {contents = None } ) :: vs ->
427
+ vs, [Trapping " continuation already consumed" @@ e.at]
428
+
429
+ | ResumeWith (x , xls ), Ref (ContRef ({contents = Some (n , ctxt )} as cont )) :: vs ->
430
+ let hs = handle_table c xls in
431
+ Printf. printf " arity: %s\n %!" (I32. to_string_u n);
432
+ let args, vs' = i32_split (I32. sub n 1l ) vs e.at in
433
+ let exception Name in
434
+ let name =
435
+ Ref (HandlerRef (ref (Some Name )))
436
+ in
437
+ cont := None ;
438
+ vs', [Handle (Some Name , Some hs, ctxt (args @ [name], [] )) @@ e.at]
407
439
408
440
| Switch (x , y ), Ref (NullRef _ ) :: vs ->
409
441
vs, [Trapping " null continuation reference" @@ e.at]
@@ -414,13 +446,13 @@ let rec step (c : config) : config =
414
446
| Switch (x , y ), Ref (ContRef {contents = Some (n , ctxt )} as cont ) :: vs ->
415
447
let tagt = tag c.frame.inst y in
416
448
let args, vs' = i32_split (Int32. sub n 1l ) vs e.at in
417
- vs', [Suspending (tagt, args, Some cont, fun code -> code) @@ e.at]
449
+ vs', [Suspending (tagt, args, Some cont, None , fun code -> code) @@ e.at]
418
450
419
451
| Barrier (bt , es' ), vs ->
420
452
let InstrT (ts1, _, _xs) = block_type c.frame.inst bt e.at in
421
453
let args, vs' = i32_split (Lib.List32. length ts1) vs e.at in
422
454
vs', [
423
- Handle (None ,
455
+ Handle (None , None ,
424
456
(args, [Plain (Block (bt, es')) @@ e.at])
425
457
) @@ e.at
426
458
]
@@ -1156,9 +1188,9 @@ let rec step (c : config) : config =
1156
1188
| Label (n , es0 , (vs' , [] )), vs ->
1157
1189
vs' @ vs, []
1158
1190
1159
- | Label (n , es0 , (vs' , {it = Suspending (tagt , vs1 , contref , ctxt ); at} :: es' )), vs ->
1191
+ | Label (n , es0 , (vs' , {it = Suspending (tagt , vs1 , contref , href , ctxt ); at} :: es' )), vs ->
1160
1192
let ctxt' code = [], [Label (n, es0, compose (ctxt code) (vs', es')) @@ e.at] in
1161
- vs, [Suspending (tagt, vs1, contref, ctxt') @@ at]
1193
+ vs, [Suspending (tagt, vs1, contref, href, ctxt') @@ at]
1162
1194
1163
1195
| Label (n , es0 , (vs' , {it = ReturningInvoke (vs0 , f ); at} :: es' )), vs ->
1164
1196
vs, [ReturningInvoke (vs0, f) @@ at]
@@ -1185,9 +1217,9 @@ let rec step (c : config) : config =
1185
1217
| Frame (n , frame' , (vs' , {it = Throwing (a , vs0 ); at} :: es' )), vs ->
1186
1218
vs, [Throwing (a, vs0) @@ at]
1187
1219
1188
- | Frame (n , frame' , (vs' , {it = Suspending (tagt , vs1 , contref , ctxt ); at} :: es' )), vs ->
1220
+ | Frame (n , frame' , (vs' , {it = Suspending (tagt , vs1 , contref , href , ctxt ); at} :: es' )), vs ->
1189
1221
let ctxt' code = [], [Frame (n, frame', compose (ctxt code) (vs', es')) @@ e.at] in
1190
- vs, [Suspending (tagt, vs1, contref, ctxt') @@ at]
1222
+ vs, [Suspending (tagt, vs1, contref, href, ctxt') @@ at]
1191
1223
1192
1224
| Frame (n , frame' , (vs' , {it = Returning vs0 ; at} :: es' )), vs ->
1193
1225
take n vs0 e.at @ vs, []
@@ -1227,9 +1259,9 @@ let rec step (c : config) : config =
1227
1259
| Handler (n , [] , (vs' , {it = Throwing (a , vs0 ); at} :: es' )), vs ->
1228
1260
vs, [Throwing (a, vs0) @@ at]
1229
1261
1230
- | Handler (n , cs , (vs' , {it = Suspending (tagt , vs1 , contref , ctxt ); at} :: es' )), vs ->
1262
+ | Handler (n , cs , (vs' , {it = Suspending (tagt , vs1 , contref , href , ctxt ); at} :: es' )), vs ->
1231
1263
let ctxt' code = [], [Handler (n, cs, compose (ctxt code) (vs', es')) @@ e.at] in
1232
- vs, [Suspending (tagt, vs1, contref, ctxt') @@ at]
1264
+ vs, [Suspending (tagt, vs1, contref, href, ctxt') @@ at]
1233
1265
1234
1266
| Handler (n , cs , (vs' , e' :: es' )), vs when is_jumping e' ->
1235
1267
vs, [e']
@@ -1261,40 +1293,48 @@ let rec step (c : config) : config =
1261
1293
with Crash (_ , msg ) -> Crash. error e.at msg)
1262
1294
)
1263
1295
1264
- | Handle (hso , (vs' , [] )), vs ->
1296
+ | Handle (name , hso , (vs' , [] )), vs ->
1265
1297
vs' @ vs, []
1266
1298
1267
- | Handle (None, (vs' , {it = Suspending _ ; at} :: es' )), vs ->
1299
+ | Handle (name , None, (vs' , {it = Suspending _ ; at} :: es' )), vs ->
1268
1300
vs, [Trapping " barrier hit by suspension" @@ at]
1269
1301
1270
- | Handle (Some (hs, _), (vs', {it = Suspending (tagt, vs1, None , ctxt); at} :: es')), vs
1302
+ | Handle (None , Some (hs, _), (vs', {it = Suspending (tagt, vs1, None , None , ctxt); at} :: es')), vs
1271
1303
when List. mem_assq tagt hs ->
1272
1304
let FuncT (_, ts) = func_type_of_tag_type c.frame.inst (Tag. type_of tagt) in
1273
1305
let ctxt' code = compose (ctxt code) (vs', es') in
1274
1306
[Ref (ContRef (ref (Some (Lib.List32. length ts, ctxt'))))] @ vs1 @ vs,
1275
1307
[Plain (Br (List. assq tagt hs)) @@ e.at]
1276
1308
1277
- | Handle (Some (_, hs) as hso, (vs', {it = Suspending (tagt, vs1, Some (ContRef ({contents = Some (_, ctxt)} as cont)), ctxt'); at} :: es')), vs
1309
+ | Handle (Some h, Some (hs, _), (vs', {it = Suspending (tagt, vs1, None , Some (HandlerRef ({contents = Some h'} as href)), ctxt); at} :: es')), vs
1310
+ when h == h' && List. mem_assq tagt hs ->
1311
+ let FuncT (_, ts) = func_type_of_tag_type c.frame.inst (Tag. type_of tagt) in
1312
+ let ctxt' code = compose (ctxt code) (vs', es') in
1313
+ href := None ;
1314
+ [Ref (ContRef (ref (Some (Int32. add (Lib.List32. length ts) 1l , ctxt'))))] @ vs1 @ vs,
1315
+ [Plain (Br (List. assq tagt hs)) @@ e.at]
1316
+
1317
+ | Handle (None , (Some (_, hs) as hso), (vs', {it = Suspending (tagt, vs1, Some (ContRef ({contents = Some (_, ctxt)} as cont)), None , ctxt'); at} :: es')), vs
1278
1318
when List. memq tagt hs ->
1279
1319
let FuncT (_, ts) = func_type_of_tag_type c.frame.inst (Tag. type_of tagt) in
1280
1320
let ctxt'' code = compose (ctxt' code) (vs', es') in
1281
1321
let cont' = Ref (ContRef (ref (Some (Int32. add (Lib.List32. length ts) 1l , ctxt'')))) in
1282
1322
let args = vs1 @ [cont'] in
1283
1323
cont := None ;
1284
- vs' @ vs, [Handle (hso, ctxt (args, [] )) @@ e.at]
1324
+ vs' @ vs, [Handle (None , hso, ctxt (args, [] )) @@ e.at]
1285
1325
1286
- | Handle (hso , (vs' , {it = Suspending (tagt , vs1 , contref , ctxt ); at} :: es' )), vs ->
1287
- let ctxt' code = [], [Handle (hso, compose (ctxt code) (vs', es')) @@ e.at] in
1288
- vs, [Suspending (tagt, vs1, contref, ctxt') @@ at]
1326
+ | Handle (name , hso , (vs' , {it = Suspending (tagt , vs1 , contref , href , ctxt ); at} :: es' )), vs ->
1327
+ let ctxt' code = [], [Handle (name, hso, compose (ctxt code) (vs', es')) @@ e.at] in
1328
+ vs, [Suspending (tagt, vs1, contref, href, ctxt') @@ at]
1289
1329
1290
- | Handle (hso , (vs' , e' :: es' )), vs when is_jumping e' ->
1330
+ | Handle (name , hso , (vs' , e' :: es' )), vs when is_jumping e' ->
1291
1331
vs, [e']
1292
1332
1293
- | Handle (hso , code' ), vs ->
1333
+ | Handle (name , hso , code' ), vs ->
1294
1334
let c' = step {c with code = code'} in
1295
- vs, [Handle (hso, c'.code) @@ e.at]
1335
+ vs, [Handle (name, hso, c'.code) @@ e.at]
1296
1336
1297
- | Suspending (_ , _ , _ , _ ), _ -> assert false
1337
+ | Suspending (_ , _ , _ , _ , _ ), _ -> assert false
1298
1338
1299
1339
in {c with code = vs', es' @ List. tl es}
1300
1340
0 commit comments