Created
November 12, 2012 13:38
-
-
Save samoht/4059441 to your computer and use it in GitHub Desktop.
Location in lambda IR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 7c0725871e7dddf8fa9b3000405199cfe96886c3 | |
Author: Thomas Gazagnaire <[email protected]> | |
Date: Sun Dec 4 22:53:34 2011 +0100 | |
Add location in lambda code | |
This is a very preliminary patch as there is just enough change to make everything compile, but location are not propagated through the backend. | |
Also the Levent are still there. | |
diff --git a/Makefile b/Makefile | |
index 46291ac..42e82ab 100644 | |
--- a/Makefile | |
+++ b/Makefile | |
@@ -17,7 +17,10 @@ | |
include config/Makefile | |
include stdlib/StdlibModules | |
-CAMLC=boot/ocamlrun boot/ocamlc -nostdlib -I boot | |
+CAMLC=boot/ocamlrun boot/ocamlc -nostdlib -I boot -annot | |
+#CAMLC= ocp-wrapper -save-types -save-last-compiled \ | |
+ boot/ocamlrun boot/ocamlc \ | |
+ -nostdlib -I boot -annot | |
CAMLOPT=boot/ocamlrun ./ocamlopt -nostdlib -I stdlib -I otherlibs/dynlink | |
COMPFLAGS=-strict-sequence -warn-error A $(INCLUDES) | |
LINKFLAGS= | |
diff --git a/asmcomp/clambda.ml b/asmcomp/clambda.ml | |
index 9bcb36f..f11202b 100644 | |
--- a/asmcomp/clambda.ml | |
+++ b/asmcomp/clambda.ml | |
@@ -20,17 +20,22 @@ open Lambda | |
type function_label = string | |
-type ulambda = | |
+and ulambda = { | |
+ u_desc : ulambda_desc; | |
+ u_debug : Debuginfo.t; | |
+} | |
+ | |
+type ulambda_desc = | |
Uvar of Ident.t | |
| Uconst of structured_constant * string option | |
- | Udirect_apply of function_label * ulambda list * Debuginfo.t | |
- | Ugeneric_apply of ulambda * ulambda list * Debuginfo.t | |
+ | Udirect_apply of function_label * ulambda list | |
+ | Ugeneric_apply of ulambda * ulambda list | |
| Uclosure of (function_label * int * Ident.t list * ulambda) list | |
* ulambda list | |
| Uoffset of ulambda * int | |
| Ulet of Ident.t * ulambda * ulambda | |
| Uletrec of (Ident.t * ulambda) list * ulambda | |
- | Uprim of primitive * ulambda list * Debuginfo.t | |
+ | Uprim of primitive * ulambda list | |
| Uswitch of ulambda * ulambda_switch | |
| Ustaticfail of int * ulambda list | |
| Ucatch of int * Ident.t list * ulambda * ulambda | |
@@ -40,7 +45,7 @@ type ulambda = | |
| Uwhile of ulambda * ulambda | |
| Ufor of Ident.t * ulambda * ulambda * direction_flag * ulambda | |
| Uassign of Ident.t * ulambda | |
- | Usend of meth_kind * ulambda * ulambda * ulambda list * Debuginfo.t | |
+ | Usend of meth_kind * ulambda * ulambda * ulambda list | |
and ulambda_switch = | |
{ us_index_consts: int array; | |
diff --git a/asmcomp/clambda.mli b/asmcomp/clambda.mli | |
index 72ab857..13d734d 100644 | |
--- a/asmcomp/clambda.mli | |
+++ b/asmcomp/clambda.mli | |
@@ -20,17 +20,22 @@ open Lambda | |
type function_label = string | |
-type ulambda = | |
+type ulambda = { | |
+ u_desc : ulambda_desc; | |
+ u_debug : Debuginfo.t; | |
+} | |
+ | |
+and ulambda_desc = | |
Uvar of Ident.t | |
| Uconst of structured_constant * string option | |
- | Udirect_apply of function_label * ulambda list * Debuginfo.t | |
- | Ugeneric_apply of ulambda * ulambda list * Debuginfo.t | |
+ | Udirect_apply of function_label * ulambda list | |
+ | Ugeneric_apply of ulambda * ulambda list | |
| Uclosure of (function_label * int * Ident.t list * ulambda) list | |
* ulambda list | |
| Uoffset of ulambda * int | |
| Ulet of Ident.t * ulambda * ulambda | |
| Uletrec of (Ident.t * ulambda) list * ulambda | |
- | Uprim of primitive * ulambda list * Debuginfo.t | |
+ | Uprim of primitive * ulambda list | |
| Uswitch of ulambda * ulambda_switch | |
| Ustaticfail of int * ulambda list | |
| Ucatch of int * Ident.t list * ulambda * ulambda | |
@@ -40,7 +45,7 @@ type ulambda = | |
| Uwhile of ulambda * ulambda | |
| Ufor of Ident.t * ulambda * ulambda * direction_flag * ulambda | |
| Uassign of Ident.t * ulambda | |
- | Usend of meth_kind * ulambda * ulambda * ulambda list * Debuginfo.t | |
+ | Usend of meth_kind * ulambda * ulambda * ulambda list | |
and ulambda_switch = | |
{ us_index_consts: int array; | |
diff --git a/asmcomp/closure.ml b/asmcomp/closure.ml | |
index f37908f..5bc7049 100644 | |
--- a/asmcomp/closure.ml | |
+++ b/asmcomp/closure.ml | |
@@ -33,7 +33,7 @@ let rec split_list n l = | |
let rec build_closure_env env_param pos = function | |
[] -> Tbl.empty | |
| id :: rem -> | |
- Tbl.add id (Uprim(Pfield pos, [Uvar env_param], Debuginfo.none)) | |
+ Tbl.add id (Uprim(Pfield pos, [Uvar env_param])) | |
(build_closure_env env_param (pos+1) rem) | |
(* Auxiliary for accessing globals. We change the name of the global | |
@@ -43,7 +43,7 @@ let rec build_closure_env env_param pos = function | |
let getglobal id = | |
Uprim(Pgetglobal (Ident.create_persistent (Compilenv.symbol_for_global id)), | |
- [], Debuginfo.none) | |
+ []) | |
(* Check if a variable occurs in a [clambda] term. *) | |
diff --git a/bytecomp/bytegen.ml b/bytecomp/bytegen.ml | |
index 9773f0b..8d33177 100644 | |
--- a/bytecomp/bytegen.ml | |
+++ b/bytecomp/bytegen.ml | |
@@ -133,17 +133,17 @@ type rhs_kind = | |
;; | |
let rec check_recordwith_updates id e = | |
- match e with | |
- | Lsequence (Lprim ((Psetfield _ | Psetfloatfield _), [Lvar id2; _]), cont) | |
+ match e.l_desc with | |
+ | Lsequence ({l_desc=Lprim ((Psetfield _ | Psetfloatfield _), [{l_desc=Lvar id2}; _])}, cont) | |
-> id2 = id && check_recordwith_updates id cont | |
| Lvar id2 -> id2 = id | |
| _ -> false | |
;; | |
-let rec size_of_lambda = function | |
- | Lfunction(kind, params, body) as funct -> | |
- RHS_block (1 + IdentSet.cardinal(free_variables funct)) | |
- | Llet (Strict, id, Lprim (Pduprecord (kind, size), _), body) | |
+let rec size_of_lambda lam = match lam.l_desc with | |
+ | Lfunction(kind, params, body) -> | |
+ RHS_block (1 + IdentSet.cardinal(free_variables lam)) | |
+ | Llet (Strict, id, {l_desc=Lprim (Pduprecord (kind, size), _)}, body) | |
when check_recordwith_updates id body -> | |
begin match kind with | |
| Record_regular -> RHS_block size | |
@@ -247,7 +247,7 @@ let find_raise_label i = | |
("exit("^string_of_int i^") outside appropriated catch") | |
(* Will the translation of l lead to a jump to label ? *) | |
-let code_as_jump l sz = match l with | |
+let code_as_jump l sz = match l.l_desc with | |
| Lstaticraise (i,[]) -> | |
let label,size = find_raise_label i in | |
if sz = size then | |
@@ -391,7 +391,7 @@ let is_immed n = immed_min <= n && n <= immed_max | |
let rec comp_expr env exp sz cont = | |
if sz > !max_stack_used then max_stack_used := sz; | |
- match exp with | |
+ match exp.l_desc with | |
Lvar id -> | |
begin try | |
let pos = Ident.find_same id env.ce_stack in | |
@@ -410,7 +410,7 @@ let rec comp_expr env exp sz cont = | |
end | |
| Lconst cst -> | |
Kconst cst :: cont | |
- | Lapply(func, args, loc) -> | |
+ | Lapply(func, args) -> | |
let nargs = List.length args in | |
if is_tailcall cont then begin | |
comp_args env args sz | |
@@ -428,12 +428,12 @@ let rec comp_expr env exp sz cont = | |
(Kapply nargs :: cont1)) | |
end | |
end | |
- | Lsend(kind, met, obj, args, _) -> | |
+ | Lsend(kind, met, obj, args) -> | |
let args = if kind = Cached then List.tl args else args in | |
let nargs = List.length args + 1 in | |
let getmethod, args' = | |
if kind = Self then (Kgetmethod, met::obj::args) else | |
- match met with | |
+ match met.l_desc with | |
Lconst(Const_base(Const_int n)) -> (Kgetpubmet n, obj::args) | |
| _ -> (Kgetdynmet, met::obj::args) | |
in | |
@@ -457,7 +457,7 @@ let rec comp_expr env exp sz cont = | |
{ params = params; body = body; label = lbl; | |
free_vars = fv; num_defs = 1; rec_vars = []; rec_pos = 0 } in | |
Stack.push to_compile functions_to_compile; | |
- comp_args env (List.map (fun n -> Lvar n) fv) sz | |
+ comp_args env (List.map (fun n -> mk_lam (Lvar n)) fv) sz | |
(Kclosure(lbl, List.length fv) :: cont) | |
| Llet(str, id, arg, body) -> | |
comp_expr env arg sz | |
@@ -465,15 +465,15 @@ let rec comp_expr env exp sz cont = | |
(add_pop 1 cont)) | |
| Lletrec(decl, body) -> | |
let ndecl = List.length decl in | |
- if List.for_all (function (_, Lfunction(_,_,_)) -> true | _ -> false) | |
+ if List.for_all (function (_, {l_desc=Lfunction(_,_,_)}) -> true | _ -> false) | |
decl then begin | |
(* let rec of functions *) | |
let fv = | |
- IdentSet.elements (free_variables (Lletrec(decl, lambda_unit))) in | |
+ IdentSet.elements (free_variables (mk_loc_lam exp.l_loc (Lletrec(decl, lambda_unit)))) in | |
let rec_idents = List.map (fun (id, lam) -> id) decl in | |
let rec comp_fun pos = function | |
[] -> [] | |
- | (id, Lfunction(kind, params, body)) :: rem -> | |
+ | (id, {l_desc=Lfunction(kind, params, body)}) :: rem -> | |
let lbl = new_label() in | |
let to_compile = | |
{ params = params; body = body; label = lbl; free_vars = fv; | |
@@ -482,7 +482,7 @@ let rec comp_expr env exp sz cont = | |
lbl :: comp_fun (pos + 1) rem | |
| _ -> assert false in | |
let lbls = comp_fun 0 decl in | |
- comp_args env (List.map (fun n -> Lvar n) fv) sz | |
+ comp_args env (List.map (fun n -> mk_lam (Lvar n)) fv) sz | |
(Kclosurerec(lbls, List.length fv) :: | |
(comp_expr (add_vars rec_idents (sz+1) env) body (sz + ndecl) | |
(add_pop ndecl cont))) | |
@@ -561,10 +561,10 @@ let rec comp_expr env exp sz cont = | |
end | |
| Lprim(Praise, [arg]) -> | |
comp_expr env arg sz (Kraise :: discard_dead_code cont) | |
- | Lprim(Paddint, [arg; Lconst(Const_base(Const_int n))]) | |
+ | Lprim(Paddint, [arg; {l_desc=Lconst(Const_base(Const_int n))}]) | |
when is_immed n -> | |
comp_expr env arg sz (Koffsetint n :: cont) | |
- | Lprim(Psubint, [arg; Lconst(Const_base(Const_int n))]) | |
+ | Lprim(Psubint, [arg; {l_desc=Lconst(Const_base(Const_int n))}]) | |
when is_immed (-n) -> | |
comp_expr env arg sz (Koffsetint (-n) :: cont) | |
| Lprim (Poffsetint n, [arg]) | |
@@ -587,7 +587,7 @@ let rec comp_expr env exp sz cont = | |
Kccall("caml_make_array", 1) :: cont) | |
end | |
(* Integer first for enabling futher optimization (cf. emitcode.ml) *) | |
- | Lprim (Pintcomp c, [arg ; (Lconst _ as k)]) -> | |
+ | Lprim (Pintcomp c, [arg ; ({l_desc=Lconst _} as k)]) -> | |
let p = Pintcomp (commute_comparison c) | |
and args = [k ; arg] in | |
comp_args env args sz (comp_primitive p args :: cont) | |
@@ -743,10 +743,10 @@ let rec comp_expr env exp sz cont = | |
comp_expr env lam sz cont | |
| Lev_after ty -> | |
let info = | |
- match lam with | |
- Lapply(_, args, _) -> Event_return (List.length args) | |
- | Lsend(_, _, _, args, _) -> Event_return (List.length args + 1) | |
- | _ -> Event_other | |
+ match lam.l_desc with | |
+ Lapply(_, args) -> Event_return (List.length args) | |
+ | Lsend(_, _, _, args) -> Event_return (List.length args + 1) | |
+ | _ -> Event_other | |
in | |
let ev = event (Event_after ty) info in | |
let cont1 = add_event ev cont in | |
@@ -781,7 +781,7 @@ and comp_expr_list_assign env exprl sz pos cont = match exprl with | |
and comp_binary_test env cond ifso ifnot sz cont = | |
let cont_cond = | |
- if ifnot = Lconst const_unit then begin | |
+ if ifnot = mk_lam (Lconst const_unit) then begin | |
let (lbl_end, cont1) = label_code cont in | |
Kstrictbranchifnot lbl_end :: comp_expr env ifso sz cont1 | |
end else | |
diff --git a/bytecomp/lambda.ml b/bytecomp/lambda.ml | |
index b1e6f16..edb058f 100644 | |
--- a/bytecomp/lambda.ml | |
+++ b/bytecomp/lambda.ml | |
@@ -123,10 +123,15 @@ type meth_kind = Self | Public | Cached | |
type shared_code = (int * int) list | |
-type lambda = | |
- Lvar of Ident.t | |
+type lambda = { | |
+ l_desc : lambda_desc; | |
+ l_loc : Location.t; | |
+} | |
+ | |
+and lambda_desc = | |
+ | Lvar of Ident.t | |
| Lconst of structured_constant | |
- | Lapply of lambda * lambda list * Location.t | |
+ | Lapply of lambda * lambda list | |
| Lfunction of function_kind * Ident.t list * lambda | |
| Llet of let_kind * Ident.t * lambda * lambda | |
| Lletrec of (Ident.t * lambda) list * lambda | |
@@ -140,7 +145,7 @@ type lambda = | |
| Lwhile of lambda * lambda | |
| Lfor of Ident.t * lambda * lambda * direction_flag * lambda | |
| Lassign of Ident.t * lambda | |
- | Lsend of meth_kind * lambda * lambda * lambda list * Location.t | |
+ | Lsend of meth_kind * lambda * lambda * lambda list | |
| Levent of lambda * lambda_event | |
| Lifused of Ident.t * lambda | |
@@ -151,28 +156,35 @@ and lambda_switch = | |
sw_blocks: (int * lambda) list; | |
sw_failaction : lambda option} | |
-and lambda_event = | |
- { lev_loc: Location.t; | |
- lev_kind: lambda_event_kind; | |
- lev_repr: int ref option; | |
- lev_env: Env.summary } | |
+and lambda_event = { | |
+ lev_loc: Location.t; | |
+ lev_kind: lambda_event_kind; | |
+ lev_repr: int ref option; | |
+ lev_env: Env.summary; | |
+} | |
and lambda_event_kind = | |
Lev_before | |
| Lev_after of Types.type_expr | |
| Lev_function | |
+let mk_lam l_desc = | |
+ { l_loc = Location.none; l_desc } | |
+ | |
+let mk_loc_lam l_loc l_desc = | |
+ { l_loc; l_desc } | |
+ | |
let const_unit = Const_pointer 0 | |
-let lambda_unit = Lconst const_unit | |
+let lambda_unit = mk_lam (Lconst const_unit) | |
let rec same l1 l2 = | |
- match (l1, l2) with | |
+ match l1.l_desc, l2.l_desc with | |
| Lvar v1, Lvar v2 -> | |
Ident.same v1 v2 | |
| Lconst c1, Lconst c2 -> | |
c1 = c2 | |
- | Lapply(a1, bl1, _), Lapply(a2, bl2, _) -> | |
+ | Lapply(a1, bl1), Lapply(a2, bl2) -> | |
same a1 a2 && samelist same bl1 bl2 | |
| Lfunction(k1, idl1, a1), Lfunction(k2, idl2, a2) -> | |
k1 = k2 && samelist Ident.same idl1 idl2 && same a1 a2 | |
@@ -201,7 +213,7 @@ let rec same l1 l2 = | |
same b1 b2 && df1 = df2 && same c1 c2 | |
| Lassign(id1, a1), Lassign(id2, a2) -> | |
Ident.same id1 id2 && same a1 a2 | |
- | Lsend(k1, a1, b1, cl1, _), Lsend(k2, a2, b2, cl2, _) -> | |
+ | Lsend(k1, a1, b1, cl1), Lsend(k2, a2, b2, cl2) -> | |
k1 = k2 && same a1 a2 && same b1 b2 && samelist same cl1 cl2 | |
| Levent(a1, ev1), Levent(a2, ev2) -> | |
same a1 a2 && ev1.lev_loc = ev2.lev_loc | |
@@ -224,25 +236,16 @@ and sameswitch sw1 sw2 = | |
| (Some a1, Some a2) -> same a1 a2 | |
| _ -> false) | |
-let name_lambda arg fn = | |
- match arg with | |
- Lvar id -> fn id | |
- | _ -> let id = Ident.create "let" in Llet(Strict, id, arg, fn id) | |
- | |
-let name_lambda_list args fn = | |
- let rec name_list names = function | |
- [] -> fn (List.rev names) | |
- | (Lvar id as arg) :: rem -> | |
- name_list (arg :: names) rem | |
- | arg :: rem -> | |
- let id = Ident.create "let" in | |
- Llet(Strict, id, arg, name_list (Lvar id :: names) rem) in | |
- name_list [] args | |
- | |
-let rec iter f = function | |
- Lvar _ | |
+let name_lambda arg fn = match arg.l_desc with | |
+ | Lvar id -> fn id | |
+ | _ -> | |
+ let id = Ident.create "let" in | |
+ mk_loc_lam arg.l_loc (Llet(Strict, id, arg, fn id)) | |
+ | |
+let rec iter f l = match l.l_desc with | |
+ | Lvar _ | |
| Lconst _ -> () | |
- | Lapply(fn, args, _) -> | |
+ | Lapply(fn, args) -> | |
f fn; List.iter f args | |
| Lfunction(kind, params, body) -> | |
f body | |
@@ -277,7 +280,7 @@ let rec iter f = function | |
f e1; f e2; f e3 | |
| Lassign(id, e) -> | |
f e | |
- | Lsend (k, met, obj, args, _) -> | |
+ | Lsend (k, met, obj, args) -> | |
List.iter f (met::obj::args) | |
| Levent (lam, evt) -> | |
f lam | |
@@ -294,8 +297,8 @@ let free_ids get l = | |
let fv = ref IdentSet.empty in | |
let rec free l = | |
iter free l; | |
- fv := List.fold_right IdentSet.add (get l) !fv; | |
- match l with | |
+ fv := List.fold_right IdentSet.add (get l.l_desc) !fv; | |
+ match l.l_desc with | |
Lfunction(kind, params, body) -> | |
List.iter (fun param -> fv := IdentSet.remove param !fv) params | |
| Llet(str, id, arg, body) -> | |
@@ -320,7 +323,7 @@ let free_variables l = | |
free_ids (function Lvar id -> [id] | _ -> []) l | |
let free_methods l = | |
- free_ids (function Lsend(Self, Lvar meth, obj, _, _) -> [meth] | _ -> []) l | |
+ free_ids (function Lsend(Self, {l_desc=Lvar meth}, obj, _) -> [meth] | _ -> []) l | |
(* Check if an action has a "when" guard *) | |
let raise_count = ref 0 | |
@@ -330,30 +333,34 @@ let next_raise_count () = | |
!raise_count | |
(* Anticipated staticraise, for guards *) | |
-let staticfail = Lstaticraise (0,[]) | |
+let staticfail = | |
+ mk_lam (Lstaticraise (0,[])) | |
-let rec is_guarded = function | |
- | Lifthenelse( cond, body, Lstaticraise (0,[])) -> true | |
+let rec is_guarded l = match l.l_desc with | |
+ | Lifthenelse( cond, body, {l_desc=Lstaticraise (0,[])}) -> true | |
| Llet(str, id, lam, body) -> is_guarded body | |
| Levent(lam, ev) -> is_guarded lam | |
| _ -> false | |
-let rec patch_guarded patch = function | |
- | Lifthenelse (cond, body, Lstaticraise (0,[])) -> | |
- Lifthenelse (cond, body, patch) | |
+let rec patch_guarded patch l = match l.l_desc with | |
+ | Lifthenelse (cond, body, {l_desc=Lstaticraise (0,[])}) -> | |
+ mk_loc_lam l.l_loc (Lifthenelse (cond, body, patch)) | |
| Llet(str, id, lam, body) -> | |
- Llet (str, id, lam, patch_guarded patch body) | |
+ mk_loc_lam l.l_loc (Llet (str, id, lam, patch_guarded patch body)) | |
| Levent(lam, ev) -> | |
- Levent (patch_guarded patch lam, ev) | |
+ mk_loc_lam l.l_loc (Levent (patch_guarded patch lam, ev)) | |
| _ -> fatal_error "Lambda.patch_guarded" | |
(* Translate an access path *) | |
let rec transl_path = function | |
Pident id -> | |
- if Ident.global id then Lprim(Pgetglobal id, []) else Lvar id | |
+ if Ident.global id then | |
+ mk_lam (Lprim(Pgetglobal id, [])) | |
+ else | |
+ mk_lam (Lvar id) | |
| Pdot(p, s, pos) -> | |
- Lprim(Pfield pos, [transl_path p]) | |
+ mk_lam (Lprim(Pfield pos, [transl_path p])) | |
| Papply(p1, p2) -> | |
fatal_error "Lambda.transl_path" | |
@@ -363,7 +370,8 @@ let rec make_sequence fn = function | |
[] -> lambda_unit | |
| [x] -> fn x | |
| x::rem -> | |
- let lam = fn x in Lsequence(lam, make_sequence fn rem) | |
+ let lam = fn x in | |
+ mk_loc_lam lam.l_loc (Lsequence(lam, make_sequence fn rem)) | |
(* Apply a substitution to a lambda-term. | |
Assumes that the bound variables of the lambda-term do not | |
@@ -372,36 +380,40 @@ let rec make_sequence fn = function | |
of the bound variables of the lambda-term (no capture). *) | |
let subst_lambda s lam = | |
- let rec subst = function | |
- Lvar id as l -> | |
- begin try Ident.find_same id s with Not_found -> l end | |
- | Lconst sc as l -> l | |
- | Lapply(fn, args, loc) -> Lapply(subst fn, List.map subst args, loc) | |
- | Lfunction(kind, params, body) -> Lfunction(kind, params, subst body) | |
- | Llet(str, id, arg, body) -> Llet(str, id, subst arg, subst body) | |
- | Lletrec(decl, body) -> Lletrec(List.map subst_decl decl, subst body) | |
- | Lprim(p, args) -> Lprim(p, List.map subst args) | |
- | Lswitch(arg, sw) -> | |
- Lswitch(subst arg, | |
- {sw with sw_consts = List.map subst_case sw.sw_consts; | |
- sw_blocks = List.map subst_case sw.sw_blocks; | |
- sw_failaction = | |
- match sw.sw_failaction with | |
- | None -> None | |
- | Some l -> Some (subst l)}) | |
- | |
- | Lstaticraise (i,args) -> Lstaticraise (i, List.map subst args) | |
- | Lstaticcatch(e1, io, e2) -> Lstaticcatch(subst e1, io, subst e2) | |
- | Ltrywith(e1, exn, e2) -> Ltrywith(subst e1, exn, subst e2) | |
- | Lifthenelse(e1, e2, e3) -> Lifthenelse(subst e1, subst e2, subst e3) | |
- | Lsequence(e1, e2) -> Lsequence(subst e1, subst e2) | |
- | Lwhile(e1, e2) -> Lwhile(subst e1, subst e2) | |
- | Lfor(v, e1, e2, dir, e3) -> Lfor(v, subst e1, subst e2, dir, subst e3) | |
- | Lassign(id, e) -> Lassign(id, subst e) | |
- | Lsend (k, met, obj, args, loc) -> | |
- Lsend (k, subst met, subst obj, List.map subst args, loc) | |
- | Levent (lam, evt) -> Levent (subst lam, evt) | |
- | Lifused (v, e) -> Lifused (v, subst e) | |
+ let rec subst l = | |
+ let make d = mk_loc_lam l.l_loc d in | |
+ match l.l_desc with | |
+ | Lvar id -> | |
+ begin try Ident.find_same id s with Not_found -> l end | |
+ | Lconst _ -> l | |
+ | Lapply(fn, args) -> make (Lapply(subst fn, List.map subst args)) | |
+ | Lfunction(kind, params, body) -> | |
+ make (Lfunction(kind, params, subst body)) | |
+ | Llet(str, id, arg, body) -> | |
+ make (Llet(str, id, subst arg, subst body)) | |
+ | Lletrec(decl, body) -> | |
+ make (Lletrec(List.map subst_decl decl, subst body)) | |
+ | Lprim(p, args) -> make (Lprim(p, List.map subst args)) | |
+ | Lswitch(arg, sw) -> | |
+ make (Lswitch(subst arg, | |
+ {sw with sw_consts = List.map subst_case sw.sw_consts; | |
+ sw_blocks = List.map subst_case sw.sw_blocks; | |
+ sw_failaction = | |
+ match sw.sw_failaction with | |
+ | None -> None | |
+ | Some l -> Some (subst l)})) | |
+ | Lstaticraise (i,args) -> make (Lstaticraise (i, List.map subst args)) | |
+ | Lstaticcatch(e1, io, e2) -> make (Lstaticcatch(subst e1, io, subst e2)) | |
+ | Ltrywith(e1, exn, e2) -> make (Ltrywith(subst e1, exn, subst e2)) | |
+ | Lifthenelse(e1, e2, e3) -> make (Lifthenelse(subst e1, subst e2, subst e3)) | |
+ | Lsequence(e1, e2) -> make (Lsequence(subst e1, subst e2)) | |
+ | Lwhile(e1, e2) -> make (Lwhile(subst e1, subst e2)) | |
+ | Lfor(v, e1, e2, dir, e3) -> make (Lfor(v, subst e1, subst e2, dir, subst e3)) | |
+ | Lassign(id, e) -> make (Lassign(id, subst e)) | |
+ | Lsend (k, met, obj, args) -> | |
+ make (Lsend (k, subst met, subst obj, List.map subst args)) | |
+ | Levent (lam, evt) -> make (Levent (subst lam, evt)) | |
+ | Lifused (v, e) -> make (Lifused (v, subst e)) | |
and subst_decl (id, exp) = (id, subst exp) | |
and subst_case (key, case) = (key, subst case) | |
in subst lam | |
@@ -410,9 +422,9 @@ let subst_lambda s lam = | |
(* To let-bind expressions to variables *) | |
let bind str var exp body = | |
- match exp with | |
+ match exp.l_desc with | |
Lvar var' when Ident.same var var' -> body | |
- | _ -> Llet(str, var, exp, body) | |
+ | _ -> mk_loc_lam exp.l_loc (Llet(str, var, exp, body)) | |
and commute_comparison = function | |
| Ceq -> Ceq| Cneq -> Cneq | |
diff --git a/bytecomp/lambda.mli b/bytecomp/lambda.mli | |
index d09a8c6..423bee3 100644 | |
--- a/bytecomp/lambda.mli | |
+++ b/bytecomp/lambda.mli | |
@@ -132,10 +132,15 @@ type meth_kind = Self | Public | Cached | |
type shared_code = (int * int) list (* stack size -> code label *) | |
-type lambda = | |
- Lvar of Ident.t | |
+type lambda = { | |
+ l_desc : lambda_desc; | |
+ l_loc : Location.t; | |
+} | |
+ | |
+and lambda_desc = | |
+ | Lvar of Ident.t | |
| Lconst of structured_constant | |
- | Lapply of lambda * lambda list * Location.t | |
+ | Lapply of lambda * lambda list | |
| Lfunction of function_kind * Ident.t list * lambda | |
| Llet of let_kind * Ident.t * lambda * lambda | |
| Lletrec of (Ident.t * lambda) list * lambda | |
@@ -149,7 +154,7 @@ type lambda = | |
| Lwhile of lambda * lambda | |
| Lfor of Ident.t * lambda * lambda * direction_flag * lambda | |
| Lassign of Ident.t * lambda | |
- | Lsend of meth_kind * lambda * lambda * lambda list * Location.t | |
+ | Lsend of meth_kind * lambda * lambda * lambda list | |
| Levent of lambda * lambda_event | |
| Lifused of Ident.t * lambda | |
@@ -170,11 +175,13 @@ and lambda_event_kind = | |
| Lev_after of Types.type_expr | |
| Lev_function | |
+val mk_lam: lambda_desc -> lambda | |
+val mk_loc_lam: Location.t -> lambda_desc -> lambda | |
+ | |
val same: lambda -> lambda -> bool | |
val const_unit: structured_constant | |
val lambda_unit: lambda | |
val name_lambda: lambda -> (Ident.t -> lambda) -> lambda | |
-val name_lambda_list: lambda list -> (lambda list -> lambda) -> lambda | |
val iter: (lambda -> unit) -> lambda -> unit | |
module IdentSet: Set.S with type elt = Ident.t | |
@@ -203,3 +210,4 @@ val staticfail : lambda (* Anticipated static failure *) | |
(* Check anticipated failure, substitute its final value *) | |
val is_guarded: lambda -> bool | |
val patch_guarded : lambda -> lambda -> lambda | |
+ | |
diff --git a/bytecomp/matching.ml b/bytecomp/matching.ml | |
index a464590..a2209f0 100644 | |
--- a/bytecomp/matching.ml | |
+++ b/bytecomp/matching.ml | |
@@ -433,17 +433,17 @@ let pretty_precompiled_res first nexts = | |
(* A slight attempt to identify semantically equivalent lambda-expressions *) | |
exception Not_simple | |
-let rec raw_rec env = function | |
+let rec raw_rec env l = match l.l_desc with | |
| Llet(Alias,x,ex, body) -> raw_rec ((x,raw_rec env ex)::env) body | |
- | Lvar id as l -> | |
+ | Lvar id -> | |
begin try List.assoc id env with | |
| Not_found -> l | |
end | |
| Lprim (Pfield i,args) -> | |
- Lprim (Pfield i, List.map (raw_rec env) args) | |
- | Lconst _ as l -> l | |
+ mk_loc_lam l.l_loc (Lprim (Pfield i, List.map (raw_rec env) args)) | |
+ | Lconst _ -> l | |
| Lstaticraise (i,args) -> | |
- Lstaticraise (i, List.map (raw_rec env) args) | |
+ mk_loc_lam l.l_loc (Lstaticraise (i, List.map (raw_rec env) args)) | |
| _ -> raise Not_simple | |
let raw_action l = try raw_rec [] l with Not_simple -> l | |
@@ -479,7 +479,7 @@ let up_ok_action act1 act2 = | |
try | |
let raw1 = raw_rec [] act1 | |
and raw2 = raw_rec [] act2 in | |
- match raw1, raw2 with | |
+ match raw1.l_desc, raw2.l_desc with | |
| Lstaticraise (i1,[]), Lstaticraise (i2,[]) -> i1=i2 | |
| _,_ -> raw1 = raw2 | |
with | |
@@ -922,7 +922,7 @@ and split_constr cls args def k = | |
and precompile_var args cls def k = match args with | |
| [] -> assert false | |
-| _::((Lvar v as av,_) as arg)::rargs -> | |
+| _::(({l_desc=Lvar v} as av,_) as arg)::rargs -> | |
begin match cls with | |
| [ps,_] -> (* as splitted as it can *) | |
dont_precompile_var args cls def k | |
@@ -959,7 +959,7 @@ and dont_precompile_var args cls def k = | |
and precompile_or argo cls ors args def k = match ors with | |
| [] -> split_constr cls args def k | |
-| _ -> | |
+| (_,{l_loc}) :: _ -> | |
let rec do_cases = function | |
| ({pat_desc=Tpat_or _} as orp::patl, action)::rem -> | |
let others,rem = get_equiv orp rem in | |
@@ -981,9 +981,11 @@ and precompile_or argo cls ors args def k = match ors with | |
let or_num = next_raise_count () in | |
let new_patl = Parmatch.omega_list patl in | |
- let mk_new_action vs = | |
- Lstaticraise | |
- (or_num, List.map (fun v -> Lvar v) vs) in | |
+ let mk_new_action vs = { | |
+ l_loc; | |
+ l_desc = Lstaticraise | |
+ (or_num, List.map (fun v -> {l_loc; l_desc=Lvar v}) vs) | |
+ } in | |
let body,handlers = do_cases rem in | |
explode_or_pat | |
@@ -1125,7 +1127,12 @@ let make_field_args binding_kind arg first_pos last_pos argl = | |
let rec make_args pos = | |
if pos > last_pos | |
then argl | |
- else (Lprim(Pfield pos, [arg]), binding_kind) :: make_args (pos + 1) | |
+ else | |
+ let lam = { | |
+ l_loc = arg.l_loc; | |
+ l_desc = Lprim(Pfield pos, [arg]); | |
+ } in | |
+ (lam, binding_kind) :: make_args (pos + 1) | |
in make_args first_pos | |
let get_key_constr = function | |
@@ -1244,11 +1251,18 @@ let make_variant_matching_nonconst p lab def ctx = function | |
| ((arg, mut) :: argl) -> | |
let def = make_default (matcher_variant_nonconst lab) def | |
and ctx = filter_ctx p ctx in | |
- {pm= | |
- {cases = []; args = (Lprim(Pfield 1, [arg]), Alias) :: argl; | |
- default=def} ; | |
+ let lam = { | |
+ l_loc = arg.l_loc; | |
+ l_desc = Lprim(Pfield 1, [arg]); | |
+ } in { | |
+ pm = { | |
+ cases = []; | |
+ args = (lam, Alias) :: argl; | |
+ default=def | |
+ }; | |
ctx=ctx ; | |
- pat = normalize_pat p} | |
+ pat = normalize_pat p | |
+ } | |
let get_key_variant p = match p.pat_desc with | |
| Tpat_variant(lab, Some _ , _) -> Cstr_block (Btype.hash_variant lab) | |
@@ -1327,11 +1341,15 @@ let get_mod_field modname field = | |
let env = Env.open_pers_signature modname Env.initial in | |
let p = try | |
match Env.lookup_value (Longident.Lident field) env with | |
- | (Path.Pdot(_,_,i), _) -> i | |
- | _ -> fatal_error ("Primitive "^modname^"."^field^" not found.") | |
- with Not_found -> fatal_error ("Primitive "^modname^"."^field^" not found.") | |
- in | |
- Lprim(Pfield p, [Lprim(Pgetglobal mod_ident, [])]) | |
+ | (Path.Pdot(_,_,i), _) -> i | |
+ | _ -> fatal_error ("Primitive "^modname^"."^field^" not found.") | |
+ with Not_found -> fatal_error ("Primitive "^modname^"."^field^" not found.") | |
+ in { | |
+ l_loc = Location.none; | |
+ l_desc = Lprim(Pfield p, [{ | |
+ l_loc = Location.none; | |
+ l_desc = Lprim(Pgetglobal mod_ident, []) | |
+ }])} | |
with Not_found -> fatal_error ("Module "^modname^" unavailable.") | |
) | |
@@ -1354,37 +1372,46 @@ let inline_lazy_force_cond arg loc = | |
let varg = Lvar idarg in | |
let tag = Ident.create "tag" in | |
let force_fun = Lazy.force code_force_lazy_block in | |
- Llet(Strict, idarg, arg, | |
- Llet(Alias, tag, Lprim(Pccall prim_obj_tag, [varg]), | |
- Lifthenelse( | |
- (* if (tag == Obj.forward_tag) then varg.(0) else ... *) | |
- Lprim(Pintcomp Ceq, | |
- [Lvar tag; Lconst(Const_base(Const_int Obj.forward_tag))]), | |
- Lprim(Pfield 0, [varg]), | |
- Lifthenelse( | |
- (* ... if (tag == Obj.lazy_tag) then Lazy.force varg else ... *) | |
- Lprim(Pintcomp Ceq, | |
- [Lvar tag; Lconst(Const_base(Const_int Obj.lazy_tag))]), | |
- Lapply(force_fun, [varg], loc), | |
- (* ... arg *) | |
- varg)))) | |
+ let make = mk_loc_lam loc in | |
+ make | |
+ (Llet(Strict, idarg, arg, | |
+ make ( | |
+ Llet(Alias, tag, make (Lprim(Pccall prim_obj_tag, [make varg])), | |
+ make (Lifthenelse( | |
+ (* if (tag == Obj.forward_tag) then varg.(0) else ... *) | |
+ make (Lprim(Pintcomp Ceq, | |
+ [make (Lvar tag); | |
+ make (Lconst(Const_base(Const_int Obj.forward_tag))) | |
+ ])), | |
+ make (Lprim(Pfield 0, [make varg])), | |
+ make (Lifthenelse( | |
+ (* ... if (tag == Obj.lazy_tag) then Lazy.force varg else ... *) | |
+ make (Lprim(Pintcomp Ceq, | |
+ [make (Lvar tag); | |
+ make (Lconst(Const_base(Const_int Obj.lazy_tag))) | |
+ ])), | |
+ make (Lapply(force_fun, [make varg])), | |
+ (* ... arg *) | |
+ make varg)))))))) | |
let inline_lazy_force_switch arg loc = | |
let idarg = Ident.create "lzarg" in | |
let varg = Lvar idarg in | |
let force_fun = Lazy.force code_force_lazy_block in | |
- Llet(Strict, idarg, arg, | |
- Lifthenelse( | |
- Lprim(Pisint, [varg]), varg, | |
- (Lswitch | |
- (varg, | |
- { sw_numconsts = 0; sw_consts = []; | |
- sw_numblocks = (max Obj.lazy_tag Obj.forward_tag) + 1; | |
- sw_blocks = | |
- [ (Obj.forward_tag, Lprim(Pfield 0, [varg])); | |
- (Obj.lazy_tag, | |
- Lapply(force_fun, [varg], loc)) ]; | |
- sw_failaction = Some varg } )))) | |
+ let make = mk_loc_lam loc in | |
+ make (Llet(Strict, idarg, arg, | |
+ make (Lifthenelse( | |
+ make (Lprim(Pisint, [make varg])), | |
+ make varg, | |
+ make (Lswitch | |
+ (make varg, | |
+ { sw_numconsts = 0; sw_consts = []; | |
+ sw_numblocks = (max Obj.lazy_tag Obj.forward_tag) + 1; | |
+ sw_blocks = [ | |
+ (Obj.forward_tag, make (Lprim(Pfield 0, [make varg]))); | |
+ (Obj.lazy_tag, make (Lapply(force_fun, [make varg]))); | |
+ ]; | |
+ sw_failaction = Some (make varg) })))))) | |
let inline_lazy_force = | |
if !Clflags.native_code then | |
@@ -1398,9 +1425,8 @@ let inline_lazy_force = | |
let make_lazy_matching def = function | |
[] -> fatal_error "Matching.make_lazy_matching" | |
| (arg,mut) :: argl -> | |
- { cases = []; | |
- args = | |
- (inline_lazy_force arg Location.none, Strict) :: argl; | |
+ { cases = []; | |
+ args = (inline_lazy_force arg arg.l_loc, Strict) :: argl; | |
default = make_default matcher_lazy def } | |
let divide_lazy p ctx pm = | |
@@ -1430,9 +1456,17 @@ let make_tuple_matching arity def = function | |
let rec make_args pos = | |
if pos >= arity | |
then argl | |
- else (Lprim(Pfield pos, [arg]), Alias) :: make_args (pos + 1) in | |
- {cases = []; args = make_args 0 ; | |
- default=make_default (matcher_tuple arity) def} | |
+ else | |
+ let lam = { | |
+ l_loc = arg.l_loc; | |
+ l_desc = Lprim(Pfield pos, [arg]); | |
+ } in | |
+ (lam, Alias) :: make_args (pos + 1) | |
+ in { | |
+ cases = []; | |
+ args = make_args 0 ; | |
+ default = make_default (matcher_tuple arity) def | |
+ } | |
let divide_tuple arity p ctx pm = | |
@@ -1475,7 +1509,11 @@ let make_record_matching all_labels def = function | |
match lbl.lbl_mut with | |
Immutable -> Alias | |
| Mutable -> StrictOpt in | |
- (Lprim(access, [arg]), str) :: make_args(pos + 1) | |
+ let lam = { | |
+ l_loc = arg.l_loc; | |
+ l_desc = Lprim(access, [arg]); | |
+ } in | |
+ (lam, str) :: make_args(pos + 1) | |
end in | |
let nfields = Array.length all_labels in | |
let def= make_default (matcher_record nfields) def in | |
@@ -1513,8 +1551,12 @@ let make_array_matching kind p def ctx = function | |
let rec make_args pos = | |
if pos >= len | |
then argl | |
- else (Lprim(Parrayrefu kind, [arg; Lconst(Const_base(Const_int pos))]), | |
- StrictOpt) :: make_args (pos + 1) in | |
+ else | |
+ let make = mk_loc_lam arg.l_loc in | |
+ let lam = | |
+ make (Lprim(Parrayrefu kind, | |
+ [arg; make (Lconst(Const_base(Const_int pos)))])) in | |
+ (lam, StrictOpt) :: make_args (pos + 1) in | |
let def = make_default (matcher_array len) def | |
and ctx = filter_ctx p ctx in | |
{pm={cases = []; args = make_args 0 ; default = def} ; | |
@@ -1548,19 +1590,23 @@ let rec cut n l = | |
let rec do_tests_fail fail tst arg = function | |
| [] -> fail | |
| (c, act)::rem -> | |
- Lifthenelse | |
- (Lprim (tst, [arg ; Lconst (Const_base c)]), | |
- do_tests_fail fail tst arg rem, | |
- act) | |
+ let make = mk_loc_lam arg.l_loc in | |
+ make | |
+ (Lifthenelse | |
+ (make (Lprim (tst, [arg ; make (Lconst (Const_base c))])), | |
+ do_tests_fail fail tst arg rem, | |
+ act)) | |
let rec do_tests_nofail tst arg = function | |
| [] -> fatal_error "Matching.do_tests_nofail" | |
| [_,act] -> act | |
| (c,act)::rem -> | |
- Lifthenelse | |
- (Lprim (tst, [arg ; Lconst (Const_base c)]), | |
- do_tests_nofail tst arg rem, | |
- act) | |
+ let make = mk_loc_lam arg.l_loc in | |
+ make | |
+ (Lifthenelse | |
+ (make (Lprim (tst, [arg ; make (Lconst (Const_base c))])), | |
+ do_tests_nofail tst arg rem, | |
+ act)) | |
let make_test_sequence fail tst lt_tst arg const_lambda_list = | |
let rec make_test_sequence const_lambda_list = | |
@@ -1573,12 +1619,22 @@ let make_test_sequence fail tst lt_tst arg const_lambda_list = | |
and split_sequence const_lambda_list = | |
let list1, list2 = | |
cut (List.length const_lambda_list / 2) const_lambda_list in | |
- Lifthenelse(Lprim(lt_tst,[arg; Lconst(Const_base (fst(List.hd list2)))]), | |
- make_test_sequence list1, make_test_sequence list2) | |
- in make_test_sequence (sort_lambda_list const_lambda_list) | |
+ let hd_const, hd_lam = List.hd list2 in | |
+ let make = mk_loc_lam hd_lam.l_loc in | |
+ make (Lifthenelse( | |
+ make (Lprim(lt_tst,[arg; make (Lconst(Const_base hd_const))])), | |
+ make_test_sequence list1, | |
+ make_test_sequence list2)) in | |
+ make_test_sequence (sort_lambda_list const_lambda_list) | |
-let make_offset x arg = if x=0 then arg else Lprim(Poffsetint(x), [arg]) | |
+let make_offset x arg = | |
+ if x=0 then | |
+ arg | |
+ else { | |
+ l_loc = arg.l_loc; | |
+ l_desc = Lprim(Poffsetint(x), [arg]); | |
+ } | |
@@ -1652,13 +1708,13 @@ let full sw = | |
List.length sw.sw_blocks = sw.sw_numblocks | |
let make_switch (arg,sw) = match sw.sw_failaction with | |
-| None -> | |
+ | None -> | |
let t = Hashtbl.create 17 in | |
- let seen l = match l with | |
- | Lstaticraise (i,[]) -> | |
+ let seen l = match l.l_desc with | |
+ | Lstaticraise (i,[]) -> | |
let old = try Hashtbl.find t i with Not_found -> 0 in | |
Hashtbl.replace t i (old+1) | |
- | _ -> () in | |
+ | _ -> () in | |
List.iter (fun (_,lam) -> seen lam) sw.sw_consts ; | |
List.iter (fun (_,lam) -> seen lam) sw.sw_blocks ; | |
let i_max = ref (-1) | |
@@ -1669,22 +1725,23 @@ let make_switch (arg,sw) = match sw.sw_failaction with | |
i_max := i ; | |
max := c | |
end) t ; | |
+ let make = mk_loc_lam arg.l_loc in | |
if !i_max >= 0 then | |
let default = !i_max in | |
let rec remove = function | |
| [] -> [] | |
- | (_,Lstaticraise (j,[]))::rem when j=default -> | |
- remove rem | |
+ | (_,{l_desc=Lstaticraise (j,[])})::rem when j=default -> | |
+ remove rem | |
| x::rem -> x::remove rem in | |
- Lswitch | |
- (arg, | |
- {sw with | |
-sw_consts = remove sw.sw_consts ; | |
-sw_blocks = remove sw.sw_blocks ; | |
-sw_failaction = Some (Lstaticraise (default,[]))}) | |
+ make (Lswitch (arg, | |
+ { sw with | |
+ sw_consts = remove sw.sw_consts ; | |
+ sw_blocks = remove sw.sw_blocks ; | |
+ sw_failaction = Some (make (Lstaticraise (default,[]))); | |
+ })) | |
else | |
- Lswitch (arg,sw) | |
-| _ -> Lswitch (arg,sw) | |
+ make (Lswitch (arg,sw)) | |
+ | _ -> { l_loc = arg.l_loc; l_desc = Lswitch (arg,sw) } | |
module SArg = struct | |
type primitive = Lambda.primitive | |
@@ -1698,28 +1755,31 @@ module SArg = struct | |
type act = Lambda.lambda | |
- let make_prim p args = Lprim (p,args) | |
+ let make_prim p args = {l_loc = Location.none; l_desc = Lprim (p,args) } | |
let make_offset arg n = match n with | |
| 0 -> arg | |
- | _ -> Lprim (Poffsetint n,[arg]) | |
+ | _ -> { l_loc = arg.l_loc; l_desc = Lprim (Poffsetint n,[arg]) } | |
let bind arg body = | |
- let newvar,newarg = match arg with | |
+ let newvar,newarg = match arg.l_desc with | |
| Lvar v -> v,arg | |
| _ -> | |
let newvar = Ident.create "switcher" in | |
- newvar,Lvar newvar in | |
+ newvar, mk_loc_lam arg.l_loc (Lvar newvar) in | |
bind Alias newvar arg (body newarg) | |
- let make_isout h arg = Lprim (Pisout, [h ; arg]) | |
- let make_isin h arg = Lprim (Pnot,[make_isout h arg]) | |
- let make_if cond ifso ifnot = Lifthenelse (cond, ifso, ifnot) | |
- let make_switch = make_switch_switcher | |
+ let make_isout h arg = mk_loc_lam arg.l_loc (Lprim (Pisout, [h ; arg])) | |
+ let make_isin h arg = mk_loc_lam arg.l_loc (Lprim (Pnot,[make_isout h arg])) | |
+ let make_if cond ifso ifnot = mk_loc_lam cond.l_loc (Lifthenelse (cond, ifso, ifnot)) | |
+ let make_switch cond ia la = mk_loc_lam cond.l_loc (make_switch_switcher cond ia la) | |
end | |
module Switcher = Switch.Make(SArg) | |
open Switch | |
-let lambda_of_int i = Lconst (Const_base (Const_int i)) | |
+let lambda_of_int loc i = { | |
+ l_loc = loc; | |
+ l_desc = Lconst (Const_base (Const_int i)); | |
+} | |
let rec last def = function | |
| [] -> def | |
@@ -1910,17 +1970,20 @@ let mk_res get_key env last_choice idef cant_fail ctx = | |
*) | |
let mk_failaction_neg partial ctx def = match partial with | |
-| Partial -> | |
+ | Partial -> | |
begin match def with | |
- | (_,idef)::_ -> | |
- Some (Lstaticraise (idef,[])),[],jumps_singleton idef ctx | |
- | _ -> | |
- (* Act as Total, this means | |
- If no appropriate default matrix exists, | |
- then this switch cannot fail *) | |
+ | (_,idef)::_ -> | |
+ Some { | |
+ l_loc = Location.none; | |
+ l_desc = Lstaticraise (idef,[]) | |
+ },[],jumps_singleton idef ctx | |
+ | _ -> | |
+ (* Act as Total, this means | |
+ If no appropriate default matrix exists, | |
+ then this switch cannot fail *) | |
None, [], jumps_empty | |
end | |
-| Total -> | |
+ | Total -> | |
None, [], jumps_empty | |
@@ -1928,25 +1991,28 @@ let mk_failaction_neg partial ctx def = match partial with | |
(* Conforme a l'article et plus simple qu'avant *) | |
and mk_failaction_pos partial seen ctx defs = | |
let rec scan_def env to_test defs = match to_test,defs with | |
- | ([],_)|(_,[]) -> | |
- List.fold_left | |
- (fun (klist,jumps) (pats,i)-> | |
- let action = Lstaticraise (i,[]) in | |
- let klist = | |
- List.fold_right | |
- (fun pat r -> (get_key_constr pat,action)::r) | |
- pats klist | |
- and jumps = | |
- jumps_add i (ctx_lub (list_as_pat pats) ctx) jumps in | |
- klist,jumps) | |
- ([],jumps_empty) env | |
- | _,(pss,idef)::rem -> | |
+ | ([],_)|(_,[]) -> | |
+ List.fold_left | |
+ (fun (klist,jumps) (pats,i)-> | |
+ let action = { | |
+ l_loc = Location.none; | |
+ l_desc = Lstaticraise (i,[]); | |
+ } in | |
+ let klist = | |
+ List.fold_right | |
+ (fun pat r -> (get_key_constr pat,action)::r) | |
+ pats klist | |
+ and jumps = | |
+ jumps_add i (ctx_lub (list_as_pat pats) ctx) jumps in | |
+ klist,jumps) | |
+ ([],jumps_empty) env | |
+ | _,(pss,idef)::rem -> | |
let now, later = | |
List.partition | |
(fun (p,p_ctx) -> ctx_match p_ctx pss) to_test in | |
match now with | |
- | [] -> scan_def env to_test rem | |
- | _ -> scan_def ((List.map fst now,idef)::env) later rem in | |
+ | [] -> scan_def env to_test rem | |
+ | _ -> scan_def ((List.map fst now,idef)::env) later rem in | |
scan_def | |
[] | |
@@ -1968,14 +2034,14 @@ let combine_constant arg cst partial ctx def | |
List.map (function Const_int n, l -> n,l | _ -> assert false) | |
const_lambda_list in | |
call_switcher | |
- lambda_of_int fail arg min_int max_int int_lambda_list | |
+ (lambda_of_int arg.l_loc) fail arg min_int max_int int_lambda_list | |
| Const_char _ -> | |
let int_lambda_list = | |
List.map (function Const_char c, l -> (Char.code c, l) | |
| _ -> assert false) | |
const_lambda_list in | |
call_switcher | |
- (fun i -> Lconst (Const_base (Const_int i))) | |
+ (fun i -> { l_loc = arg.l_loc; l_desc = Lconst (Const_base (Const_int i))}) | |
fail arg 0 255 int_lambda_list | |
| Const_string _ -> | |
make_test_sequence | |
@@ -2038,9 +2104,12 @@ let combine_constructor arg ex_pat cstr partial ctx def | |
(fun (ex, act) rem -> | |
match ex with | |
| Cstr_exception path -> | |
- Lifthenelse(Lprim(Pintcomp Ceq, | |
- [Lprim(Pfield 0, [arg]); transl_path path]), | |
- act, rem) | |
+ let make = mk_loc_lam arg.l_loc in | |
+ make (Lifthenelse( | |
+ make (Lprim( | |
+ Pintcomp Ceq, | |
+ [make (Lprim(Pfield 0, [arg])); transl_path path])), | |
+ act, rem)) | |
| _ -> assert false) | |
tests default in | |
lambda1, jumps_union local_jumps total1 | |
@@ -2050,41 +2119,43 @@ let combine_constructor arg ex_pat cstr partial ctx def | |
and nconstrs = cstr.cstr_consts + cstr.cstr_nonconsts in | |
let sig_complete = ncases = nconstrs in | |
let fails,local_jumps = | |
- if sig_complete then [],jumps_empty | |
+ if sig_complete then | |
+ [],jumps_empty | |
else | |
mk_failaction_pos partial pats ctx def in | |
let tag_lambda_list = fails @ tag_lambda_list in | |
let (consts, nonconsts) = split_cases tag_lambda_list in | |
+ let make = mk_loc_lam arg.l_loc in | |
let lambda1 = | |
match same_actions tag_lambda_list with | |
- | Some act -> act | |
- | _ -> | |
+ | Some act -> act | |
+ | _ -> | |
match | |
(cstr.cstr_consts, cstr.cstr_nonconsts, consts, nonconsts) | |
with | |
- | (1, 1, [0, act1], [0, act2]) -> | |
- Lifthenelse(arg, act2, act1) | |
- | (n,_,_,[]) -> | |
+ | (1, 1, [0, act1], [0, act2]) -> | |
+ make (Lifthenelse(arg, act2, act1)) | |
+ | (n,_,_,[]) -> | |
call_switcher | |
- (fun i -> Lconst (Const_base (Const_int i))) | |
+ (fun i -> make (Lconst (Const_base (Const_int i)))) | |
None arg 0 (n-1) consts | |
- | (n, _, _, _) -> | |
+ | (n, _, _, _) -> | |
match same_actions nonconsts with | |
- | None -> | |
+ | None -> | |
make_switch(arg, {sw_numconsts = cstr.cstr_consts; | |
- sw_consts = consts; | |
- sw_numblocks = cstr.cstr_nonconsts; | |
- sw_blocks = nonconsts; | |
- sw_failaction = None}) | |
- | Some act -> | |
- Lifthenelse | |
- (Lprim (Pisint, [arg]), | |
- call_switcher | |
- (fun i -> Lconst (Const_base (Const_int i))) | |
- None arg | |
- 0 (n-1) consts, | |
- act) in | |
+ sw_consts = consts; | |
+ sw_numblocks = cstr.cstr_nonconsts; | |
+ sw_blocks = nonconsts; | |
+ sw_failaction = None}) | |
+ | Some act -> | |
+ make (Lifthenelse | |
+ (make (Lprim (Pisint, [arg])), | |
+ call_switcher | |
+ (fun i -> make (Lconst (Const_base (Const_int i)))) | |
+ None arg | |
+ 0 (n-1) consts, | |
+ act)) in | |
lambda1, jumps_union local_jumps total1 | |
end | |
@@ -2092,20 +2163,24 @@ let make_test_sequence_variant_constant fail arg int_lambda_list = | |
let _, (cases, actions) = | |
as_interval fail min_int max_int int_lambda_list in | |
Switcher.test_sequence | |
- (fun i -> Lconst (Const_base (Const_int i))) arg cases actions | |
+ (fun i -> { l_loc = arg.l_loc; | |
+ l_desc = Lconst (Const_base (Const_int i))}) | |
+ arg cases actions | |
let call_switcher_variant_constant fail arg int_lambda_list = | |
call_switcher | |
- (fun i -> Lconst (Const_base (Const_int i))) | |
+ (fun i -> { l_loc = arg.l_loc; | |
+ l_desc = Lconst (Const_base (Const_int i))}) | |
fail arg min_int max_int int_lambda_list | |
let call_switcher_variant_constr fail arg int_lambda_list = | |
let v = Ident.create "variant" in | |
- Llet(Alias, v, Lprim(Pfield 0, [arg]), | |
- call_switcher | |
- (fun i -> Lconst (Const_base (Const_int i))) | |
- fail (Lvar v) min_int max_int int_lambda_list) | |
+ let make = mk_loc_lam arg.l_loc in | |
+ make (Llet(Alias, v, make (Lprim(Pfield 0, [arg])), | |
+ call_switcher | |
+ (fun i -> make (Lconst (Const_base (Const_int i)))) | |
+ fail (make (Lvar v)) min_int max_int int_lambda_list)) | |
let combine_variant row arg partial ctx def (tag_lambda_list, total1, pats) = | |
let row = Btype.row_repr row in | |
@@ -2120,7 +2195,8 @@ let combine_variant row arg partial ctx def (tag_lambda_list, total1, pats) = | |
else | |
num_constr := max_int; | |
let test_int_or_block arg if_int if_block = | |
- Lifthenelse(Lprim (Pisint, [arg]), if_int, if_block) in | |
+ let make = mk_loc_lam arg.l_loc in | |
+ make (Lifthenelse(make (Lprim (Pisint, [arg])), if_int, if_block)) in | |
let sig_complete = List.length tag_lambda_list = !num_constr | |
and one_action = same_actions tag_lambda_list in | |
let fail, to_add, local_jumps = | |
@@ -2166,36 +2242,33 @@ let combine_array arg kind partial ctx def | |
let len_lambda_list = to_add @ len_lambda_list in | |
let lambda1 = | |
let newvar = Ident.create "len" in | |
+ let make = mk_loc_lam arg.l_loc in | |
let switch = | |
call_switcher | |
- lambda_of_int | |
- fail (Lvar newvar) | |
+ (lambda_of_int arg.l_loc) | |
+ fail (make (Lvar newvar)) | |
0 max_int len_lambda_list in | |
- bind | |
- Alias newvar (Lprim(Parraylength kind, [arg])) switch in | |
+ bind Alias newvar (make (Lprim(Parraylength kind, [arg]))) switch in | |
lambda1, jumps_union local_jumps total1 | |
(* Insertion of debugging events *) | |
-let rec event_branch repr lam = | |
- begin match lam, repr with | |
- (_, None) -> | |
- lam | |
+let rec event_branch repr lam = match lam.l_desc, repr with | |
+ | (_, None) -> lam | |
| (Levent(lam', ev), Some r) -> | |
- incr r; | |
- Levent(lam', {lev_loc = ev.lev_loc; | |
- lev_kind = ev.lev_kind; | |
- lev_repr = repr; | |
- lev_env = ev.lev_env}) | |
+ incr r; | |
+ mk_loc_lam lam.l_loc | |
+ (Levent(lam', {lev_loc = ev.lev_loc; | |
+ lev_kind = ev.lev_kind; | |
+ lev_repr = repr; | |
+ lev_env = ev.lev_env})) | |
| (Llet(str, id, lam, body), _) -> | |
- Llet(str, id, lam, event_branch repr body) | |
+ mk_loc_lam lam.l_loc (Llet(str, id, lam, event_branch repr body)) | |
| Lstaticraise _,_ -> lam | |
| (_, Some r) -> | |
- Printlambda.lambda Format.str_formatter lam ; | |
- fatal_error | |
- ("Matching.event_branch: "^Format.flush_str_formatter ()) | |
- end | |
- | |
+ Printlambda.lambda Format.str_formatter lam ; | |
+ fatal_error | |
+ ("Matching.event_branch: "^Format.flush_str_formatter ()) | |
(* | |
This exception is raised when the compiler cannot produce code | |
@@ -2237,27 +2310,29 @@ let compile_orhandlers compile_fun lambda1 total1 ctx to_catch = | |
let rec do_rec r total_r = function | |
| [] -> r,total_r | |
| (mat,i,vars,pm)::rem -> | |
- begin try | |
- let ctx = select_columns mat ctx in | |
- let handler_i, total_i = compile_fun ctx pm in | |
- match raw_action r with | |
+ let lam = raw_action r in | |
+ try | |
+ let ctx = select_columns mat ctx in | |
+ let handler_i, total_i = compile_fun ctx pm in | |
+ match lam.l_desc with | |
| Lstaticraise (j,args) -> | |
- if i=j then | |
- List.fold_right2 (bind Alias) vars args handler_i, | |
- jumps_map (ctx_rshift_num (ncols mat)) total_i | |
- else | |
- do_rec r total_r rem | |
+ if i=j then | |
+ List.fold_right2 (bind Alias) vars args handler_i, | |
+ jumps_map (ctx_rshift_num (ncols mat)) total_i | |
+ else | |
+ do_rec r total_r rem | |
| _ -> | |
- do_rec | |
- (Lstaticcatch (r,(i,vars), handler_i)) | |
- (jumps_union | |
- (jumps_remove i total_r) | |
- (jumps_map (ctx_rshift_num (ncols mat)) total_i)) | |
+ do_rec | |
+ (mk_loc_lam lam.l_loc (Lstaticcatch (r,(i,vars), handler_i))) | |
+ (jumps_union | |
+ (jumps_remove i total_r) | |
+ (jumps_map (ctx_rshift_num (ncols mat)) total_i)) | |
rem | |
- with | |
+ with | |
| Unused -> | |
- do_rec (Lstaticcatch (r, (i,vars), lambda_unit)) total_r rem | |
- end in | |
+ do_rec | |
+ (mk_loc_lam lam.l_loc (Lstaticcatch (r, (i,vars), lambda_unit))) | |
+ total_r rem in | |
do_rec lambda1 total1 to_catch | |
@@ -2276,7 +2351,7 @@ let compile_test compile_fun partial divide combine ctx to_match = | |
(* Attempt to avoid some useless bindings by lowering them *) | |
(* Approximation of v present in lam *) | |
-let rec approx_present v = function | |
+let rec approx_present v l = match l.l_desc with | |
| Lconst _ -> false | |
| Lstaticraise (_,args) -> | |
List.exists (fun lam -> approx_present v lam) args | |
@@ -2291,76 +2366,81 @@ let string_of_lam lam = | |
Printlambda.lambda Format.str_formatter lam ; | |
Format.flush_str_formatter () | |
-let rec lower_bind v arg lam = match lam with | |
-| Lifthenelse (cond, ifso, ifnot) -> | |
+let rec lower_bind v arg lam = match lam.l_desc with | |
+ | Lifthenelse (cond, ifso, ifnot) -> | |
let pcond = approx_present v cond | |
and pso = approx_present v ifso | |
and pnot = approx_present v ifnot in | |
begin match pcond, pso, pnot with | |
- | false, false, false -> lam | |
- | false, true, false -> | |
- Lifthenelse (cond, lower_bind v arg ifso, ifnot) | |
- | false, false, true -> | |
- Lifthenelse (cond, ifso, lower_bind v arg ifnot) | |
- | _,_,_ -> bind Alias v arg lam | |
+ | false, false, false -> lam | |
+ | false, true, false -> | |
+ (mk_loc_lam lam.l_loc (Lifthenelse (cond, lower_bind v arg ifso, ifnot))) | |
+ | false, false, true -> | |
+ (mk_loc_lam lam.l_loc (Lifthenelse (cond, ifso, lower_bind v arg ifnot))) | |
+ | _,_,_ -> bind Alias v arg lam | |
end | |
-| Lswitch (ls,({sw_consts=[i,act] ; sw_blocks = []} as sw)) | |
- when not (approx_present v ls) -> | |
- Lswitch (ls, {sw with sw_consts = [i,lower_bind v arg act]}) | |
-| Lswitch (ls,({sw_consts=[] ; sw_blocks = [i,act]} as sw)) | |
- when not (approx_present v ls) -> | |
- Lswitch (ls, {sw with sw_blocks = [i,lower_bind v arg act]}) | |
-| Llet (Alias, vv, lv, l) -> | |
+ | Lswitch (ls,({sw_consts=[i,act] ; sw_blocks = []} as sw)) | |
+ when not (approx_present v ls) -> | |
+ {lam with | |
+ l_desc = Lswitch (ls, {sw with sw_consts = [i,lower_bind v arg act]})} | |
+ | Lswitch (ls,({sw_consts=[] ; sw_blocks = [i,act]} as sw)) | |
+ when not (approx_present v ls) -> | |
+ {lam with | |
+ l_desc = Lswitch (ls, {sw with sw_blocks = [i,lower_bind v arg act]})} | |
+ | Llet (Alias, vv, lv, l) -> | |
if approx_present v lv then | |
bind Alias v arg lam | |
else | |
- Llet (Alias, vv, lv, lower_bind v arg l) | |
-| _ -> | |
+ (mk_loc_lam lam.l_loc (Llet (Alias, vv, lv, lower_bind v arg l))) | |
+ | _ -> | |
bind Alias v arg lam | |
-let bind_check str v arg lam = match str,arg with | |
-| _, Lvar _ ->bind str v arg lam | |
-| Alias,_ -> lower_bind v arg lam | |
-| _,_ -> bind str v arg lam | |
+let bind_check str v arg lam = match str,arg.l_desc with | |
+ | _, Lvar _ ->bind str v arg lam | |
+ | Alias,_ -> lower_bind v arg lam | |
+ | _,_ -> bind str v arg lam | |
let rec comp_exit ctx m = match m.default with | |
-| (_,i)::_ -> Lstaticraise (i,[]), jumps_singleton i ctx | |
-| _ -> fatal_error "Matching.comp_exit" | |
+ | (_,i)::_ -> | |
+ { l_loc = Location.none; l_desc = Lstaticraise (i,[])}, | |
+ jumps_singleton i ctx | |
+ | _ -> fatal_error "Matching.comp_exit" | |
-let rec comp_match_handlers comp_fun partial ctx arg first_match next_matchs = match next_matchs with | |
+let rec comp_match_handlers comp_fun partial ctx arg first_match = function | |
| [] -> comp_fun partial ctx arg first_match | |
| rem -> | |
- let rec c_rec body total_body = function | |
- | [] -> body, total_body | |
- (* Hum, -1 meant never taken | |
- | (-1,pm)::rem -> c_rec body total_body rem *) | |
- | (i,pm)::rem -> | |
- let ctx_i,total_rem = jumps_extract i total_body in | |
- begin match ctx_i with | |
- | [] -> c_rec body total_body rem | |
- | _ -> | |
- try | |
- let li,total_i = | |
- comp_fun | |
- (match rem with [] -> partial | _ -> Partial) | |
- ctx_i arg pm in | |
- c_rec | |
- (Lstaticcatch (body,(i,[]),li)) | |
- (jumps_union total_i total_rem) | |
- rem | |
- with | |
- | Unused -> | |
- c_rec (Lstaticcatch (body,(i,[]),lambda_unit)) | |
- total_rem rem | |
- end in | |
- try | |
+ let make = mk_loc_lam arg.l_loc in | |
+ let rec c_rec body total_body = function | |
+ | [] -> body, total_body | |
+ (* Hum, -1 meant never taken | |
+ | (-1,pm)::rem -> c_rec body total_body rem *) | |
+ | (i,pm)::rem -> | |
+ let ctx_i,total_rem = jumps_extract i total_body in | |
+ begin match ctx_i with | |
+ | [] -> c_rec body total_body rem | |
+ | _ -> | |
+ try | |
+ let li,total_i = | |
+ comp_fun | |
+ (match rem with [] -> partial | _ -> Partial) | |
+ ctx_i arg pm in | |
+ c_rec | |
+ (make (Lstaticcatch (body,(i,[]),li))) | |
+ (jumps_union total_i total_rem) | |
+ rem | |
+ with | |
+ | Unused -> | |
+ c_rec (make (Lstaticcatch (body,(i,[]),lambda_unit))) | |
+ total_rem rem | |
+ end in | |
+ try | |
let first_lam,total = comp_fun Partial ctx arg first_match in | |
c_rec first_lam total rem | |
- with Unused -> match next_matchs with | |
- | [] -> raise Unused | |
- | (_,x)::xs -> comp_match_handlers comp_fun partial ctx arg x xs | |
+ with Unused -> match rem with | |
+ | [] -> raise Unused | |
+ | (_,x)::xs -> comp_match_handlers comp_fun partial ctx arg x xs | |
(* To find reasonable names for variables *) | |
@@ -2373,11 +2453,11 @@ let rec name_pattern default = function | |
end | |
| _ -> Ident.create default | |
-let arg_to_var arg cls = match arg with | |
+let arg_to_var arg cls = match arg.l_desc with | |
| Lvar v -> v,arg | |
| _ -> | |
let v = name_pattern "match" cls in | |
- v,Lvar v | |
+ v,{l_loc = arg.l_loc; l_desc = Lvar v} | |
(* | |
@@ -2393,15 +2473,15 @@ let arg_to_var arg cls = match arg with | |
let rec compile_match repr partial ctx m = match m with | |
-| { cases = [] } -> comp_exit ctx m | |
-| { cases = ([], action) :: rem } -> | |
+ | { cases = [] } -> comp_exit ctx m | |
+ | { cases = ([], action) :: rem } -> | |
if is_guarded action then begin | |
let (lambda, total) = | |
compile_match None partial ctx { m with cases = rem } in | |
event_branch repr (patch_guarded lambda action), total | |
end else | |
(event_branch repr action, jumps_empty) | |
-| { args = (arg, str)::argl } -> | |
+ | { args = (arg, str)::argl } -> | |
let v,newarg = arg_to_var arg m.cases in | |
let first_match,rem = | |
split_precompile (Some v) | |
@@ -2410,12 +2490,12 @@ let rec compile_match repr partial ctx m = match m with | |
comp_match_handlers | |
(do_compile_matching repr) partial ctx newarg first_match rem in | |
bind_check str v arg lam, total | |
-| _ -> assert false | |
+ | _ -> assert false | |
(* verbose version of do_compile_matching, for debug *) | |
(* | |
-and do_compile_matching_pr repr partial ctx arg x = | |
+ and do_compile_matching_pr repr partial ctx arg x = | |
prerr_string "COMPILE: " ; | |
prerr_endline (match partial with Partial -> "Partial" | Total -> "Total") ; | |
prerr_endline "MATCH" ; | |
@@ -2428,52 +2508,52 @@ and do_compile_matching_pr repr partial ctx arg x = | |
r | |
*) | |
and do_compile_matching repr partial ctx arg pmh = match pmh with | |
-| Pm pm -> | |
- let pat = what_is_cases pm.cases in | |
- begin match pat.pat_desc with | |
- | Tpat_any -> | |
- compile_no_test | |
- divide_var ctx_rshift repr partial ctx pm | |
- | Tpat_tuple patl -> | |
- compile_no_test | |
- (divide_tuple (List.length patl) (normalize_pat pat)) ctx_combine | |
- repr partial ctx pm | |
- | Tpat_record ((lbl,_)::_) -> | |
- compile_no_test | |
- (divide_record lbl.lbl_all (normalize_pat pat)) | |
- ctx_combine repr partial ctx pm | |
- | Tpat_constant cst -> | |
- compile_test | |
- (compile_match repr partial) partial | |
- divide_constant | |
- (combine_constant arg cst partial) | |
- ctx pm | |
- | Tpat_construct (cstr, _) -> | |
- compile_test | |
- (compile_match repr partial) partial | |
- divide_constructor (combine_constructor arg pat cstr partial) | |
- ctx pm | |
- | Tpat_array _ -> | |
- let kind = Typeopt.array_pattern_kind pat in | |
- compile_test (compile_match repr partial) partial | |
- (divide_array kind) (combine_array arg kind partial) | |
- ctx pm | |
- | Tpat_lazy _ -> | |
- compile_no_test | |
- (divide_lazy (normalize_pat pat)) | |
- ctx_combine repr partial ctx pm | |
- | Tpat_variant(lab, _, row) -> | |
- compile_test (compile_match repr partial) partial | |
- (divide_variant !row) | |
- (combine_variant !row arg partial) | |
- ctx pm | |
- | _ -> assert false | |
- end | |
-| PmVar {inside=pmh ; var_arg=arg} -> | |
+ | Pm pm -> | |
+ let pat = what_is_cases pm.cases in | |
+ begin match pat.pat_desc with | |
+ | Tpat_any -> | |
+ compile_no_test | |
+ divide_var ctx_rshift repr partial ctx pm | |
+ | Tpat_tuple patl -> | |
+ compile_no_test | |
+ (divide_tuple (List.length patl) (normalize_pat pat)) ctx_combine | |
+ repr partial ctx pm | |
+ | Tpat_record ((lbl,_)::_) -> | |
+ compile_no_test | |
+ (divide_record lbl.lbl_all (normalize_pat pat)) | |
+ ctx_combine repr partial ctx pm | |
+ | Tpat_constant cst -> | |
+ compile_test | |
+ (compile_match repr partial) partial | |
+ divide_constant | |
+ (combine_constant arg cst partial) | |
+ ctx pm | |
+ | Tpat_construct (cstr, _) -> | |
+ compile_test | |
+ (compile_match repr partial) partial | |
+ divide_constructor (combine_constructor arg pat cstr partial) | |
+ ctx pm | |
+ | Tpat_array _ -> | |
+ let kind = Typeopt.array_pattern_kind pat in | |
+ compile_test (compile_match repr partial) partial | |
+ (divide_array kind) (combine_array arg kind partial) | |
+ ctx pm | |
+ | Tpat_lazy _ -> | |
+ compile_no_test | |
+ (divide_lazy (normalize_pat pat)) | |
+ ctx_combine repr partial ctx pm | |
+ | Tpat_variant(lab, _, row) -> | |
+ compile_test (compile_match repr partial) partial | |
+ (divide_variant !row) | |
+ (combine_variant !row arg partial) | |
+ ctx pm | |
+ | _ -> assert false | |
+ end | |
+ | PmVar {inside=pmh ; var_arg=arg} -> | |
let lam, total = | |
do_compile_matching repr partial (ctx_lshift ctx) arg pmh in | |
lam, jumps_map ctx_rshift total | |
-| PmOr {body=body ; handlers=handlers} -> | |
+ | PmOr {body=body ; handlers=handlers} -> | |
let lam, total = compile_match repr partial ctx body in | |
compile_orhandlers (compile_match repr partial) lam total ctx handlers | |
@@ -2512,7 +2592,7 @@ let check_total total lambda i handler_fun = | |
if jumps_is_empty total then | |
lambda | |
else begin | |
- Lstaticcatch(lambda, (i,[]), handler_fun()) | |
+ mk_loc_lam lambda.l_loc (Lstaticcatch(lambda, (i,[]), handler_fun())) | |
end | |
let compile_matching loc repr handler_fun arg pat_act_list partial = | |
@@ -2543,19 +2623,26 @@ let compile_matching loc repr handler_fun arg pat_act_list partial = | |
let partial_function loc () = | |
(* [Location.get_pos_info] is too expensive *) | |
let (fname, line, char) = Location.get_pos_info loc.Location.loc_start in | |
- Lprim(Praise, [Lprim(Pmakeblock(0, Immutable), | |
- [transl_path Predef.path_match_failure; | |
- Lconst(Const_block(0, | |
- [Const_base(Const_string fname); | |
- Const_base(Const_int line); | |
- Const_base(Const_int char)]))])]) | |
+ let make = mk_loc_lam loc in | |
+ make | |
+ (Lprim | |
+ (Praise, | |
+ [make (Lprim(Pmakeblock(0, Immutable), | |
+ [transl_path Predef.path_match_failure; | |
+ make (Lconst | |
+ (Const_block(0, | |
+ [Const_base(Const_string fname); | |
+ Const_base(Const_int line); | |
+ Const_base(Const_int char)])))]) | |
+ )])) | |
let for_function loc repr param pat_act_list partial = | |
compile_matching loc repr (partial_function loc) param pat_act_list partial | |
(* In the following two cases, exhaustiveness info is not available! *) | |
let for_trywith param pat_act_list = | |
- compile_matching Location.none None (fun () -> Lprim(Praise, [param])) | |
+ compile_matching Location.none None | |
+ (fun () -> { l_loc = Location.none; l_desc = Lprim(Praise, [param])}) | |
param pat_act_list Partial | |
let for_let loc param pat body = | |
@@ -2568,11 +2655,12 @@ let for_tupled_function loc paraml pats_act_list partial = | |
let partial = check_partial pats_act_list partial in | |
let raise_num = next_raise_count () in | |
let omegas = [List.map (fun _ -> omega) paraml] in | |
- let pm = | |
- { cases = pats_act_list; | |
- args = List.map (fun id -> (Lvar id, Strict)) paraml ; | |
- default = [omegas,raise_num] | |
- } in | |
+ let pm = { | |
+ cases = pats_act_list; | |
+ args = List.map | |
+ (fun id -> ({l_loc=loc; l_desc=Lvar id}, Strict)) paraml ; | |
+ default = [omegas,raise_num] | |
+ } in | |
try | |
let (lambda, total) = compile_match None partial | |
(start_ctx (List.length paraml)) pm in | |
@@ -2647,28 +2735,29 @@ let compile_flattened repr partial ctx _ pmh = match pmh with | |
let do_for_multiple_match loc paraml pat_act_list partial = | |
let repr = None in | |
let partial = check_partial pat_act_list partial in | |
+ let make = mk_loc_lam loc in | |
let raise_num,pm1 = | |
match partial with | |
- | Partial -> | |
+ | Partial -> | |
let raise_num = next_raise_count () in | |
raise_num, | |
{ cases = List.map (fun (pat, act) -> ([pat], act)) pat_act_list; | |
- args = [Lprim(Pmakeblock(0, Immutable), paraml), Strict] ; | |
+ args = [make (Lprim(Pmakeblock(0, Immutable), paraml)), Strict] ; | |
default = [[[omega]],raise_num] } | |
- | _ -> | |
+ | _ -> | |
-1, | |
{ cases = List.map (fun (pat, act) -> ([pat], act)) pat_act_list; | |
- args = [Lprim(Pmakeblock(0, Immutable), paraml), Strict] ; | |
+ args = [make (Lprim(Pmakeblock(0, Immutable), paraml)), Strict] ; | |
default = [] } in | |
try | |
try | |
-(* Once for checking that compilation is possible *) | |
+ (* Once for checking that compilation is possible *) | |
let next, nexts = split_precompile None pm1 in | |
let size = List.length paraml | |
and idl = List.map (fun _ -> Ident.create "match") paraml in | |
- let args = List.map (fun id -> Lvar id, Alias) idl in | |
+ let args = List.map (fun id -> {l_loc = loc; l_desc = Lvar id}, Alias) idl in | |
let flat_next = flatten_precompiled size args next | |
and flat_nexts = | |
@@ -2676,23 +2765,24 @@ let do_for_multiple_match loc paraml pat_act_list partial = | |
(fun (e,pm) -> e,flatten_precompiled size args pm) | |
nexts in | |
+ let dummy_arg = { l_loc = loc; l_desc = Lvar (Ident.create "dummy") } in | |
let lam, total = | |
comp_match_handlers | |
(compile_flattened repr) | |
- partial (start_ctx size) () flat_next flat_nexts in | |
+ partial (start_ctx size) dummy_arg flat_next flat_nexts in | |
List.fold_right2 (bind Strict) idl paraml | |
(match partial with | |
- | Partial -> | |
+ | Partial -> | |
check_total total lam raise_num (partial_function loc) | |
- | Total -> | |
+ | Total -> | |
assert (jumps_is_empty total) ; | |
lam) | |
with Cannot_flatten -> | |
let (lambda, total) = compile_match None partial (start_ctx 1) pm1 in | |
begin match partial with | |
- | Partial -> | |
+ | Partial -> | |
check_total total lambda raise_num (partial_function loc) | |
- | Total -> | |
+ | Total -> | |
assert (jumps_is_empty total) ; | |
lambda | |
end | |
@@ -2702,14 +2792,14 @@ let do_for_multiple_match loc paraml pat_act_list partial = | |
(* #PR4828: Believe it or not, the 'paraml' argument below | |
may not be side effect free. *) | |
-let arg_to_var arg cls = match arg with | |
-| Lvar v -> v,arg | |
-| _ -> | |
+let arg_to_var arg cls = match arg.l_desc with | |
+ | Lvar v -> v,arg | |
+ | _ -> | |
let v = name_pattern "match" cls in | |
- v,Lvar v | |
+ v, {l_loc = arg.l_loc; l_desc = Lvar v} | |
-let rec param_to_var param = match param with | |
+let rec param_to_var param = match param.l_desc with | |
| Lvar v -> v,None | |
| _ -> Ident.create "match",Some param | |
@@ -2719,6 +2809,6 @@ let bind_opt (v,eo) k = match eo with | |
let for_multiple_match loc paraml pat_act_list partial = | |
let v_paraml = List.map param_to_var paraml in | |
- let paraml = List.map (fun (v,_) -> Lvar v) v_paraml in | |
+ let paraml = List.map (fun (v,_) -> {l_loc = loc; l_desc = Lvar v}) v_paraml in | |
List.fold_right bind_opt v_paraml | |
(do_for_multiple_match loc paraml pat_act_list partial) | |
diff --git a/bytecomp/printlambda.ml b/bytecomp/printlambda.ml | |
index 38182db..a7465a0 100644 | |
--- a/bytecomp/printlambda.ml | |
+++ b/bytecomp/printlambda.ml | |
@@ -183,12 +183,15 @@ let primitive ppf = function | |
| Pbigarrayset(unsafe, n, kind, layout) -> | |
print_bigarray "set" unsafe kind ppf layout | |
-let rec lam ppf = function | |
+let rec lam ppf l = | |
+ lam_desc ppf l.l_desc | |
+ | |
+and lam_desc ppf = function | |
| Lvar id -> | |
Ident.print ppf id | |
| Lconst cst -> | |
struct_const ppf cst | |
- | Lapply(lfun, largs, _) -> | |
+ | Lapply(lfun, largs) -> | |
let lams ppf largs = | |
List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in | |
fprintf ppf "@[<2>(apply@ %a%a)@]" lam lfun lams largs | |
@@ -211,11 +214,11 @@ let rec lam ppf = function | |
let rec letbody = function | |
| Llet(str, id, arg, body) -> | |
fprintf ppf "@ @[<2>%a@ %a@]" Ident.print id lam arg; | |
- letbody body | |
+ letbody body.l_desc | |
| expr -> expr in | |
fprintf ppf "@[<2>(let@ @[<hv 1>(@[<2>%a@ %a@]" Ident.print id lam arg; | |
- let expr = letbody body in | |
- fprintf ppf ")@]@ %a)@]" lam expr | |
+ let expr = letbody body.l_desc in | |
+ fprintf ppf ")@]@ %a)@]" lam_desc expr | |
| Lletrec(id_arg_list, body) -> | |
let bindings ppf id_arg_list = | |
let spc = ref false in | |
@@ -285,7 +288,7 @@ let rec lam ppf = function | |
lam hi lam body | |
| Lassign(id, expr) -> | |
fprintf ppf "@[<2>(assign@ %a@ %a)@]" Ident.print id lam expr | |
- | Lsend (k, met, obj, largs, _) -> | |
+ | Lsend (k, met, obj, largs) -> | |
let args ppf largs = | |
List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in | |
let kind = | |
@@ -304,11 +307,11 @@ let rec lam ppf = function | |
| Lifused(id, expr) -> | |
fprintf ppf "@[<2>(ifused@ %a@ %a)@]" Ident.print id lam expr | |
-and sequence ppf = function | |
+and sequence ppf l = match l.l_desc with | |
| Lsequence(l1, l2) -> | |
fprintf ppf "%a@ %a" sequence l1 sequence l2 | |
| l -> | |
- lam ppf l | |
+ lam_desc ppf l | |
let structured_constant = struct_const | |
diff --git a/bytecomp/simplif.ml b/bytecomp/simplif.ml | |
index e26524e..82b3388 100644 | |
--- a/bytecomp/simplif.ml | |
+++ b/bytecomp/simplif.ml | |
@@ -22,31 +22,33 @@ open Lambda | |
exception Real_reference | |
-let rec eliminate_ref id = function | |
- Lvar v as lam -> | |
+let rec eliminate_ref id lam = | |
+ let mk = mk_loc_lam lam.l_loc in | |
+ match lam.l_desc with | |
+ Lvar v -> | |
if Ident.same v id then raise Real_reference else lam | |
- | Lconst cst as lam -> lam | |
- | Lapply(e1, el, loc) -> | |
- Lapply(eliminate_ref id e1, List.map (eliminate_ref id) el, loc) | |
- | Lfunction(kind, params, body) as lam -> | |
+ | Lconst cst -> lam | |
+ | Lapply(e1, el) -> | |
+ mk (Lapply(eliminate_ref id e1, List.map (eliminate_ref id) el)) | |
+ | Lfunction(kind, params, body) -> | |
if IdentSet.mem id (free_variables lam) | |
then raise Real_reference | |
else lam | |
| Llet(str, v, e1, e2) -> | |
- Llet(str, v, eliminate_ref id e1, eliminate_ref id e2) | |
+ mk (Llet(str, v, eliminate_ref id e1, eliminate_ref id e2)) | |
| Lletrec(idel, e2) -> | |
- Lletrec(List.map (fun (v, e) -> (v, eliminate_ref id e)) idel, | |
- eliminate_ref id e2) | |
- | Lprim(Pfield 0, [Lvar v]) when Ident.same v id -> | |
- Lvar id | |
- | Lprim(Psetfield(0, _), [Lvar v; e]) when Ident.same v id -> | |
- Lassign(id, eliminate_ref id e) | |
- | Lprim(Poffsetref delta, [Lvar v]) when Ident.same v id -> | |
- Lassign(id, Lprim(Poffsetint delta, [Lvar id])) | |
+ mk (Lletrec(List.map (fun (v, e) -> (v, eliminate_ref id e)) idel, | |
+ eliminate_ref id e2)) | |
+ | Lprim(Pfield 0, [{l_desc=Lvar v}]) when Ident.same v id -> | |
+ mk (Lvar id) | |
+ | Lprim(Psetfield(0, _), [{l_desc=Lvar v}; e]) when Ident.same v id -> | |
+ mk (Lassign(id, eliminate_ref id e)) | |
+ | Lprim(Poffsetref delta, [({l_desc=Lvar v} as lamv)]) when Ident.same v id -> | |
+ mk (Lassign(id, mk(Lprim(Poffsetint delta, [mk_loc_lam lamv.l_loc (Lvar id)])))) | |
| Lprim(p, el) -> | |
- Lprim(p, List.map (eliminate_ref id) el) | |
+ mk (Lprim(p, List.map (eliminate_ref id) el)) | |
| Lswitch(e, sw) -> | |
- Lswitch(eliminate_ref id e, | |
+ mk (Lswitch(eliminate_ref id e, | |
{sw_numconsts = sw.sw_numconsts; | |
sw_consts = | |
List.map (fun (n, e) -> (n, eliminate_ref id e)) sw.sw_consts; | |
@@ -55,33 +57,33 @@ let rec eliminate_ref id = function | |
List.map (fun (n, e) -> (n, eliminate_ref id e)) sw.sw_blocks; | |
sw_failaction = match sw.sw_failaction with | |
| None -> None | |
- | Some l -> Some (eliminate_ref id l)}) | |
+ | Some l -> Some (eliminate_ref id l)})) | |
| Lstaticraise (i,args) -> | |
- Lstaticraise (i,List.map (eliminate_ref id) args) | |
+ mk (Lstaticraise (i,List.map (eliminate_ref id) args)) | |
| Lstaticcatch(e1, i, e2) -> | |
- Lstaticcatch(eliminate_ref id e1, i, eliminate_ref id e2) | |
+ mk (Lstaticcatch(eliminate_ref id e1, i, eliminate_ref id e2)) | |
| Ltrywith(e1, v, e2) -> | |
- Ltrywith(eliminate_ref id e1, v, eliminate_ref id e2) | |
+ mk (Ltrywith(eliminate_ref id e1, v, eliminate_ref id e2)) | |
| Lifthenelse(e1, e2, e3) -> | |
- Lifthenelse(eliminate_ref id e1, | |
- eliminate_ref id e2, | |
- eliminate_ref id e3) | |
+ mk (Lifthenelse(eliminate_ref id e1, | |
+ eliminate_ref id e2, | |
+ eliminate_ref id e3)) | |
| Lsequence(e1, e2) -> | |
- Lsequence(eliminate_ref id e1, eliminate_ref id e2) | |
+ mk (Lsequence(eliminate_ref id e1, eliminate_ref id e2)) | |
| Lwhile(e1, e2) -> | |
- Lwhile(eliminate_ref id e1, eliminate_ref id e2) | |
+ mk (Lwhile(eliminate_ref id e1, eliminate_ref id e2)) | |
| Lfor(v, e1, e2, dir, e3) -> | |
- Lfor(v, eliminate_ref id e1, eliminate_ref id e2, | |
- dir, eliminate_ref id e3) | |
+ mk (Lfor(v, eliminate_ref id e1, eliminate_ref id e2, | |
+ dir, eliminate_ref id e3)) | |
| Lassign(v, e) -> | |
- Lassign(v, eliminate_ref id e) | |
- | Lsend(k, m, o, el, loc) -> | |
- Lsend(k, eliminate_ref id m, eliminate_ref id o, | |
- List.map (eliminate_ref id) el, loc) | |
+ mk (Lassign(v, eliminate_ref id e)) | |
+ | Lsend(k, m, o, el) -> | |
+ mk (Lsend(k, eliminate_ref id m, eliminate_ref id o, | |
+ List.map (eliminate_ref id) el)) | |
| Levent(l, ev) -> | |
- Levent(eliminate_ref id l, ev) | |
+ mk (Levent(eliminate_ref id l, ev)) | |
| Lifused(v, e) -> | |
- Lifused(v, eliminate_ref id e) | |
+ mk (Lifused(v, eliminate_ref id e)) | |
(* Simplification of exits *) | |
@@ -102,9 +104,9 @@ let simplify_exits lam = | |
with | |
| Not_found -> Hashtbl.add exits i (ref 1) in | |
- let rec count = function | |
+ let rec count lam = match lam.l_desc with | |
| (Lvar _| Lconst _) -> () | |
- | Lapply(l1, ll, _) -> count l1; List.iter count ll | |
+ | Lapply(l1, ll) -> count l1; List.iter count ll | |
| Lfunction(kind, params, l) -> count l | |
| Llet(str, v, l1, l2) -> | |
count l2; count l1 | |
@@ -118,7 +120,7 @@ let simplify_exits lam = | |
List.iter (fun (_, l) -> count l) sw.sw_consts; | |
List.iter (fun (_, l) -> count l) sw.sw_blocks | |
| Lstaticraise (i,ls) -> incr_exit i ; List.iter count ls | |
- | Lstaticcatch (l1,(i,[]),Lstaticraise (j,[])) -> | |
+ | Lstaticcatch (l1,(i,[]),{l_desc=Lstaticraise (j,[])}) -> | |
(* i will be replaced by j in l1, so each occurence of i in l1 | |
increases j's ref count *) | |
count l1 ; | |
@@ -144,7 +146,7 @@ let simplify_exits lam = | |
(* Lalias-bound variables are never assigned, so don't increase | |
v's refcount *) | |
count l | |
- | Lsend(k, m, o, ll, _) -> List.iter count (m::o::ll) | |
+ | Lsend(k, m, o, ll) -> List.iter count (m::o::ll) | |
| Levent(l, _) -> count l | |
| Lifused(v, l) -> count l | |
@@ -183,14 +185,16 @@ let simplify_exits lam = | |
let subst = Hashtbl.create 17 in | |
- let rec simplif = function | |
- | (Lvar _|Lconst _) as l -> l | |
- | Lapply(l1, ll, loc) -> Lapply(simplif l1, List.map simplif ll, loc) | |
- | Lfunction(kind, params, l) -> Lfunction(kind, params, simplif l) | |
- | Llet(kind, v, l1, l2) -> Llet(kind, v, simplif l1, simplif l2) | |
+ let rec simplif lam = | |
+ let mk = mk_loc_lam lam.l_loc in | |
+ match lam.l_desc with | |
+ | (Lvar _|Lconst _) -> lam | |
+ | Lapply(l1, ll) -> mk (Lapply(simplif l1, List.map simplif ll)) | |
+ | Lfunction(kind, params, l) -> mk (Lfunction(kind, params, simplif l)) | |
+ | Llet(kind, v, l1, l2) -> mk (Llet(kind, v, simplif l1, simplif l2)) | |
| Lletrec(bindings, body) -> | |
- Lletrec(List.map (fun (v, l) -> (v, simplif l)) bindings, simplif body) | |
- | Lprim(p, ll) -> Lprim(p, List.map simplif ll) | |
+ mk (Lletrec(List.map (fun (v, l) -> (v, simplif l)) bindings, simplif body)) | |
+ | Lprim(p, ll) -> mk (Lprim(p, List.map simplif ll)) | |
| Lswitch(l, sw) -> | |
let new_l = simplif l | |
and new_consts = List.map (fun (n, e) -> (n, simplif e)) sw.sw_consts | |
@@ -198,16 +202,16 @@ let simplify_exits lam = | |
and new_fail = match sw.sw_failaction with | |
| None -> None | |
| Some l -> Some (simplif l) in | |
- Lswitch | |
+ mk (Lswitch | |
(new_l, | |
{sw with sw_consts = new_consts ; sw_blocks = new_blocks; | |
- sw_failaction = new_fail}) | |
- | Lstaticraise (i,[]) as l -> | |
+ sw_failaction = new_fail})) | |
+ | Lstaticraise (i,[]) -> | |
begin try | |
let _,handler = Hashtbl.find subst i in | |
handler | |
with | |
- | Not_found -> l | |
+ | Not_found -> lam | |
end | |
| Lstaticraise (i,ls) -> | |
let ls = List.map simplif ls in | |
@@ -216,18 +220,18 @@ let simplify_exits lam = | |
let ys = List.map Ident.rename xs in | |
let env = | |
List.fold_right2 | |
- (fun x y t -> Ident.add x (Lvar y) t) | |
+ (fun x y t -> Ident.add x (mk_lam (Lvar y)) t) | |
xs ys Ident.empty in | |
List.fold_right2 | |
- (fun y l r -> Llet (Alias, y, l, r)) | |
+ (fun y l r -> mk_lam (Llet (Alias, y, l, r))) | |
ys ls (Lambda.subst_lambda env handler) | |
with | |
- | Not_found -> Lstaticraise (i,ls) | |
+ | Not_found -> mk (Lstaticraise (i,ls)) | |
end | |
- | Lstaticcatch (l1,(i,[]),(Lstaticraise (j,[]) as l2)) -> | |
+ | Lstaticcatch (l1,(i,[]),({l_desc=Lstaticraise (j,[])} as l2)) -> | |
Hashtbl.add subst i ([],simplif l2) ; | |
simplif l1 | |
- | Lstaticcatch (l1,(i,xs), (Lvar _ as l2)) -> | |
+ | Lstaticcatch (l1,(i,xs), ({l_desc=Lvar _} as l2)) -> | |
begin match count_exit i with | |
| 0 -> simplif l1 | |
| _ -> | |
@@ -241,18 +245,18 @@ let simplify_exits lam = | |
Hashtbl.add subst i (xs,simplif l2) ; | |
simplif l1 | |
| _ -> | |
- Lstaticcatch (simplif l1, (i,xs), simplif l2) | |
+ mk (Lstaticcatch (simplif l1, (i,xs), simplif l2)) | |
end | |
- | Ltrywith(l1, v, l2) -> Ltrywith(simplif l1, v, simplif l2) | |
- | Lifthenelse(l1, l2, l3) -> Lifthenelse(simplif l1, simplif l2, simplif l3) | |
- | Lsequence(l1, l2) -> Lsequence(simplif l1, simplif l2) | |
- | Lwhile(l1, l2) -> Lwhile(simplif l1, simplif l2) | |
+ | Ltrywith(l1, v, l2) -> mk (Ltrywith(simplif l1, v, simplif l2)) | |
+ | Lifthenelse(l1, l2, l3) -> mk (Lifthenelse(simplif l1, simplif l2, simplif l3)) | |
+ | Lsequence(l1, l2) -> mk (Lsequence(simplif l1, simplif l2)) | |
+ | Lwhile(l1, l2) -> mk (Lwhile(simplif l1, simplif l2)) | |
| Lfor(v, l1, l2, dir, l3) -> | |
- Lfor(v, simplif l1, simplif l2, dir, simplif l3) | |
- | Lassign(v, l) -> Lassign(v, simplif l) | |
- | Lsend(k, m, o, ll, loc) -> Lsend(k, simplif m, simplif o, List.map simplif ll, loc) | |
- | Levent(l, ev) -> Levent(simplif l, ev) | |
- | Lifused(v, l) -> Lifused (v,simplif l) | |
+ mk (Lfor(v, simplif l1, simplif l2, dir, simplif l3)) | |
+ | Lassign(v, l) -> mk (Lassign(v, simplif l)) | |
+ | Lsend(k, m, o, ll) -> mk (Lsend(k, simplif m, simplif o, List.map simplif ll)) | |
+ | Levent(l, ev) -> mk (Levent(simplif l, ev)) | |
+ | Lifused(v, l) -> mk (Lifused (v,simplif l)) | |
in | |
simplif lam | |
@@ -299,15 +303,15 @@ let simplify_lets lam = | |
(* Not a let-bound variable, ignore *) | |
() in | |
- let rec count bv = function | |
+ let rec count bv lam = match lam.l_desc with | |
| Lconst cst -> () | |
| Lvar v -> | |
use_var bv v 1 | |
- | Lapply(l1, ll, _) -> | |
+ | Lapply(l1, ll) -> | |
count bv l1; List.iter (count bv) ll | |
| Lfunction(kind, params, l) -> | |
count Tbl.empty l | |
- | Llet(str, v, Lvar w, l2) when not !Clflags.debug -> | |
+ | Llet(str, v, {l_desc=Lvar w}, l2) when not !Clflags.debug -> | |
(* v will be replaced by w in l2, so each occurrence of v in l2 | |
increases w's refcount *) | |
count (bind_var bv v) l2; | |
@@ -336,7 +340,7 @@ let simplify_lets lam = | |
(* Lalias-bound variables are never assigned, so don't increase | |
v's refcount *) | |
count bv l | |
- | Lsend(_, m, o, ll, _) -> List.iter (count bv) (m::o::ll) | |
+ | Lsend(_, m, o, ll) -> List.iter (count bv) (m::o::ll) | |
| Levent(l, _) -> count bv l | |
| Lifused(v, l) -> | |
if count_var v > 0 then count bv l | |
@@ -366,38 +370,40 @@ let simplify_lets lam = | |
(* This (small) optimisation is always legal, it may uncover some | |
tail call later on. *) | |
- let mklet (kind,v,e1,e2) = match e2 with | |
+ let mklet (kind,v,e1,e2) = match e2.l_desc with | |
| Lvar w when optimize && Ident.same v w -> e1 | |
- | _ -> Llet (kind,v,e1,e2) in | |
+ | _ -> mk_lam (Llet (kind,v,e1,e2)) in | |
- let rec simplif = function | |
- Lvar v as l -> | |
+ let rec simplif lam = | |
+ let mk = mk_loc_lam lam.l_loc in | |
+ match lam.l_desc with | |
+ Lvar v -> | |
begin try | |
Hashtbl.find subst v | |
with Not_found -> | |
- l | |
+ lam | |
end | |
- | Lconst cst as l -> l | |
- | Lapply(l1, ll, loc) -> Lapply(simplif l1, List.map simplif ll, loc) | |
- | Lfunction(kind, params, l) -> Lfunction(kind, params, simplif l) | |
- | Llet(str, v, Lvar w, l2) when optimize -> | |
- Hashtbl.add subst v (simplif (Lvar w)); | |
+ | Lconst cst -> lam | |
+ | Lapply(l1, ll) -> mk (Lapply(simplif l1, List.map simplif ll)) | |
+ | Lfunction(kind, params, l) -> mk (Lfunction(kind, params, simplif l)) | |
+ | Llet(str, v, ({l_desc=Lvar w} as lamw), l2) when optimize -> | |
+ Hashtbl.add subst v (simplif lamw); | |
simplif l2 | |
- | Llet(Strict, v, Lprim(Pmakeblock(0, Mutable), [linit]), lbody) | |
+ | Llet(Strict, v, ({l_desc=Lprim(Pmakeblock(0, Mutable), [linit])} as l), lbody) | |
when optimize -> | |
let slinit = simplif linit in | |
let slbody = simplif lbody in | |
begin try | |
mklet (Variable, v, slinit, eliminate_ref v slbody) | |
with Real_reference -> | |
- mklet(Strict, v, Lprim(Pmakeblock(0, Mutable), [slinit]), slbody) | |
+ mklet(Strict, v, mk_loc_lam l.l_loc (Lprim(Pmakeblock(0, Mutable), [slinit])), slbody) | |
end | |
| Llet(Alias, v, l1, l2) -> | |
begin match count_var v with | |
0 -> simplif l2 | |
| 1 when optimize -> Hashtbl.add subst v (simplif l1); simplif l2 | |
- | n -> Llet(Alias, v, simplif l1, simplif l2) | |
+ | n -> mk (Llet(Alias, v, simplif l1, simplif l2)) | |
end | |
| Llet(StrictOpt, v, l1, l2) -> | |
begin match count_var v with | |
@@ -406,8 +412,8 @@ let simplify_lets lam = | |
end | |
| Llet(kind, v, l1, l2) -> mklet(kind, v, simplif l1, simplif l2) | |
| Lletrec(bindings, body) -> | |
- Lletrec(List.map (fun (v, l) -> (v, simplif l)) bindings, simplif body) | |
- | Lprim(p, ll) -> Lprim(p, List.map simplif ll) | |
+ mk (Lletrec(List.map (fun (v, l) -> (v, simplif l)) bindings, simplif body)) | |
+ | Lprim(p, ll) -> mk (Lprim(p, List.map simplif ll)) | |
| Lswitch(l, sw) -> | |
let new_l = simplif l | |
and new_consts = List.map (fun (n, e) -> (n, simplif e)) sw.sw_consts | |
@@ -415,27 +421,27 @@ let simplify_lets lam = | |
and new_fail = match sw.sw_failaction with | |
| None -> None | |
| Some l -> Some (simplif l) in | |
- Lswitch | |
+ mk (Lswitch | |
(new_l, | |
{sw with sw_consts = new_consts ; sw_blocks = new_blocks; | |
- sw_failaction = new_fail}) | |
+ sw_failaction = new_fail})) | |
| Lstaticraise (i,ls) -> | |
- Lstaticraise (i, List.map simplif ls) | |
+ mk (Lstaticraise (i, List.map simplif ls)) | |
| Lstaticcatch(l1, (i,args), l2) -> | |
- Lstaticcatch (simplif l1, (i,args), simplif l2) | |
- | Ltrywith(l1, v, l2) -> Ltrywith(simplif l1, v, simplif l2) | |
- | Lifthenelse(l1, l2, l3) -> Lifthenelse(simplif l1, simplif l2, simplif l3) | |
- | Lsequence(Lifused(v, l1), l2) -> | |
+ mk (Lstaticcatch (simplif l1, (i,args), simplif l2)) | |
+ | Ltrywith(l1, v, l2) -> mk (Ltrywith(simplif l1, v, simplif l2)) | |
+ | Lifthenelse(l1, l2, l3) -> mk (Lifthenelse(simplif l1, simplif l2, simplif l3)) | |
+ | Lsequence({l_desc=Lifused(v, l1)}, l2) -> | |
if count_var v > 0 | |
- then Lsequence(simplif l1, simplif l2) | |
+ then mk (Lsequence(simplif l1, simplif l2)) | |
else simplif l2 | |
- | Lsequence(l1, l2) -> Lsequence(simplif l1, simplif l2) | |
- | Lwhile(l1, l2) -> Lwhile(simplif l1, simplif l2) | |
+ | Lsequence(l1, l2) -> mk (Lsequence(simplif l1, simplif l2)) | |
+ | Lwhile(l1, l2) -> mk (Lwhile(simplif l1, simplif l2)) | |
| Lfor(v, l1, l2, dir, l3) -> | |
- Lfor(v, simplif l1, simplif l2, dir, simplif l3) | |
- | Lassign(v, l) -> Lassign(v, simplif l) | |
- | Lsend(k, m, o, ll, loc) -> Lsend(k, simplif m, simplif o, List.map simplif ll, loc) | |
- | Levent(l, ev) -> Levent(simplif l, ev) | |
+ mk (Lfor(v, simplif l1, simplif l2, dir, simplif l3)) | |
+ | Lassign(v, l) -> mk (Lassign(v, simplif l)) | |
+ | Lsend(k, m, o, ll) -> mk (Lsend(k, simplif m, simplif o, List.map simplif ll)) | |
+ | Levent(l, ev) -> mk (Levent(simplif l, ev)) | |
| Lifused(v, l) -> | |
if count_var v > 0 then simplif l else lambda_unit | |
in | |
@@ -453,12 +459,12 @@ let rec emit_tail_infos is_tail lambda = | |
|| (!is_tail_native_heuristic (List.length args))) | |
then Annot.Tail | |
else Annot.Stack in | |
- match lambda with | |
+ match lambda.l_desc with | |
| Lvar _ -> () | |
| Lconst _ -> () | |
- | Lapply (func, l, loc) -> | |
+ | Lapply (func, l) -> | |
list_emit_tail_infos false l; | |
- Stypes.record (Stypes.An_call (loc, call_kind l)) | |
+ Stypes.record (Stypes.An_call (lambda.l_loc, call_kind l)) | |
| Lfunction (_, _, lam) -> | |
emit_tail_infos true lam | |
| Llet (_, _, lam, body) -> | |
@@ -503,11 +509,11 @@ let rec emit_tail_infos is_tail lambda = | |
emit_tail_infos false body | |
| Lassign (_, lam) -> | |
emit_tail_infos false lam | |
- | Lsend (_, meth, obj, args, loc) -> | |
+ | Lsend (_, meth, obj, args) -> | |
emit_tail_infos false meth; | |
emit_tail_infos false obj; | |
list_emit_tail_infos false args; | |
- Stypes.record (Stypes.An_call (loc, call_kind (obj :: args))) | |
+ Stypes.record (Stypes.An_call (lambda.l_loc, call_kind (obj :: args))) | |
| Levent (lam, _) -> | |
emit_tail_infos is_tail lam | |
| Lifused (_, lam) -> | |
diff --git a/bytecomp/translclass.ml b/bytecomp/translclass.ml | |
index f06e43b..2217a60 100644 | |
--- a/bytecomp/translclass.ml | |
+++ b/bytecomp/translclass.ml | |
@@ -28,55 +28,67 @@ exception Error of Location.t * error | |
let lfunction params body = | |
if params = [] then body else | |
- match body with | |
- Lfunction (Curried, params', body') -> | |
- Lfunction (Curried, params @ params', body') | |
- | _ -> | |
- Lfunction (Curried, params, body) | |
+ mk_lam | |
+ begin match body.l_desc with | |
+ | Lfunction (Curried, params', body') -> | |
+ Lfunction (Curried, params @ params', body') | |
+ | _ -> | |
+ Lfunction (Curried, params, body) | |
+ end | |
let lapply func args loc = | |
- match func with | |
- Lapply(func', args', _) -> | |
- Lapply(func', args' @ args, loc) | |
- | _ -> | |
- Lapply(func, args, loc) | |
+ mk_loc_lam loc | |
+ begin match func.l_desc with | |
+ | Lapply(func', args') -> Lapply(func', args' @ args) | |
+ | _ -> Lapply(func, args) | |
+ end | |
-let mkappl (func, args) = Lapply (func, args, Location.none);; | |
+let mkappl (func, args) = | |
+ mk_lam (Lapply (func, args)) | |
let lsequence l1 l2 = | |
- if l2 = lambda_unit then l1 else Lsequence(l1, l2) | |
+ if l2 = lambda_unit then | |
+ l1 | |
+ else | |
+ mk_lam (Lsequence(l1, l2)) | |
-let lfield v i = Lprim(Pfield i, [Lvar v]) | |
+let lfield v i = | |
+ mk_lam (Lprim(Pfield i, [mk_lam (Lvar v)])) | |
let transl_label l = share (Const_immstring l) | |
-let rec transl_meth_list lst = | |
- if lst = [] then Lconst (Const_pointer 0) else | |
+let transl_meth_list lst = | |
+ if lst = [] then mk_lam (Lconst (Const_pointer 0)) else | |
share (Const_block | |
(0, List.map (fun lab -> Const_immstring lab) lst)) | |
let set_inst_var obj id expr = | |
let kind = if Typeopt.maybe_pointer expr then Paddrarray else Pintarray in | |
- Lprim(Parraysetu kind, [Lvar obj; Lvar id; transl_exp expr]) | |
+ mk_lam (Lprim(Parraysetu kind, [mk_lam (Lvar obj); mk_lam (Lvar id); transl_exp expr])) | |
let copy_inst_var obj id expr templ offset = | |
let kind = if Typeopt.maybe_pointer expr then Paddrarray else Pintarray in | |
let id' = Ident.create (Ident.name id) in | |
- Llet(Strict, id', Lprim (Pidentity, [Lvar id]), | |
- Lprim(Parraysetu kind, | |
- [Lvar obj; Lvar id'; | |
- Lprim(Parrayrefu kind, [Lvar templ; Lprim(Paddint, | |
- [Lvar id'; | |
- Lvar offset])])])) | |
+ mk_lam (Llet(Strict, id', | |
+ mk_lam (Lprim (Pidentity, [mk_lam (Lvar id)])), | |
+ mk_lam (Lprim(Parraysetu kind, | |
+ [mk_lam (Lvar obj); | |
+ mk_lam (Lvar id'); | |
+ mk_lam (Lprim(Parrayrefu kind, | |
+ [mk_lam (Lvar templ); | |
+ mk_lam (Lprim(Paddint, | |
+ [mk_lam (Lvar id'); | |
+ mk_lam (Lvar offset); | |
+ ]))]))])))) | |
let transl_val tbl create name = | |
mkappl (oo_prim (if create then "new_variable" else "get_variable"), | |
- [Lvar tbl; transl_label name]) | |
+ [mk_lam (Lvar tbl); transl_label name]) | |
let transl_vals tbl create strict vals rem = | |
List.fold_right | |
(fun (name, id) rem -> | |
- Llet(strict, id, transl_val tbl create name, rem)) | |
+ mk_lam (Llet(strict, id, transl_val tbl create name, rem))) | |
vals rem | |
let meths_super tbl meths inh_meths = | |
@@ -84,14 +96,15 @@ let meths_super tbl meths inh_meths = | |
(fun (nm, id) rem -> | |
try | |
(nm, id, | |
- mkappl(oo_prim "get_method", [Lvar tbl; Lvar (Meths.find nm meths)])) | |
+ mkappl(oo_prim "get_method", [mk_lam (Lvar tbl); | |
+ mk_lam (Lvar (Meths.find nm meths))])) | |
:: rem | |
with Not_found -> rem) | |
inh_meths [] | |
let bind_super tbl (vals, meths) cl_init = | |
transl_vals tbl false StrictOpt vals | |
- (List.fold_right (fun (nm, id, def) rem -> Llet(StrictOpt, id, def, rem)) | |
+ (List.fold_right (fun (nm, id, def) rem -> mk_lam (Llet(StrictOpt, id, def, rem))) | |
meths cl_init) | |
let create_object cl obj init = | |
@@ -101,15 +114,19 @@ let create_object cl obj init = | |
(inh_init, | |
mkappl (oo_prim (if has_init then "create_object_and_run_initializers" | |
else"create_object_opt"), | |
- [obj; Lvar cl])) | |
+ [obj; mk_lam (Lvar cl)])) | |
else begin | |
(inh_init, | |
- Llet(Strict, obj', | |
- mkappl (oo_prim "create_object_opt", [obj; Lvar cl]), | |
- Lsequence(obj_init, | |
- if not has_init then Lvar obj' else | |
- mkappl (oo_prim "run_initializers_opt", | |
- [obj; Lvar obj'; Lvar cl])))) | |
+ mk_lam (Llet(Strict, obj', | |
+ mkappl (oo_prim "create_object_opt", [obj; mk_lam (Lvar cl)]), | |
+ mk_lam (Lsequence(obj_init, | |
+ if not has_init then | |
+ mk_lam (Lvar obj') | |
+ else | |
+ mkappl (oo_prim "run_initializers_opt", | |
+ [obj; | |
+ mk_lam (Lvar obj'); | |
+ mk_lam (Lvar cl)])))))) | |
end | |
let rec build_object_init cl_table obj params inh_init obj_init cl = | |
@@ -119,10 +136,10 @@ let rec build_object_init cl_table obj params inh_init obj_init cl = | |
let envs, inh_init = inh_init in | |
let env = | |
match envs with None -> [] | |
- | Some envs -> [Lprim(Pfield (List.length inh_init + 1), [Lvar envs])] | |
+ | Some envs -> [mk_lam (Lprim(Pfield (List.length inh_init + 1), [mk_lam (Lvar envs)]))] | |
in | |
((envs, (obj_init, path)::inh_init), | |
- mkappl(Lvar obj_init, env @ [obj])) | |
+ mkappl(mk_lam (Lvar obj_init), env @ [obj])) | |
| Tclass_structure str -> | |
create_object cl_table obj (fun obj -> | |
let (inh_init, obj_init, has_init) = | |
@@ -131,7 +148,7 @@ let rec build_object_init cl_table obj params inh_init obj_init cl = | |
match field with | |
Cf_inher (cl, _, _) -> | |
let (inh_init, obj_init') = | |
- build_object_init cl_table (Lvar obj) [] inh_init | |
+ build_object_init cl_table (mk_lam (Lvar obj)) [] inh_init | |
(fun _ -> lambda_unit) cl | |
in | |
(inh_init, lsequence obj_init' obj_init, true) | |
@@ -147,7 +164,7 @@ let rec build_object_init cl_table obj params inh_init obj_init cl = | |
Translcore.transl_let rec_flag defs | |
(List.fold_right | |
(fun (id, expr) rem -> | |
- lsequence (Lifused(id, set_inst_var obj id expr)) | |
+ lsequence (mk_lam (Lifused(id, set_inst_var obj id expr))) | |
rem) | |
vals obj_init), | |
has_init)) | |
@@ -157,7 +174,7 @@ let rec build_object_init cl_table obj params inh_init obj_init cl = | |
(inh_init, | |
List.fold_right | |
(fun (id, expr) rem -> | |
- lsequence (Lifused (id, set_inst_var obj id expr)) rem) | |
+ lsequence (mk_lam (Lifused (id, set_inst_var obj id expr))) rem) | |
params obj_init, | |
has_init)) | |
| Tclass_fun (pat, vals, cl, partial) -> | |
@@ -167,13 +184,13 @@ let rec build_object_init cl_table obj params inh_init obj_init cl = | |
(inh_init, | |
let build params rem = | |
let param = name_pattern "param" [pat, ()] in | |
- Lfunction (Curried, param::params, | |
+ mk_lam (Lfunction (Curried, param::params, | |
Matching.for_function | |
- pat.pat_loc None (Lvar param) [pat, rem] partial) | |
+ pat.pat_loc None (mk_lam (Lvar param)) [pat, rem] partial)) | |
in | |
- begin match obj_init with | |
+ begin match obj_init.l_desc with | |
Lfunction (Curried, params, rem) -> build params rem | |
- | rem -> build [] rem | |
+ | _ -> build [] obj_init | |
end) | |
| Tclass_apply (cl, oexprs) -> | |
let (inh_init, obj_init) = | |
@@ -195,7 +212,7 @@ let rec build_object_init_0 cl_table params cl copy_env subst_env top ids = | |
| _ -> | |
let self = Ident.create "self" in | |
let env = Ident.create "env" in | |
- let obj = if ids = [] then lambda_unit else Lvar self in | |
+ let obj = if ids = [] then lambda_unit else mk_lam (Lvar self) in | |
let envs = if top then None else Some env in | |
let ((_,inh_init), obj_init) = | |
build_object_init cl_table obj params (envs,[]) (copy_env env) cl in | |
@@ -205,9 +222,9 @@ let rec build_object_init_0 cl_table params cl copy_env subst_env top ids = | |
let bind_method tbl lab id cl_init = | |
- Llet(Strict, id, mkappl (oo_prim "get_method_label", | |
- [Lvar tbl; transl_label lab]), | |
- cl_init) | |
+ mk_lam (Llet(Strict, id, mkappl (oo_prim "get_method_label", | |
+ [mk_lam (Lvar tbl); transl_label lab]), | |
+ cl_init)) | |
let bind_methods tbl meths vals cl_init = | |
let methl = Meths.fold (fun lab id tl -> (lab,id) :: tl) meths [] in | |
@@ -220,21 +237,22 @@ let bind_methods tbl meths vals cl_init = | |
if nvals = 0 then "get_method_labels", [] else | |
"new_methods_variables", [transl_meth_list (List.map fst vals)] | |
in | |
- Llet(Strict, ids, | |
- mkappl (oo_prim getter, | |
- [Lvar tbl; transl_meth_list (List.map fst methl)] @ names), | |
- List.fold_right | |
- (fun (lab,id) lam -> decr i; Llet(StrictOpt, id, lfield ids !i, lam)) | |
- (methl @ vals) cl_init) | |
+ mk_lam (Llet(Strict, ids, | |
+ mkappl (oo_prim getter, | |
+ [mk_lam (Lvar tbl); transl_meth_list (List.map fst methl)] @ names), | |
+ List.fold_right | |
+ (fun (lab,id) lam -> decr i; mk_lam (Llet(StrictOpt, id, lfield ids !i, lam))) | |
+ (methl @ vals) cl_init)) | |
let output_methods tbl methods lam = | |
match methods with | |
[] -> lam | |
| [lab; code] -> | |
- lsequence (mkappl(oo_prim "set_method", [Lvar tbl; lab; code])) lam | |
+ lsequence (mkappl(oo_prim "set_method", [mk_lam (Lvar tbl); lab; code])) lam | |
| _ -> | |
lsequence (mkappl(oo_prim "set_methods", | |
- [Lvar tbl; Lprim(Pmakeblock(0,Immutable), methods)])) | |
+ [mk_lam (Lvar tbl); | |
+ mk_lam (Lprim(Pmakeblock(0,Immutable), methods))])) | |
lam | |
let rec ignore_cstrs cl = | |
@@ -257,10 +275,15 @@ let rec build_class_init cla cstr super inh_init cl_init msubst top cl = | |
(obj_init, path')::inh_init -> | |
let lpath = transl_path path in | |
(inh_init, | |
- Llet (Strict, obj_init, | |
- mkappl(Lprim(Pfield 1, [lpath]), Lvar cla :: | |
- if top then [Lprim(Pfield 3, [lpath])] else []), | |
- bind_super cla super cl_init)) | |
+ mk_lam (Llet (Strict, obj_init, | |
+ mkappl( | |
+ mk_lam (Lprim(Pfield 1, [lpath])), | |
+ mk_lam (Lvar cla) :: | |
+ if top then | |
+ [mk_lam (Lprim(Pfield 3, [lpath]))] | |
+ else | |
+ []), | |
+ bind_super cla super cl_init))) | |
| _ -> | |
assert false | |
end | |
@@ -286,11 +309,11 @@ let rec build_class_init cla cstr super inh_init cl_init msubst top cl = | |
if !Clflags.native_code && List.length met_code = 1 then | |
(* Force correct naming of method for profiles *) | |
let met = Ident.create ("method_" ^ name) in | |
- [Llet(Strict, met, List.hd met_code, Lvar met)] | |
+ [mk_lam (Llet(Strict, met, List.hd met_code, mk_lam (Lvar met)))] | |
else met_code | |
in | |
(inh_init, cl_init, | |
- Lvar (Meths.find name str.cl_meths) :: met_code @ methods, | |
+ mk_lam (Lvar (Meths.find name str.cl_meths)) :: met_code @ methods, | |
values) | |
| Cf_let (rec_flag, defs, vals) -> | |
let vals = | |
@@ -299,9 +322,10 @@ let rec build_class_init cla cstr super inh_init cl_init msubst top cl = | |
(inh_init, cl_init, methods, vals @ values) | |
| Cf_init exp -> | |
(inh_init, | |
- Lsequence(mkappl (oo_prim "add_initializer", | |
- Lvar cla :: msubst false (transl_exp exp)), | |
- cl_init), | |
+ mk_lam (Lsequence(mkappl (oo_prim "add_initializer", | |
+ mk_lam (Lvar cla) :: | |
+ msubst false (transl_exp exp)), | |
+ cl_init)), | |
methods, values)) | |
str.cl_field | |
(inh_init, cl_init, [], []) | |
@@ -327,7 +351,7 @@ let rec build_class_init cla cstr super inh_init cl_init msubst top cl = | |
List.filter (fun lab -> not (Concr.mem lab concr_meths)) meths in | |
let concr_meths = Concr.elements concr_meths in | |
let narrow_args = | |
- [Lvar cla; | |
+ [mk_lam (Lvar cla); | |
transl_meth_list vals; | |
transl_meth_list virt_meths; | |
transl_meth_list concr_meths] in | |
@@ -342,30 +366,31 @@ let rec build_class_init cla cstr super inh_init cl_init msubst top cl = | |
let cl_init = | |
List.fold_left | |
(fun init (nm, id, _) -> | |
- Llet(StrictOpt, id, lfield inh (index nm concr_meths + ofs), | |
- init)) | |
+ mk_lam (Llet(StrictOpt, id, lfield inh (index nm concr_meths + ofs), | |
+ init))) | |
cl_init methids in | |
let cl_init = | |
List.fold_left | |
(fun init (nm, id) -> | |
- Llet(StrictOpt, id, lfield inh (index nm vals + 1), init)) | |
+ mk_lam (Llet(StrictOpt, id, lfield inh (index nm vals + 1), init))) | |
cl_init valids in | |
(inh_init, | |
- Llet (Strict, inh, | |
- mkappl(oo_prim "inherits", narrow_args @ | |
- [lpath; Lconst(Const_pointer(if top then 1 else 0))]), | |
- Llet(StrictOpt, obj_init, lfield inh 0, cl_init))) | |
+ mk_lam (Llet (Strict, inh, | |
+ mkappl(oo_prim "inherits", narrow_args @ | |
+ [lpath; | |
+ mk_lam (Lconst(Const_pointer(if top then 1 else 0)))]), | |
+ mk_lam (Llet(StrictOpt, obj_init, lfield inh 0, cl_init))))) | |
| _ -> | |
let core cl_init = | |
build_class_init cla true super inh_init cl_init msubst top cl | |
in | |
if cstr then core cl_init else | |
let (inh_init, cl_init) = | |
- core (Lsequence (mkappl (oo_prim "widen", [Lvar cla]), cl_init)) | |
+ core (mk_lam (Lsequence (mkappl (oo_prim "widen", [mk_lam (Lvar cla)]), cl_init))) | |
in | |
(inh_init, | |
- Lsequence(mkappl (oo_prim "narrow", narrow_args), | |
- cl_init)) | |
+ mk_lam (Lsequence(mkappl (oo_prim "narrow", narrow_args), | |
+ cl_init))) | |
end | |
let rec build_class_lets cl = | |
@@ -402,14 +427,14 @@ let rec transl_class_rebind obj_init cl vf = | |
let path, obj_init = transl_class_rebind obj_init cl vf in | |
let build params rem = | |
let param = name_pattern "param" [pat, ()] in | |
- Lfunction (Curried, param::params, | |
+ mk_lam (Lfunction (Curried, param::params, | |
Matching.for_function | |
- pat.pat_loc None (Lvar param) [pat, rem] partial) | |
+ pat.pat_loc None (mk_lam (Lvar param)) [pat, rem] partial)) | |
in | |
(path, | |
- match obj_init with | |
+ match obj_init.l_desc with | |
Lfunction (Curried, params, rem) -> build params rem | |
- | rem -> build [] rem) | |
+ | _ -> build [] obj_init) | |
| Tclass_apply (cl, oexprs) -> | |
let path, obj_init = transl_class_rebind obj_init cl vf in | |
(path, transl_apply obj_init oexprs Location.none) | |
@@ -440,7 +465,7 @@ let transl_class_rebind ids cl vf = | |
try | |
let obj_init = Ident.create "obj_init" | |
and self = Ident.create "self" in | |
- let obj_init0 = lapply (Lvar obj_init) [Lvar self] Location.none in | |
+ let obj_init0 = lapply (mk_lam (Lvar obj_init)) [mk_lam (Lvar self)] Location.none in | |
let path, obj_init' = transl_class_rebind_0 self obj_init0 cl vf in | |
if not (Translcore.check_recursive_lambda ids obj_init') then | |
raise(Error(cl.cl_loc, Illegal_class_expr)); | |
@@ -452,81 +477,82 @@ let transl_class_rebind ids cl vf = | |
and env_init = Ident.create "env_init" | |
and table = Ident.create "table" | |
and envs = Ident.create "envs" in | |
- Llet( | |
+ mk_lam (Llet( | |
Strict, new_init, lfunction [obj_init] obj_init', | |
- Llet( | |
+ mk_lam (Llet( | |
Alias, cla, transl_path path, | |
- Lprim(Pmakeblock(0, Immutable), | |
- [mkappl(Lvar new_init, [lfield cla 0]); | |
+ mk_lam (Lprim(Pmakeblock(0, Immutable), | |
+ [mkappl(mk_lam (Lvar new_init), [lfield cla 0]); | |
lfunction [table] | |
- (Llet(Strict, env_init, | |
- mkappl(lfield cla 1, [Lvar table]), | |
+ (mk_lam (Llet(Strict, env_init, | |
+ mkappl(lfield cla 1, [mk_lam (Lvar table)]), | |
lfunction [envs] | |
- (mkappl(Lvar new_init, | |
- [mkappl(Lvar env_init, [Lvar envs])])))); | |
+ (mkappl(mk_lam (Lvar new_init), | |
+ [mkappl(mk_lam (Lvar env_init), [mk_lam (Lvar envs)])] | |
+ ))))); | |
lfield cla 2; | |
- lfield cla 3]))) | |
+ lfield cla 3])))))) | |
with Exit -> | |
lambda_unit | |
(* Rewrite a closure using builtins. Improves native code size. *) | |
-let rec module_path = function | |
+let rec module_path l = match l.l_desc with | |
Lvar id -> | |
let s = Ident.name id in s <> "" && s.[0] >= 'A' && s.[0] <= 'Z' | |
| Lprim(Pfield _, [p]) -> module_path p | |
| Lprim(Pgetglobal _, []) -> true | |
| _ -> false | |
-let const_path local = function | |
+let const_path local l = match l.l_desc with | |
Lvar id -> not (List.mem id local) | |
| Lconst _ -> true | |
| Lfunction (Curried, _, body) -> | |
let fv = free_variables body in | |
List.for_all (fun x -> not (IdentSet.mem x fv)) local | |
- | p -> module_path p | |
+ | _ -> module_path l | |
let rec builtin_meths self env env2 body = | |
let const_path = const_path (env::self) in | |
- let conv = function | |
+ let conv l = match l.l_desc with | |
(* Lvar s when List.mem s self -> "_self", [] *) | |
- | p when const_path p -> "const", [p] | |
- | Lprim(Parrayrefu _, [Lvar s; Lvar n]) when List.mem s self -> | |
- "var", [Lvar n] | |
- | Lprim(Pfield n, [Lvar e]) when Ident.same e env -> | |
- "env", [Lvar env2; Lconst(Const_pointer n)] | |
- | Lsend(Self, met, Lvar s, [], _) when List.mem s self -> | |
+ | _ when const_path l -> "const", [l] | |
+ | Lprim(Parrayrefu _, [{l_desc=Lvar s}; {l_desc=Lvar n}]) when List.mem s self -> | |
+ "var", [mk_lam (Lvar n)] | |
+ | Lprim(Pfield n, [{l_desc=Lvar e}]) when Ident.same e env -> | |
+ "env", [mk_lam (Lvar env2); mk_lam (Lconst(Const_pointer n))] | |
+ | Lsend(Self, met, {l_desc=Lvar s}, []) when List.mem s self -> | |
"meth", [met] | |
| _ -> raise Not_found | |
in | |
- match body with | |
- | Llet(_, s', Lvar s, body) when List.mem s self -> | |
+ match body.l_desc with | |
+ | Llet(_, s', {l_desc=Lvar s}, body) when List.mem s self -> | |
builtin_meths (s'::self) env env2 body | |
- | Lapply(f, [arg], _) when const_path f -> | |
+ | Lapply(f, [arg]) when const_path f -> | |
let s, args = conv arg in ("app_"^s, f :: args) | |
- | Lapply(f, [arg; p], _) when const_path f && const_path p -> | |
+ | Lapply(f, [arg; p]) when const_path f && const_path p -> | |
let s, args = conv arg in | |
("app_"^s^"_const", f :: args @ [p]) | |
- | Lapply(f, [p; arg], _) when const_path f && const_path p -> | |
+ | Lapply(f, [p; arg]) when const_path f && const_path p -> | |
let s, args = conv arg in | |
("app_const_"^s, f :: p :: args) | |
- | Lsend(Self, Lvar n, Lvar s, [arg], _) when List.mem s self -> | |
+ | Lsend(Self, {l_desc=Lvar n}, {l_desc=Lvar s}, [arg]) when List.mem s self -> | |
let s, args = conv arg in | |
- ("meth_app_"^s, Lvar n :: args) | |
- | Lsend(Self, met, Lvar s, [], _) when List.mem s self -> | |
+ ("meth_app_"^s, mk_lam (Lvar n) :: args) | |
+ | Lsend(Self, met, {l_desc=Lvar s}, []) when List.mem s self -> | |
("get_meth", [met]) | |
- | Lsend(Public, met, arg, [], _) -> | |
+ | Lsend(Public, met, arg, []) -> | |
let s, args = conv arg in | |
("send_"^s, met :: args) | |
- | Lsend(Cached, met, arg, [_;_], _) -> | |
+ | Lsend(Cached, met, arg, [_;_]) -> | |
let s, args = conv arg in | |
("send_"^s, met :: args) | |
| Lfunction (Curried, [x], body) -> | |
- let rec enter self = function | |
- | Lprim(Parraysetu _, [Lvar s; Lvar n; Lvar x']) | |
+ let rec enter self l = match l.l_desc with | |
+ | Lprim(Parraysetu _, [{l_desc=Lvar s}; {l_desc=Lvar n}; {l_desc=Lvar x'}]) | |
when Ident.same x x' && List.mem s self -> | |
- ("set_var", [Lvar n]) | |
- | Llet(_, s', Lvar s, body) when List.mem s self -> | |
+ ("set_var", [mk_lam (Lvar n)]) | |
+ | Llet(_, s', {l_desc=Lvar s}, body) when List.mem s self -> | |
enter (s'::self) body | |
| _ -> raise Not_found | |
in enter self body | |
@@ -565,7 +591,7 @@ module M = struct | |
| "send_env" -> SendEnv | |
| "send_meth" -> SendMeth | |
| _ -> assert false | |
- in Lconst(Const_pointer(Obj.magic tag)) :: args | |
+ in mk_lam (Lconst(Const_pointer(Obj.magic tag))) :: args | |
end | |
open M | |
@@ -628,7 +654,7 @@ let transl_class ids cl_id arity pub_meths cl vflag = | |
Ident.empty !new_ids' | |
in | |
let new_ids_meths = ref [] in | |
- let msubst arr = function | |
+ let msubst arr l = match l.l_desc with | |
Lfunction (Curried, self :: args, body) -> | |
let env = Ident.create "env" in | |
let body' = | |
@@ -642,9 +668,11 @@ let transl_class ids cl_id arity pub_meths cl vflag = | |
with Not_found -> | |
[lfunction (self :: args) | |
(if not (IdentSet.mem env (free_variables body')) then body' else | |
- Llet(Alias, env, | |
- Lprim(Parrayrefu Paddrarray, | |
- [Lvar self; Lvar env2]), body'))] | |
+ mk_lam (Llet(Alias, env, | |
+ mk_lam (Lprim(Parrayrefu Paddrarray, | |
+ [mk_lam (Lvar self); | |
+ mk_lam (Lvar env2)])), | |
+ body')))] | |
end | |
| _ -> assert false | |
in | |
@@ -652,16 +680,26 @@ let transl_class ids cl_id arity pub_meths cl vflag = | |
let env1 = Ident.create "env" and env1' = Ident.create "env'" in | |
let copy_env envs self = | |
if top then lambda_unit else | |
- Lifused(env2, Lprim(Parraysetu Paddrarray, | |
- [Lvar self; Lvar env2; Lvar env1'])) | |
+ mk_lam (Lifused(env2, | |
+ mk_lam (Lprim(Parraysetu Paddrarray, | |
+ [mk_lam (Lvar self); | |
+ mk_lam (Lvar env2); | |
+ mk_lam (Lvar env1')])))) | |
and subst_env envs l lam = | |
if top then lam else | |
(* must be called only once! *) | |
let lam = subst_lambda (subst env1 lam 1 new_ids_init) lam in | |
- Llet(Alias, env1, (if l = [] then Lvar envs else lfield envs 0), | |
- Llet(Alias, env1', | |
- (if !new_ids_init = [] then Lvar env1 else lfield env1 0), | |
- lam)) | |
+ mk_lam (Llet(Alias, env1, | |
+ (if l = [] then | |
+ mk_lam (Lvar envs) | |
+ else | |
+ lfield envs 0), | |
+ mk_lam(Llet(Alias, env1', | |
+ (if !new_ids_init = [] then | |
+ mk_lam (Lvar env1) | |
+ else | |
+ lfield env1 0), | |
+ lam)))) | |
in | |
(* Now we start compiling the class *) | |
@@ -691,36 +729,39 @@ let transl_class ids cl_id arity pub_meths cl vflag = | |
if name' <> name then raise(Error(cl.cl_loc, Tags(name, name')))) | |
tags pub_meths; | |
let ltable table lam = | |
- Llet(Strict, table, | |
- mkappl (oo_prim "create_table", [transl_meth_list pub_meths]), lam) | |
+ mk_lam (Llet(Strict, table, | |
+ mkappl (oo_prim "create_table", [transl_meth_list pub_meths]), lam)) | |
and ldirect obj_init = | |
- Llet(Strict, obj_init, cl_init, | |
- Lsequence(mkappl (oo_prim "init_class", [Lvar cla]), | |
- mkappl (Lvar obj_init, [lambda_unit]))) | |
+ mk_lam (Llet(Strict, obj_init, cl_init, | |
+ mk_lam (Lsequence(mkappl (oo_prim "init_class", [mk_lam (Lvar cla)]), | |
+ mkappl (mk_lam (Lvar obj_init), [lambda_unit]))))) | |
in | |
(* Simplest case: an object defined at toplevel (ids=[]) *) | |
if top && ids = [] then llets (ltable cla (ldirect obj_init)) else | |
let concrete = (vflag = Concrete) | |
and lclass lam = | |
- let cl_init = llets (Lfunction(Curried, [cla], cl_init)) in | |
- Llet(Strict, class_init, cl_init, lam (free_variables cl_init)) | |
+ let cl_init = llets (mk_lam (Lfunction(Curried, [cla], cl_init))) in | |
+ mk_lam (Llet(Strict, class_init, cl_init, lam (free_variables cl_init))) | |
and lbody fv = | |
if List.for_all (fun id -> not (IdentSet.mem id fv)) ids then | |
mkappl (oo_prim "make_class",[transl_meth_list pub_meths; | |
- Lvar class_init]) | |
+ mk_lam (Lvar class_init)]) | |
else | |
ltable table ( | |
- Llet( | |
- Strict, env_init, mkappl (Lvar class_init, [Lvar table]), | |
- Lsequence( | |
- mkappl (oo_prim "init_class", [Lvar table]), | |
- Lprim(Pmakeblock(0, Immutable), | |
- [mkappl (Lvar env_init, [lambda_unit]); | |
- Lvar class_init; Lvar env_init; lambda_unit])))) | |
+ mk_lam (Llet( | |
+ Strict, env_init, mkappl (mk_lam (Lvar class_init), [mk_lam (Lvar table)]), | |
+ mk_lam (Lsequence( | |
+ mkappl (oo_prim "init_class", [mk_lam (Lvar table)]), | |
+ mk_lam (Lprim(Pmakeblock(0, Immutable), | |
+ [mkappl (mk_lam (Lvar env_init), [lambda_unit]); | |
+ mk_lam (Lvar class_init); mk_lam (Lvar env_init); lambda_unit] | |
+ ))))))) | |
and lbody_virt lenvs = | |
- Lprim(Pmakeblock(0, Immutable), | |
- [lambda_unit; Lfunction(Curried,[cla], cl_init); lambda_unit; lenvs]) | |
+ mk_lam (Lprim(Pmakeblock(0, Immutable), | |
+ [lambda_unit; | |
+ mk_lam (Lfunction(Curried,[cla], cl_init)); | |
+ lambda_unit; lenvs])) | |
in | |
(* Still easy: a class defined at toplevel *) | |
if top && concrete then lclass lbody else | |
@@ -732,74 +773,80 @@ let transl_class ids cl_id arity pub_meths cl vflag = | |
let lenvs = | |
if !new_ids_meths = [] && !new_ids_init = [] && inh_init = [] | |
then lambda_unit | |
- else Lvar envs in | |
+ else mk_lam (Lvar envs) in | |
let lenv = | |
let menv = | |
if !new_ids_meths = [] then lambda_unit else | |
- Lprim(Pmakeblock(0, Immutable), | |
- List.map (fun id -> Lvar id) !new_ids_meths) in | |
+ mk_lam (Lprim(Pmakeblock(0, Immutable), | |
+ List.map (fun id -> mk_lam (Lvar id)) !new_ids_meths)) in | |
if !new_ids_init = [] then menv else | |
- Lprim(Pmakeblock(0, Immutable), | |
- menv :: List.map (fun id -> Lvar id) !new_ids_init) | |
+ mk_lam (Lprim(Pmakeblock(0, Immutable), | |
+ menv :: List.map (fun id -> mk_lam (Lvar id)) !new_ids_init)) | |
and linh_envs = | |
- List.map (fun (_, p) -> Lprim(Pfield 3, [transl_path p])) | |
+ List.map (fun (_, p) -> mk_lam (Lprim(Pfield 3, [transl_path p]))) | |
(List.rev inh_init) | |
in | |
let make_envs lam = | |
- Llet(StrictOpt, envs, | |
- (if linh_envs = [] then lenv else | |
- Lprim(Pmakeblock(0, Immutable), lenv :: linh_envs)), | |
- lam) | |
+ mk_lam (Llet(StrictOpt, envs, | |
+ (if linh_envs = [] then | |
+ lenv | |
+ else | |
+ mk_lam (Lprim(Pmakeblock(0, Immutable), lenv :: linh_envs))), | |
+ lam)) | |
and def_ids cla lam = | |
- Llet(StrictOpt, env2, | |
- mkappl (oo_prim "new_variable", [Lvar cla; transl_label ""]), | |
- lam) | |
+ mk_lam (Llet(StrictOpt, env2, | |
+ mkappl (oo_prim "new_variable", [mk_lam (Lvar cla); transl_label ""]), | |
+ lam)) | |
in | |
let inh_paths = | |
List.filter | |
(fun (_,path) -> List.mem (Path.head path) new_ids) inh_init in | |
let inh_keys = | |
- List.map (fun (_,p) -> Lprim(Pfield 1, [transl_path p])) inh_paths in | |
+ List.map (fun (_,p) -> mk_lam (Lprim(Pfield 1, [transl_path p]))) inh_paths in | |
let lclass lam = | |
- Llet(Strict, class_init, | |
- Lfunction(Curried, [cla], def_ids cla cl_init), lam) | |
+ mk_lam (Llet(Strict, class_init, | |
+ mk_lam (Lfunction(Curried, [cla], def_ids cla cl_init)), lam)) | |
and lcache lam = | |
- if inh_keys = [] then Llet(Alias, cached, Lvar tables, lam) else | |
- Llet(Strict, cached, | |
- mkappl (oo_prim "lookup_tables", | |
- [Lvar tables; Lprim(Pmakeblock(0, Immutable), inh_keys)]), | |
- lam) | |
+ if inh_keys = [] then | |
+ mk_lam (Llet(Alias, cached, mk_lam (Lvar tables), lam)) | |
+ else | |
+ mk_lam (Llet(Strict, cached, | |
+ mkappl (oo_prim "lookup_tables", | |
+ [mk_lam (Lvar tables); | |
+ mk_lam (Lprim(Pmakeblock(0, Immutable), inh_keys))]), | |
+ lam)) | |
and lset cached i lam = | |
- Lprim(Psetfield(i, true), [Lvar cached; lam]) | |
+ mk_lam (Lprim(Psetfield(i, true), [mk_lam (Lvar cached); lam])) | |
in | |
let ldirect () = | |
ltable cla | |
- (Llet(Strict, env_init, def_ids cla cl_init, | |
- Lsequence(mkappl (oo_prim "init_class", [Lvar cla]), | |
- lset cached 0 (Lvar env_init)))) | |
+ (mk_lam (Llet(Strict, env_init, def_ids cla cl_init, | |
+ mk_lam (Lsequence(mkappl (oo_prim "init_class", [mk_lam (Lvar cla)]), | |
+ lset cached 0 (mk_lam (Lvar env_init))))))) | |
and lclass_virt () = | |
- lset cached 0 (Lfunction(Curried, [cla], def_ids cla cl_init)) | |
+ lset cached 0 (mk_lam (Lfunction(Curried, [cla], def_ids cla cl_init))) | |
in | |
llets ( | |
lcache ( | |
- Lsequence( | |
- Lifthenelse(lfield cached 0, lambda_unit, | |
+ mk_lam (Lsequence( | |
+ mk_lam (Lifthenelse(lfield cached 0, lambda_unit, | |
if ids = [] then ldirect () else | |
if not concrete then lclass_virt () else | |
lclass ( | |
mkappl (oo_prim "make_class_store", | |
[transl_meth_list pub_meths; | |
- Lvar class_init; Lvar cached]))), | |
+ mk_lam (Lvar class_init); | |
+ mk_lam (Lvar cached)])))), | |
make_envs ( | |
if ids = [] then mkappl (lfield cached 0, [lenvs]) else | |
- Lprim(Pmakeblock(0, Immutable), | |
+ mk_lam (Lprim(Pmakeblock(0, Immutable), | |
if concrete then | |
[mkappl (lfield cached 0, [lenvs]); | |
lfield cached 1; | |
lfield cached 0; | |
lenvs] | |
else [lambda_unit; lfield cached 0; lambda_unit; lenvs] | |
- ))))) | |
+ ))))))) | |
(* Wrapper for class compilation *) | |
diff --git a/bytecomp/translcore.ml b/bytecomp/translcore.ml | |
index 9441fcc..088da1e 100644 | |
--- a/bytecomp/translcore.ml | |
+++ b/bytecomp/translcore.ml | |
@@ -40,6 +40,11 @@ let transl_object = | |
ref (fun id s cl -> assert false : | |
Ident.t -> string list -> class_expr -> lambda) | |
+let lambda l_desc = { | |
+ l_loc = Location.none; | |
+ l_desc; | |
+} | |
+ | |
(* Translation of primitives *) | |
let comparisons_table = create_hashtable 11 [ | |
@@ -361,19 +366,19 @@ let transl_primitive p = | |
match prim with | |
Plazyforce -> | |
let parm = Ident.create "prim" in | |
- Lfunction(Curried, [parm], Matching.inline_lazy_force (Lvar parm) Location.none) | |
+ lambda (Lfunction(Curried, [parm], Matching.inline_lazy_force (lambda (Lvar parm)) Location.none)) | |
| _ -> | |
let rec make_params n = | |
if n <= 0 then [] else Ident.create "prim" :: make_params (n-1) in | |
let params = make_params p.prim_arity in | |
- Lfunction(Curried, params, Lprim(prim, List.map (fun id -> Lvar id) params)) | |
+ lambda (Lfunction(Curried, params, lambda (Lprim(prim, List.map (fun id -> lambda (Lvar id)) params)))) | |
(* To check the well-formedness of r.h.s. of "let rec" definitions *) | |
let check_recursive_lambda idlist lam = | |
- let rec check_top idlist = function | |
+ let rec check_top idlist l = match l.l_desc with | |
| Lvar v -> not (List.mem v idlist) | |
- | Llet (_, _, _, _) as lam when check_recursive_recordwith idlist lam -> | |
+ | Llet _ when check_recursive_recordwith idlist l -> | |
true | |
| Llet(str, id, arg, body) -> | |
check idlist arg && check_top (add_let id arg idlist) body | |
@@ -384,12 +389,12 @@ let check_recursive_lambda idlist lam = | |
| Lprim (Pmakearray (Pgenarray), args) -> false | |
| Lsequence (lam1, lam2) -> check idlist lam1 && check_top idlist lam2 | |
| Levent (lam, _) -> check_top idlist lam | |
- | lam -> check idlist lam | |
+ | _ -> check idlist l | |
- and check idlist = function | |
+ and check idlist l = match l.l_desc with | |
| Lvar _ -> true | |
| Lfunction(kind, params, body) -> true | |
- | Llet (_, _, _, _) as lam when check_recursive_recordwith idlist lam -> | |
+ | Llet _ when check_recursive_recordwith idlist l -> | |
true | |
| Llet(str, id, arg, body) -> | |
check idlist arg && check (add_let id arg idlist) body | |
@@ -403,8 +408,8 @@ let check_recursive_lambda idlist lam = | |
List.for_all (check idlist) args | |
| Lsequence (lam1, lam2) -> check idlist lam1 && check idlist lam2 | |
| Levent (lam, _) -> check idlist lam | |
- | lam -> | |
- let fv = free_variables lam in | |
+ | _ -> | |
+ let fv = free_variables l in | |
not (List.exists (fun id -> IdentSet.mem id fv) idlist) | |
and add_let id arg idlist = | |
@@ -419,14 +424,14 @@ let check_recursive_lambda idlist lam = | |
(* reverse-engineering the code generated by transl_record case 2 *) | |
(* If you change this, you probably need to change Bytegen.size_of_lambda. *) | |
- and check_recursive_recordwith idlist = function | |
- | Llet (Strict, id1, Lprim (Pduprecord _, [e1]), body) -> | |
+ and check_recursive_recordwith idlist l = match l.l_desc with | |
+ | Llet (Strict, id1, {l_desc=Lprim (Pduprecord _, [e1])}, body) -> | |
check_top idlist e1 | |
&& check_recordwith_updates idlist id1 body | |
| _ -> false | |
- and check_recordwith_updates idlist id1 = function | |
- | Lsequence (Lprim ((Psetfield _ | Psetfloatfield _), [Lvar id2; e1]), cont) | |
+ and check_recordwith_updates idlist id1 l = match l.l_desc with | |
+ | Lsequence ({l_desc=Lprim((Psetfield _ | Psetfloatfield _), [{l_desc=Lvar id2}; e1])}, cont) | |
-> id2 = id1 && check idlist e1 | |
&& check_recordwith_updates idlist id1 cont | |
| Lvar id2 -> id2 = id1 | |
@@ -438,7 +443,7 @@ let check_recursive_lambda idlist lam = | |
exception Not_constant | |
-let extract_constant = function | |
+let extract_constant l = match l.l_desc with | |
Lconst sc -> sc | |
| _ -> raise Not_constant | |
@@ -491,33 +496,38 @@ let rec push_defaults loc bindings pat_expr_list partial = | |
(* Insertion of debugging events *) | |
-let event_before exp lam = match lam with | |
-| Lstaticraise (_,_) -> lam | |
-| _ -> | |
- if !Clflags.debug | |
- then Levent(lam, {lev_loc = exp.exp_loc; | |
- lev_kind = Lev_before; | |
- lev_repr = None; | |
- lev_env = Env.summary exp.exp_env}) | |
- else lam | |
+let event_before exp lam = match lam.l_desc with | |
+ | Lstaticraise (_,_) -> lam | |
+ | _ -> | |
+ if !Clflags.debug then | |
+ mk_loc_lam exp.exp_loc | |
+ (Levent(lam, {lev_loc = exp.exp_loc; | |
+ lev_kind = Lev_before; | |
+ lev_repr = None; | |
+ lev_env = Env.summary exp.exp_env})) | |
+ else | |
+ lam | |
let event_after exp lam = | |
- if !Clflags.debug | |
- then Levent(lam, {lev_loc = exp.exp_loc; | |
+ if !Clflags.debug then | |
+ mk_loc_lam exp.exp_loc | |
+ (Levent(lam, {lev_loc = exp.exp_loc; | |
lev_kind = Lev_after exp.exp_type; | |
lev_repr = None; | |
- lev_env = Env.summary exp.exp_env}) | |
- else lam | |
+ lev_env = Env.summary exp.exp_env})) | |
+ else | |
+ lam | |
let event_function exp lam = | |
if !Clflags.debug then | |
let repr = Some (ref 0) in | |
let (info, body) = lam repr in | |
(info, | |
- Levent(body, {lev_loc = exp.exp_loc; | |
- lev_kind = Lev_function; | |
- lev_repr = repr; | |
- lev_env = Env.summary exp.exp_env})) | |
+ mk_loc_lam exp.exp_loc | |
+ (Levent(body, {lev_loc = exp.exp_loc; | |
+ lev_kind = Lev_function; | |
+ lev_repr = repr; | |
+ lev_env = Env.summary exp.exp_env}))) | |
else | |
lam None | |
@@ -532,13 +542,15 @@ let primitive_is_ccall = function | |
let assert_failed loc = | |
let (fname, line, char) = Location.get_pos_info loc.Location.loc_start in | |
- Lprim(Praise, [Lprim(Pmakeblock(0, Immutable), | |
- [transl_path Predef.path_assert_failure; | |
- Lconst(Const_block(0, | |
- [Const_base(Const_string fname); | |
- Const_base(Const_int line); | |
- Const_base(Const_int char)]))])]) | |
-;; | |
+ let make = mk_loc_lam loc in | |
+ make | |
+ (Lprim(Praise, | |
+ [make (Lprim(Pmakeblock(0, Immutable), | |
+ [transl_path Predef.path_assert_failure; | |
+ make (Lconst(Const_block(0, | |
+ [Const_base(Const_string fname); | |
+ Const_base(Const_int line); | |
+ Const_base(Const_int char)])))]))])) | |
let rec cut n l = | |
if n = 0 then ([],l) else | |
@@ -561,15 +573,20 @@ and transl_exp0 e = | |
match e.exp_desc with | |
Texp_ident(path, {val_kind = Val_prim p}) -> | |
let public_send = p.prim_name = "%send" in | |
+ let make = mk_loc_lam e.exp_loc in | |
if public_send || p.prim_name = "%sendself" then | |
let kind = if public_send then Public else Self in | |
let obj = Ident.create "obj" and meth = Ident.create "meth" in | |
- Lfunction(Curried, [obj; meth], Lsend(kind, Lvar meth, Lvar obj, [], e.exp_loc)) | |
+ make | |
+ (Lfunction(Curried, [obj; meth], | |
+ make (Lsend(kind, make (Lvar meth), make (Lvar obj), [])))) | |
else if p.prim_name = "%sendcache" then | |
let obj = Ident.create "obj" and meth = Ident.create "meth" in | |
let cache = Ident.create "cache" and pos = Ident.create "pos" in | |
- Lfunction(Curried, [obj; meth; cache; pos], | |
- Lsend(Cached, Lvar meth, Lvar obj, [Lvar cache; Lvar pos], e.exp_loc)) | |
+ make | |
+ (Lfunction(Curried, [obj; meth; cache; pos], | |
+ make (Lsend(Cached, make (Lvar meth), make (Lvar obj), | |
+ [make (Lvar cache); make (Lvar pos)])))) | |
else | |
transl_primitive p | |
| Texp_ident(path, {val_kind = Val_anc _}) -> | |
@@ -577,8 +594,7 @@ and transl_exp0 e = | |
| Texp_ident(path, {val_kind = Val_reg | Val_self _}) -> | |
transl_path path | |
| Texp_ident _ -> fatal_error "Translcore.transl_exp: bad Texp_ident" | |
- | Texp_constant cst -> | |
- Lconst(Const_base cst) | |
+ | Texp_constant cst -> mk_loc_lam e.exp_loc (Lconst(Const_base cst)) | |
| Texp_let(rec_flag, pat_expr_list, body) -> | |
transl_let rec_flag pat_expr_list (event_before body (transl_exp body)) | |
| Texp_function (pat_expr_list, partial) -> | |
@@ -588,7 +604,7 @@ and transl_exp0 e = | |
let pl = push_defaults e.exp_loc [] pat_expr_list partial in | |
transl_function e.exp_loc !Clflags.native_code repr partial pl) | |
in | |
- Lfunction(kind, params, body) | |
+ mk_loc_lam e.exp_loc (Lfunction(kind, params, body)) | |
| Texp_apply({exp_desc = Texp_ident(path, {val_kind = Val_prim p})}, oargs) | |
when List.length oargs >= p.prim_arity | |
&& List.for_all (fun (arg,_) -> arg <> None) oargs -> | |
@@ -607,22 +623,22 @@ and transl_exp0 e = | |
if public_send || p.prim_name = "%sendself" then | |
let kind = if public_send then Public else Self in | |
let obj = List.hd argl in | |
- wrap (Lsend (kind, List.nth argl 1, obj, [], e.exp_loc)) | |
+ wrap (mk_loc_lam e.exp_loc (Lsend (kind, List.nth argl 1, obj, []))) | |
else if p.prim_name = "%sendcache" then | |
match argl with [obj; meth; cache; pos] -> | |
- wrap (Lsend(Cached, meth, obj, [cache; pos], e.exp_loc)) | |
+ wrap (mk_loc_lam e.exp_loc (Lsend(Cached, meth, obj, [cache; pos]))) | |
| _ -> assert false | |
else begin | |
let prim = transl_prim p args in | |
match (prim, args) with | |
(Praise, [arg1]) -> | |
- wrap0 (Lprim(Praise, [event_after arg1 (List.hd argl)])) | |
+ wrap0 (mk_loc_lam e.exp_loc (Lprim(Praise, [event_after arg1 (List.hd argl)]))) | |
| (_, _) -> | |
begin match (prim, argl) with | |
| (Plazyforce, [a]) -> | |
wrap (Matching.inline_lazy_force a e.exp_loc) | |
| (Plazyforce, _) -> assert false | |
- |_ -> let p = Lprim(prim, argl) in | |
+ |_ -> let p = mk_loc_lam e.exp_loc (Lprim(prim, argl)) in | |
if primitive_is_ccall prim then wrap p else wrap0 p | |
end | |
end | |
@@ -636,17 +652,21 @@ and transl_exp0 e = | |
(transl_exp arg) (transl_cases pat_expr_list) partial | |
| Texp_try(body, pat_expr_list) -> | |
let id = name_pattern "exn" pat_expr_list in | |
- Ltrywith(transl_exp body, id, | |
- Matching.for_trywith (Lvar id) (transl_cases pat_expr_list)) | |
+ mk_loc_lam e.exp_loc | |
+ (Ltrywith(transl_exp body, id, | |
+ Matching.for_trywith | |
+ (mk_loc_lam e.exp_loc (Lvar id)) | |
+ (transl_cases pat_expr_list))) | |
| Texp_tuple el -> | |
let ll = transl_list el in | |
begin try | |
- Lconst(Const_block(0, List.map extract_constant ll)) | |
+ mk_loc_lam e.exp_loc (Lconst(Const_block(0, List.map extract_constant ll))) | |
with Not_constant -> | |
- Lprim(Pmakeblock(0, Immutable), ll) | |
+ mk_loc_lam e.exp_loc (Lprim(Pmakeblock(0, Immutable), ll)) | |
end | |
| Texp_construct(cstr, args) -> | |
let ll = transl_list args in | |
+ mk_loc_lam e.exp_loc | |
begin match cstr.cstr_tag with | |
Cstr_constant n -> | |
Lconst(Const_pointer n) | |
@@ -661,6 +681,7 @@ and transl_exp0 e = | |
end | |
| Texp_variant(l, arg) -> | |
let tag = Btype.hash_variant l in | |
+ mk_loc_lam e.exp_loc | |
begin match arg with | |
None -> Lconst(Const_pointer tag) | |
| Some arg -> | |
@@ -670,7 +691,8 @@ and transl_exp0 e = | |
extract_constant lam])) | |
with Not_constant -> | |
Lprim(Pmakeblock(0, Immutable), | |
- [Lconst(Const_base(Const_int tag)); lam]) | |
+ [mk_loc_lam e.exp_loc (Lconst(Const_base(Const_int tag))); | |
+ lam]) | |
end | |
| Texp_record ((lbl1, _) :: _ as lbl_expr_list, opt_init_expr) -> | |
transl_record lbl1.lbl_all lbl1.lbl_repres lbl_expr_list opt_init_expr | |
@@ -681,86 +703,99 @@ and transl_exp0 e = | |
match lbl.lbl_repres with | |
Record_regular -> Pfield lbl.lbl_pos | |
| Record_float -> Pfloatfield lbl.lbl_pos in | |
- Lprim(access, [transl_exp arg]) | |
+ mk_loc_lam e.exp_loc (Lprim(access, [transl_exp arg])) | |
| Texp_setfield(arg, lbl, newval) -> | |
let access = | |
match lbl.lbl_repres with | |
Record_regular -> Psetfield(lbl.lbl_pos, maybe_pointer newval) | |
| Record_float -> Psetfloatfield lbl.lbl_pos in | |
- Lprim(access, [transl_exp arg; transl_exp newval]) | |
+ mk_loc_lam e.exp_loc (Lprim(access, [transl_exp arg; transl_exp newval])) | |
| Texp_array expr_list -> | |
let kind = array_kind e in | |
let ll = transl_list expr_list in | |
+ mk_loc_lam e.exp_loc | |
begin try | |
(* Deactivate constant optimization if array is small enough *) | |
if List.length ll <= 4 then raise Not_constant; | |
let cl = List.map extract_constant ll in | |
let master = | |
- match kind with | |
+ mk_loc_lam e.exp_loc | |
+ (match kind with | |
| Paddrarray | Pintarray -> | |
Lconst(Const_block(0, cl)) | |
| Pfloatarray -> | |
Lconst(Const_float_array(List.map extract_float cl)) | |
| Pgenarray -> | |
- raise Not_constant in (* can this really happen? *) | |
+ raise Not_constant) in (* can this really happen? *) | |
Lprim(Pccall prim_obj_dup, [master]) | |
with Not_constant -> | |
Lprim(Pmakearray kind, ll) | |
end | |
| Texp_ifthenelse(cond, ifso, Some ifnot) -> | |
- Lifthenelse(transl_exp cond, | |
- event_before ifso (transl_exp ifso), | |
- event_before ifnot (transl_exp ifnot)) | |
+ mk_loc_lam e.exp_loc | |
+ (Lifthenelse(transl_exp cond, | |
+ event_before ifso (transl_exp ifso), | |
+ event_before ifnot (transl_exp ifnot))) | |
| Texp_ifthenelse(cond, ifso, None) -> | |
- Lifthenelse(transl_exp cond, | |
- event_before ifso (transl_exp ifso), | |
- lambda_unit) | |
+ mk_loc_lam e.exp_loc | |
+ (Lifthenelse(transl_exp cond, | |
+ event_before ifso (transl_exp ifso), | |
+ lambda_unit)) | |
| Texp_sequence(expr1, expr2) -> | |
- Lsequence(transl_exp expr1, event_before expr2 (transl_exp expr2)) | |
+ mk_loc_lam e.exp_loc | |
+ (Lsequence(transl_exp expr1, event_before expr2 (transl_exp expr2))) | |
| Texp_while(cond, body) -> | |
- Lwhile(transl_exp cond, event_before body (transl_exp body)) | |
+ mk_loc_lam e.exp_loc | |
+ (Lwhile(transl_exp cond, event_before body (transl_exp body))) | |
| Texp_for(param, low, high, dir, body) -> | |
- Lfor(param, transl_exp low, transl_exp high, dir, | |
- event_before body (transl_exp body)) | |
+ mk_loc_lam e.exp_loc | |
+ (Lfor(param, transl_exp low, transl_exp high, dir, | |
+ event_before body (transl_exp body))) | |
| Texp_when(cond, body) -> | |
event_before cond | |
- (Lifthenelse(transl_exp cond, event_before body (transl_exp body), | |
- staticfail)) | |
+ (mk_loc_lam e.exp_loc | |
+ (Lifthenelse(transl_exp cond, event_before body (transl_exp body), | |
+ staticfail))) | |
| Texp_send(expr, met) -> | |
let obj = transl_exp expr in | |
- let lam = | |
+ let lamd = | |
match met with | |
- Tmeth_val id -> Lsend (Self, Lvar id, obj, [], e.exp_loc) | |
+ Tmeth_val id -> Lsend (Self, mk_loc_lam e.exp_loc (Lvar id), obj, []) | |
| Tmeth_name nm -> | |
let (tag, cache) = Translobj.meth obj nm in | |
let kind = if cache = [] then Public else Cached in | |
- Lsend (kind, tag, obj, cache, e.exp_loc) | |
+ Lsend (kind, tag, obj, cache) | |
in | |
- event_after e lam | |
+ event_after e (mk_loc_lam e.exp_loc lamd) | |
| Texp_new (cl, _) -> | |
- Lapply(Lprim(Pfield 0, [transl_path cl]), [lambda_unit], Location.none) | |
+ mk_loc_lam e.exp_loc | |
+ (Lapply(mk_loc_lam e.exp_loc (Lprim(Pfield 0, [transl_path cl])), [lambda_unit])) | |
| Texp_instvar(path_self, path) -> | |
- Lprim(Parrayrefu Paddrarray, [transl_path path_self; transl_path path]) | |
+ mk_loc_lam e.exp_loc (Lprim(Parrayrefu Paddrarray, [transl_path path_self; transl_path path])) | |
| Texp_setinstvar(path_self, path, expr) -> | |
transl_setinstvar (transl_path path_self) path expr | |
| Texp_override(path_self, modifs) -> | |
let cpy = Ident.create "copy" in | |
- Llet(Strict, cpy, | |
- Lapply(Translobj.oo_prim "copy", [transl_path path_self], | |
- Location.none), | |
+ mk_loc_lam e.exp_loc | |
+ (Llet(Strict, cpy, | |
+ mk_loc_lam e.exp_loc | |
+ (Lapply(Translobj.oo_prim "copy", [transl_path path_self])), | |
List.fold_right | |
(fun (path, expr) rem -> | |
- Lsequence(transl_setinstvar (Lvar cpy) path expr, rem)) | |
+ mk_loc_lam e.exp_loc | |
+ (Lsequence(transl_setinstvar (mk_loc_lam e.exp_loc (Lvar cpy)) path expr, rem))) | |
modifs | |
- (Lvar cpy)) | |
+ (mk_loc_lam e.exp_loc (Lvar cpy)))) | |
| Texp_letmodule(id, modl, body) -> | |
- Llet(Strict, id, !transl_module Tcoerce_none None modl, transl_exp body) | |
+ mk_loc_lam e.exp_loc | |
+ (Llet(Strict, id, !transl_module Tcoerce_none None modl, transl_exp body)) | |
| Texp_pack modl -> | |
!transl_module Tcoerce_none None modl | |
| Texp_assert (cond) -> | |
if !Clflags.noassert | |
then lambda_unit | |
- else Lifthenelse (transl_exp cond, lambda_unit, assert_failed e.exp_loc) | |
+ else mk_loc_lam e.exp_loc | |
+ (Lifthenelse (transl_exp cond, lambda_unit, assert_failed e.exp_loc)) | |
| Texp_assertfalse -> assert_failed e.exp_loc | |
| Texp_lazy e -> | |
(* when e needs no computation (constants, identifiers, ...), we | |
@@ -775,14 +810,15 @@ and transl_exp0 e = | |
| Texp_construct ({cstr_arity = 0}, _) | |
-> transl_exp e | |
| Texp_constant(Const_float _) -> | |
- Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp e]) | |
+ mk_loc_lam e.exp_loc | |
+ (Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp e])) | |
| Texp_ident(_, _) -> (* according to the type *) | |
begin match e.exp_type.desc with | |
(* the following may represent a float/forward/lazy: need a | |
forward_tag *) | |
| Tvar _ | Tlink _ | Tsubst _ | Tunivar _ | |
| Tpoly(_,_) | Tfield(_,_,_,_) -> | |
- Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp e]) | |
+ mk_loc_lam e.exp_loc (Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp e])) | |
(* the following cannot be represented as float/forward/lazy: | |
optimize *) | |
| Tarrow(_,_,_,_) | Ttuple _ | Tpackage _ | Tobject(_,_) | Tnil | |
@@ -805,12 +841,14 @@ and transl_exp0 e = | |
|| has_base_type e Predef.path_int64 | |
then transl_exp e | |
else | |
- Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp e]) | |
+ mk_loc_lam e.exp_loc (Lprim(Pmakeblock(Obj.forward_tag, Immutable), [transl_exp e])) | |
end | |
(* other cases compile to a lazy block holding a function *) | |
| _ -> | |
- let fn = Lfunction (Curried, [Ident.create "param"], transl_exp e) in | |
- Lprim(Pmakeblock(Config.lazy_tag, Immutable), [fn]) | |
+ let fn = mk_loc_lam e.exp_loc | |
+ (Lfunction (Curried, [Ident.create "param"], transl_exp e)) in | |
+ mk_loc_lam e.exp_loc | |
+ (Lprim(Pmakeblock(Config.lazy_tag, Immutable), [fn])) | |
end | |
| Texp_object (cs, cty, meths) -> | |
let cl = Ident.create "class" in | |
@@ -833,26 +871,27 @@ and transl_tupled_cases patl_expr_list = | |
and transl_apply lam sargs loc = | |
let lapply funct args = | |
- match funct with | |
- Lsend(k, lmet, lobj, largs, loc) -> | |
- Lsend(k, lmet, lobj, largs @ args, loc) | |
- | Levent(Lsend(k, lmet, lobj, largs, loc), _) -> | |
- Lsend(k, lmet, lobj, largs @ args, loc) | |
- | Lapply(lexp, largs, _) -> | |
- Lapply(lexp, largs @ args, loc) | |
- | lexp -> | |
- Lapply(lexp, args, loc) | |
+ let make = mk_loc_lam funct.l_loc in | |
+ match funct.l_desc with | |
+ Lsend(k, lmet, lobj, largs) -> | |
+ make (Lsend(k, lmet, lobj, largs @ args)) | |
+ | Levent({l_desc=Lsend(k, lmet, lobj, largs)},_) -> | |
+ make (Lsend(k, lmet, lobj, largs @ args)) | |
+ | Lapply(lexp, largs) -> | |
+ make (Lapply(lexp, largs @ args)) | |
+ | _ -> | |
+ make (Lapply(funct, args)) | |
in | |
let rec build_apply lam args = function | |
(None, optional) :: l -> | |
let defs = ref [] in | |
let protect name lam = | |
- match lam with | |
+ match lam.l_desc with | |
Lvar _ | Lconst _ -> lam | |
| _ -> | |
let id = Ident.create name in | |
defs := (id, lam) :: !defs; | |
- Lvar id | |
+ mk_loc_lam lam.l_loc (Lvar id) | |
in | |
let args, args' = | |
if List.for_all (fun (_,opt) -> opt = Optional) args then [], args | |
@@ -863,16 +902,18 @@ and transl_apply lam sargs loc = | |
and l = List.map (fun (arg, opt) -> may_map (protect "arg") arg, opt) l | |
and id_arg = Ident.create "param" in | |
let body = | |
- match build_apply handle ((Lvar id_arg, optional)::args') l with | |
- Lfunction(Curried, ids, lam) -> | |
- Lfunction(Curried, id_arg::ids, lam) | |
- | Levent(Lfunction(Curried, ids, lam), _) -> | |
- Lfunction(Curried, id_arg::ids, lam) | |
- | lam -> | |
- Lfunction(Curried, [id_arg], lam) | |
- in | |
+ let app = build_apply handle ((lambda (Lvar id_arg), optional)::args') l in | |
+ mk_loc_lam app.l_loc | |
+ begin match app.l_desc with | |
+ | Lfunction(Curried, ids, lam) -> | |
+ Lfunction(Curried, id_arg::ids, lam) | |
+ | Levent({l_desc=Lfunction(Curried, ids, lam)}, _) -> | |
+ Lfunction(Curried, id_arg::ids, lam) | |
+ | _ -> | |
+ Lfunction(Curried, [id_arg], lam) | |
+ end in | |
List.fold_left | |
- (fun body (id, lam) -> Llet(Strict, id, lam, body)) | |
+ (fun body (id, lam) -> lambda (Llet(Strict, id, lam, body))) | |
body !defs | |
| (Some arg, optional) :: l -> | |
build_apply lam ((arg, optional) :: args) l | |
@@ -889,7 +930,7 @@ and transl_function loc untuplify_fn repr partial pat_expr_list = | |
let ((_, params), body) = | |
transl_function exp.exp_loc false repr partial' pl in | |
((Curried, param :: params), | |
- Matching.for_function loc None (Lvar param) [pat, body] partial) | |
+ Matching.for_function loc None (mk_loc_lam loc (Lvar param)) [pat, body] partial) | |
| ({pat_desc = Tpat_tuple pl}, _) :: _ when untuplify_fn -> | |
begin try | |
let size = List.length pl in | |
@@ -904,13 +945,13 @@ and transl_function loc untuplify_fn repr partial pat_expr_list = | |
with Matching.Cannot_flatten -> | |
let param = name_pattern "param" pat_expr_list in | |
((Curried, [param]), | |
- Matching.for_function loc repr (Lvar param) | |
+ Matching.for_function loc repr (mk_loc_lam loc (Lvar param)) | |
(transl_cases pat_expr_list) partial) | |
end | |
| _ -> | |
let param = name_pattern "param" pat_expr_list in | |
((Curried, [param]), | |
- Matching.for_function loc repr (Lvar param) | |
+ Matching.for_function loc repr (mk_loc_lam loc (Lvar param)) | |
(transl_cases pat_expr_list) partial) | |
and transl_let rec_flag pat_expr_list body = | |
@@ -935,11 +976,12 @@ and transl_let rec_flag pat_expr_list body = | |
if not (check_recursive_lambda idlist lam) then | |
raise(Error(expr.exp_loc, Illegal_letrec_expr)); | |
(id, lam) in | |
- Lletrec(List.map2 transl_case pat_expr_list idlist, body) | |
+ (mk_loc_lam body.l_loc (Lletrec(List.map2 transl_case pat_expr_list idlist, body))) | |
and transl_setinstvar self var expr = | |
- Lprim(Parraysetu (if maybe_pointer expr then Paddrarray else Pintarray), | |
- [self; transl_path var; transl_exp expr]) | |
+ mk_loc_lam expr.exp_loc | |
+ (Lprim(Parraysetu (if maybe_pointer expr then Paddrarray else Pintarray), | |
+ [self; transl_path var; transl_exp expr])) | |
and transl_record all_labels repres lbl_expr_list opt_init_expr = | |
let size = Array.length all_labels in | |
@@ -958,7 +1000,7 @@ and transl_record all_labels repres lbl_expr_list opt_init_expr = | |
match all_labels.(i).lbl_repres with | |
Record_regular -> Pfield i | |
| Record_float -> Pfloatfield i in | |
- lv.(i) <- Lprim(access, [Lvar init_id]) | |
+ lv.(i) <- lambda (Lprim(access, [lambda (Lvar init_id)])) | |
done | |
end; | |
List.iter | |
@@ -970,20 +1012,20 @@ and transl_record all_labels repres lbl_expr_list opt_init_expr = | |
then Mutable | |
else Immutable in | |
let lam = | |
- try | |
- if mut = Mutable then raise Not_constant; | |
- let cl = List.map extract_constant ll in | |
- match repres with | |
- Record_regular -> Lconst(Const_block(0, cl)) | |
- | Record_float -> | |
- Lconst(Const_float_array(List.map extract_float cl)) | |
- with Not_constant -> | |
- match repres with | |
- Record_regular -> Lprim(Pmakeblock(0, mut), ll) | |
- | Record_float -> Lprim(Pmakearray Pfloatarray, ll) in | |
+ lambda | |
+ begin try | |
+ if mut = Mutable then raise Not_constant; | |
+ let cl = List.map extract_constant ll in | |
+ match repres with | |
+ | Record_regular -> Lconst(Const_block(0, cl)) | |
+ | Record_float -> Lconst(Const_float_array(List.map extract_float cl)) | |
+ with Not_constant -> match repres with | |
+ | Record_regular -> Lprim(Pmakeblock(0, mut), ll) | |
+ | Record_float -> Lprim(Pmakearray Pfloatarray, ll) | |
+ end in | |
begin match opt_init_expr with | |
None -> lam | |
- | Some init_expr -> Llet(Strict, init_id, transl_exp init_expr, lam) | |
+ | Some init_expr -> lambda (Llet(Strict, init_id, transl_exp init_expr, lam)) | |
end | |
end else begin | |
(* Take a shallow copy of the init record, then mutate the fields | |
@@ -996,13 +1038,15 @@ and transl_record all_labels repres lbl_expr_list opt_init_expr = | |
match lbl.lbl_repres with | |
Record_regular -> Psetfield(lbl.lbl_pos, maybe_pointer expr) | |
| Record_float -> Psetfloatfield lbl.lbl_pos in | |
- Lsequence(Lprim(upd, [Lvar copy_id; transl_exp expr]), cont) in | |
+ lambda | |
+ (Lsequence(lambda (Lprim(upd, [lambda (Lvar copy_id); transl_exp expr])), | |
+ cont)) in | |
begin match opt_init_expr with | |
None -> assert false | |
| Some init_expr -> | |
- Llet(Strict, copy_id, | |
- Lprim(Pduprecord (repres, size), [transl_exp init_expr]), | |
- List.fold_right update_field lbl_expr_list (Lvar copy_id)) | |
+ lambda (Llet(Strict, copy_id, | |
+ lambda (Lprim(Pduprecord (repres, size), [transl_exp init_expr])), | |
+ List.fold_right update_field lbl_expr_list (lambda (Lvar copy_id)))) | |
end | |
end | |
@@ -1026,7 +1070,8 @@ let transl_exception id path decl = | |
match path with | |
None -> Ident.name id | |
| Some p -> Path.name p in | |
- Lprim(Pmakeblock(0, Immutable), [Lconst(Const_base(Const_string name))]) | |
+ lambda (Lprim(Pmakeblock(0, Immutable), | |
+ [lambda (Lconst(Const_base(Const_string name)))])) | |
(* Error report *) | |
diff --git a/bytecomp/translmod.ml b/bytecomp/translmod.ml | |
index 38eab85..570eabf 100644 | |
--- a/bytecomp/translmod.ml | |
+++ b/bytecomp/translmod.ml | |
@@ -40,20 +40,21 @@ let rec apply_coercion restr arg = | |
arg | |
| Tcoerce_structure pos_cc_list -> | |
name_lambda arg (fun id -> | |
- Lprim(Pmakeblock(0, Immutable), | |
- List.map (apply_coercion_field id) pos_cc_list)) | |
+ mk_lam (Lprim(Pmakeblock(0, Immutable), | |
+ List.map (apply_coercion_field id) pos_cc_list))) | |
| Tcoerce_functor(cc_arg, cc_res) -> | |
let param = Ident.create "funarg" in | |
name_lambda arg (fun id -> | |
- Lfunction(Curried, [param], | |
+ mk_lam (Lfunction(Curried, [param], | |
apply_coercion cc_res | |
- (Lapply(Lvar id, [apply_coercion cc_arg (Lvar param)], | |
- Location.none)))) | |
+ (mk_lam (Lapply(mk_lam (Lvar id), | |
+ [apply_coercion cc_arg (mk_lam (Lvar param))] | |
+ )))))) | |
| Tcoerce_primitive p -> | |
transl_primitive p | |
and apply_coercion_field id (pos, cc) = | |
- apply_coercion cc (Lprim(Pfield pos, [Lvar id])) | |
+ apply_coercion cc (mk_lam (Lprim(Pfield pos, [mk_lam (Lvar id)]))) | |
(* Compose two coercions | |
apply_coercion c1 (apply_coercion c2 e) behaves like | |
@@ -110,10 +111,10 @@ let mod_prim name = | |
let undefined_location loc = | |
let (fname, line, char) = Location.get_pos_info loc.Location.loc_start in | |
- Lconst(Const_block(0, | |
+ mk_lam (Lconst(Const_block(0, | |
[Const_base(Const_string fname); | |
Const_base(Const_int line); | |
- Const_base(Const_int char)])) | |
+ Const_base(Const_int char)]))) | |
let init_shape modl = | |
let rec init_shape_mod env mty = | |
@@ -153,7 +154,7 @@ let init_shape modl = | |
in | |
try | |
Some(undefined_location modl.mod_loc, | |
- Lconst(init_shape_mod modl.mod_env modl.mod_type)) | |
+ mk_lam (Lconst(init_shape_mod modl.mod_env modl.mod_type))) | |
with Not_found -> | |
None | |
@@ -200,13 +201,13 @@ let eval_rec_bindings bindings cont = | |
| (id, None, rhs) :: rem -> | |
bind_inits rem | |
| (id, Some(loc, shape), rhs) :: rem -> | |
- Llet(Strict, id, Lapply(mod_prim "init_mod", [loc; shape], Location.none), | |
- bind_inits rem) | |
+ mk_lam (Llet(Strict, id, mk_lam (Lapply(mod_prim "init_mod", [loc; shape])), | |
+ bind_inits rem)) | |
and bind_strict = function | |
[] -> | |
patch_forwards bindings | |
| (id, None, rhs) :: rem -> | |
- Llet(Strict, id, rhs, bind_strict rem) | |
+ mk_lam (Llet(Strict, id, rhs, bind_strict rem)) | |
| (id, Some(loc, shape), rhs) :: rem -> | |
bind_strict rem | |
and patch_forwards = function | |
@@ -215,9 +216,9 @@ let eval_rec_bindings bindings cont = | |
| (id, None, rhs) :: rem -> | |
patch_forwards rem | |
| (id, Some(loc, shape), rhs) :: rem -> | |
- Lsequence(Lapply(mod_prim "update_mod", [shape; Lvar id; rhs], | |
- Location.none), | |
- patch_forwards rem) | |
+ mk_lam (Lsequence(mk_lam (Lapply(mod_prim "update_mod", | |
+ [shape; mk_lam (Lvar id); rhs])), | |
+ patch_forwards rem)) | |
in | |
bind_inits bindings | |
@@ -243,21 +244,25 @@ let rec transl_module cc rootpath mexp = | |
oo_wrap mexp.mod_env true | |
(function | |
| Tcoerce_none -> | |
- Lfunction(Curried, [param], | |
- transl_module Tcoerce_none bodypath body) | |
+ mk_loc_lam mexp.mod_loc | |
+ (Lfunction(Curried, [param], | |
+ transl_module Tcoerce_none bodypath body)) | |
| Tcoerce_functor(ccarg, ccres) -> | |
let param' = Ident.create "funarg" in | |
- Lfunction(Curried, [param'], | |
- Llet(Alias, param, apply_coercion ccarg (Lvar param'), | |
- transl_module ccres bodypath body)) | |
+ mk_loc_lam mexp.mod_loc | |
+ (Lfunction(Curried, [param'], | |
+ mk_lam (Llet(Alias, param, | |
+ apply_coercion ccarg (mk_lam (Lvar param')), | |
+ transl_module ccres bodypath body)))) | |
| _ -> | |
fatal_error "Translmod.transl_module") | |
cc | |
| Tmod_apply(funct, arg, ccarg) -> | |
oo_wrap mexp.mod_env true | |
(apply_coercion cc) | |
- (Lapply(transl_module Tcoerce_none None funct, | |
- [transl_module ccarg None arg], mexp.mod_loc)) | |
+ (mk_loc_lam mexp.mod_loc | |
+ (Lapply(transl_module Tcoerce_none None funct, | |
+ [transl_module ccarg None arg]))) | |
| Tmod_constraint(arg, mty, ccarg) -> | |
transl_module (compose_coercions cc ccarg) rootpath arg | |
| Tmod_unpack(arg, _) -> | |
@@ -267,22 +272,22 @@ and transl_structure fields cc rootpath = function | |
[] -> | |
begin match cc with | |
Tcoerce_none -> | |
- Lprim(Pmakeblock(0, Immutable), | |
- List.map (fun id -> Lvar id) (List.rev fields)) | |
+ mk_lam (Lprim(Pmakeblock(0, Immutable), | |
+ List.map (fun id -> mk_lam (Lvar id)) (List.rev fields))) | |
| Tcoerce_structure pos_cc_list -> | |
let v = Array.of_list (List.rev fields) in | |
- Lprim(Pmakeblock(0, Immutable), | |
+ mk_lam (Lprim(Pmakeblock(0, Immutable), | |
List.map | |
(fun (pos, cc) -> | |
match cc with | |
Tcoerce_primitive p -> transl_primitive p | |
- | _ -> apply_coercion cc (Lvar v.(pos))) | |
- pos_cc_list) | |
+ | _ -> apply_coercion cc (mk_lam (Lvar v.(pos)))) | |
+ pos_cc_list)) | |
| _ -> | |
fatal_error "Translmod.transl_structure" | |
end | |
| Tstr_eval expr :: rem -> | |
- Lsequence(transl_exp expr, transl_structure fields cc rootpath rem) | |
+ mk_lam (Lsequence(transl_exp expr, transl_structure fields cc rootpath rem)) | |
| Tstr_value(rec_flag, pat_expr_list) :: rem -> | |
let ext_fields = rev_let_bound_idents pat_expr_list @ fields in | |
transl_let rec_flag pat_expr_list | |
@@ -293,15 +298,15 @@ and transl_structure fields cc rootpath = function | |
| Tstr_type(decls) :: rem -> | |
transl_structure fields cc rootpath rem | |
| Tstr_exception(id, decl) :: rem -> | |
- Llet(Strict, id, transl_exception id (field_path rootpath id) decl, | |
- transl_structure (id :: fields) cc rootpath rem) | |
+ mk_lam (Llet(Strict, id, transl_exception id (field_path rootpath id) decl, | |
+ transl_structure (id :: fields) cc rootpath rem)) | |
| Tstr_exn_rebind(id, path) :: rem -> | |
- Llet(Strict, id, transl_path path, | |
- transl_structure (id :: fields) cc rootpath rem) | |
+ mk_lam (Llet(Strict, id, transl_path path, | |
+ transl_structure (id :: fields) cc rootpath rem)) | |
| Tstr_module(id, modl) :: rem -> | |
- Llet(Strict, id, | |
- transl_module Tcoerce_none (field_path rootpath id) modl, | |
- transl_structure (id :: fields) cc rootpath rem) | |
+ mk_lam (Llet(Strict, id, | |
+ transl_module Tcoerce_none (field_path rootpath id) modl, | |
+ transl_structure (id :: fields) cc rootpath rem)) | |
| Tstr_recmodule bindings :: rem -> | |
let ext_fields = List.rev_append (List.map fst bindings) fields in | |
compile_recmodule | |
@@ -315,11 +320,11 @@ and transl_structure fields cc rootpath = function | |
transl_structure fields cc rootpath rem | |
| Tstr_class cl_list :: rem -> | |
let ids = List.map (fun (i, _, _, _, _) -> i) cl_list in | |
- Lletrec(List.map | |
- (fun (id, arity, meths, cl, vf) -> | |
- (id, transl_class ids id arity meths cl vf)) | |
- cl_list, | |
- transl_structure (List.rev ids @ fields) cc rootpath rem) | |
+ mk_lam (Lletrec(List.map | |
+ (fun (id, arity, meths, cl, vf) -> | |
+ (id, transl_class ids id arity meths cl vf)) | |
+ cl_list, | |
+ transl_structure (List.rev ids @ fields) cc rootpath rem)) | |
| Tstr_cltype cl_list :: rem -> | |
transl_structure fields cc rootpath rem | |
| Tstr_include(modl, ids) :: rem -> | |
@@ -328,10 +333,11 @@ and transl_structure fields cc rootpath = function | |
[] -> | |
transl_structure newfields cc rootpath rem | |
| id :: ids -> | |
- Llet(Alias, id, Lprim(Pfield pos, [Lvar mid]), | |
- rebind_idents (pos + 1) (id :: newfields) ids) in | |
- Llet(Strict, mid, transl_module Tcoerce_none None modl, | |
- rebind_idents 0 fields ids) | |
+ mk_lam (Llet(Alias, id, | |
+ mk_lam (Lprim(Pfield pos, [mk_lam (Lvar mid)])), | |
+ rebind_idents (pos + 1) (id :: newfields) ids)) in | |
+ mk_lam (Llet(Strict, mid, transl_module Tcoerce_none None modl, | |
+ rebind_idents 0 fields ids)) | |
(* Update forward declaration in Translcore *) | |
let _ = | |
@@ -343,9 +349,9 @@ let transl_implementation module_name (str, cc) = | |
reset_labels (); | |
primitive_declarations := []; | |
let module_id = Ident.create_persistent module_name in | |
- Lprim(Psetglobal module_id, | |
- [transl_label_init | |
- (transl_structure [] cc (global_path module_id) str)]) | |
+ mk_lam (Lprim(Psetglobal module_id, | |
+ [transl_label_init | |
+ (transl_structure [] cc (global_path module_id) str)])) | |
(* A variant of transl_structure used to compile toplevel structure definitions | |
for the native-code compiler. Store the defined values in the fields | |
@@ -361,8 +367,8 @@ let transl_store_subst = ref Ident.empty | |
calls of transl_store_structure *) | |
let nat_toplevel_name id = | |
- try match Ident.find_same id !transl_store_subst with | |
- | Lprim(Pfield pos, [Lprim(Pgetglobal glob, [])]) -> (glob,pos) | |
+ try match (Ident.find_same id !transl_store_subst).l_desc with | |
+ | Lprim(Pfield pos, [{l_desc=Lprim(Pgetglobal glob, [])}]) -> (glob,pos) | |
| _ -> raise Not_found | |
with Not_found -> | |
fatal_error("Translmod.nat_toplevel_name: " ^ Ident.unique_name id) | |
@@ -373,13 +379,13 @@ let transl_store_structure glob map prims str = | |
transl_store_subst := subst; | |
lambda_unit | |
| Tstr_eval expr :: rem -> | |
- Lsequence(subst_lambda subst (transl_exp expr), | |
- transl_store subst rem) | |
+ mk_lam (Lsequence(subst_lambda subst (transl_exp expr), | |
+ transl_store subst rem)) | |
| Tstr_value(rec_flag, pat_expr_list) :: rem -> | |
let ids = let_bound_idents pat_expr_list in | |
let lam = transl_let rec_flag pat_expr_list (store_idents ids) in | |
- Lsequence(subst_lambda subst lam, | |
- transl_store (add_idents false ids subst) rem) | |
+ mk_lam (Lsequence(subst_lambda subst lam, | |
+ transl_store (add_idents false ids subst) rem)) | |
| Tstr_primitive(id, descr) :: rem -> | |
record_primitive descr; | |
transl_store subst rem | |
@@ -387,12 +393,12 @@ let transl_store_structure glob map prims str = | |
transl_store subst rem | |
| Tstr_exception(id, decl) :: rem -> | |
let lam = transl_exception id (field_path (global_path glob) id) decl in | |
- Lsequence(Llet(Strict, id, lam, store_ident id), | |
- transl_store (add_ident false id subst) rem) | |
+ mk_lam (Lsequence(mk_lam (Llet(Strict, id, lam, store_ident id)), | |
+ transl_store (add_ident false id subst) rem)) | |
| Tstr_exn_rebind(id, path) :: rem -> | |
let lam = subst_lambda subst (transl_path path) in | |
- Lsequence(Llet(Strict, id, lam, store_ident id), | |
- transl_store (add_ident false id subst) rem) | |
+ mk_lam (Lsequence(mk_lam (Llet(Strict, id, lam, store_ident id)), | |
+ transl_store (add_ident false id subst) rem)) | |
| Tstr_module(id, modl) :: rem -> | |
let lam = | |
transl_module Tcoerce_none (field_path (global_path glob) id) modl in | |
@@ -402,8 +408,8 @@ let transl_store_structure glob map prims str = | |
the compilation unit (add_ident true returns subst unchanged). | |
If not, we can use the value from the global | |
(add_ident true adds id -> Pgetglobal... to subst). *) | |
- Llet(Strict, id, subst_lambda subst lam, | |
- Lsequence(store_ident id, transl_store(add_ident true id subst) rem)) | |
+ mk_lam (Llet(Strict, id, subst_lambda subst lam, | |
+ mk_lam (Lsequence(store_ident id, transl_store(add_ident true id subst) rem)))) | |
| Tstr_recmodule bindings :: rem -> | |
let ids = List.map fst bindings in | |
compile_recmodule | |
@@ -412,8 +418,8 @@ let transl_store_structure glob map prims str = | |
(transl_module Tcoerce_none | |
(field_path (global_path glob) id) modl)) | |
bindings | |
- (Lsequence(store_idents ids, | |
- transl_store (add_idents true ids subst) rem)) | |
+ (mk_lam (Lsequence(store_idents ids, | |
+ transl_store (add_idents true ids subst) rem))) | |
| Tstr_modtype(id, decl) :: rem -> | |
transl_store subst rem | |
| Tstr_open path :: rem -> | |
@@ -421,13 +427,13 @@ let transl_store_structure glob map prims str = | |
| Tstr_class cl_list :: rem -> | |
let ids = List.map (fun (i, _, _, _, _) -> i) cl_list in | |
let lam = | |
- Lletrec(List.map | |
- (fun (id, arity, meths, cl, vf) -> | |
- (id, transl_class ids id arity meths cl vf)) | |
- cl_list, | |
- store_idents ids) in | |
- Lsequence(subst_lambda subst lam, | |
- transl_store (add_idents false ids subst) rem) | |
+ mk_lam (Lletrec(List.map | |
+ (fun (id, arity, meths, cl, vf) -> | |
+ (id, transl_class ids id arity meths cl vf)) | |
+ cl_list, | |
+ store_idents ids)) in | |
+ mk_lam (Lsequence(subst_lambda subst lam, | |
+ transl_store (add_idents false ids subst) rem)) | |
| Tstr_cltype cl_list :: rem -> | |
transl_store subst rem | |
| Tstr_include(modl, ids) :: rem -> | |
@@ -435,17 +441,18 @@ let transl_store_structure glob map prims str = | |
let rec store_idents pos = function | |
[] -> transl_store (add_idents true ids subst) rem | |
| id :: idl -> | |
- Llet(Alias, id, Lprim(Pfield pos, [Lvar mid]), | |
- Lsequence(store_ident id, store_idents (pos + 1) idl)) in | |
- Llet(Strict, mid, | |
- subst_lambda subst (transl_module Tcoerce_none None modl), | |
- store_idents 0 ids) | |
+ mk_lam (Llet(Alias, id, | |
+ mk_lam (Lprim(Pfield pos, [mk_lam (Lvar mid)])), | |
+ mk_lam (Lsequence(store_ident id, store_idents (pos + 1) idl)))) in | |
+ mk_lam (Llet(Strict, mid, | |
+ subst_lambda subst (transl_module Tcoerce_none None modl), | |
+ store_idents 0 ids)) | |
and store_ident id = | |
try | |
let (pos, cc) = Ident.find_same id map in | |
- let init_val = apply_coercion cc (Lvar id) in | |
- Lprim(Psetfield(pos, false), [Lprim(Pgetglobal glob, []); init_val]) | |
+ let init_val = apply_coercion cc (mk_lam (Lvar id)) in | |
+ mk_lam (Lprim(Psetfield(pos, false), [mk_lam (Lprim(Pgetglobal glob, [])); init_val])) | |
with Not_found -> | |
fatal_error("Translmod.store_ident: " ^ Ident.unique_name id) | |
@@ -457,7 +464,7 @@ let transl_store_structure glob map prims str = | |
let (pos, cc) = Ident.find_same id map in | |
match cc with | |
Tcoerce_none -> | |
- Ident.add id (Lprim(Pfield pos, [Lprim(Pgetglobal glob, [])])) subst | |
+ Ident.add id (mk_lam (Lprim(Pfield pos, [mk_lam (Lprim(Pgetglobal glob, []))]))) subst | |
| _ -> | |
if may_coerce then subst else assert false | |
with Not_found -> | |
@@ -467,9 +474,10 @@ let transl_store_structure glob map prims str = | |
List.fold_right (add_ident may_coerce) idlist subst | |
and store_primitive (pos, prim) cont = | |
- Lsequence(Lprim(Psetfield(pos, false), | |
- [Lprim(Pgetglobal glob, []); transl_primitive prim]), | |
- cont) | |
+ mk_lam (Lsequence(mk_lam (Lprim(Psetfield(pos, false), | |
+ [mk_lam (Lprim(Pgetglobal glob, [])); | |
+ transl_primitive prim])), | |
+ cont)) | |
in List.fold_right store_primitive prims (transl_store !transl_store_subst str) | |
@@ -573,21 +581,19 @@ let toplevel_name id = | |
with Not_found -> Ident.name id | |
let toploop_getvalue id = | |
- Lapply(Lprim(Pfield toploop_getvalue_pos, | |
- [Lprim(Pgetglobal toploop_ident, [])]), | |
- [Lconst(Const_base(Const_string (toplevel_name id)))], | |
- Location.none) | |
+ mk_lam (Lapply(mk_lam(Lprim(Pfield toploop_getvalue_pos, | |
+ [mk_lam (Lprim(Pgetglobal toploop_ident, []))])), | |
+ [mk_lam (Lconst(Const_base(Const_string (toplevel_name id))))])) | |
let toploop_setvalue id lam = | |
- Lapply(Lprim(Pfield toploop_setvalue_pos, | |
- [Lprim(Pgetglobal toploop_ident, [])]), | |
- [Lconst(Const_base(Const_string (toplevel_name id))); lam], | |
- Location.none) | |
+ mk_lam (Lapply(mk_lam(Lprim(Pfield toploop_setvalue_pos, | |
+ [mk_lam (Lprim(Pgetglobal toploop_ident, []))])), | |
+ [mk_lam (Lconst(Const_base(Const_string (toplevel_name id)))); lam])) | |
-let toploop_setvalue_id id = toploop_setvalue id (Lvar id) | |
+let toploop_setvalue_id id = toploop_setvalue id (mk_lam (Lvar id)) | |
let close_toplevel_term lam = | |
- IdentSet.fold (fun id l -> Llet(Strict, id, toploop_getvalue id, l)) | |
+ IdentSet.fold (fun id l -> mk_lam (Llet(Strict, id, toploop_getvalue id, l))) | |
(free_variables lam) lam | |
let transl_toplevel_item = function | |
@@ -626,13 +632,13 @@ let transl_toplevel_item = function | |
be a value named identically *) | |
let ids = List.map (fun (i, _, _, _, _) -> i) cl_list in | |
List.iter set_toplevel_unique_name ids; | |
- Lletrec(List.map | |
+ mk_lam (Lletrec(List.map | |
(fun (id, arity, meths, cl, vf) -> | |
(id, transl_class ids id arity meths cl vf)) | |
cl_list, | |
make_sequence | |
(fun (id, _, _, _, _) -> toploop_setvalue_id id) | |
- cl_list) | |
+ cl_list)) | |
| Tstr_cltype cl_list -> | |
lambda_unit | |
| Tstr_include(modl, ids) -> | |
@@ -641,9 +647,9 @@ let transl_toplevel_item = function | |
[] -> | |
lambda_unit | |
| id :: ids -> | |
- Lsequence(toploop_setvalue id (Lprim(Pfield pos, [Lvar mid])), | |
- set_idents (pos + 1) ids) in | |
- Llet(Strict, mid, transl_module Tcoerce_none None modl, set_idents 0 ids) | |
+ mk_lam (Lsequence(toploop_setvalue id (mk_lam (Lprim(Pfield pos, [mk_lam (Lvar mid)]))), | |
+ set_idents (pos + 1) ids)) in | |
+ mk_lam (Llet(Strict, mid, transl_module Tcoerce_none None modl, set_idents 0 ids)) | |
let transl_toplevel_item_and_close itm = | |
close_toplevel_term (transl_label_init (transl_toplevel_item itm)) | |
@@ -655,8 +661,8 @@ let transl_toplevel_definition str = | |
(* Compile the initialization code for a packed library *) | |
let get_component = function | |
- None -> Lconst const_unit | |
- | Some id -> Lprim(Pgetglobal id, []) | |
+ None -> mk_lam (Lconst const_unit) | |
+ | Some id -> mk_lam (Lprim(Pgetglobal id, [])) | |
let transl_package component_names target_name coercion = | |
let components = | |
@@ -670,30 +676,31 @@ let transl_package component_names target_name coercion = | |
pos_cc_list | |
| _ -> | |
assert false in | |
- Lprim(Psetglobal target_name, [Lprim(Pmakeblock(0, Immutable), components)]) | |
+ mk_lam (Lprim(Psetglobal target_name, | |
+ [mk_lam (Lprim(Pmakeblock(0, Immutable), components))])) | |
let transl_store_package component_names target_name coercion = | |
let rec make_sequence fn pos arg = | |
match arg with | |
[] -> lambda_unit | |
- | hd :: tl -> Lsequence(fn pos hd, make_sequence fn (pos + 1) tl) in | |
+ | hd :: tl -> mk_lam (Lsequence(fn pos hd, make_sequence fn (pos + 1) tl)) in | |
match coercion with | |
Tcoerce_none -> | |
(List.length component_names, | |
make_sequence | |
(fun pos id -> | |
- Lprim(Psetfield(pos, false), | |
- [Lprim(Pgetglobal target_name, []); | |
- get_component id])) | |
+ mk_lam (Lprim(Psetfield(pos, false), | |
+ [mk_lam (Lprim(Pgetglobal target_name, [])); | |
+ get_component id]))) | |
0 component_names) | |
| Tcoerce_structure pos_cc_list -> | |
let id = Array.of_list component_names in | |
(List.length pos_cc_list, | |
make_sequence | |
(fun dst (src, cc) -> | |
- Lprim(Psetfield(dst, false), | |
- [Lprim(Pgetglobal target_name, []); | |
- apply_coercion cc (get_component id.(src))])) | |
+ mk_lam (Lprim(Psetfield(dst, false), | |
+ [mk_lam (Lprim(Pgetglobal target_name, [])); | |
+ apply_coercion cc (get_component id.(src))]))) | |
0 pos_cc_list) | |
| _ -> assert false | |
diff --git a/bytecomp/translobj.ml b/bytecomp/translobj.ml | |
index f72e34b..7ee894e 100644 | |
--- a/bytecomp/translobj.ml | |
+++ b/bytecomp/translobj.ml | |
@@ -18,6 +18,12 @@ open Asttypes | |
open Longident | |
open Lambda | |
+(* Create a lambda term with a dummy location *) | |
+let lambda l_desc = { | |
+ l_loc = Location.none; | |
+ l_desc; | |
+} | |
+ | |
(* Get oo primitives identifiers *) | |
let oo_prim name = | |
@@ -35,13 +41,13 @@ let share c = | |
match c with | |
Const_block (n, l) when l <> [] -> | |
begin try | |
- Lvar (Hashtbl.find consts c) | |
+ lambda (Lvar (Hashtbl.find consts c)) | |
with Not_found -> | |
let id = Ident.create "shared" in | |
Hashtbl.add consts c id; | |
- Lvar id | |
+ lambda (Lvar id) | |
end | |
- | _ -> Lconst c | |
+ | _ -> lambda (Lconst c) | |
(* Collect labels *) | |
@@ -50,14 +56,14 @@ let method_cache = ref lambda_unit | |
let method_count = ref 0 | |
let method_table = ref [] | |
-let meth_tag s = Lconst(Const_base(Const_int(Btype.hash_variant s))) | |
+let meth_tag s = lambda (Lconst(Const_base(Const_int(Btype.hash_variant s)))) | |
let next_cache tag = | |
let n = !method_count in | |
incr method_count; | |
- (tag, [!method_cache; Lconst(Const_base(Const_int n))]) | |
+ (tag, [!method_cache; lambda (Lconst(Const_base(Const_int n)))]) | |
-let rec is_path = function | |
+let rec is_path l = match l.l_desc with | |
Lvar _ | Lprim (Pgetglobal _, []) | Lconst _ -> true | |
| Lprim (Pfield _, [lam]) -> is_path lam | |
| Lprim ((Parrayrefu _ | Parrayrefs _), [lam1; lam2]) -> | |
@@ -88,8 +94,8 @@ let reset_labels () = | |
(* Insert labels *) | |
-let string s = Lconst (Const_base (Const_string s)) | |
-let int n = Lconst (Const_base (Const_int n)) | |
+let string s = lambda (Lconst (Const_base (Const_string s))) | |
+let int n = lambda (Lconst (Const_base (Const_int n))) | |
let prim_makearray = | |
{ prim_name = "caml_make_vect"; prim_arity = 2; prim_alloc = true; | |
@@ -98,23 +104,23 @@ let prim_makearray = | |
let transl_label_init expr = | |
let expr = | |
Hashtbl.fold | |
- (fun c id expr -> Llet(Alias, id, Lconst c, expr)) | |
+ (fun c id expr -> lambda (Llet(Alias, id, lambda (Lconst c), expr))) | |
consts expr | |
in | |
reset_labels (); | |
expr | |
let transl_store_label_init glob size f arg = | |
- method_cache := Lprim(Pfield size, [Lprim(Pgetglobal glob, [])]); | |
+ method_cache := lambda (Lprim(Pfield size, [lambda (Lprim(Pgetglobal glob, []))])); | |
let expr = f arg in | |
let (size, expr) = | |
if !method_count = 0 then (size, expr) else | |
- (size+1, | |
- Lsequence( | |
- Lprim(Psetfield(size, false), | |
- [Lprim(Pgetglobal glob, []); | |
- Lprim (Pccall prim_makearray, [int !method_count; int 0])]), | |
- expr)) | |
+ (size+1, | |
+ lambda (Lsequence( | |
+ lambda (Lprim(Psetfield(size, false), | |
+ [lambda (Lprim(Pgetglobal glob, [])); | |
+ lambda (Lprim (Pccall prim_makearray, [int !method_count; int 0]))])), | |
+ expr))) | |
in | |
(size, transl_label_init expr) | |
@@ -132,28 +138,28 @@ let oo_add_class id = | |
let oo_wrap env req f x = | |
if !wrapping then | |
if !cache_required then f x else | |
- try cache_required := true; let lam = f x in cache_required := false; lam | |
- with exn -> cache_required := false; raise exn | |
+ try cache_required := true; let lam = f x in cache_required := false; lam | |
+ with exn -> cache_required := false; raise exn | |
else try | |
- wrapping := true; | |
- cache_required := req; | |
- top_env := env; | |
- classes := []; | |
- method_ids := IdentSet.empty; | |
- let lambda = f x in | |
- let lambda = | |
- List.fold_left | |
- (fun lambda id -> | |
- Llet(StrictOpt, id, | |
- Lprim(Pmakeblock(0, Mutable), | |
- [lambda_unit; lambda_unit; lambda_unit]), | |
- lambda)) | |
- lambda !classes | |
- in | |
- wrapping := false; | |
- top_env := Env.empty; | |
- lambda | |
- with exn -> | |
- wrapping := false; | |
- top_env := Env.empty; | |
- raise exn | |
+ wrapping := true; | |
+ cache_required := req; | |
+ top_env := env; | |
+ classes := []; | |
+ method_ids := IdentSet.empty; | |
+ let l = f x in | |
+ let lambda = | |
+ List.fold_left | |
+ (fun expr id -> | |
+ lambda (Llet(StrictOpt, id, | |
+ lambda (Lprim(Pmakeblock(0, Mutable), | |
+ [lambda_unit; lambda_unit; lambda_unit])), | |
+ expr))) | |
+ l !classes | |
+ in | |
+ wrapping := false; | |
+ top_env := Env.empty; | |
+ lambda | |
+ with exn -> | |
+ wrapping := false; | |
+ top_env := Env.empty; | |
+ raise exn |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment