Skip to content

Commit e2c9df1

Browse files
committed
Use a try_table like instruction internally
1 parent 0d1cc4a commit e2c9df1

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
@@ -328,6 +328,16 @@ module Output () = struct
328328
| Br_on_cast_fail _
329329
| ExternExternalize _
330330
| ExternInternalize _ -> assert false (* Not supported *)
331+
| Try (ty, body, catches) ->
332+
Feature.require exception_handling;
333+
line (string "try" ^^ block_type ty)
334+
^^ indent (concat_map (instruction m) body)
335+
^^ concat_map
336+
(fun (tag, i, ty) ->
337+
line (string "catch " ^^ index tag)
338+
^^ indent (instruction m (Wa_ast.Br (i, Some (Pop ty)))))
339+
catches
340+
^^ line (string "end_try")
331341

332342
and instruction m i =
333343
match i with
@@ -378,19 +388,6 @@ module Output () = struct
378388
| CallInstr (x, l) -> concat_map (expression m) l ^^ line (string "call " ^^ index x)
379389
| Nop -> empty
380390
| Push e -> expression m e
381-
| Try (ty, body, catches, catch_all) ->
382-
Feature.require exception_handling;
383-
line (string "try" ^^ block_type ty)
384-
^^ indent (concat_map (instruction m) body)
385-
^^ concat_map
386-
(fun (tag, l) ->
387-
line (string "catch " ^^ index tag)
388-
^^ indent (concat_map (instruction m) l))
389-
catches
390-
^^ (match catch_all with
391-
| None -> empty
392-
| Some l -> line (string "catch_all") ^^ indent (concat_map (instruction m) l))
393-
^^ line (string "end_try")
394391
| Throw (i, e) ->
395392
Feature.require exception_handling;
396393
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
@@ -158,6 +158,7 @@ type expression =
158158
| Br_on_cast of int * ref_type * ref_type * expression
159159
| Br_on_cast_fail of int * ref_type * ref_type * expression
160160
| IfExpr of value_type * expression * expression * expression
161+
| Try of func_type * instruction list * (var * int * value_type) list
161162

162163
and instruction =
163164
| Drop of expression
@@ -175,11 +176,6 @@ and instruction =
175176
| CallInstr of var * expression list
176177
| Nop
177178
| Push of expression
178-
| Try of
179-
func_type
180-
* instruction list
181-
* (var * instruction list) list
182-
* instruction list option
183179
| Throw of var * expression
184180
| Rethrow of int
185181
| 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
@@ -441,7 +441,8 @@ let rec is_smi e =
441441
| ExternInternalize _
442442
| ExternExternalize _
443443
| Br_on_cast _
444-
| Br_on_cast_fail _ -> false
444+
| Br_on_cast_fail _
445+
| Try _ -> false
445446
| BinOp ((F32 _ | F64 _), _, _) | RefTest _ | RefEq _ -> true
446447
| IfExpr (_, _, ift, iff) -> is_smi ift && is_smi iff
447448

@@ -559,11 +560,9 @@ let if_ ty e l1 l2 =
559560
| W.UnOp (I32 Eqz, e') -> instr (If (ty, e', instrs2, instrs1))
560561
| _ -> instr (If (ty, e, instrs1, instrs2))
561562

562-
let try_ ty body handlers =
563+
let try_expr ty body handlers =
563564
let* body = blk body in
564-
let tags = List.map ~f:fst handlers in
565-
let* handler_bodies = expression_list blk (List.map ~f:snd handlers) in
566-
instr (Try (ty, body, List.combine tags handler_bodies, None))
565+
return (W.Try (ty, body, handlers))
567566

568567
let need_apply_fun ~cps ~arity st =
569568
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
@@ -110,7 +110,8 @@ val block_expr : Wa_ast.func_type -> unit t -> expression
110110

111111
val if_ : Wa_ast.func_type -> expression -> unit t -> unit t -> unit t
112112

113-
val try_ : Wa_ast.func_type -> unit t -> (Code.Var.t * unit t) list -> unit t
113+
val try_expr :
114+
Wa_ast.func_type -> unit t -> (Code.Var.t * int * Wa_ast.value_type) list -> expression
114115

115116
val add_var : ?typ:Wa_ast.value_type -> Wa_ast.var -> Wa_ast.var t
116117

compiler/lib/wasm/wa_core_target.ml

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

