@@ -604,6 +604,8 @@ module Generate (Target : Target_sig.S) = struct
604
604
in
605
605
Memory. allocate ~tag: 0 ~deadcode_sentinal: ctx.deadcode_sentinal l)
606
606
607
+ let exception_handler_pc = - 3
608
+
607
609
let rec translate_expr ctx context x e =
608
610
match e with
609
611
| Apply { f; args; exact }
@@ -621,17 +623,21 @@ module Generate (Target : Target_sig.S) = struct
621
623
(load funct)
622
624
in
623
625
let * b = is_closure f in
626
+ let label = label_index context exception_handler_pc in
624
627
if b
625
- then return (W. Call (f, List. rev (closure :: acc)))
628
+ then return (W. Br_on_null (label, W. Call (f, List. rev (closure :: acc) )))
626
629
else
627
630
match funct with
628
631
| W. RefFunc g ->
629
632
(* Functions with constant closures ignore their
630
633
environment. In case of partial application, we
631
634
still need the closure. *)
632
635
let * cl = if exact then Value. unit else return closure in
633
- return (W. Call (g, List. rev (cl :: acc)))
634
- | _ -> return (W. Call_ref (ty, funct, List. rev (closure :: acc))))
636
+ return (W. Br_on_null (label, W. Call (g, List. rev (cl :: acc))))
637
+ | _ ->
638
+ return
639
+ (W. Br_on_null
640
+ (label, W. Call_ref (ty, funct, List. rev (closure :: acc)))))
635
641
| x :: r ->
636
642
let * x = load x in
637
643
loop (x :: acc) r
@@ -643,7 +649,9 @@ module Generate (Target : Target_sig.S) = struct
643
649
in
644
650
let * args = expression_list load args in
645
651
let * closure = load f in
646
- return (W. Call (apply, args @ [ closure ]))
652
+ return
653
+ (W. Br_on_null
654
+ (label_index context exception_handler_pc, W. Call (apply, args @ [ closure ])))
647
655
| Block (tag , a , _ , _ ) ->
648
656
Memory. allocate
649
657
~deadcode_sentinal: ctx.deadcode_sentinal
@@ -869,32 +877,55 @@ module Generate (Target : Target_sig.S) = struct
869
877
{ params = [] ; result = [] }
870
878
(body ~result_typ: [] ~fall_through: (`Block pc) ~context: (`Block pc :: context))
871
879
in
872
- if List. is_empty result_typ
880
+ if true && List. is_empty result_typ
873
881
then handler
874
882
else
875
883
let * () = handler in
876
- instr (W. Return (Some (RefI31 (Const (I32 0l )))))
884
+ let * u = Value. unit in
885
+ instr (W. Return (Some u))
877
886
else body ~result_typ ~fall_through ~context
878
887
879
- let wrap_with_handlers p pc ~result_typ ~fall_through ~context body =
888
+ let wrap_with_handlers ~ location p pc ~result_typ ~fall_through ~context body =
880
889
let need_zero_divide_handler, need_bound_error_handler = needed_handlers p pc in
881
890
wrap_with_handler
882
- need_bound_error_handler
883
- bound_error_pc
884
- (let * f =
885
- register_import ~name: " caml_bound_error" (Fun { params = [] ; result = [] })
886
- in
887
- instr (CallInstr (f, [] )))
891
+ true
892
+ exception_handler_pc
893
+ (match location with
894
+ | `Toplevel ->
895
+ let * exn =
896
+ register_import
897
+ ~import_module: " env"
898
+ ~name: " caml_exception"
899
+ (Global { mut = true ; typ = Type. value })
900
+ in
901
+ let * tag = register_import ~name: exception_name (Tag Type. value) in
902
+ instr (Throw (tag, GlobalGet exn ))
903
+ | `Exception_handler ->
904
+ let * exn =
905
+ register_import
906
+ ~import_module: " env"
907
+ ~name: " caml_exception"
908
+ (Global { mut = true ; typ = Type. value })
909
+ in
910
+ instr (Br (2 , Some (GlobalGet exn )))
911
+ | `Function -> instr (Return (Some (RefNull Any ))))
888
912
(wrap_with_handler
889
- need_zero_divide_handler
890
- zero_divide_pc
913
+ need_bound_error_handler
914
+ bound_error_pc
891
915
(let * f =
892
- register_import
893
- ~name: " caml_raise_zero_divide"
894
- (Fun { params = [] ; result = [] })
916
+ register_import ~name: " caml_bound_error" (Fun { params = [] ; result = [] })
895
917
in
896
918
instr (CallInstr (f, [] )))
897
- body)
919
+ (wrap_with_handler
920
+ need_zero_divide_handler
921
+ zero_divide_pc
922
+ (let * f =
923
+ register_import
924
+ ~name: " caml_raise_zero_divide"
925
+ (Fun { params = [] ; result = [] })
926
+ in
927
+ instr (CallInstr (f, [] )))
928
+ body))
898
929
~result_typ
899
930
~fall_through
900
931
~context
@@ -996,19 +1027,34 @@ module Generate (Target : Target_sig.S) = struct
996
1027
instr (Br_table (e, List. map ~f: dest l, dest a.(len - 1 )))
997
1028
| Raise (x , _ ) -> (
998
1029
let * e = load x in
999
- let * tag = register_import ~name: exception_name (Tag Type. value) in
1000
1030
match fall_through with
1001
1031
| `Catch -> instr (Push e)
1002
1032
| `Block _ | `Return | `Skip -> (
1003
1033
match catch_index context with
1004
1034
| Some i -> instr (Br (i, Some e))
1005
- | None -> instr (Throw (tag, e))))
1035
+ | None ->
1036
+ if Option. is_some name_opt
1037
+ then
1038
+ let * exn =
1039
+ register_import
1040
+ ~import_module: " env"
1041
+ ~name: " caml_exception"
1042
+ (Global { mut = true ; typ = Type. value })
1043
+ in
1044
+ let * () = instr (GlobalSet (exn , e)) in
1045
+ instr (Return (Some (RefNull Any )))
1046
+ else
1047
+ let * tag =
1048
+ register_import ~name: exception_name (Tag Type. value)
1049
+ in
1050
+ instr (Throw (tag, e))))
1006
1051
| Pushtrap (cont , x , cont' ) ->
1007
1052
handle_exceptions
1008
1053
~result_typ
1009
1054
~fall_through
1010
1055
~context: (extend_context fall_through context)
1011
1056
(wrap_with_handlers
1057
+ ~location: `Exception_handler
1012
1058
p
1013
1059
(fst cont)
1014
1060
(fun ~result_typ ~fall_through ~context ->
@@ -1079,6 +1125,10 @@ module Generate (Target : Target_sig.S) = struct
1079
1125
let * () = build_initial_env in
1080
1126
let * () =
1081
1127
wrap_with_handlers
1128
+ ~location:
1129
+ (match name_opt with
1130
+ | None -> `Toplevel
1131
+ | Some _ -> `Function )
1082
1132
p
1083
1133
pc
1084
1134
~result_typ: [ Type. value ]
@@ -1130,7 +1180,9 @@ module Generate (Target : Target_sig.S) = struct
1130
1180
in
1131
1181
let * () = instr (Drop (Call (f, [] ))) in
1132
1182
cont)
1133
- ~init: (instr (Push (RefI31 (Const (I32 0l )))))
1183
+ ~init:
1184
+ (let * u = Value. unit in
1185
+ instr (Push u))
1134
1186
to_link)
1135
1187
in
1136
1188
context.other_fields < -
0 commit comments