Skip to content

Commit 75c295c

Browse files
committed
Rebase
1 parent 1ccd8e8 commit 75c295c

File tree

13 files changed

+247
-31
lines changed

13 files changed

+247
-31
lines changed

interpreter/binary/decode.ml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ let heap_type s =
193193
| -0x16 -> ArrayHT
194194
| -0x17 -> ExnHT
195195
| -0x18 -> ContHT
196+
| -0x19 -> HandlerHT
197+
| -0x1a -> NoHandlerHT
196198
| _ -> error s pos "malformed heap type"
197199
)
198200
] s
@@ -214,6 +216,8 @@ let ref_type s =
214216
| -0x16 -> (Null, ArrayHT)
215217
| -0x17 -> (Null, ExnHT)
216218
| -0x18 -> (Null, ContHT)
219+
| -0x19 -> (Null, HandlerHT)
220+
| -0x1a -> (Null, NoHandlerHT)
217221
| -0x1c -> (NoNull, heap_type s)
218222
| -0x1d -> (Null, heap_type s)
219223
| _ -> error s pos "malformed reference type"
@@ -259,12 +263,16 @@ let func_type s =
259263
let cont_type s =
260264
ContT (heap_type s)
261265

266+
let handler_type s =
267+
HandlerT (result_type s)
268+
262269
let str_type s =
263270
match s7 s with
264271
| -0x20 -> DefFuncT (func_type s)
265272
| -0x21 -> DefStructT (struct_type s)
266273
| -0x22 -> DefArrayT (array_type s)
267274
| -0x23 -> DefContT (cont_type s) (* TODO(dhil): See comment in encode.ml *)
275+
| -0x24 -> DefHandlerT (handler_type s)
268276
| _ -> error s (pos s - 1) "malformed definition type"
269277

270278
let sub_type s =
@@ -650,6 +658,14 @@ let rec instr s =
650658
let x = at var s in
651659
let y = at var s in
652660
switch x y
661+
| 0xe7 ->
662+
let x = at var s in
663+
let y = at var s in
664+
suspend_to x y
665+
| 0xe8 ->
666+
let x = at var s in
667+
let xls = vec on_clause s in
668+
resume_with x xls
653669

654670
| 0xfb as b ->
655671
(match u32 s with

interpreter/binary/encode.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ struct
132132
| NoExternHT -> s7 (-0x0e)
133133
| ContHT -> s7 (-0x18)
134134
| NoContHT -> s7 (-0x0b)
135+
| HandlerHT -> s7 (-0x19)
136+
| NoHandlerHT -> s7 (-0x1a)
135137
| VarHT x -> var_type s33 x
136138
| DefHT _ | BotHT -> assert false
137139

@@ -187,6 +189,9 @@ struct
187189
let cont_type = function
188190
| ContT ht -> heap_type ht
189191

192+
let handler_type = function
193+
| HandlerT ts -> vec val_type ts
194+
190195
let str_type = function
191196
| DefStructT st -> s7 (-0x21); struct_type st
192197
| DefArrayT at -> s7 (-0x22); array_type at
@@ -195,6 +200,7 @@ struct
195200
(* TODO(dhil): This might need to change again in the future as a
196201
different proposal might claim this opcode! GC proposal claimed
197202
the previous opcode we were using. *)
203+
| DefHandlerT ht -> s7 (-0x24); handler_type ht
198204

199205
let sub_type = function
200206
| SubT (Final, [], st) -> str_type st
@@ -301,8 +307,10 @@ struct
301307
| ContNew x -> op 0xe0; var x
302308
| ContBind (x, y) -> op 0xe1; var x; var y
303309
| Suspend x -> op 0xe2; var x
310+
| SuspendTo (x, y) -> op 0xe7; var x; var y
304311
| Resume (x, xls) -> op 0xe3; var x; resumetable xls
305312
| ResumeThrow (x, y, xls) -> op 0xe4; var x; var y; resumetable xls
313+
| ResumeWith (x, xls) -> op 0xe8; var x; resumetable xls
306314
| Switch (x, y) -> op 0xe5; var x; var y
307315

308316
| Throw x -> op 0x08; var x

interpreter/exec/eval.ml

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ type frame =
5858
}
5959

