Skip to content

Commit 35cc298

Browse files
committed
Use a try_table like instruction internally
1 parent 57185d7 commit 35cc298

File tree

9 files changed

+57
-65
lines changed

9 files changed

+57
-65
lines changed

compiler/lib/wasm/wa_asm_output.ml

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,16 @@ module Output () = struct
346346
| Br_on_cast_fail _
347347
| ExternExternalize _
348348
| ExternInternalize _ -> assert false (* Not supported *)
349+
| Try (ty, body, catches) ->
350+
Feature.require exception_handling;
351+
line (string "try" ^^ block_type ty)
352+
^^ indent (concat_map (instruction m) body)
353+
^^ concat_map
354+
(fun (tag, i, ty) ->
355+
line (string "catch " ^^ index tag)
356+
^^ indent (instruction m (Wa_ast.Br (i, Some (Pop ty)))))
357+
catches
358+
^^ line (string "end_try")
349359

350360
and instruction m i =
351361
match i with
@@ -396,19 +406,6 @@ module Output () = struct
396406
| CallInstr (x, l) -> concat_map (expression m) l ^^ line (string "call " ^^ index x)
397407
| Nop -> empty
398408
| Push e -> expression m e
399-
| Try (ty, body, catches, catch_all) ->
400-
Feature.require exception_handling;
401-
line (string "try" ^^ block_type ty)
402-
^^ indent (concat_map (instruction m) body)
403-
^^ concat_map
404-
(fun (tag, l) ->
405-
line (string "catch " ^^ index tag)
406-
^^ indent (concat_map (instruction m) l))
407-
catches
408-
^^ (match catch_all with
409-
| None -> empty
410-
| Some l -> line (string "catch_all") ^^ indent (concat_map (instruction m) l))
411-
^^ line (string "end_try")
412409
| Throw (i, e) ->
413410
Feature.require exception_handling;
414411
expression m e ^^ line (string "throw " ^^ index i)

compiler/lib/wasm/wa_ast.ml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ type expression =
176176
| Br_on_cast of int * ref_type * ref_type * expression
177177
| Br_on_cast_fail of int * ref_type * ref_type * expression
178178
| IfExpr of value_type * expression * expression * expression
179+
| Try of func_type * instruction list * (var * int * value_type) list
179180

180181
and instruction =
181182
| Drop of expression
@@ -193,11 +194,6 @@ and instruction =
193194
| CallInstr of var * expression list
194195
| Nop
195196
| Push of expression
196-
| Try of
197-
func_type
198-
* instruction list
199-
* (var * instruction list) list
200-
* instruction list option
201197
| Throw of var * expression
202198
| Rethrow of int
203199
| ArraySet of var * expression * expression * expression

compiler/lib/wasm/wa_code_generation.ml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,8 @@ let rec is_smi e =
459459
| ExternInternalize _
460460
| ExternExternalize _
461461
| Br_on_cast _
462-
| Br_on_cast_fail _ -> false
462+
| Br_on_cast_fail _
463+
| Try _ -> false
463464
| BinOp ((F32 _ | F64 _), _, _) | RefTest _ | RefEq _ -> true
464465
| IfExpr (_, _, ift, iff) -> is_smi ift && is_smi iff
465466

@@ -577,11 +578,9 @@ let if_ ty e l1 l2 =
577578
| W.UnOp (I32 Eqz, e') -> instr (If (ty, e', instrs2, instrs1))
578579
| _ -> instr (If (ty, e, instrs1, instrs2))
579580

580-
let try_ ty body handlers =
581+
let try_expr ty body handlers =
581582
let* body = blk body in
582-
let tags = List.map ~f:fst handlers in
583-
let* handler_bodies = expression_list blk (List.map ~f:snd handlers) in
584-
instr (Try (ty, body, List.combine tags handler_bodies, None))
583+
return (W.Try (ty, body, handlers))
585584

586585
let need_apply_fun ~cps ~arity st =
587586
let ctx = st.context in

compiler/lib/wasm/wa_code_generation.mli

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ val block_expr : Wa_ast.func_type -> unit t -> expression
128128

129129
val if_ : Wa_ast.func_type -> expression -> unit t -> unit t -> unit t
130130

131-
val try_ : Wa_ast.func_type -> unit t -> (Code.Var.t * unit t) list -> unit t
131+
val try_expr :
132+
Wa_ast.func_type -> unit t -> (Code.Var.t * int * Wa_ast.value_type) list -> expression
132133

133134
val add_var : ?typ:Wa_ast.value_type -> Wa_ast.var -> Wa_ast.var t
134135

compiler/lib/wasm/wa_core_target.ml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -648,13 +648,17 @@ let internal_primitives = Hashtbl.create 0
648648

