@@ -604,6 +604,8 @@ module Generate (Target : Target_sig.S) = struct
604604 in
605605 Memory. allocate ~tag: 0 ~deadcode_sentinal: ctx.deadcode_sentinal l)
606606
607+ let exception_handler_pc = - 3
608+
607609 let rec translate_expr ctx context x e =
608610 match e with
609611 | Apply { f; args; exact }
@@ -621,17 +623,21 @@ module Generate (Target : Target_sig.S) = struct
621623 (load funct)
622624 in
623625 let * b = is_closure f in
626+ let label = label_index context exception_handler_pc in
624627 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) )))
626629 else
627630 match funct with
628631 | W. RefFunc g ->
629632 (* Functions with constant closures ignore their
630633 environment. In case of partial application, we
631634 still need the closure. *)
632635 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)))))
635641 | x :: r ->
636642 let * x = load x in
637643 loop (x :: acc) r
@@ -643,7 +649,9 @@ module Generate (Target : Target_sig.S) = struct
643649 in
644650 let * args = expression_list load args in
645651 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 ])))
647655 | Block (tag , a , _ , _ ) ->
648656 Memory. allocate
649657 ~deadcode_sentinal: ctx.deadcode_sentinal
@@ -869,32 +877,55 @@ module Generate (Target : Target_sig.S) = struct
869877 { params = [] ; result = [] }
870878 (body ~result_typ: [] ~fall_through: (`Block pc) ~context: (`Block pc :: context))
871879 in
872- if List. is_empty result_typ
880+ if true && List. is_empty result_typ
873881 then handler
874882 else
875883 let * () = handler in
876- instr (W. Return (Some (RefI31 (Const (I32 0l )))))
884+ let * u = Value. unit in
885+ instr (W. Return (Some u))
877886 else body ~result_typ ~fall_through ~context
878887
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 =
880889 let need_zero_divide_handler, need_bound_error_handler = needed_handlers p pc in
881890 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 ))))
888912 (wrap_with_handler
889- need_zero_divide_handler
890- zero_divide_pc
913+ need_bound_error_handler
914+ bound_error_pc
891915 (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 = [] })
895917 in
896918 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))
898929 ~result_typ
899930 ~fall_through
900931 ~context
@@ -996,19 +1027,34 @@ module Generate (Target : Target_sig.S) = struct
9961027 instr (Br_table (e, List. map ~f: dest l, dest a.(len - 1 )))
9971028 | Raise (x , _ ) -> (
9981029 let * e = load x in
999- let * tag = register_import ~name: exception_name (Tag Type. value) in
10001030 match fall_through with
10011031 | `Catch -> instr (Push e)
10021032 | `Block _ | `Return | `Skip -> (
10031033 match catch_index context with
10041034 | 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))))
10061051 | Pushtrap (cont , x , cont' ) ->
10071052 handle_exceptions
10081053 ~result_typ
10091054 ~fall_through
10101055 ~context: (extend_context fall_through context)
10111056 (wrap_with_handlers
1057+ ~location: `Exception_handler
10121058 p
10131059 (fst cont)
10141060 (fun ~result_typ ~fall_through ~context ->
@@ -1079,6 +1125,10 @@ module Generate (Target : Target_sig.S) = struct
10791125 let * () = build_initial_env in
10801126 let * () =
10811127 wrap_with_handlers
1128+ ~location:
1129+ (match name_opt with
1130+ | None -> `Toplevel
1131+ | Some _ -> `Function )
10821132 p
10831133 pc
10841134 ~result_typ: [ Type. value ]
@@ -1130,7 +1180,9 @@ module Generate (Target : Target_sig.S) = struct
11301180 in
11311181 let * () = instr (Drop (Call (f, [] ))) in
11321182 cont)
1133- ~init: (instr (Push (RefI31 (Const (I32 0l )))))
1183+ ~init:
1184+ (let * u = Value. unit in
1185+ instr (Push u))
11341186 to_link)
11351187 in
11361188 context.other_fields < -
0 commit comments