6060
type code = value stack * admin_instr list
61+
and handler_name = exn
6162

6263
and admin_instr = admin_instr' phrase
6364
and admin_instr' =
@@ -72,25 +73,28 @@ and admin_instr' =
7273
| Label of int * instr list * code
7374
| Frame of int * frame * code
7475
| Handler of int * catch list * code
75-
| Handle of handle_table * 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
7778

7879
and ctxt = code -> code
7980
and handle_table = (tag_inst * idx) list * tag_inst list
8081

8182
type cont = int32 * ctxt (* TODO: represent type properly *)
8283
type ref_ += ContRef of cont option ref
84+
type ref_ += HandlerRef of handler_name option ref
8385

8486
let () =
8587
let type_of_ref' = !Value.type_of_ref' in
8688
Value.type_of_ref' := function
8789
| ContRef _ -> ContHT
90+
| HandlerRef _ -> HandlerHT
8891
| r -> type_of_ref' r
8992

9093
let () =
9194
let string_of_ref' = !Value.string_of_ref' in
9295
Value.string_of_ref' := function
9396
| ContRef _ -> "cont"
97+
| HandlerRef _ -> "handler"
9498
| r -> string_of_ref' r
9599

96100
let plain e = Plain e.it @@ e.at
@@ -379,7 +383,18 @@ let rec step (c : config) : config =
379383
let tagt = tag c.frame.inst x in
380384
let FuncT (ts, _) = func_type_of_tag_type c.frame.inst (Tag.type_of tagt) in
381385
let args, vs' = i32_split (Lib.List32.length ts) vs e.at in
382-
vs', [Suspending (tagt, args, None, fun code -> code) @@ e.at]
386+
vs', [Suspending (tagt, args, None, None, fun code -> code) @@ e.at]
387+
388+
| SuspendTo (x, y), vs ->
389+
let tagt = tag c.frame.inst y in
390+
let FuncT (ts, _) = func_type_of_tag_type c.frame.inst (Tag.type_of tagt) in
391+
let args, vs' = i32_split (Lib.List32.length ts) vs e.at in
392+
let args, href =
393+
match Lib.List.lead args, Lib.List.last args with
394+
| args, Ref r -> args, r
395+
| _ -> Crash.error e.at "type mismatch at suspend to"
396+
in
397+
vs', [Suspending (tagt, args, None, Some href, fun code -> code) @@ e.at]
383398

384399
| Resume (x, xls), Ref (NullRef _) :: vs ->
385400
vs, [Trapping "null continuation reference" @@ e.at]
@@ -391,7 +406,7 @@ let rec step (c : config) : config =
391406
let hs = handle_table c xls in
392407
let args, vs' = i32_split n vs e.at in
393408
cont := None;
394-
vs', [Handle (hs, ctxt (args, [])) @@ e.at]
409+
vs', [Handle (None, Some hs, ctxt (args, [])) @@ e.at]
395410

396411
| ResumeThrow (x, y, xls), Ref (NullRef _) :: vs ->
397412
vs, [Trapping "null continuation reference" @@ e.at]
@@ -405,7 +420,24 @@ let rec step (c : config) : config =
405420
let hs = handle_table c xls in
406421
let args, vs' = i32_split (Lib.List32.length ts) vs e.at in
407422
cont := None;
408-
vs', [Handle (hs, ctxt ([], [Throwing (tagt, args) @@ e.at])) @@ e.at]
423+
vs', [Handle (None, Some hs, ctxt ([], [Throwing (tagt, args) @@ e.at])) @@ e.at]
424+
425+
| ResumeWith (x, xls), Ref (NullRef _) :: vs ->
426+
vs, [Trapping "null continuation reference" @@ e.at]
427+
428+
| ResumeWith (x, xls), Ref (ContRef {contents = None}) :: vs ->
429+
vs, [Trapping "continuation already consumed" @@ e.at]
430+
431+
| ResumeWith (x, xls), Ref (ContRef ({contents = Some (n, ctxt)} as cont)) :: vs ->
432+
let hs = handle_table c xls in
433+
Printf.printf "arity: %s\n%!" (I32.to_string_u n);
434+
let args, vs' = i32_split (I32.sub n 1l) vs e.at in
435+
let exception Name in
436+
let name =
437+
Ref (HandlerRef (ref (Some Name)))
438+
in
439+
cont := None;
440+
vs', [Handle (Some Name, Some hs, ctxt (args @ [name], [])) @@ e.at]
409441

