Browse Source

added optimized FlashList iteration

Nicolas Cannasse 17 năm trước cách đây
mục cha
commit
76b168dd79
4 tập tin đã thay đổi với 28 bổ sung6 xóa
  1. 4 3
      genswf9.ml
  2. 2 2
      std/flash9/FastList.hx
  3. 1 1
      type.ml
  4. 21 0
      typer.ml

+ 4 - 3
genswf9.ml

@@ -1256,14 +1256,15 @@ let generate_construct ctx fdata c =
 	(* make all args optional to allow no-param constructor *)
 	let f = begin_fun ctx (List.map (fun (a,o,t) -> a,true,t) fdata.tf_args) fdata.tf_type [ethis;fdata.tf_expr] false fdata.tf_expr.epos in
 	(* if skip_constructor, then returns immediatly *)
-	if c.cl_kind <> KGenericInstance then begin
+	(match c.cl_kind with
+	| KGenericInstance _ -> ()
+	| _ ->
 		let id = ident "skip_constructor" in
 		getvar ctx (VGlobal (type_path ctx ([],ctx.boot)));
 		getvar ctx (VId id);
 		let j = jump ctx J3False in
 		write ctx HRetVoid;
-		j();
-	end;
+		j());	
 	(* --- *)
 	PMap.iter (fun _ f ->
 		match f.cf_expr with

+ 2 - 2
std/flash9/FastList.hx

@@ -54,7 +54,7 @@ class FastList<T> implements haxe.rtti.Generic {
 		Returns the first element of the list, or null
 		if the list is empty.
 	**/
-	public inline function first() : T {
+	public inline function first() : Null<T> {
 		return if( head == null ) null else head.elt;
 	}
 
@@ -63,7 +63,7 @@ class FastList<T> implements haxe.rtti.Generic {
 		returns it or simply returns null if the
 		list is empty.
 	**/
-	public inline function pop() : T {
+	public inline function pop() : Null<T> {
 		var k = head;
 		if( k== null )
 			return null;

+ 1 - 1
type.ml

@@ -119,7 +119,7 @@ and tclass_kind =
 	| KExtension of tclass * tparams
 	| KConstant of tconstant
 	| KGeneric
-	| KGenericInstance
+	| KGenericInstance of tclass * tparams
 
 and tclass = {
 	cl_path : module_path;

+ 21 - 0
typer.ml

@@ -527,6 +527,7 @@ and build_generic ctx c allow p tl =
 		in
 		if c.cl_super <> None || c.cl_init <> None || c.cl_dynamic <> None then error "This class can't be generic" p;
 		if c.cl_ordered_statics <> [] then error "A generic class can't have static fields" p;
+		cg.cl_kind <- KGenericInstance (c,tl);
 		cg.cl_constructor <- (match c.cl_constructor with None -> None | Some c -> Some (build_field c));
 		cg.cl_implements <- List.map (fun (i,tl) -> i, List.map build_type tl) c.cl_implements;
 		cg.cl_ordered_fields <- List.map (fun f ->
@@ -2399,6 +2400,26 @@ and optimize_for_loop ctx i e1 e2 p =
 					NormalWhile
 				)) t_void p;
 			]) t_void p
+		| TInst ({ cl_kind = KGenericInstance ({ cl_path = ["flash"],"FastList" },[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
+			let cell = gen_local ctx tcell in
+			let cexpr = mk (TLocal cell) tcell p in
+			let e2 = type_expr ~need_val:false ctx e2 in
+			let evar = mk (TVars [i,t,Some (mk (TField (cexpr,"elt")) t p)]) t_void p in
+			let enext = mk (TBinop (OpAssign,cexpr,mk (TField (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
+			mk (TBlock [
+				mk (TVars [cell,tcell,Some (mk (TField (e1,"head")) tcell p)]) t_void p;
+				mk (TWhile (
+					mk (TBinop (OpNotEq, cexpr, mk (TConst TNull) tcell p)) (t_bool ctx) p,
+					block,
+					NormalWhile
+				)) t_void p
+			]) t_void p
 		| _ ->
 			let t, pt = t_iterator ctx in
 			let i = add_local ctx i pt in