diff options
author | Pierre Chambart <pierre.chambart@ocamlpro.com> | 2016-10-25 16:09:53 +0100 |
---|---|---|
committer | Pierre Chambart <chambart@users.noreply.github.com> | 2016-10-28 13:03:59 +0200 |
commit | c3d056de682de562e98c6d91cee706f6b7131fba (patch) | |
tree | 1697f50c061bdaca186cd373412a87cf756ac535 /asmcomp/split.ml | |
parent | 4c03ef70fd1563d283d038dda180c3b855c37517 (diff) | |
download | ocaml-c3d056de682de562e98c6d91cee706f6b7131fba.tar.gz |
Change Cmm Ccatch construct to allow recursive cases
Diffstat (limited to 'asmcomp/split.ml')
-rw-r--r-- | asmcomp/split.ml | 25 |
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 |