Skip to content

Commit a3e80ab

Browse files
committed
Use a try_table like instruction internally
1 parent 7d9119a commit a3e80ab

File tree

10 files changed

+70
-96
lines changed

10 files changed

+70
-96
lines changed

compiler/lib/wasm/wa_ast.ml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ type expression =
165165
| Br_on_cast of int * ref_type * ref_type * expression
166166
| Br_on_cast_fail of int * ref_type * ref_type * expression
167167
| IfExpr of value_type * expression * expression * expression
168+
| Try of func_type * instruction list * (var * int * value_type) list
168169

169170
and instruction =
170171
| Drop of expression
@@ -180,11 +181,6 @@ and instruction =
180181
| CallInstr of var * expression list
181182
| Nop
182183
| Push of expression
183-
| Try of
184-
func_type
185-
* instruction list
186-
* (var * instruction list) list
187-
* instruction list option
188184
| Throw of var * expression
189185
| Rethrow of int
190186
| 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
@@ -452,7 +452,8 @@ let rec is_smi e =
452452
| RefCast _
453453
| RefNull _
454454
| Br_on_cast _
455-
| Br_on_cast_fail _ -> false
455+
| Br_on_cast_fail _
456+
| Try _ -> false
456457
| BinOp ((F32 _ | F64 _), _, _) | RefTest _ | RefEq _ -> true
457458
| IfExpr (_, _, ift, iff) -> is_smi ift && is_smi iff
458459

@@ -575,11 +576,9 @@ let if_ ty e l1 l2 =
575576
| W.UnOp (I32 Eqz, e') -> instr (If (ty, e', instrs2, instrs1))
576577
| _ -> instr (If (ty, e, instrs1, instrs2))
577578

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

584583
let need_apply_fun ~cps ~arity st =
585584
let ctx = st.context in

compiler/lib/wasm/wa_code_generation.mli

Lines changed: 4 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

@@ -142,6 +143,8 @@ val event : Parse_info.t -> unit t
142143

143144
val no_event : unit t
144145

146+
val hidden_location : Parse_info.t
147+
145148
type type_def =
146149
{ supertype : Wa_ast.var option
147150
; final : bool

compiler/lib/wasm/wa_gc_target.ml

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,8 @@ module Value = struct
526526
| Pop _
527527
| Call_ref _
528528
| Br_on_cast _
529-
| Br_on_cast_fail _ -> false
529+
| Br_on_cast_fail _
530+
| Try _ -> false
530531
| IfExpr (_, e1, e2, e3) -> effect_free e1 && effect_free e2 && effect_free e3
531532
| ArrayNewFixed (_, l) | StructNew (_, l) -> List.for_all ~f:effect_free l
532533

@@ -1676,19 +1677,25 @@ let handle_exceptions ~result_typ ~fall_through ~context body x exn_handler =
16761677
block
16771678
{ params = []; result = result_typ }
16781679
(let* () =
1679-
try_
1680-
{ params = []; result = [] }
1681-
(body ~result_typ:[] ~fall_through:(`Catch x) ~context:(`Catch x :: context))
1682-
[ ( ocaml_tag
1683-
, let* () = no_event in
1684-
store ~always:true x (return (W.Pop Value.value)) )
1685-
; ( js_tag
1686-
, let* () = no_event in
1687-
let exn = Code.Var.fresh () in
1688-
let* () = store ~always:true ~typ:externref exn (return (W.Pop externref)) in
1689-
let* exn = load exn in
1690-
store ~always:true x (return (W.Call (f, [ exn ]))) )
1691-
]
1680+
store
1681+
x
1682+
(block_expr
1683+
{ params = []; result = [ Value.value ] }
1684+
(let* exn =
1685+
block_expr
1686+
{ params = []; result = [ externref ] }
1687+
(let* e =
1688+
try_expr
1689+
{ params = []; result = [ externref ] }
1690+
(body
1691+
~result_typ:[ externref ]
1692+
~fall_through:`Skip
1693+
~context:(`Skip :: `Skip :: `Catch :: context))
1694+
[ ocaml_tag, 1, Value.value; js_tag, 0, externref ]
1695+
in
1696+
instr (W.Push e))
1697+
in
1698+
instr (W.CallInstr (f, [ exn ]))))
16921699
in
16931700
let* () = no_event in
16941701
exn_handler ~result_typ ~fall_through ~context)

compiler/lib/wasm/wa_generate.ml

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,15 @@ module Generate (Target : Wa_target_sig.S) = struct
160160
let rec index_rec context pc i =
161161
match context with
162162
| `Block pc' :: _ when pc = pc' -> i
163-
| (`Block _ | `Skip | `Catch _) :: rem -> index_rec rem pc (i + 1)
163+
| (`Block _ | `Skip | `Catch) :: rem -> index_rec rem pc (i + 1)
164164
| [] -> assert false
165165
in
166166
index_rec context pc 0
167167

168168
let catch_index context =
169169
let rec index_rec context i =
170170
match context with
171-
| `Catch x :: _ -> Some (x, i)
171+
| `Catch :: _ -> Some i
172172
| (`Block _ | `Skip | `Return) :: rem -> index_rec rem (i + 1)
173173
| [] -> None
174174
in
@@ -759,7 +759,7 @@ module Generate (Target : Wa_target_sig.S) = struct
759759

