|
@@ -549,7 +549,7 @@ let rec optimize_for_loop ctx i e1 e2 p =
|
|
|
let mk_field e n =
|
|
|
TField (e,try quick_field e.etype n with Not_found -> assert false)
|
|
|
in
|
|
|
- let gen_int_iter pt =
|
|
|
+ let gen_int_iter pt f_get f_length =
|
|
|
let i = add_local ctx i pt in
|
|
|
let index = gen_local ctx t_int in
|
|
|
let arr, avars = (match e1.eexpr with
|
|
@@ -560,21 +560,14 @@ let rec optimize_for_loop ctx i e1 e2 p =
|
|
|
) in
|
|
|
let iexpr = mk (TLocal index) t_int p in
|
|
|
let e2 = type_expr ctx e2 NoValue in
|
|
|
- let aget = mk (TVar (i,Some (mk (TArray (arr,iexpr)) pt p))) t_void p in
|
|
|
+ let aget = mk (TVar (i,Some (f_get 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 = 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
|
|
|
- let ethis = mk (TTypeExpr (TClassDecl c)) ta e1.epos in
|
|
|
- let efield = mk (mk_field ethis "get_length") (tfun [arr.etype] t_int) p in
|
|
|
- make_call ctx efield [arr] t_int e1.epos
|
|
|
- | _ -> mk (mk_field arr "length") t_int p
|
|
|
- in
|
|
|
+ let elength = f_length arr p in
|
|
|
let el = [mk (TWhile (
|
|
|
mk (TBinop (OpLt, iexpr, elength)) ctx.t.tbool p,
|
|
|
block,
|
|
@@ -585,6 +578,12 @@ let rec optimize_for_loop ctx i e1 e2 p =
|
|
|
let el = (mk (TVar (index,ivar)) t_void p) :: el in
|
|
|
lblock el
|
|
|
in
|
|
|
+ let get_next_array_element arr iexpr pt p =
|
|
|
+ (mk (TArray (arr,iexpr)) pt p)
|
|
|
+ in
|
|
|
+ let get_array_length arr p =
|
|
|
+ mk (mk_field arr "length") ctx.com.basic.tint p
|
|
|
+ in
|
|
|
match e1.eexpr, follow e1.etype with
|
|
|
| TNew ({ cl_path = ([],"IntIterator") },[],[i1;i2]) , _ ->
|
|
|
let max = (match i1.eexpr , i2.eexpr with
|
|
@@ -642,11 +641,42 @@ let rec optimize_for_loop ctx i e1 e2 p =
|
|
|
])
|
|
|
| _ , TInst({ cl_path = [],"Array" },[pt])
|
|
|
| _ , TInst({ cl_path = ["flash"],"Vector" },[pt]) ->
|
|
|
- gen_int_iter pt
|
|
|
+ gen_int_iter pt get_next_array_element get_array_length
|
|
|
| _ , TInst({ cl_array_access = Some pt } as c,pl) when (try match follow (PMap.find "length" c.cl_fields).cf_type with TAbstract ({ a_path = [],"Int" },[]) -> true | _ -> false with Not_found -> false) && not (PMap.mem "iterator" c.cl_fields) ->
|
|
|
- gen_int_iter (apply_params c.cl_types pl pt)
|
|
|
- | (TLocal _ | TField _), TAbstract({a_impl = Some c} as a,[pt]) when Meta.has Meta.ArrayAccess a.a_meta && (try match follow (PMap.find "length" c.cl_statics).cf_type with TAbstract ({ a_path = [],"Int" },[]) -> true | _ -> false with Not_found -> false) && not (PMap.mem "iterator" c.cl_statics) ->
|
|
|
- gen_int_iter pt
|
|
|
+ gen_int_iter (apply_params c.cl_types pl pt) get_next_array_element get_array_length
|
|
|
+ | _, TAbstract({a_impl = Some c} as a,tl) ->
|
|
|
+ begin try
|
|
|
+ let cf_length = PMap.find "get_length" c.cl_statics in
|
|
|
+ let get_length e p =
|
|
|
+ make_static_call ctx c cf_length (apply_params a.a_types tl) [e] ctx.com.basic.tint p
|
|
|
+ in
|
|
|
+ begin match follow cf_length.cf_type with
|
|
|
+ | TFun(_,tr) ->
|
|
|
+ begin match follow tr with
|
|
|
+ | TAbstract({a_path = [],"Int"},_) -> ()
|
|
|
+ | _ -> raise Not_found
|
|
|
+ end
|
|
|
+ | _ ->
|
|
|
+ raise Not_found
|
|
|
+ end;
|
|
|
+ begin try
|
|
|
+ (* first try: do we have an @:arrayAccess getter field? *)
|
|
|
+ let cf,tf,r = find_array_access a tl ctx.com.basic.tint (mk_mono()) false in
|
|
|
+ let get_next e_base e_index t p =
|
|
|
+ make_static_call ctx c cf (apply_params a.a_types tl) [e_base;e_index] r p
|
|
|
+ in
|
|
|
+ gen_int_iter r get_next get_length
|
|
|
+ with Not_found ->
|
|
|
+ (* second try: do we have @:arrayAccess on the abstract itself? *)
|
|
|
+ if not (Meta.has Meta.ArrayAccess a.a_meta) then raise Not_found;
|
|
|
+ (* let's allow this only for core-type abstracts *)
|
|
|
+ if not (Meta.has Meta.CoreType a.a_meta) then raise Not_found;
|
|
|
+ (* in which case we assume that a singular type parameter is the element type *)
|
|
|
+ let t = match tl with [t] -> t | _ -> raise Not_found in
|
|
|
+ gen_int_iter t get_next_array_element get_length
|
|
|
+ end with Not_found ->
|
|
|
+ None
|
|
|
+ end
|
|
|
| _ , TInst ({ cl_kind = KGenericInstance ({ cl_path = ["haxe";"ds"],"GenericStack" },[t]) } as c,[]) ->
|
|
|
let tcell = (try (PMap.find "head" c.cl_fields).cf_type with Not_found -> assert false) in
|
|
|
let i = add_local ctx i t in
|