Skip to content

Commit 3bb7854

Browse files
committed
Fix tail call support
1 parent df968ae commit 3bb7854

File tree

2 files changed

+31
-16
lines changed

2 files changed

+31
-16
lines changed

asmcomp/linearize.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,15 @@ let linear i n contains_calls =
163163
| Iop op ->
164164
copy_instr (Lop op) i (linear env i.Mach.next n)
165165
| Ireturn traps ->
166+
let delta_traps =
167+
List.fold_left
168+
(fun delta trap ->
169+
match trap with
170+
| Cmm.Pop -> delta - 1
171+
| Cmm.Push _ -> delta + 1)
172+
0 traps
173+
in
174+
let n = adjust_trap_depth (-delta_traps) n in
166175
let n1 = copy_instr Lreturn i (discard_dead_code n) in
167176
let n2 =
168177
if contains_calls

asmcomp/selectgen.ml

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,19 @@ let set_traps nfail traps_ref base_traps exit_traps =
7878
Misc.fatal_errorf "Mismatching trap stacks for continuation %d" nfail
7979
else ()
8080

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+
8194
let env_empty = {
8295
vars = V.Map.empty;
8396
static_exceptions = Int.Map.empty;
@@ -937,7 +950,7 @@ method emit_expr (env:environment) exp =
937950
None
938951
| Return_lbl ->
939952
begin match simple_list with
940-
| [expr] -> self#emit_return env expr traps; None
953+
| [expr] -> self#emit_return ext_env expr traps; None
941954
| [] ->
942955
Misc.fatal_error
943956
"Selection.emit_expr: Return without arguments"
@@ -1147,7 +1160,7 @@ method emit_tail (env:environment) exp =
11471160
let r1 = self#emit_tuple env new_args in
11481161
let rarg = Array.sub r1 1 (Array.length r1 - 1) in
11491162
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
11511164
let call = Iop (Itailcall_ind { label_after; }) in
11521165
let spacetime_reg =
11531166
self#about_to_emit_call env call [| r1.(0) |] dbg
@@ -1167,12 +1180,12 @@ method emit_tail (env:environment) exp =
11671180
self#insert_debug env (Iop new_op) dbg
11681181
(Array.append [|r1.(0)|] loc_arg) loc_res;
11691182
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 [||]
11711184
end
11721185
| Icall_imm { func; label_after; } ->
11731186
let r1 = self#emit_tuple env new_args in
11741187
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
11761189
let call = Iop (Itailcall_imm { func; label_after; }) in
11771190
let spacetime_reg =
11781191
self#about_to_emit_call env call [| |] dbg
@@ -1199,7 +1212,7 @@ method emit_tail (env:environment) exp =
11991212
self#maybe_emit_spacetime_move env ~spacetime_reg;
12001213
self#insert_debug env (Iop new_op) dbg loc_arg loc_res;
12011214
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 [||]
12031216
end
12041217
| _ -> Misc.fatal_error "Selection.emit_tail"
12051218
end
@@ -1283,22 +1296,15 @@ method emit_tail (env:environment) exp =
12831296
[||] [||]
12841297
| Ctrywith(e1, kind, v, e2, _dbg) ->
12851298
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
12871300
let rv = self#regs_for typ_val in
12881301
let s2 = self#emit_tail_sequence (env_add v rv env) e2 in
12891302
self#insert env
1290-
(Itrywith(s1#extract, kind,
1303+
(Itrywith(s1, kind,
12911304
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+
[||] [||]
13001306
| _ ->
1301-
self#emit_return env exp []
1307+
self#emit_return env exp (pop_all_traps env)
13021308

13031309
method private emit_tail_sequence env exp =
13041310
let s = {< instr_seq = dummy_instr >} in

0 commit comments

Comments
 (0)