760760
let extend_context fall_through context =
761761
match fall_through with
762-
| (`Block _ | `Catch _) as b -> b :: context
762+
| (`Block _ | `Catch | `Skip) as b -> b :: context
763763
| `Return -> `Skip :: context
764764

765765
let needed_handlers (p : program) pc =
@@ -911,7 +911,7 @@ module Generate (Target : Wa_target_sig.S) = struct
911911
let* e = load x in
912912
match fall_through with
913913
| `Return -> instr (Push e)
914-
| `Block _ | `Catch _ -> instr (Return (Some e)))
914+
| `Block _ | `Catch | `Skip -> instr (Return (Some e)))
915915
| Cond (x, cont1, cont2) ->
916916
let context' = extend_context fall_through context in
917917
if_
@@ -923,7 +923,7 @@ module Generate (Target : Wa_target_sig.S) = struct
923923
let* e = Value.unit in
924924
match fall_through with
925925
| `Return -> instr (Push e)
926-
| `Block _ | `Catch _ -> instr (Return (Some e)))
926+
| `Block _ | `Catch | `Skip -> instr (Return (Some e)))
927927
| Switch (x, a) ->
928928
let len = Array.length a in
929929
let l = Array.to_list (Array.sub a ~pos:0 ~len:(len - 1)) in
@@ -937,12 +937,10 @@ module Generate (Target : Wa_target_sig.S) = struct
937937
let* e = load x in
938938
let* tag = register_import ~name:exception_name (Tag Value.value) in
939939
match fall_through with
940-
| `Catch x -> store ~always:true x (return e)
941-
| `Block _ | `Return -> (
940+
| `Catch -> instr (Push e)
941+
| `Block _ | `Return | `Skip -> (
942942
match catch_index context with
943-
| Some (x, i) ->
944-
let* () = store ~always:true x (return e) in
945-
instr (Br (i, None))
943+
| Some i -> instr (Br (i, Some e))
946944
| None -> instr (Throw (tag, e))))
947945
| Pushtrap (cont, x, cont') ->
948946
handle_exceptions

compiler/lib/wasm/wa_initialize_locals.ml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ let rec scan_expression ctx e =
6868
scan_expression ctx cond;
6969
scan_expression (fork_context ctx) e1;
7070
scan_expression (fork_context ctx) e2
71+
| Try (_, body, _) -> scan_instructions ctx body
7172

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

@@ -92,10 +93,6 @@ and scan_instruction ctx i =
9293
scan_expression ctx e;
9394
scan_instructions ctx l;
9495
scan_instructions ctx l'
95-
| Try (_, body, catches, catch_all) ->
96-
scan_instructions ctx body;
97-
List.iter ~f:(fun (_, l) -> scan_instructions ctx l) catches;
98-
Option.iter ~f:(fun l -> scan_instructions ctx l) catch_all
9996
| CallInstr (_, l) | Return_call (_, l) -> scan_expressions ctx l
10097
| Br (_, None) | Return None | Rethrow _ | Nop | Event _ -> ()
10198
| 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
@@ -37,12 +37,6 @@ let rec instruction ~tail i =
3737
| Wa_ast.Loop (ty, l) -> Wa_ast.Loop (ty, instructions ~tail l)
3838
| Block (ty, l) -> Block (ty, instructions ~tail l)
3939
| If (ty, e, l1, l2) -> If (ty, e, instructions ~tail l1, instructions ~tail l2)
40-
| Try (ty, l, catches, catch_all) ->
41-
Try
42-
( ty
43-
, l
44-
, List.map ~f:(fun (tag, l) -> tag, instructions ~tail l) catches
45-
, Option.map ~f:(fun l -> instructions ~tail l) catch_all )
4640
| Return (Some (Call (symb, l))) -> Return_call (symb, l)
4741
| Return (Some (Call_ref (ty, e, l))) -> Return_call_ref (ty, e, l)
4842
| Push (Call (symb, l)) when tail -> Return_call (symb, l)

compiler/lib/wasm/wa_target_sig.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,9 @@ module type S = sig
252252
val handle_exceptions :
253253
result_typ:Wa_ast.value_type list
254254
-> fall_through:'a
255-
-> context:([> `Catch of Code.Var.t ] as 'b) list
255+
-> context:([> `Catch | `Skip ] as 'b) list
256256
-> ( result_typ:Wa_ast.value_type list
257-
-> fall_through:[> `Catch of Code.Var.t ]
257+
-> fall_through:[> `Skip ]
258258
-> context:'b list
259259
-> unit Wa_code_generation.t)
260260
-> Wa_ast.var

compiler/lib/wasm/wa_wasm_output.ml

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,18 @@ end = struct
628628
output_byte ch 0x05;
629629
output_expression st ch e3;
630630
output_byte ch 0x0B
631+
| Try (typ, l, catches) ->
632+
Feature.require exception_handling;
633+
output_byte ch 0x06;
634+
output_blocktype st.type_names ch typ;
635+
List.iter ~f:(fun i' -> output_instruction st ch i') l;
636+
List.iter
637+
~f:(fun (tag, l, ty) ->
638+
output_byte ch 0x07;
639+
output_uint ch (Hashtbl.find st.tag_names tag);
640+
output_instruction st ch (Br (l + 1, Some (Pop ty))))
641+
catches;
642+
output_byte ch 0X0B
631643

632644
and output_instruction st ch i =
633645
match i with
@@ -688,23 +700,6 @@ end = struct
688700
output_uint ch (Hashtbl.find st.func_names f)
689701
| Nop -> ()
690702
| Push e -> output_expression st ch e
691-
| Try (typ, l, catches, catchall) ->
692-
Feature.require exception_handling;
693-
output_byte ch 0x06;
694-
output_blocktype st.type_names ch typ;
695-
List.iter ~f:(fun i' -> output_instruction st ch i') l;
696-
List.iter
697-
~f:(fun (tag, l) ->
698-
output_byte ch 0x07;
699-
output_uint ch (Hashtbl.find st.tag_names tag);
700-
List.iter ~f:(fun i' -> output_instruction st ch i') l)
701-
catches;
702-
(match catchall with
703-
| Some l ->
704-
output_byte ch 0x05;
705-
List.iter ~f:(fun i' -> output_instruction st ch i') l
706-
| None -> ());
707-
output_byte ch 0X0B
708703
| Throw (tag, e) ->
709704
Feature.require exception_handling;
710705
output_expression st ch e;
@@ -881,6 +876,8 @@ end = struct
881876
~f:(fun set i -> expr_function_references i set)
882877
~init:(expr_function_references e' set)
883878
l
879+
| Try (_, l, _) ->
880+
List.fold_left ~f:(fun set i -> instr_function_references i set) ~init:set l
884881

885882
and instr_function_references i set =
886883
match i with
@@ -905,24 +902,6 @@ end = struct
905902
| Br (_, None) | Return None | Nop | Rethrow _ -> set
906903
| CallInstr (_, l) ->
907904
List.fold_left ~f:(fun set i -> expr_function_references i set) ~init:set l
908-
| Try (_, l, catches, catchall) ->
909-
List.fold_left ~f:(fun set i -> instr_function_references i set) ~init:set l
910-
|> (fun init ->
911-
List.fold_left
912-
~f:(fun set (_, l) ->
913-
List.fold_left
914-
~f:(fun set i -> instr_function_references i set)
915-
~init:set
916-
l)
917-
~init
918-
catches)
919-
|> fun init ->
920-
List.fold_left
921-
~f:(fun set i -> instr_function_references i set)
922-
~init
923-
(match catchall with
924-
| Some l -> l
925-
| None -> [])
926905
| ArraySet (_, e1, e2, e3) ->
927906
set
928907
|> expr_function_references e1

compiler/lib/wasm/wa_wat_output.ml

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,21 @@ let expression_or_instructions ctx st in_function =
442442
@ [ List (Atom "then" :: expression ift) ]
443443
@ [ List (Atom "else" :: expression iff) ])
444444
]
445+
| Try (ty, body, catches) ->
446+
[ List
447+
(Atom "try"
448+
:: (block_type st ty
449+
@ List (Atom "do" :: instructions body)
450+
:: List.map
451+
~f:(fun (tag, i, ty) ->
452+
List
453+
(Atom "catch"
454+
:: index st.tag_names tag
455+
:: (instruction
456+
(Wa_ast.Event Wa_code_generation.hidden_location)
457+
@ instruction (Wa_ast.Br (i + 1, Some (Pop ty))))))
458+
catches))
459+
]
445460
and instruction i =
446461
match i with
447462
| Drop e -> [ List (Atom "drop" :: expression e) ]
@@ -460,20 +475,6 @@ let expression_or_instructions ctx st in_function =
460475
@ list ~always:true "then" instructions (remove_nops l1)
461476
@ list "else" instructions (remove_nops l2)))
462477
]
463-
| Try (ty, body, catches, catch_all) ->
464-
[ List
465-
(Atom "try"
466-
:: (block_type st ty
467-
@ List (Atom "do" :: instructions body)
468-
:: (List.map
469-
~f:(fun (tag, l) ->
470-
List (Atom "catch" :: index st.tag_names tag :: instructions l))
471-
catches
472-
@
473-
match catch_all with
474-
| None -> []
475-
| Some l -> [ List (Atom "catch_all" :: instructions l) ])))
476-
]
477478
| Br_table (e, l, i) ->
478479
[ List
479480
(Atom "br_table"

0 commit comments

Comments
 (0)