@@ -784,11 +784,14 @@ module Generate (Target : Target_sig.S) = struct
784
784
in
785
785
Memory. allocate ~tag: 0 ~deadcode_sentinal: ctx.deadcode_sentinal ~load l)
786
786
787
+ let exception_handler_pc = - 3
788
+
787
789
let rec translate_expr ctx context x e =
788
790
match e with
789
791
| Apply { f; args; exact; _ } ->
790
792
let * closure = load f in
791
793
let * args = expression_list (fun x -> load_and_box ctx x) args in
794
+ let label = label_index context exception_handler_pc in
792
795
if exact || List. length args = if Var.Set. mem x ctx.in_cps then 2 else 1
793
796
then
794
797
match
@@ -803,7 +806,7 @@ module Generate (Target : Target_sig.S) = struct
803
806
if Option. is_some init then Value. unit else return closure
804
807
| _ -> return closure
805
808
in
806
- return (W. Call (g, args @ [ cl ]))
809
+ return (W. Br_on_null (label, W. Call (g, args @ [ cl ]) ))
807
810
| None -> (
808
811
let funct = Var. fresh () in
809
812
let * closure = tee funct (return closure) in
@@ -814,13 +817,16 @@ module Generate (Target : Target_sig.S) = struct
814
817
(load funct)
815
818
in
816
819
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 ]))))
819
825
else
820
826
let * apply =
821
827
need_apply_fun ~cps: (Var.Set. mem x ctx.in_cps) ~arity: (List. length args)
822
828
in
823
- return (W. Call (apply, args @ [ closure ]))
829
+ return (W. Br_on_null (label, W. Call (apply, args @ [ closure ]) ))
824
830
| Block (tag , a , _ , _ ) ->
825
831
Memory. allocate
826
832
~deadcode_sentinal: ctx.deadcode_sentinal
@@ -1075,32 +1081,55 @@ module Generate (Target : Target_sig.S) = struct
1075
1081
{ params = [] ; result = [] }
1076
1082
(body ~result_typ: [] ~fall_through: (`Block pc) ~context: (`Block pc :: context))
1077
1083
in
1078
- if List. is_empty result_typ
1084
+ if true && List. is_empty result_typ
1079
1085
then handler
1080
1086
else
1081
1087
let * () = handler in
1082
- instr (W. Return (Some (RefI31 (Const (I32 0l )))))
1088
+ let * u = Value. unit in
1089
+ instr (W. Return (Some u))
1083
1090
else body ~result_typ ~fall_through ~context
1084
1091
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 =
1086
1093
let need_zero_divide_handler, need_bound_error_handler = needed_handlers p pc in
1087
1094
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 ))))
1094
1116
(wrap_with_handler
1095
- need_zero_divide_handler
1096
- zero_divide_pc
1117
+ need_bound_error_handler
1118
+ bound_error_pc
1097
1119
(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 = [] })
1101
1121
in
1102
1122
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))
1104
1133
~result_typ
1105
1134
~fall_through
1106
1135
~context
@@ -1208,19 +1237,34 @@ module Generate (Target : Target_sig.S) = struct
1208
1237
instr (Br_table (e, List. map ~f: dest l, dest a.(len - 1 )))
1209
1238
| Raise (x , _ ) -> (
1210
1239
let * e = load x in
1211
- let * tag = register_import ~name: exception_name (Tag Type. value) in
1212
1240
match fall_through with
1213
1241
| `Catch -> instr (Push e)
1214
1242
| `Block _ | `Return | `Skip -> (
1215
1243
match catch_index context with
1216
1244
| 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))))
1218
1261
| Pushtrap (cont , x , cont' ) ->
1219
1262
handle_exceptions
1220
1263
~result_typ
1221
1264
~fall_through
1222
1265
~context: (extend_context fall_through context)
1223
1266
(wrap_with_handlers
1267
+ ~location: `Exception_handler
1224
1268
p
1225
1269
(fst cont)
1226
1270
(fun ~result_typ ~fall_through ~context ->
@@ -1292,6 +1336,10 @@ module Generate (Target : Target_sig.S) = struct
1292
1336
let * () = build_initial_env in
1293
1337
let * () =
1294
1338
wrap_with_handlers
1339
+ ~location:
1340
+ (match name_opt with
1341
+ | None -> `Toplevel
1342
+ | Some _ -> `Function )
1295
1343
p
1296
1344
pc
1297
1345
~result_typ: [ Type. value ]
@@ -1343,7 +1391,9 @@ module Generate (Target : Target_sig.S) = struct
1343
1391
in
1344
1392
let * () = instr (Drop (Call (f, [] ))) in
1345
1393
cont)
1346
- ~init: (instr (Push (RefI31 (Const (I32 0l )))))
1394
+ ~init:
1395
+ (let * u = Value. unit in
1396
+ instr (Push u))
1347
1397
to_link)
1348
1398
in
1349
1399
context.other_fields < -
0 commit comments