@@ -24,30 +24,46 @@ let get_return ~tail i =
2424 | Push (LocalGet y ) when tail -> Some y
2525 | _ -> None
2626
27- let rewrite_tail_call ~no_tail_call ~y i =
27+ let rewrite_tail_call ~return_exn ~ no_tail_call ~y i =
2828 match i with
2929 | Wasm_ast. LocalSet (x, Call (symb, l))
3030 when Code.Var. equal x y && not (Code.Var.Hashtbl. mem no_tail_call symb) ->
3131 Some (Wasm_ast. Return_call (symb, l))
3232 | LocalSet (x , Call_ref (ty , e , l )) when Code.Var. equal x y ->
3333 Some (Return_call_ref (ty, e, l))
34+ | LocalSet (x , Br_on_null (_ , Call (symb , l ))) when return_exn && Code.Var. equal x y ->
35+ Some (Wasm_ast. Return_call (symb, l))
36+ | LocalSet (x, Br_on_null (_, Call_ref (ty, e, l)))
37+ when return_exn && Code.Var. equal x y -> Some (Return_call_ref (ty, e, l))
3438 | _ -> None
3539
36- let rec instruction ~no_tail_call ~tail i =
40+ let rec instruction ~return_exn ~ no_tail_call ~tail i =
3741 match i with
38- | Wasm_ast. Loop (ty , l ) -> Wasm_ast. Loop (ty, instructions ~no_tail_call ~tail l)
39- | Block (ty , l ) -> Block (ty, instructions ~no_tail_call ~tail l)
42+ | Wasm_ast. Loop (ty , l ) ->
43+ Wasm_ast. Loop (ty, instructions ~return_exn ~no_tail_call ~tail l)
44+ | Block (ty , l ) -> Block (ty, instructions ~return_exn ~no_tail_call ~tail l)
4045 | If (ty , e , l1 , l2 ) ->
41- If (ty, e, instructions ~no_tail_call ~tail l1, instructions ~no_tail_call ~tail l2)
46+ If
47+ ( ty
48+ , e
49+ , instructions ~return_exn ~no_tail_call ~tail l1
50+ , instructions ~return_exn ~no_tail_call ~tail l2 )
4251 | Return (Some (Call (symb , l ))) when not (Code.Var.Hashtbl. mem no_tail_call symb) ->
4352 Return_call (symb, l)
4453 | Return (Some (Call_ref (ty , e , l ))) -> Return_call_ref (ty, e, l)
4554 | Push (Call (symb , l )) when tail && not (Code.Var.Hashtbl. mem no_tail_call symb) ->
4655 Return_call (symb, l)
4756 | Push (Call_ref (ty , e , l )) when tail -> Return_call_ref (ty, e, l)
4857 | Push (Call_ref _ ) -> i
58+ | Return (Some (Br_on_null (_ , Call (symb , l )))) when return_exn -> Return_call (symb, l)
59+ | Return (Some (Br_on_null (_ , Call_ref (ty , e , l )))) when return_exn ->
60+ Return_call_ref (ty, e, l)
61+ | Push (Br_on_null (_ , Call (symb , l ))) when return_exn && tail -> Return_call (symb, l)
62+ | Push (Br_on_null (_ , Call_ref (ty , e , l ))) when return_exn && tail ->
63+ Return_call_ref (ty, e, l)
64+ | Push (Br_on_null (_ , Call_ref _ )) when return_exn -> i
4965 | Drop (BlockExpr (typ , l )) ->
50- Drop (BlockExpr (typ, instructions ~no_tail_call ~tail: false l))
66+ Drop (BlockExpr (typ, instructions ~return_exn ~ no_tail_call ~tail: false l))
5167 | Drop _
5268 | LocalSet _
5369 | GlobalSet _
@@ -67,28 +83,29 @@ let rec instruction ~no_tail_call ~tail i =
6783 | Unreachable
6884 | Event _ -> i
6985
70- and instructions ~no_tail_call ~tail l =
86+ and instructions ~return_exn ~ no_tail_call ~tail l =
7187 match l with
7288 | [] -> []
73- | [ i ] -> [ instruction ~no_tail_call ~tail i ]
74- | i :: Nop :: rem -> instructions ~no_tail_call ~tail (i :: rem)
75- | i :: i' :: Nop :: rem -> instructions ~no_tail_call ~tail (i :: i' :: rem)
89+ | [ i ] -> [ instruction ~return_exn ~ no_tail_call ~tail i ]
90+ | i :: Nop :: rem -> instructions ~return_exn ~ no_tail_call ~tail (i :: rem)
91+ | i :: i' :: Nop :: rem -> instructions ~return_exn ~ no_tail_call ~tail (i :: i' :: rem)
7692 | i :: i' :: (([] | [ Event _ ]) as event_opt ) -> (
7793 (* There can be an event at the end of the function, which we
7894 should keep. *)
7995 match get_return ~tail i' with
8096 | None ->
81- instruction ~no_tail_call ~tail: false i
82- :: instruction ~no_tail_call ~tail i'
97+ instruction ~return_exn ~ no_tail_call ~tail: false i
98+ :: instruction ~return_exn ~ no_tail_call ~tail i'
8399 :: event_opt
84100 | Some y -> (
85- match rewrite_tail_call ~no_tail_call ~y i with
101+ match rewrite_tail_call ~return_exn ~ no_tail_call ~y i with
86102 | None ->
87- instruction ~no_tail_call ~tail: false i
88- :: instruction ~no_tail_call ~tail i'
103+ instruction ~return_exn ~ no_tail_call ~tail: false i
104+ :: instruction ~return_exn ~ no_tail_call ~tail i'
89105 :: event_opt
90106 | Some i'' -> i'' :: event_opt))
91107 | i :: rem ->
92- instruction ~no_tail_call ~tail: false i :: instructions ~no_tail_call ~tail rem
108+ instruction ~return_exn ~no_tail_call ~tail: false i
109+ :: instructions ~return_exn ~no_tail_call ~tail rem
93110
94- let f ~no_tail_call l = instructions ~no_tail_call ~tail: true l
111+ let f ~return_exn ~ no_tail_call l = instructions ~return_exn ~no_tail_call ~tail: true l
0 commit comments