410442
| Switch (x, y), Ref (NullRef _) :: vs ->
411443
vs, [Trapping "null continuation reference" @@ e.at]
@@ -416,7 +448,7 @@ let rec step (c : config) : config =
416448
| Switch (x, y), Ref (ContRef {contents = Some (n, ctxt)} as cont) :: vs ->
417449
let tagt = tag c.frame.inst y in
418450
let args, vs' = i32_split (Int32.sub n 1l) vs e.at in
419-
vs', [Suspending (tagt, args, Some cont, fun code -> code) @@ e.at]
451+
vs', [Suspending (tagt, args, Some cont, None, fun code -> code) @@ e.at]
420452

421453
| ReturnCall x, vs ->
422454
(match (step {c with code = (vs, [Plain (Call x) @@ e.at])}).code with
@@ -1177,9 +1209,9 @@ let rec step (c : config) : config =
11771209
| Label (n, es0, (vs', [])), vs ->
11781210
vs' @ vs, []
11791211

1180-
| Label (n, es0, (vs', {it = Suspending (tagt, vs1, contref, ctxt); at} :: es')), vs ->
1212+
| Label (n, es0, (vs', {it = Suspending (tagt, vs1, contref, href, ctxt); at} :: es')), vs ->
11811213
let ctxt' code = [], [Label (n, es0, compose (ctxt code) (vs', es')) @@ e.at] in
1182-
vs, [Suspending (tagt, vs1, contref, ctxt') @@ at]
1214+
vs, [Suspending (tagt, vs1, contref, href, ctxt') @@ at]
11831215

11841216
| Label (n, es0, (vs', {it = ReturningInvoke (vs0, f); at} :: es')), vs ->
11851217
vs, [ReturningInvoke (vs0, f) @@ at]
@@ -1206,9 +1238,9 @@ let rec step (c : config) : config =
12061238
| Frame (n, frame', (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
12071239
vs, [Throwing (a, vs0) @@ at]
12081240

1209-
| Frame (n, frame', (vs', {it = Suspending (tagt, vs1, contref, ctxt); at} :: es')), vs ->
1241+
| Frame (n, frame', (vs', {it = Suspending (tagt, vs1, contref, href, ctxt); at} :: es')), vs ->
12101242
let ctxt' code = [], [Frame (n, frame', compose (ctxt code) (vs', es')) @@ e.at] in
1211-
vs, [Suspending (tagt, vs1, contref, ctxt') @@ at]
1243+
vs, [Suspending (tagt, vs1, contref, href, ctxt') @@ at]
12121244

12131245
| Frame (n, frame', (vs', {it = Returning vs0; at} :: es')), vs ->
12141246
take n vs0 e.at @ vs, []
@@ -1248,9 +1280,9 @@ let rec step (c : config) : config =
12481280
| Handler (n, [], (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
12491281
vs, [Throwing (a, vs0) @@ at]
12501282

1251-
| Handler (n, cs, (vs', {it = Suspending (tagt, vs1, contref, ctxt); at} :: es')), vs ->
1283+
| Handler (n, cs, (vs', {it = Suspending (tagt, vs1, contref, href, ctxt); at} :: es')), vs ->
12521284
let ctxt' code = [], [Handler (n, cs, compose (ctxt code) (vs', es')) @@ e.at] in
1253-
vs, [Suspending (tagt, vs1, contref, ctxt') @@ at]
1285+
vs, [Suspending (tagt, vs1, contref, href, ctxt') @@ at]
12541286

12551287
| Handler (n, cs, (vs', e' :: es')), vs when is_jumping e' ->
12561288
vs, [e']
@@ -1282,37 +1314,45 @@ let rec step (c : config) : config =
12821314
with Crash (_, msg) -> Crash.error e.at msg)
12831315
)
12841316

1285-
| Handle (hso, (vs', [])), vs ->
1317+
| Handle (name, hso, (vs', [])), vs ->
12861318
vs' @ vs, []
12871319

1288-
| Handle ((hs, _), (vs', {it = Suspending (tagt, vs1, None, ctxt); at} :: es')), vs
1320+
| Handle (name, Some (hs, _), (vs', {it = Suspending (tagt, vs1, None, None, ctxt); at} :: es')), vs
12891321
when List.mem_assq tagt hs ->
12901322
let FuncT (_, ts) = func_type_of_tag_type c.frame.inst (Tag.type_of tagt) in
12911323
let ctxt' code = compose (ctxt code) (vs', es') in
12921324
[Ref (ContRef (ref (Some (Lib.List32.length ts, ctxt'))))] @ vs1 @ vs,
12931325
[Plain (Br (List.assq tagt hs)) @@ e.at]
12941326

1295-
| Handle ((_, hs) as hso, (vs', {it = Suspending (tagt, vs1, Some (ContRef ({contents = Some (_, ctxt)} as cont)), ctxt'); at} :: es')), vs
1327+
| Handle (Some h, Some (hs, _), (vs', {it = Suspending (tagt, vs1, None, Some (HandlerRef ({contents = Some h'} as href)), ctxt); at} :: es')), vs
1328+
when h == h' && List.mem_assq tagt hs ->
1329+
let FuncT (_, ts) = func_type_of_tag_type c.frame.inst (Tag.type_of tagt) in
1330+
let ctxt' code = compose (ctxt code) (vs', es') in
1331+
href := None;
1332+
[Ref (ContRef (ref (Some (Int32.add (Lib.List32.length ts) 1l, ctxt'))))] @ vs1 @ vs,
1333+
[Plain (Br (List.assq tagt hs)) @@ e.at]
1334+
1335+
| Handle (None, (Some (_, hs) as hso), (vs', {it = Suspending (tagt, vs1, Some (ContRef ({contents = Some (_, ctxt)} as cont)), None, ctxt'); at} :: es')), vs
12961336
when List.memq tagt hs ->
12971337
let FuncT (_, ts) = func_type_of_tag_type c.frame.inst (Tag.type_of tagt) in
12981338
let ctxt'' code = compose (ctxt' code) (vs', es') in
12991339
let cont' = Ref (ContRef (ref (Some (Int32.add (Lib.List32.length ts) 1l, ctxt'')))) in
13001340
let args = cont' :: vs1 in
13011341
cont := None;
1302-
vs' @ vs, [Handle (hso, ctxt (args, [])) @@ e.at]
1342+
vs' @ vs, [Handle (None, hso, ctxt (args, [])) @@ e.at]
13031343

1304-
| Handle (hso, (vs', {it = Suspending (tagt, vs1, contref, ctxt); at} :: es')), vs ->
1305-
let ctxt' code = [], [Handle (hso, compose (ctxt code) (vs', es')) @@ e.at] in
1306-
vs, [Suspending (tagt, vs1, contref, ctxt') @@ at]
1344+
| Handle (name, hso, (vs', {it = Suspending (tagt, vs1, contref, href, ctxt); at} :: es')), vs ->
1345+
let ctxt' code = [], [Handle (name, hso, compose (ctxt code) (vs', es')) @@ e.at] in
1346+
vs, [Suspending (tagt, vs1, contref, href, ctxt') @@ at]
13071347

1308-
| Handle (hso, (vs', e' :: es')), vs when is_jumping e' ->
1348+
| Handle (name, hso, (vs', e' :: es')), vs when is_jumping e' ->
13091349
vs, [e']
13101350

1311-
| Handle (hso, code'), vs ->
1351+
| Handle (name, hso, code'), vs ->
13121352
let c' = step {c with code = code'} in
1313-
vs, [Handle (hso, c'.code) @@ e.at]
1353+
vs, [Handle (name, hso, c'.code) @@ e.at]
13141354

1315-
| Suspending (_, _, _, _), _ -> assert false
1355+
| Suspending (_, _, _, _, _), _ -> assert false
13161356

13171357
in {c with code = vs', es' @ List.tl es}
13181358

interpreter/syntax/ast.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,10 @@ and instr' =
175175
| ContNew of idx (* create continuation *)
176176
| ContBind of idx * idx (* bind continuation arguments *)
177177
| Suspend of idx (* suspend continuation *)
178+
| SuspendTo of idx * idx (* named suspend continuation *)
178179
| Resume of idx * (idx * hdl) list (* resume continuation *)
179180
| ResumeThrow of idx * idx * (idx * hdl) list (* abort continuation *)
181+
| ResumeWith of idx * (idx * hdl) list (* named resume continuation *)
180182
| Switch of idx * idx (* direct switch continuation *)
181183
| Throw of idx (* throw exception *)
182184
| ThrowRef (* rethrow exception *)

interpreter/syntax/free.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ let heap_type = function
8282
| ExnHT | NoExnHT -> empty
8383
| ExternHT | NoExternHT -> empty
8484
| ContHT | NoContHT -> empty
85+
| HandlerHT | NoHandlerHT -> empty
8586
| VarHT x -> var_type x
8687
| DefHT _ct -> empty (* assume closed *)
8788
| BotHT -> empty
@@ -109,12 +110,14 @@ let field_type (FieldT (_mut, st)) = storage_type st
109110
let struct_type (StructT fts) = list field_type fts
110111
let array_type (ArrayT ft) = field_type ft
111112
let func_type (FuncT (ts1, ts2)) = list val_type ts1 ++ list val_type ts2
113+
let handler_type (HandlerT ts) = list val_type ts
112114

113115
let str_type = function
114116
| DefStructT st -> struct_type st
115117
| DefArrayT at -> array_type at
116118
| DefFuncT ft -> func_type ft
117119
| DefContT ct -> cont_type ct
120+
| DefHandlerT ht -> handler_type ht
118121

119122
let sub_type = function
120123
| SubT (_fin, hts, st) -> list heap_type hts ++ str_type st
@@ -182,7 +185,9 @@ let rec instr (e : instr) =
182185
| ContBind (x, y) -> types (idx x) ++ types (idx y)
183186
| ResumeThrow (x, y, xys) -> types (idx x) ++ tags (idx y) ++ list (fun (x, y) -> tags (idx x) ++ hdl y) xys
184187
| Resume (x, xys) -> types (idx x) ++ list (fun (x, y) -> tags (idx x) ++ hdl y) xys
188+
| ResumeWith (x, xys) -> types (idx x) ++ list (fun (x, y) -> tags (idx x) ++ hdl y) xys
185189
| Suspend x -> tags (idx x)
190+
| SuspendTo (x, y) -> types (idx x) ++ tags (idx y)
186191
| Switch (x, z) -> types (idx x) ++ tags (idx z)
187192
| Throw x -> tags (idx x)
188193
| ThrowRef -> empty

interpreter/syntax/operators.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ let return_call_indirect x y = ReturnCallIndirect (x, y)
5252
let cont_new x = ContNew x
5353
let cont_bind x y = ContBind (x, y)
5454
let suspend x = Suspend x
55+
let suspend_to x y = SuspendTo (x, y)
5556
let resume x xys = Resume (x, xys)
5657
let resume_throw x y xys = ResumeThrow (x, y, xys)
58+
let resume_with x xys = ResumeWith (x, xys)
5759
let switch x y = Switch (x, y)
5860
let throw x = Throw x
5961
let throw_ref = ThrowRef

0 commit comments

Comments
 (0)