Skip to content

Commit e099dfc

Browse files
committed
Fix jump targets and substitution bugs
1 parent 12a247b commit e099dfc

File tree

3 files changed

+54
-15
lines changed

3 files changed

+54
-15
lines changed

compiler/lib/effects.ml

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -461,12 +461,15 @@ let cps_last ~st ~alloc_jump_closures pc ((last, last_loc) : last * loc) ~k :
461461
( alloc_jump_closures
462462
, ( Switch (x, Array.map c1 ~f:cps_jump_cont, Array.map c2 ~f:cps_jump_cont)
463463
, last_loc ) )
464-
| Pushtrap (body_cont, exn, ((handler_pc, _) as handler_cont), _) -> (
464+
| Pushtrap (body_cont, exn, ((handler_pc, _) as handler_cont), poptraps) -> (
465465
assert (Hashtbl.mem st.is_continuation handler_pc);
466466
match Addr.Set.mem handler_pc st.blocks_to_transform with
467-
| false -> alloc_jump_closures, (last, last_loc)
467+
| false ->
468+
let body_cont = cps_cont_of_direct ~st body_cont in
469+
let handler_cont = cps_cont_of_direct ~st handler_cont in
470+
let last = Pushtrap (body_cont, exn, handler_cont, poptraps) in
471+
alloc_jump_closures, (last, last_loc)
468472
| true ->
469-
let handler_cps_cont = cps_cont_of_direct ~st handler_cont in
470473
let constr_cont, exn_handler =
471474
allocate_continuation
472475
~st
@@ -475,7 +478,8 @@ let cps_last ~st ~alloc_jump_closures pc ((last, last_loc) : last * loc) ~k :
475478
~direct_pc:handler_pc
476479
pc
477480
exn
478-
handler_cps_cont
481+
handler_cont (* We pass the direct pc, the mapping to CPS is made
482+
by the called functions. *)
479483
last_loc
480484
in
481485
mark_single_version ~st exn_handler;
@@ -777,7 +781,25 @@ let rewrite_direct_block
777781
{ block with body }, subst
778782

779783
(* Apply a substitution in a set of blocks *)
780-
let subst_blocks blocks s =
784+
let subst_in_blocks blocks s =
785+
Addr.Map.mapi
786+
(fun pc block ->
787+
if debug ()
788+
then (
789+
debug_print "@[<v>block before first subst: @,";
790+
Code.Print.block (fun _ _ -> "") pc block;
791+
debug_print "@]");
792+
let res = Subst.block s block in
793+
if debug ()
794+
then (
795+
debug_print "@[<v>block after first subst: @,";
796+
Code.Print.block (fun _ _ -> "") pc res;
797+
debug_print "@]");
798+
res)
799+
blocks
800+
801+
(* Apply a substitution in a set of blocks, including to bound variables *)
802+
let subst_bound_in_blocks blocks s =
781803
Addr.Map.mapi
782804
(fun pc block ->
783805
if debug ()
@@ -824,9 +846,8 @@ let cps_transform ~lifter_functions ~live_vars ~flow_info ~cps_needed p =
824846
match name_opt with
825847
| Some name -> Var.Set.mem name cps_needed
826848
| None ->
827-
(* We are handling the toplevel code. There may remain
828-
some CPS calls at toplevel. *)
829-
true
849+
(* The toplevel code does not need to be in CPS. *)
850+
false
830851
in
831852
let blocks_to_transform, matching_exn_handler, is_continuation =
832853
if should_compute_needed_transformations
@@ -871,10 +892,8 @@ let cps_transform ~lifter_functions ~live_vars ~flow_info ~cps_needed p =
871892
should_compute_needed_transformations
872893
&& not (Var.Set.mem name lifter_functions)
873894
| None ->
874-
(* We are handling the toplevel code. If it performs no
875-
CPS call, we can leave it in direct style and we
876-
don't need to wrap it within a [caml_callback]. *)
877-
not (Addr.Set.is_empty blocks_to_transform)
895+
(* The toplevel code does not need to be in CPS. *)
896+
false
878897
in
879898
if debug ()
880899
then (
@@ -963,7 +982,7 @@ let cps_transform ~lifter_functions ~live_vars ~flow_info ~cps_needed p =
963982
Var.Set.fold (fun v m -> Var.Map.add v (Var.fork v) m) bound Var.Map.empty
964983
|> Subst.from_map
965984
in
966-
let cps_blocks = subst_blocks cps_blocks s in
985+
let cps_blocks = subst_bound_in_blocks cps_blocks s in
967986
(* Also apply susbstitution to set of CPS calls and lifter functions *)
968987
st.cps_calls := Var.Set.map s !(st.cps_calls);
969988
st.single_version_closures := Var.Set.map s !(st.single_version_closures);
@@ -972,7 +991,7 @@ let cps_transform ~lifter_functions ~live_vars ~flow_info ~cps_needed p =
972991
[rewrite_direct], because CPS closures are only ever defined in (toplevel)
973992
direct-style blocks). *)
974993
let direct_subst = Subst.from_map direct_subst in
975-
let cps_blocks = subst_blocks cps_blocks direct_subst in
994+
let cps_blocks = subst_in_blocks cps_blocks direct_subst in
976995
(* Also apply susbstitution to set of CPS calls and lifter functions *)
977996
st.cps_calls := Var.Set.map direct_subst !(st.cps_calls);
978997
st.single_version_closures :=

compiler/lib/subst.ml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,25 @@ module Bound = struct
145145

146146
let instrs s l = List.map l ~f:(fun (i, loc) -> instr s i, loc)
147147

148+
let last s (l, loc) =
149+
let l =
150+
match l with
151+
| Stop -> l
152+
| Branch cont -> Branch (subst_cont s cont)
153+
| Pushtrap (cont1, x, cont2, pcs) ->
154+
Pushtrap (subst_cont s cont1, s x, subst_cont s cont2, pcs)
155+
| Return x -> Return (s x)
156+
| Raise (x, k) -> Raise (s x, k)
157+
| Cond (x, cont1, cont2) -> Cond (s x, subst_cont s cont1, subst_cont s cont2)
158+
| Switch (x, a1, a2) ->
159+
Switch
160+
( s x
161+
, Array.map a1 ~f:(fun cont -> subst_cont s cont)
162+
, Array.map a2 ~f:(fun cont -> subst_cont s cont) )
163+
| Poptrap cont -> Poptrap (subst_cont s cont)
164+
in
165+
l, loc
166+
148167
let block s block =
149168
{ params = List.map block.params ~f:s
150169
; body = instrs s block.body

compiler/lib/subst.mli

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ val from_map : Var.t Var.Map.t -> Var.t -> Var.t
4242

4343
(** The operations of this module also substitute the variables names that
4444
appear on the left-hand-side of a {!constructor:Code.Let}, or as block
45-
parameters, or as closure parameters. *)
45+
parameters, or as closure parameters, or are bound by an exception handler.
46+
*)
4647
module Bound : sig
4748
val instr : (Var.t -> Var.t) -> instr -> instr
4849

0 commit comments

Comments
 (0)