649649
let handle_exceptions ~result_typ ~fall_through ~context body x exn_handler =
650650
let* ocaml_tag = register_import ~name:"ocaml_exception" (Tag Value.value) in
651-
try_
651+
block
652652
{ params = []; result = result_typ }
653-
(body ~result_typ ~fall_through:(`Block (-1)) ~context)
654-
[ ( ocaml_tag
655-
, let* () = store ~always:true x (return (W.Pop Value.value)) in
656-
exn_handler ~result_typ ~fall_through ~context )
657-
]
653+
(let* () =
654+
store
655+
x
656+
(try_expr
657+
{ params = []; result = [ Value.value ] }
658+
(body ~result_typ ~fall_through:(`Block (-1)) ~context:(`Skip :: context))
659+
[ ocaml_tag, 0, Value.value ])
660+
in
661+
exn_handler ~result_typ ~fall_through ~context)
658662

659663
let post_process_function_body ~param_names:_ ~locals:_ instrs = instrs
660664

compiler/lib/wasm/wa_gc_target.ml

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,8 @@ module Value = struct
532532
| Pop _
533533
| Call_ref _
534534
| Br_on_cast _
535-
| Br_on_cast_fail _ -> false
535+
| Br_on_cast_fail _
536+
| Try _ -> false
536537
| IfExpr (_, e1, e2, e3) -> effect_free e1 && effect_free e2 && effect_free e3
537538
| ArrayNewFixed (_, l) | StructNew (_, l) -> List.for_all ~f:effect_free l
538539

@@ -1702,16 +1703,20 @@ let handle_exceptions ~result_typ ~fall_through ~context body x exn_handler =
17021703
block
17031704
{ params = []; result = result_typ }
17041705
(let* () =
1705-
try_
1706-
{ params = []; result = [] }
1707-
(body ~result_typ:[] ~fall_through:(`Block (-1)) ~context:(`Skip :: context))
1708-
[ ocaml_tag, store ~always:true x (return (W.Pop Value.value))
1709-
; ( js_tag
1710-
, let exn = Code.Var.fresh () in
1711-
let* () = store ~always:true ~typ:externref exn (return (W.Pop externref)) in
1712-
let* exn = load exn in
1713-
store ~always:true x (return (W.Call (f, [ exn ]))) )
1714-
]
1706+
store
1707+
x
1708+
(block_expr
1709+
{ params = []; result = [ Value.value ] }
1710+
(let* exn =
1711+
try_expr
1712+
{ params = []; result = [ externref ] }
1713+
(body
1714+
~result_typ:[ externref ]
1715+
~fall_through:(`Block (-1))
1716+
~context:(`Skip :: `Skip :: context))
1717+
[ ocaml_tag, 1, Value.value; js_tag, 0, externref ]
1718+
in
1719+
instr (W.CallInstr (f, [ exn ]))))
17151720
in
17161721
exn_handler ~result_typ ~fall_through ~context)
17171722

compiler/lib/wasm/wa_initialize_locals.ml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ let rec scan_expression ctx e =
7373
scan_expression ctx cond;
7474
scan_expression (fork_context ctx) e1;
7575
scan_expression (fork_context ctx) e2
76+
| Try (_, body, _) -> scan_instructions ctx body
7677

7778
and scan_expressions ctx l = List.iter ~f:(fun e -> scan_expression ctx e) l
7879

@@ -97,10 +98,6 @@ and scan_instruction ctx i =
9798
scan_expression ctx e;
9899
scan_instructions ctx l;
99100
scan_instructions ctx l'
100-
| Try (_, body, catches, catch_all) ->
101-
scan_instructions ctx body;
102-
List.iter ~f:(fun (_, l) -> scan_instructions ctx l) catches;
103-
Option.iter ~f:(fun l -> scan_instructions ctx l) catch_all
104101
| CallInstr (_, l) | Return_call (_, l) -> scan_expressions ctx l
105102
| Br (_, None) | Return None | Rethrow _ | Nop -> ()
106103
| ArraySet (_, e, e', e'') ->

compiler/lib/wasm/wa_tail_call.ml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,6 @@ let rec instruction ~tail i =
4141
| Wa_ast.Loop (ty, l) -> Wa_ast.Loop (ty, instructions ~tail l)
4242
| Block (ty, l) -> Block (ty, instructions ~tail l)
4343
| If (ty, e, l1, l2) -> If (ty, e, instructions ~tail l1, instructions ~tail l2)
44-
| Try (ty, l, catches, catch_all) ->
45-
Try
46-
( ty
47-
, l
48-
, List.map ~f:(fun (tag, l) -> tag, instructions ~tail l) catches
49-
, Option.map ~f:(fun l -> instructions ~tail l) catch_all )
5044
| Return (Some (Call (symb, l))) -> Return_call (symb, l)
5145
| Return (Some (Call_indirect (ty, e, l))) -> Return_call_indirect (ty, e, l)
5246
| Return (Some (Call_ref (ty, e, l))) -> Return_call_ref (ty, e, l)

compiler/lib/wasm/wa_wat_output.ml

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,19 @@ let expression_or_instructions ctx st in_function =
478478
@ [ List (Atom "then" :: expression ift) ]
479479
@ [ List (Atom "else" :: expression iff) ])
480480
]
481+
| Try (ty, body, catches) ->
482+
[ List
483+
(Atom "try"
484+
:: (block_type st ty
485+
@ List (Atom "do" :: instructions body)
486+
:: List.map
487+
~f:(fun (tag, i, ty) ->
488+
List
489+
(Atom "catch"
490+
:: index st.tag_names tag
491+
:: instruction (Wa_ast.Br (i, Some (Pop ty)))))
492+
catches))
493+
]
481494
and instruction i =
482495
match i with
483496
| Drop e -> [ List (Atom "drop" :: expression e) ]
@@ -511,20 +524,6 @@ let expression_or_instructions ctx st in_function =
511524
@ list ~always:true "then" instructions (remove_nops l1)
512525
@ list "else" instructions (remove_nops l2)))
513526
]
514-
| Try (ty, body, catches, catch_all) ->
515-
[ List
516-
(Atom "try"
517-
:: (block_type st ty
518-
@ List (Atom "do" :: instructions body)
519-
:: (List.map
520-
~f:(fun (tag, l) ->
521-
List (Atom "catch" :: index st.tag_names tag :: instructions l))
522-
catches
523-
@
524-
match catch_all with
525-
| None -> []
526-
| Some l -> [ List (Atom "catch_all" :: instructions l) ])))
527-
]
528527
| Br_table (e, l, i) ->
529528
[ List
530529
(Atom "br_table"

0 commit comments

Comments
 (0)