summaryrefslogtreecommitdiff
path: root/asmcomp/split.ml
diff options
context:
space:
mode:
authorPierre Chambart <pierre.chambart@ocamlpro.com>2016-10-25 16:09:53 +0100
committerPierre Chambart <chambart@users.noreply.github.com>2016-10-28 13:03:59 +0200
commitc3d056de682de562e98c6d91cee706f6b7131fba (patch)
tree1697f50c061bdaca186cd373412a87cf756ac535 /asmcomp/split.ml
parent4c03ef70fd1563d283d038dda180c3b855c37517 (diff)
downloadocaml-c3d056de682de562e98c6d91cee706f6b7131fba.tar.gz
Change Cmm Ccatch construct to allow recursive cases
Diffstat (limited to 'asmcomp/split.ml')
-rw-r--r--asmcomp/split.ml25
1 files changed, 16 insertions, 9 deletions
diff --git a/asmcomp/split.ml b/asmcomp/split.ml
index 00b009ec79..437a85e6ba 100644
--- a/asmcomp/split.ml
+++ b/asmcomp/split.ml
@@ -165,16 +165,23 @@ let rec rename i sub =
let (new_next, sub_next) = rename i.next (merge_substs sub sub_body i) in
(instr_cons (Iloop(new_body)) [||] [||] new_next,
sub_next)
- | Icatch(nfail, body, handler) ->
- let new_subst = ref None in
- exit_subst := (nfail, new_subst) :: !exit_subst ;
+ | Icatch(handlers, body) ->
+ let new_subst = List.map (fun (nfail, _) -> nfail, ref None)
+ handlers in
+ let previous_exit_subst = !exit_subst in
+ exit_subst := new_subst @ !exit_subst;
let (new_body, sub_body) = rename body sub in
- let sub_entry_handler = !new_subst in
- exit_subst := List.tl !exit_subst;
- let (new_handler, sub_handler) = rename handler sub_entry_handler in
- let (new_next, sub_next) =
- rename i.next (merge_substs sub_body sub_handler i.next) in
- (instr_cons (Icatch(nfail, new_body, new_handler)) [||] [||] new_next,
+ let res = List.map2 (fun (_, handler) (_, new_subst) -> rename handler !new_subst)
+ handlers new_subst in
+ exit_subst := previous_exit_subst;
+ let merged_subst =
+ List.fold_left (fun acc (_, sub_handler) ->
+ merge_substs acc sub_handler i.next)
+ sub_body res in
+ let (new_next, sub_next) = rename i.next merged_subst in
+ let new_handlers = List.map2 (fun (nfail, _) (handler, _) ->
+ (nfail, handler)) handlers res in
+ (instr_cons (Icatch(new_handlers, new_body)) [||] [||] new_next,
sub_next)
| Iexit nfail ->
let r = find_exit_subst nfail in