@@ -78,6 +78,19 @@ let set_traps nfail traps_ref base_traps exit_traps =
78
78
Misc. fatal_errorf " Mismatching trap stacks for continuation %d" nfail
79
79
else ()
80
80
81
+ let trap_stack_is_empty env =
82
+ match env.trap_stack with
83
+ | Uncaught -> true
84
+ | Generic_trap _ | Specific_trap _ -> false
85
+
86
+ let pop_all_traps env =
87
+ let rec pop_all acc = function
88
+ | Uncaught -> acc
89
+ | Generic_trap t
90
+ | Specific_trap (_ , t ) -> pop_all (Cmm. Pop :: acc) t
91
+ in
92
+ pop_all [] env.trap_stack
93
+
81
94
let env_empty = {
82
95
vars = V.Map. empty;
83
96
static_exceptions = Int.Map. empty;
@@ -937,7 +950,7 @@ method emit_expr (env:environment) exp =
937
950
None
938
951
| Return_lbl ->
939
952
begin match simple_list with
940
- | [expr] -> self#emit_return env expr traps; None
953
+ | [expr] -> self#emit_return ext_env expr traps; None
941
954
| [] ->
942
955
Misc. fatal_error
943
956
" Selection.emit_expr: Return without arguments"
@@ -1147,7 +1160,7 @@ method emit_tail (env:environment) exp =
1147
1160
let r1 = self#emit_tuple env new_args in
1148
1161
let rarg = Array. sub r1 1 (Array. length r1 - 1 ) in
1149
1162
let (loc_arg, stack_ofs) = Proc. loc_arguments rarg in
1150
- if stack_ofs = 0 then begin
1163
+ if stack_ofs = 0 && trap_stack_is_empty env then begin
1151
1164
let call = Iop (Itailcall_ind { label_after; }) in
1152
1165
let spacetime_reg =
1153
1166
self#about_to_emit_call env call [| r1.(0 ) |] dbg
@@ -1167,12 +1180,12 @@ method emit_tail (env:environment) exp =
1167
1180
self#insert_debug env (Iop new_op) dbg
1168
1181
(Array. append [|r1.(0 )|] loc_arg) loc_res;
1169
1182
self#insert env (Iop (Istackoffset (- stack_ofs))) [||] [||];
1170
- self#insert env (Ireturn [] ) loc_res [||]
1183
+ self#insert env (Ireturn (pop_all_traps env) ) loc_res [||]
1171
1184
end
1172
1185
| Icall_imm { func; label_after; } ->
1173
1186
let r1 = self#emit_tuple env new_args in
1174
1187
let (loc_arg, stack_ofs) = Proc. loc_arguments r1 in
1175
- if stack_ofs = 0 then begin
1188
+ if stack_ofs = 0 && trap_stack_is_empty env then begin
1176
1189
let call = Iop (Itailcall_imm { func; label_after; }) in
1177
1190
let spacetime_reg =
1178
1191
self#about_to_emit_call env call [| |] dbg
@@ -1199,7 +1212,7 @@ method emit_tail (env:environment) exp =
1199
1212
self#maybe_emit_spacetime_move env ~spacetime_reg ;
1200
1213
self#insert_debug env (Iop new_op) dbg loc_arg loc_res;
1201
1214
self#insert env (Iop (Istackoffset (- stack_ofs))) [||] [||];
1202
- self#insert env (Ireturn [] ) loc_res [||]
1215
+ self#insert env (Ireturn (pop_all_traps env) ) loc_res [||]
1203
1216
end
1204
1217
| _ -> Misc. fatal_error " Selection.emit_tail"
1205
1218
end
@@ -1283,22 +1296,15 @@ method emit_tail (env:environment) exp =
1283
1296
[||] [||]
1284
1297
| Ctrywith (e1 , kind , v , e2 , _dbg ) ->
1285
1298
let env_body = env_enter_trywith env kind in
1286
- let (opt_r1, s1) = self#emit_sequence env_body e1 in
1299
+ let s1 = self#emit_tail_sequence env_body e1 in
1287
1300
let rv = self#regs_for typ_val in
1288
1301
let s2 = self#emit_tail_sequence (env_add v rv env) e2 in
1289
1302
self#insert env
1290
- (Itrywith (s1#extract , kind,
1303
+ (Itrywith (s1, kind,
1291
1304
instr_cons (Iop Imove ) [|Proc. loc_exn_bucket|] rv s2))
1292
- [||] [||];
1293
- begin match opt_r1 with
1294
- None -> ()
1295
- | Some r1 ->
1296
- let loc = Proc. loc_results r1 in
1297
- self#insert_moves env r1 loc;
1298
- self#insert env (Ireturn [] ) loc [||]
1299
- end
1305
+ [||] [||]
1300
1306
| _ ->
1301
- self#emit_return env exp []
1307
+ self#emit_return env exp (pop_all_traps env)
1302
1308
1303
1309
method private emit_tail_sequence env exp =
1304
1310
let s = {< instr_seq = dummy_instr > } in
0 commit comments