소스 검색

cleanup python dce, fix #5820, fix #5817

frabbit 8 년 전
부모
커밋
52c7b67cf9
4개의 변경된 파일119개의 추가작업 그리고 74개의 파일을 삭제
  1. 17 3
      src/generators/genpy.ml
  2. 69 39
      src/optimization/dce.ml
  3. 20 20
      std/python/internal/ArrayImpl.hx
  4. 13 12
      std/python/internal/StringImpl.hx

+ 17 - 3
src/generators/genpy.ml

@@ -27,7 +27,7 @@ module Utils = struct
 	let class_of_module_type mt = match mt with
 		| TClassDecl c -> c
 		| _ -> failwith ("Not a class: " ^ (s_type_path (t_infos mt).mt_path))
-
+	
 	let find_type com path =
 		try
 			List.find (fun mt -> match mt with
@@ -846,9 +846,13 @@ module Transformer = struct
 		| (is_value, TBinop(OpAssignOp op,{eexpr = TField(e1,FDynamic s); etype = t},e2)) ->
 			let e = dynamic_field_read_write ae.a_next_id e1 s op e2 t in
 			transform_expr ~is_value:is_value e
-		| (is_value, TField(e1, FClosure(Some ({cl_path = [],("str" | "list")},_),cf))) ->
+		(*
+		| (is_value, TField(e1, FClosure(Some ({cl_path = [],("str")},_),cf))) ->
+
+		| (is_value, TField(e1, FClosure(Some ({cl_path = [],("list")},_),cf))) ->
 			let e = dynamic_field_read e1 cf.cf_name ae.a_expr.etype in
 			transform_expr ~is_value:is_value e
+		*)
 		| (is_value, TBinop(OpAssign, left, right))->
 			(let left = trans true [] left in
 			let right = trans true [] right in
@@ -1423,12 +1427,20 @@ module Printer = struct
 				Printf.sprintf "HxString.fromCharCode"
 			| FStatic({cl_path = ["python";"internal"],"UBuiltins"},{cf_name = s}) ->
 				s
+			| FClosure (Some(c,cf),_)  when call_override(name) && ((is_type "" "list")(TClassDecl c)) ->
+				Printf.sprintf "_hx_partial(python_internal_ArrayImpl.%s, %s)" name obj
+			| FInstance (c,_,cf) when call_override(name) && ((is_type "" "list")(TClassDecl c)) ->
+				Printf.sprintf "_hx_partial(python_internal_ArrayImpl.%s, %s)" name obj
+			| FClosure (Some(c,cf),_)  when call_override(name) && ((is_type "" "str")(TClassDecl c)) ->
+				Printf.sprintf "_hx_partial(HxString.%s, %s)" name obj
+			| FInstance (c,_,cf) when call_override(name) && ((is_type "" "str")(TClassDecl c)) ->
+				Printf.sprintf "_hx_partial(HxString.%s, %s)" name obj
 			| FInstance _ | FStatic _ ->
 				do_default ()
 			| FAnon cf when is_assign && call_override(name) ->
 				begin match follow cf.cf_type with
 					| TFun([],_) ->
-						Printf.sprintf "python_lib_FuncTools.partial(HxOverrides.%s, %s)" name obj
+						Printf.sprintf "_hx_partial(HxOverrides.%s, %s)" name obj
 					| _ ->
 						do_default()
 				end
@@ -2450,6 +2462,8 @@ module Generator = struct
 		Transformer.init com;
 		let ctx = mk_context com in
 		Codegen.map_source_header com (fun s -> print ctx "# %s\n" s);
+		if has_feature ctx "closure_Array" || has_feature ctx "closure_String" then
+			spr ctx "from functools import partial as _hx_partial";
 		gen_imports ctx;
 		gen_resources ctx;
 		gen_types ctx;

+ 69 - 39
src/optimization/dce.ml

@@ -351,6 +351,70 @@ and is_const_string e = match e.eexpr with
 	| TConst(TString(_)) -> true
 	| _ -> false
 
+and expr_field dce e fa is_call_expr =
+	let do_default = fun () ->
+		let n = field_name fa in
+			(match fa with
+			| FAnon cf ->
+				if Meta.has Meta.Optional cf.cf_meta then begin
+					check_and_add_feature dce "anon_optional_read";
+					check_and_add_feature dce ("anon_optional_read." ^ n);
+				end else begin
+					check_and_add_feature dce "anon_read";
+					check_and_add_feature dce ("anon_read." ^ n);
+				end
+			| FDynamic _ ->
+				check_and_add_feature dce "dynamic_read";
+				check_and_add_feature dce ("dynamic_read." ^ n);
+			| _ -> ());
+			begin match follow e.etype with
+				| TInst(c,_) ->
+					mark_class dce c;
+					field dce c n false;
+				| TAnon a ->
+					(match !(a.a_status) with
+					| Statics c ->
+						mark_class dce c;
+						field dce c n true;
+					| _ -> ())
+
+
+				| _ -> ()
+			end
+	in
+	let mark_instance_field_access c cf =
+		if (not is_call_expr && dce.com.platform = Python) then begin
+			if c.cl_path = ([], "Array") then begin
+				check_and_add_feature dce "closure_Array";
+				check_and_add_feature dce ("python.internal.ArrayImpl." ^ cf.cf_name);
+				check_and_add_feature dce ("python.internal.ArrayImpl")
+			end
+			else if c.cl_path = ([], "String") then begin
+				check_and_add_feature dce "closure_String";
+				check_and_add_feature dce ("python.internal.StringImpl." ^ cf.cf_name);
+				check_and_add_feature dce ("python.internal.StringImpl")
+			end
+		end;
+	in
+	begin match fa with
+		| FStatic(c,cf) ->
+			mark_class dce c;
+			mark_field dce c cf true;
+		| FInstance(c,_,cf) ->
+			(*mark_instance_field_access c cf;*)
+			mark_class dce c;
+			mark_field dce c cf false
+		| FClosure (Some(c, _), cf) ->
+		 	mark_instance_field_access c cf;
+			do_default()
+		| FClosure _ ->
+			do_default()
+		| _ ->
+			do_default()
+	end;
+	expr dce e;
+
+
 and expr dce e =
 	mark_t dce e.epos e.etype;
 	match e.eexpr with
@@ -485,46 +549,12 @@ and expr dce e =
 		check_and_add_feature dce "binop_>>>";
 		expr dce e1;
 		expr dce e2;
+	| TCall(({ eexpr = TField(ef, fa) } as e2), el ) ->
+		mark_t dce e2.epos e2.etype;
+		expr_field dce ef fa true;
+		List.iter (expr dce) el;
 	| TField(e,fa) ->
-		begin match fa with
-			| FStatic(c,cf) ->
-				mark_class dce c;
-				mark_field dce c cf true;
-			| FInstance(c,_,cf) ->
-				mark_class dce c;
-				mark_field dce c cf false;
-			| _ ->
-
-				let n = field_name fa in
-				(match fa with
-				| FAnon cf ->
-					if Meta.has Meta.Optional cf.cf_meta then begin
-						check_and_add_feature dce "anon_optional_read";
-						check_and_add_feature dce ("anon_optional_read." ^ n);
-					end else begin
-						check_and_add_feature dce "anon_read";
-						check_and_add_feature dce ("anon_read." ^ n);
-					end
-				| FDynamic _ ->
-					check_and_add_feature dce "dynamic_read";
-					check_and_add_feature dce ("dynamic_read." ^ n);
-				| _ -> ());
-				begin match follow e.etype with
-					| TInst(c,_) ->
-						mark_class dce c;
-						field dce c n false;
-					| TAnon a ->
-						(match !(a.a_status) with
-						| Statics c ->
-							mark_class dce c;
-							field dce c n true;
-						| _ -> ())
-
-
-					| _ -> ()
-				end;
-		end;
-		expr dce e;
+		expr_field dce e fa false;
 	| TThrow e ->
 		check_and_add_feature dce "has_throw";
 		expr dce e;

+ 20 - 20
std/python/internal/ArrayImpl.hx

@@ -27,25 +27,25 @@ import python.lib.Functools;
 @:allow(Array)
 class ArrayImpl {
 
-	@:ifFeature("dynamic_read.length", "anon_optional_read.length")
+	@:ifFeature("dynamic_read.length", "anon_optional_read.length", "python.internal.ArrayImpl.length")
 	public static inline function get_length <T>(x:Array<T>):Int return UBuiltins.len(x);
 
-	@:ifFeature("dynamic_read.concat", "anon_optional_read.concat")
+	@:ifFeature("dynamic_read.concat", "anon_optional_read.concat", "python.internal.ArrayImpl.concat")
 	public static inline function concat<T>(a1:Array<T>, a2 : Array<T>) : Array<T> {
 		return Syntax.binop(a1, "+", a2);
 	}
 
-	@:ifFeature("dynamic_read.copy", "anon_optional_read.copy")
+	@:ifFeature("dynamic_read.copy", "anon_optional_read.copy", "python.internal.ArrayImpl.copy")
 	public static inline function copy<T>(x:Array<T>) : Array<T> {
 		return UBuiltins.list(x);
 	}
 
-	@:ifFeature("dynamic_read.iterator", "anon_optional_read.iterator")
+	@:ifFeature("dynamic_read.iterator", "anon_optional_read.iterator", "python.internal.ArrayImpl.iterator")
 	public static inline function iterator<T>(x:Array<T>) : Iterator<T> {
 		return new HaxeIterator(Syntax.callField(x, "__iter__"));
 	}
 
-	@:ifFeature("dynamic_read.indexOf", "anon_optional_read.indexOf")
+	@:ifFeature("dynamic_read.indexOf", "anon_optional_read.indexOf", "python.internal.ArrayImpl.indexOf")
 	public static function indexOf<T>(a:Array<T>, x : T, ?fromIndex:Int) : Int {
 		var len = a.length;
 		var l =
@@ -59,7 +59,7 @@ class ArrayImpl {
 		return -1;
 	}
 
-	@:ifFeature("dynamic_read.lastIndexOf", "anon_optional_read.lastIndexOf")
+	@:ifFeature("dynamic_read.lastIndexOf", "anon_optional_read.lastIndexOf", "python.internal.ArrayImpl.lastIndexOf")
 	public static function lastIndexOf<T>(a:Array<T>, x : T, ?fromIndex:Int) : Int {
 		var len = a.length;
 		var l =
@@ -74,33 +74,33 @@ class ArrayImpl {
 	}
 
 	@:access(python.Boot)
-	@:ifFeature("dynamic_read.join", "anon_optional_read.join")
+	@:ifFeature("dynamic_read.join", "anon_optional_read.join", "python.internal.ArrayImpl.join")
 	public static inline function join<T>(x:Array<T>, sep : String ) : String {
 		return Boot.arrayJoin(x, sep);
 	}
 
-	@:ifFeature("dynamic_read.toString", "anon_optional_read.toString")
+	@:ifFeature("dynamic_read.toString", "anon_optional_read.toString", "python.internal.ArrayImpl.toString")
 	public static inline function toString<T>(x:Array<T>) : String {
 		return "[" + join(x, ",") + "]";
 	}
 
-	@:ifFeature("dynamic_read.pop", "anon_optional_read.pop")
+	@:ifFeature("dynamic_read.pop", "anon_optional_read.pop", "python.internal.ArrayImpl.pop")
 	public static inline function pop<T>(x:Array<T>) : Null<T> {
 		return if (x.length == 0) null else Syntax.callField(x, "pop");
 	}
 
-	@:ifFeature("dynamic_read.push", "anon_optional_read.push")
+	@:ifFeature("dynamic_read.push", "anon_optional_read.push", "python.internal.ArrayImpl.push")
 	public static inline function push<T>(x:Array<T>, e:T) : Int {
 		Syntax.callField(x, "append", e);
 		return x.length;
 	}
 
-	@:ifFeature("dynamic_read.unshift", "anon_optional_read.unshift")
+	@:ifFeature("dynamic_read.unshift", "anon_optional_read.unshift", "python.internal.ArrayImpl.unshift")
 	public static inline function unshift<T>(x:Array<T>,e : T) : Void {
 		x.insert(0,e);
 	}
 
-	@:ifFeature("dynamic_read.remove", "anon_optional_read.remove")
+	@:ifFeature("dynamic_read.remove", "anon_optional_read.remove", "python.internal.ArrayImpl.remove")
 	public static function remove<T>(x:Array<T>,e : T) : Bool {
 		try {
 			Syntax.callField(x, "remove", e);
@@ -110,22 +110,22 @@ class ArrayImpl {
 		}
 	}
 
-	@:ifFeature("dynamic_read.shift", "anon_optional_read.shift")
+	@:ifFeature("dynamic_read.shift", "anon_optional_read.shift", "python.internal.ArrayImpl.shift")
 	public static inline function shift<T>(x:Array<T>) : Null<T> {
 		if (x.length == 0) return null;
 		return Syntax.callField(x, "pop", 0);
 	}
 
-	@:ifFeature("dynamic_read.slice", "anon_optional_read.slice")
+	@:ifFeature("dynamic_read.slice", "anon_optional_read.slice", "python.internal.ArrayImpl.slice")
 	public static inline function slice<T>(x:Array<T>, pos : Int, ?end : Int ) : Array<T> {
 		return Syntax.arrayAccess(x, pos, end);
 	}
-	@:ifFeature("dynamic_read.sort", "anon_optional_read.sort")
+	@:ifFeature("dynamic_read.sort", "anon_optional_read.sort", "python.internal.ArrayImpl.sort")
 	public static inline function sort<T>(x:Array<T>, f:T->T->Int) : Void {
 		Syntax.callNamedUntyped(Syntax.field(x, "sort"), { key : Functools.cmp_to_key(f) });
 	}
 
-	@:ifFeature("dynamic_read.splice", "anon_optional_read.splice")
+	@:ifFeature("dynamic_read.splice", "anon_optional_read.splice", "python.internal.ArrayImpl.splice")
 	public static inline function splice<T>(x:Array<T>, pos : Int, len : Int ) : Array<T> {
 		if (pos < 0) pos = x.length+pos;
 		if (pos < 0) pos = 0;
@@ -134,21 +134,21 @@ class ArrayImpl {
 		return res;
 	}
 
-	@:ifFeature("dynamic_read.map", "anon_optional_read.map")
+	@:ifFeature("dynamic_read.map", "anon_optional_read.map", "python.internal.ArrayImpl.map")
 	public static inline function map<S,T>(x:Array<T>, f : T -> S) : Array<S> {
 		return UBuiltins.list(UBuiltins.map(f, cast x));
 	}
 
-	@:ifFeature("dynamic_read.filter", "anon_optional_read.filter")
+	@:ifFeature("dynamic_read.filter", "anon_optional_read.filter", "python.internal.ArrayImpl.filter")
 	public static inline function filter<T>(x:Array<T>, f : T -> Bool) : Array<T> {
 		return UBuiltins.list(UBuiltins.filter(f, cast x));
 	}
 
-	@:ifFeature("dynamic_read.insert", "anon_optional_read.insert")
+	@:ifFeature("dynamic_read.insert", "anon_optional_read.insert", "python.internal.ArrayImpl.insert")
 	public static inline function insert<T>(a:Array<T>, pos : Int, x : T ) : Void {
 		Syntax.callField(a, "insert", pos, x);
 	}
-	@:ifFeature("dynamic_read.reverse", "anon_optional_read.reverse")
+	@:ifFeature("dynamic_read.reverse", "anon_optional_read.reverse", "python.internal.ArrayImpl.reverse")
 	public static inline function reverse<T>(a:Array<T>) : Void {
 		Syntax.callField(a, "reverse");
 	}

+ 13 - 12
std/python/internal/StringImpl.hx

@@ -26,24 +26,24 @@ import python.internal.Internal;
 @:native("HxString")
 class StringImpl {
 
-	@:ifFeature("dynamic_read.split", "anon_optional_read.split")
+	@:ifFeature("dynamic_read.split", "anon_optional_read.split", "python.internal.StringImpl.split")
 	public static inline function split (s:String, d:String) {
 		return if (d == "") UBuiltins.list(s) else Syntax.callField(s, "split", d);
 	}
 
-	@:ifFeature("dynamic_read.charCodeAt", "anon_optional_read.charCodeAt")
+	@:ifFeature("dynamic_read.charCodeAt", "anon_optional_read.charCodeAt", "python.internal.StringImpl.charCodeAt")
 	public static function charCodeAt(s:String, index:Int) {
 		return
 			if (s == null || s.length == 0 || index < 0 || index >= s.length) null
 			else UBuiltins.ord(Syntax.arrayAccess(s, index));
 	}
 
-	@:ifFeature("dynamic_read.charAt", "anon_optional_read.charAt")
+	@:ifFeature("dynamic_read.charAt", "anon_optional_read.charAt", "python.internal.StringImpl.charAt")
 	public static inline function charAt(s:String, index:Int) {
 		return if (index < 0 || index >= s.length) "" else Syntax.arrayAccess(s,index);
 	}
 
-	@:ifFeature("dynamic_read.lastIndexOf", "anon_optional_read.lastIndexOf")
+	@:ifFeature("dynamic_read.lastIndexOf", "anon_optional_read.lastIndexOf", "python.internal.StringImpl.lastIndexOf")
 	public static inline function lastIndexOf(s:String, str:String, ?startIndex:Int):Int {
 		if (startIndex == null) {
 			return Syntax.callField(s, "rfind", str, 0, s.length);
@@ -60,30 +60,31 @@ class StringImpl {
 		}
 	}
 
-	@:ifFeature("dynamic_read.toUpperCase", "anon_optional_read.toUpperCase")
+	@:ifFeature("dynamic_read.toUpperCase", "anon_optional_read.toUpperCase", "python.internal.StringImpl.toUpperCase")
 	public static inline function toUpperCase (s:String) {
+		
 		return Syntax.callField(s, "upper");
 	}
-	@:ifFeature("dynamic_read.toLowerCase", "anon_optional_read.toLowerCase")
+	@:ifFeature("dynamic_read.toLowerCase", "anon_optional_read.toLowerCase", "python.internal.StringImpl.toLowerCase")
 	public static inline function toLowerCase (s:String) {
 		return Syntax.callField(s, "lower");
 	}
-	@:ifFeature("dynamic_read.indexOf", "anon_optional_read.indexOf")
+	@:ifFeature("dynamic_read.indexOf", "anon_optional_read.indexOf", "python.internal.StringImpl.indexOf")
 	public static inline function indexOf (s:String, str:String, ?startIndex:Int) {
 		if (startIndex == null)
 			return Syntax.callField(s, "find", str);
 		else
 			return Syntax.callField(s, "find", str, startIndex);
 	}
-	@:ifFeature("dynamic_read.toString", "anon_optional_read.toString")
+	@:ifFeature("dynamic_read.toString", "anon_optional_read.toString", "python.internal.StringImpl.toString")
 	public static inline function toString (s:String) {
 		return s;
 	}
-	@:ifFeature("dynamic_read.length", "anon_optional_read.length")
+	@:ifFeature("dynamic_read.length", "anon_optional_read.length", "python.internal.StringImpl.length")
 	public static inline function get_length (s:String) {
 		return UBuiltins.len(s);
 	}
-	@:ifFeature("dynamic_read.fromCharCode", "anon_optional_read.fromCharCode")
+	@:ifFeature("dynamic_read.fromCharCode", "anon_optional_read.fromCharCode", "python.internal.StringImpl.fromCharCode")
 	public static inline function fromCharCode( code : Int ) : String {
 		#if doc_gen
 		return "";
@@ -91,7 +92,7 @@ class StringImpl {
 		return Syntax.callField('', "join", UBuiltins.map(UBuiltins.chr, cast [code])); // TODO: check cast
 		#end
 	}
-	@:ifFeature("dynamic_read.substring", "anon_optional_read.substring")
+	@:ifFeature("dynamic_read.substring", "anon_optional_read.substring", "python.internal.StringImpl.substring")
 	public static function substring( s:String, startIndex : Int, ?endIndex : Int ) : String {
 		if (startIndex < 0) startIndex = 0;
 		if (endIndex == null) {
@@ -107,7 +108,7 @@ class StringImpl {
 			}
 		}
 	}
-	@:ifFeature("dynamic_read.substr", "anon_optional_read.substr")
+	@:ifFeature("dynamic_read.substr", "anon_optional_read.substr", "python.internal.StringImpl.substr")
 	public static function substr( s:String, startIndex : Int, ?len : Int ) : String {
 		if (len == null) {
 			return Syntax.arrayAccessWithTrailingColon(s, startIndex);