@@ -784,11 +784,14 @@ module Generate (Target : Target_sig.S) = struct
784784 in
785785 Memory. allocate ~tag: 0 ~deadcode_sentinal: ctx.deadcode_sentinal ~load l)
786786
787+ let exception_handler_pc = - 3
788+
787789 let rec translate_expr ctx context x e =
788790 match e with
789791 | Apply { f; args; exact; _ } ->
790792 let * closure = load f in
791793 let * args = expression_list (fun x -> load_and_box ctx x) args in
794+ let label = label_index context exception_handler_pc in
792795 if exact || List. length args = if Var.Set. mem x ctx.in_cps then 2 else 1
793796 then
794797 match
@@ -803,7 +806,7 @@ module Generate (Target : Target_sig.S) = struct
803806 if Option. is_some init then Value. unit else return closure
804807 | _ -> return closure
805808 in
806- return (W. Call (g, args @ [ cl ]))
809+ return (W. Br_on_null (label, W. Call (g, args @ [ cl ]) ))
807810 | None -> (
808811 let funct = Var. fresh () in
809812 let * closure = tee funct (return closure) in
@@ -814,13 +817,16 @@ module Generate (Target : Target_sig.S) = struct
814817 (load funct)
815818 in
816819 match funct with
817- | W. RefFunc g -> return (W. Call (g, args @ [ closure ]))
818- | _ -> return (W. Call_ref (ty, funct, args @ [ closure ])))
820+ | W. RefFunc g ->
821+ return (W. Br_on_null (label, W. Call (g, args @ [ closure ])))
822+ | _ ->
823+ return
824+ (W. Br_on_null (label, W. Call_ref (ty, funct, args @ [ closure ]))))
819825 else
820826 let * apply =
821827 need_apply_fun ~cps: (Var.Set. mem x ctx.in_cps) ~arity: (List. length args)
822828 in
823- return (W. Call (apply, args @ [ closure ]))
829+ return (W. Br_on_null (label, W. Call (apply, args @ [ closure ]) ))
824830 | Block (tag , a , _ , _ ) ->
825831 Memory. allocate
826832 ~deadcode_sentinal: ctx.deadcode_sentinal
@@ -1075,32 +1081,55 @@ module Generate (Target : Target_sig.S) = struct
10751081 { params = [] ; result = [] }
10761082 (body ~result_typ: [] ~fall_through: (`Block pc) ~context: (`Block pc :: context))
10771083 in
1078- if List. is_empty result_typ
1084+ if true && List. is_empty result_typ
10791085 then handler
10801086 else
10811087 let * () = handler in
1082- instr (W. Return (Some (RefI31 (Const (I32 0l )))))
1088+ let * u = Value. unit in
1089+ instr (W. Return (Some u))
10831090 else body ~result_typ ~fall_through ~context
10841091
1085- let wrap_with_handlers p pc ~result_typ ~fall_through ~context body =
1092+ let wrap_with_handlers ~ location p pc ~result_typ ~fall_through ~context body =
10861093 let need_zero_divide_handler, need_bound_error_handler = needed_handlers p pc in
10871094 wrap_with_handler
1088- need_bound_error_handler
1089- bound_error_pc
1090- (let * f =
1091- register_import ~name: " caml_bound_error" (Fun { params = [] ; result = [] })
1092- in
1093- instr (CallInstr (f, [] )))
1095+ true
1096+ exception_handler_pc
1097+ (match location with
1098+ | `Toplevel ->
1099+ let * exn =
1100+ register_import
1101+ ~import_module: " env"
1102+ ~name: " caml_exception"
1103+ (Global { mut = true ; typ = Type. value })
1104+ in
1105+ let * tag = register_import ~name: exception_name (Tag Type. value) in
1106+ instr (Throw (tag, GlobalGet exn ))
1107+ | `Exception_handler ->
1108+ let * exn =
1109+ register_import
1110+ ~import_module: " env"
1111+ ~name: " caml_exception"
1112+ (Global { mut = true ; typ = Type. value })
1113+ in
1114+ instr (Br (2 , Some (GlobalGet exn )))
1115+ | `Function -> instr (Return (Some (RefNull Any ))))
10941116 (wrap_with_handler
1095- need_zero_divide_handler
1096- zero_divide_pc
1117+ need_bound_error_handler
1118+ bound_error_pc
10971119 (let * f =
1098- register_import
1099- ~name: " caml_raise_zero_divide"
1100- (Fun { params = [] ; result = [] })
1120+ register_import ~name: " caml_bound_error" (Fun { params = [] ; result = [] })
11011121 in
11021122 instr (CallInstr (f, [] )))
1103- body)
1123+ (wrap_with_handler
1124+ need_zero_divide_handler
1125+ zero_divide_pc
1126+ (let * f =
1127+ register_import
1128+ ~name: " caml_raise_zero_divide"
1129+ (Fun { params = [] ; result = [] })
1130+ in
1131+ instr (CallInstr (f, [] )))
1132+ body))
11041133 ~result_typ
11051134 ~fall_through
11061135 ~context
@@ -1208,19 +1237,34 @@ module Generate (Target : Target_sig.S) = struct
12081237 instr (Br_table (e, List. map ~f: dest l, dest a.(len - 1 )))
12091238 | Raise (x , _ ) -> (
12101239 let * e = load x in
1211- let * tag = register_import ~name: exception_name (Tag Type. value) in
12121240 match fall_through with
12131241 | `Catch -> instr (Push e)
12141242 | `Block _ | `Return | `Skip -> (
12151243 match catch_index context with
12161244 | Some i -> instr (Br (i, Some e))
1217- | None -> instr (Throw (tag, e))))
1245+ | None ->
1246+ if Option. is_some name_opt
1247+ then
1248+ let * exn =
1249+ register_import
1250+ ~import_module: " env"
1251+ ~name: " caml_exception"
1252+ (Global { mut = true ; typ = Type. value })
1253+ in
1254+ let * () = instr (GlobalSet (exn , e)) in
1255+ instr (Return (Some (RefNull Any )))
1256+ else
1257+ let * tag =
1258+ register_import ~name: exception_name (Tag Type. value)
1259+ in
1260+ instr (Throw (tag, e))))
12181261 | Pushtrap (cont , x , cont' ) ->
12191262 handle_exceptions
12201263 ~result_typ
12211264 ~fall_through
12221265 ~context: (extend_context fall_through context)
12231266 (wrap_with_handlers
1267+ ~location: `Exception_handler
12241268 p
12251269 (fst cont)
12261270 (fun ~result_typ ~fall_through ~context ->
@@ -1292,6 +1336,10 @@ module Generate (Target : Target_sig.S) = struct
12921336 let * () = build_initial_env in
12931337 let * () =
12941338 wrap_with_handlers
1339+ ~location:
1340+ (match name_opt with
1341+ | None -> `Toplevel
1342+ | Some _ -> `Function )
12951343 p
12961344 pc
12971345 ~result_typ: [ Type. value ]
@@ -1343,7 +1391,9 @@ module Generate (Target : Target_sig.S) = struct
13431391 in
13441392 let * () = instr (Drop (Call (f, [] ))) in
13451393 cont)
1346- ~init: (instr (Push (RefI31 (Const (I32 0l )))))
1394+ ~init:
1395+ (let * u = Value. unit in
1396+ instr (Push u))
13471397 to_link)
13481398 in
13491399 context.other_fields < -
0 commit comments