631631
let handle_exceptions ~result_typ ~fall_through ~context body x exn_handler =
632632
let* ocaml_tag = register_import ~name:"ocaml_exception" (Tag Value.value) in
633-
try_
633+
block
634634
{ params = []; result = result_typ }
635-
(body ~result_typ ~fall_through:(`Block (-1)) ~context)
636-
[ ( ocaml_tag
637-
, let* () = store ~always:true x (return (W.Pop Value.value)) in
638-
exn_handler ~result_typ ~fall_through ~context )
639-
]
635+
(let* () =
636+
store
637+
x
638+
(try_expr
639+
{ params = []; result = [ Value.value ] }
640+
(body ~result_typ ~fall_through:(`Block (-1)) ~context:(`Skip :: context))
641+
[ ocaml_tag, 0, Value.value ])
642+
in
643+
exn_handler ~result_typ ~fall_through ~context)
640644

641645
let post_process_function_body ~param_names:_ ~locals:_ instrs = instrs
642646

compiler/lib/wasm/wa_gc_target.ml

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,8 @@ module Value = struct
514514
| Pop _
515515
| Call_ref _
516516
| Br_on_cast _
517-
| Br_on_cast_fail _ -> false
517+
| Br_on_cast_fail _
518+
| Try _ -> false
518519
| IfExpr (_, e1, e2, e3) -> effect_free e1 && effect_free e2 && effect_free e3
519520
| ArrayNewFixed (_, l) | StructNew (_, l) -> List.for_all ~f:effect_free l
520521

@@ -1682,16 +1683,20 @@ let handle_exceptions ~result_typ ~fall_through ~context body x exn_handler =
16821683
block
16831684
{ params = []; result = result_typ }
16841685
(let* () =
1685-
try_
1686-
{ params = []; result = [] }
1687-
(body ~result_typ:[] ~fall_through:(`Block (-1)) ~context:(`Skip :: context))
1688-
[ ocaml_tag, store ~always:true x (return (W.Pop Value.value))
1689-
; ( js_tag
1690-
, let exn = Code.Var.fresh () in
1691-
let* () = store ~always:true ~typ:externref exn (return (W.Pop externref)) in
1692-
let* exn = load exn in
1693-
store ~always:true x (return (W.Call (f, [ exn ]))) )
1694-
]
1686+
store
1687+
x
1688+
(block_expr
1689+
{ params = []; result = [ Value.value ] }
1690+
(let* exn =
1691+
try_expr
1692+
{ params = []; result = [ externref ] }
1693+
(body
1694+
~result_typ:[ externref ]
1695+
~fall_through:(`Block (-1))
1696+
~context:(`Skip :: `Skip :: context))
1697+
[ ocaml_tag, 1, Value.value; js_tag, 0, externref ]
1698+
in
1699+
instr (W.CallInstr (f, [ exn ]))))
16951700
in
16961701
exn_handler ~result_typ ~fall_through ~context)
16971702

compiler/lib/wasm/wa_initialize_locals.ml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ let rec scan_expression ctx e =
5555
scan_expression ctx cond;
5656
scan_expression (fork_context ctx) e1;
5757
scan_expression (fork_context ctx) e2
58+
| Try (_, body, _) -> scan_instructions ctx body
5859

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

@@ -79,10 +80,6 @@ and scan_instruction ctx i =
7980
scan_expression ctx e;
8081
scan_instructions ctx l;
8182
scan_instructions ctx l'
82-
| Try (_, body, catches, catch_all) ->
83-
scan_instructions ctx body;
84-
List.iter ~f:(fun (_, l) -> scan_instructions ctx l) catches;
85-
Option.iter ~f:(fun l -> scan_instructions ctx l) catch_all
8683
| CallInstr (_, l) | Return_call (_, l) -> scan_expressions ctx l
8784
| Br (_, None) | Return None | Rethrow _ | Nop -> ()
8885
| 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
@@ -23,12 +23,6 @@ let rec instruction ~tail i =
2323
| Wa_ast.Loop (ty, l) -> Wa_ast.Loop (ty, instructions ~tail l)
2424
| Block (ty, l) -> Block (ty, instructions ~tail l)
2525
| If (ty, e, l1, l2) -> If (ty, e, instructions ~tail l1, instructions ~tail l2)
26-
| Try (ty, l, catches, catch_all) ->
27-
Try
28-
( ty
29-
, l
30-
, List.map ~f:(fun (tag, l) -> tag, instructions ~tail l) catches
31-
, Option.map ~f:(fun l -> instructions ~tail l) catch_all )
3226
| Return (Some (Call (symb, l))) -> Return_call (symb, l)
3327
| Return (Some (Call_indirect (ty, e, l))) -> Return_call_indirect (ty, e, l)
3428
| 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
@@ -460,6 +460,19 @@ let expression_or_instructions ctx st in_function =
460460
@ [ List (Atom "then" :: expression ift) ]
461461
@ [ List (Atom "else" :: expression iff) ])
462462
]
463+
| Try (ty, body, catches) ->
464+
[ List
465+
(Atom "try"
466+
:: (block_type st ty
467+
@ List (Atom "do" :: instructions body)
468+
:: List.map
469+
~f:(fun (tag, i, ty) ->
470+
List
471+
(Atom "catch"
472+
:: index st.tag_names tag
473+
:: instruction (Wa_ast.Br (i, Some (Pop ty)))))
474+
catches))
475+
]
463476
and instruction i =
464477
match i with
465478
| Drop e -> [ List (Atom "drop" :: expression e) ]
@@ -493,20 +506,6 @@ let expression_or_instructions ctx st in_function =
493506
@ list ~always:true "then" instructions (remove_nops l1)
494507
@ list "else" instructions (remove_nops l2)))
495508
]
496-
| Try (ty, body, catches, catch_all) ->
497-
[ List
498-
(Atom "try"
499-
:: (block_type st ty
500-
@ List (Atom "do" :: instructions body)
501-
:: (List.map
502-
~f:(fun (tag, l) ->
503-
List (Atom "catch" :: index st.tag_names tag :: instructions l))
504-
catches
505-
@
506-
match catch_all with
507-
| None -> []
508-
| Some l -> [ List (Atom "catch_all" :: instructions l) ])))
509-
]
510509
| Br_table (e, l, i) ->
511510
[ List
512511
(Atom "br_table"

0 commit comments

Comments
 (0)