|
@@ -222,12 +222,9 @@ let rec type_inline ctx cf f ethis params tret config p force =
|
|
|
let l = read_local vthis in
|
|
|
l.i_read <- l.i_read + (if !in_loop then 2 else 1);
|
|
|
{ e with eexpr = TLocal l.i_subst }
|
|
|
- | TVars vl ->
|
|
|
+ | TVars (v,eo) ->
|
|
|
has_vars := true;
|
|
|
- let vl = List.map (fun (v,e) ->
|
|
|
- (local v).i_subst,opt (map false) e
|
|
|
- ) vl in
|
|
|
- { e with eexpr = TVars vl }
|
|
|
+ { e with eexpr = TVars ((local v).i_subst,opt (map false) eo)}
|
|
|
| TReturn eo when not !in_local_fun ->
|
|
|
if not term then error "Cannot inline a not final return" po;
|
|
|
(match eo with
|
|
@@ -385,7 +382,7 @@ let rec type_inline ctx cf f ethis params tret config p force =
|
|
|
| _ -> Type.map_expr inline_params e
|
|
|
in
|
|
|
let e = (if PMap.is_empty subst then e else inline_params e) in
|
|
|
- let init = (match vars with [] -> None | l -> Some (mk (TVars (List.rev l)) ctx.t.tvoid p)) in
|
|
|
+ let init = match vars with [] -> None | l -> Some l in
|
|
|
(*
|
|
|
If we have local variables and returning a value, then this will result in
|
|
|
unoptimized JS code, so let's instead skip inlining.
|
|
@@ -424,8 +421,12 @@ let rec type_inline ctx cf f ethis params tret config p force =
|
|
|
{e with etype = tret}
|
|
|
| TBlock [e] , None -> wrap e
|
|
|
| _ , None -> wrap e
|
|
|
- | TBlock l, Some init -> mk (TBlock (init :: l)) tret e.epos
|
|
|
- | _, Some init -> mk (TBlock [init;e]) tret e.epos
|
|
|
+ | TBlock l, Some vl ->
|
|
|
+ let el_v = List.map (fun (v,eo) -> mk (TVars (v,eo)) ctx.t.tvoid e.epos) vl in
|
|
|
+ mk (TBlock (el_v @ l)) tret e.epos
|
|
|
+ | _, Some vl ->
|
|
|
+ let el_v = List.map (fun (v,eo) -> mk (TVars (v,eo)) ctx.t.tvoid e.epos) vl in
|
|
|
+ mk (TBlock (el_v @ [e])) tret e.epos
|
|
|
) in
|
|
|
(* we need to replace type-parameters that were used in the expression *)
|
|
|
if not has_params then
|
|
@@ -473,20 +474,20 @@ let rec optimize_for_loop ctx i e1 e2 p =
|
|
|
let i = add_local ctx i pt in
|
|
|
let index = gen_local ctx t_int in
|
|
|
let arr, avars = (match e1.eexpr with
|
|
|
- | TLocal _ -> e1, []
|
|
|
+ | TLocal _ -> e1, None
|
|
|
| _ ->
|
|
|
let atmp = gen_local ctx e1.etype in
|
|
|
- mk (TLocal atmp) e1.etype e1.epos, [atmp,Some e1]
|
|
|
+ mk (TLocal atmp) e1.etype e1.epos, (Some (atmp,Some e1))
|
|
|
) in
|
|
|
let iexpr = mk (TLocal index) t_int p in
|
|
|
let e2 = type_expr ctx e2 NoValue in
|
|
|
- let aget = mk (TVars [i,Some (mk (TArray (arr,iexpr)) pt p)]) t_void p in
|
|
|
+ let aget = mk (TVars (i,Some (mk (TArray (arr,iexpr)) pt p))) t_void p in
|
|
|
let incr = mk (TUnop (Increment,Prefix,iexpr)) t_int p in
|
|
|
let block = match e2.eexpr with
|
|
|
| TBlock el -> mk (TBlock (aget :: incr :: el)) t_void e2.epos
|
|
|
| _ -> mk (TBlock [aget;incr;e2]) t_void p
|
|
|
in
|
|
|
- let ivar = index, Some (mk (TConst (TInt 0l)) t_int p) in
|
|
|
+ let ivar = Some (mk (TConst (TInt 0l)) t_int p) in
|
|
|
let elength = match follow e1.etype with
|
|
|
| TAbstract({a_impl = Some c},_) ->
|
|
|
let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in
|
|
@@ -495,14 +496,15 @@ let rec optimize_for_loop ctx i e1 e2 p =
|
|
|
make_call ctx efield [arr] t_int e1.epos
|
|
|
| _ -> mk (mk_field arr "length") t_int p
|
|
|
in
|
|
|
- lblock [
|
|
|
- mk (TVars (ivar :: avars)) t_void p;
|
|
|
- mk (TWhile (
|
|
|
+ let el = [mk (TWhile (
|
|
|
mk (TBinop (OpLt, iexpr, elength)) ctx.t.tbool p,
|
|
|
block,
|
|
|
NormalWhile
|
|
|
)) t_void p;
|
|
|
- ]
|
|
|
+ ] in
|
|
|
+ let el = match avars with None -> el | Some (v,eo) -> (mk (TVars (v,eo)) t_void p) :: el in
|
|
|
+ let el = (mk (TVars (index,ivar)) t_void p) :: el in
|
|
|
+ lblock el
|
|
|
in
|
|
|
match e1.eexpr, follow e1.etype with
|
|
|
| TNew ({ cl_path = ([],"IntIterator") },[],[i1;i2]) , _ ->
|
|
@@ -527,7 +529,7 @@ let rec optimize_for_loop ctx i e1 e2 p =
|
|
|
check e2;
|
|
|
let etmp = mk (TLocal tmp) t_int p in
|
|
|
let incr = mk (TUnop (Increment,Postfix,etmp)) t_int p in
|
|
|
- let init = mk (TVars [i,Some incr]) t_void p in
|
|
|
+ let init = mk (TVars (i,Some incr)) t_void p in
|
|
|
let block = match e2.eexpr with
|
|
|
| TBlock el -> mk (TBlock (init :: el)) t_void e2.epos
|
|
|
| _ -> mk (TBlock [init;e2]) t_void p
|
|
@@ -542,7 +544,7 @@ let rec optimize_for_loop ctx i e1 e2 p =
|
|
|
(match max with
|
|
|
| None ->
|
|
|
lblock [
|
|
|
- mk (TVars [tmp,Some i1]) t_void p;
|
|
|
+ mk (TVars (tmp,Some i1)) t_void p;
|
|
|
mk (TWhile (
|
|
|
mk (TBinop (OpLt, etmp, i2)) ctx.t.tbool p,
|
|
|
block,
|
|
@@ -551,7 +553,8 @@ let rec optimize_for_loop ctx i e1 e2 p =
|
|
|
]
|
|
|
| Some max ->
|
|
|
lblock [
|
|
|
- mk (TVars [tmp,Some i1;max,Some i2]) t_void p;
|
|
|
+ mk (TVars (tmp,Some i1)) t_void p;
|
|
|
+ mk (TVars (max,Some i2)) t_void p;
|
|
|
mk (TWhile (
|
|
|
mk (TBinop (OpLt, etmp, mk (TLocal max) t_int p)) ctx.t.tbool p,
|
|
|
block,
|
|
@@ -571,14 +574,14 @@ let rec optimize_for_loop ctx i e1 e2 p =
|
|
|
let cell = gen_local ctx tcell in
|
|
|
let cexpr = mk (TLocal cell) tcell p in
|
|
|
let e2 = type_expr ctx e2 NoValue in
|
|
|
- let evar = mk (TVars [i,Some (mk (mk_field cexpr "elt") t p)]) t_void p in
|
|
|
+ let evar = mk (TVars (i,Some (mk (mk_field cexpr "elt") t p))) t_void p in
|
|
|
let enext = mk (TBinop (OpAssign,cexpr,mk (mk_field cexpr "next") tcell p)) tcell p in
|
|
|
let block = match e2.eexpr with
|
|
|
| TBlock el -> mk (TBlock (evar :: enext :: el)) t_void e2.epos
|
|
|
| _ -> mk (TBlock [evar;enext;e2]) t_void p
|
|
|
in
|
|
|
lblock [
|
|
|
- mk (TVars [cell,Some (mk (mk_field e1 "head") tcell p)]) t_void p;
|
|
|
+ mk (TVars (cell,Some (mk (mk_field e1 "head") tcell p))) t_void p;
|
|
|
mk (TWhile (
|
|
|
mk (TBinop (OpNotEq, cexpr, mk (TConst TNull) tcell p)) ctx.t.tbool p,
|
|
|
block,
|
|
@@ -1008,10 +1011,9 @@ let inline_constructors ctx e =
|
|
|
in
|
|
|
let rec find_locals e =
|
|
|
match e.eexpr with
|
|
|
- | TVars vl ->
|
|
|
+ | TVars (v,eo) ->
|
|
|
Type.iter find_locals e;
|
|
|
- List.iter (fun (v,e) ->
|
|
|
- match e with
|
|
|
+ begin match eo with
|
|
|
| Some n ->
|
|
|
begin match get_inline_ctor_info n with
|
|
|
| Some (f,cst,c,pl) ->
|
|
@@ -1048,7 +1050,7 @@ let inline_constructors ctx e =
|
|
|
()
|
|
|
end
|
|
|
| None -> ()
|
|
|
- ) vl
|
|
|
+ end
|
|
|
| TField ({ eexpr = TLocal _ },FInstance (_,{ cf_kind = Var _ })) ->
|
|
|
()
|
|
|
| TLocal v when v.v_id < 0 ->
|
|
@@ -1076,19 +1078,16 @@ let inline_constructors ctx e =
|
|
|
) vars in
|
|
|
let rec subst e =
|
|
|
match e.eexpr with
|
|
|
- | TVars vl ->
|
|
|
- let rec loop acc vl =
|
|
|
- match vl with
|
|
|
- | [] -> List.rev acc
|
|
|
- | (v,None) :: vl -> loop ((v,None) :: acc) vl
|
|
|
- | (v,Some e) :: vl when v.v_id < 0 ->
|
|
|
+ | TVars (v,eo) ->
|
|
|
+ let v,eo = match eo with
|
|
|
+ | None -> (v,None)
|
|
|
+ | Some e when v.v_id < 0 ->
|
|
|
let vars, _ = PMap.find (-v.v_id) vfields in
|
|
|
- loop (List.map (fun (v,e) -> v, Some (subst e)) vars @ acc) vl
|
|
|
- | (v,Some e) :: vl ->
|
|
|
- loop ((v,Some (subst e)) :: acc) vl
|
|
|
+ v, Some (subst e)
|
|
|
+ | Some e ->
|
|
|
+ v,Some (subst e)
|
|
|
in
|
|
|
- let vl = loop [] vl in
|
|
|
- mk (TVars vl) e.etype e.epos
|
|
|
+ mk (TVars (v,eo)) e.etype e.epos
|
|
|
| TField ({ eexpr = TLocal v },FInstance (_,cf)) when v.v_id < 0 ->
|
|
|
let _, vars = PMap.find (-v.v_id) vfields in
|
|
|
(try
|