瀏覽代碼

Merge branch 'development' of https://github.com/proletariatgames/haxe into no_map_cache

Dan Ogles 10 年之前
父節點
當前提交
779117485a

+ 4 - 2
dce.ml

@@ -448,7 +448,7 @@ let run com main full =
 			List.iter (fun (c,cf,stat) -> mark_dependent_fields dce c cf.cf_name stat) cfl;
 			(* mark fields as used *)
 			List.iter (fun (c,cf,stat) ->
-				mark_class dce c;
+				if not (is_extern_field cf) then mark_class dce c;
 				mark_field dce c cf stat;
 				mark_t dce cf.cf_pos cf.cf_type
 			) cfl;
@@ -512,8 +512,10 @@ let run com main full =
 				b
 			) c.cl_ordered_fields;
 			(match c.cl_constructor with Some cf when not (keep_field dce cf) -> c.cl_constructor <- None | _ -> ());
+			let inef cf = not (is_extern_field cf) in
+			let has_non_extern_fields = List.exists inef c.cl_ordered_fields || List.exists inef c.cl_ordered_statics in
 			(* we keep a class if it was used or has a used field *)
-			if Meta.has Meta.Used c.cl_meta || c.cl_ordered_statics <> [] || c.cl_ordered_fields <> [] then loop (mt :: acc) l else begin
+			if Meta.has Meta.Used c.cl_meta || has_non_extern_fields then loop (mt :: acc) l else begin
 				(match c.cl_init with
 				| Some f when Meta.has Meta.KeepInit c.cl_meta ->
 					(* it means that we only need the __init__ block *)

+ 1 - 0
extra/ImportAll.hx

@@ -84,6 +84,7 @@ class ImportAll {
 					case "haxe.macro.ExampleJSGenerator","haxe.macro.Context", "haxe.macro.Compiler": if( !Context.defined("neko") ) continue;
 					case "haxe.remoting.SocketWrapper": if( !Context.defined("flash") ) continue;
 					case "haxe.remoting.SyncSocketConnection": if( !(Context.defined("neko") || Context.defined("php") || Context.defined("cpp")) ) continue;
+					case "sys.db.Sqlite" | "sys.db.Mysql" | "cs.db.AdoNet": continue;
 					}
 					Context.getModule(cl);
 				} else if( sys.FileSystem.isDirectory(p + "/" + file) )

+ 1 - 1
filters.ml

@@ -330,7 +330,7 @@ let captured_vars com e =
 	| Cs | Java ->
 		let cnativearray =
 			match (List.find (fun md -> match md with
-					| TClassDecl ({ cl_path = ["cs" | "java"],"NativeArray" }) -> true
+					| TClassDecl ({ cl_path = ["cs"|"java"],"NativeArray" }) -> true
 					| _ -> false
 				) com.types)
 			with TClassDecl cl -> cl | _ -> assert false

+ 9 - 0
gencommon.ml

@@ -1709,6 +1709,7 @@ struct
 			let local_map = Hashtbl.create (List.length cur_tf_args) in
 			let static_tf_args = (me, None) :: List.map (fun (v,b) ->
 				let new_v = alloc_var v.v_name (apply_params cl.cl_params ctor_params v.v_type) in
+				new_v.v_capture <- v.v_capture;
 				Hashtbl.add local_map v.v_id new_v;
 				(new_v, b)
 			) cur_tf_args in
@@ -6388,6 +6389,14 @@ struct
 					in
 					let base_type = List.hd base_type in
 					{ e with eexpr = TArrayDecl( List.map (fun e -> handle (run e) base_type e.etype) el ); etype = et }
+				| TCall ({ eexpr = TLocal { v_name = "__array__" } } as arr_local, el) ->
+					let et = e.etype in
+					let base_type = match follow et with
+						| TInst(cl, bt) -> gen.greal_type_param (TClassDecl cl) bt
+						| _ -> assert false
+					in
+					let base_type = List.hd base_type in
+					{ e with eexpr = TCall(arr_local, List.map (fun e -> handle (run e) base_type e.etype) el ); etype = et }
 				| TCall( ({ eexpr = TLocal v } as local), params ) when String.get v.v_name 0 = '_' && String.get v.v_name 1 = '_' && Hashtbl.mem gen.gspecial_vars v.v_name ->
 					{ e with eexpr = TCall(local, List.map (fun e -> (match e.eexpr with TBlock _ -> in_value := false | _ -> ()); run e) params) }
 				| TCall( ({ eexpr = TField(ef, f) }) as e1, elist ) ->

+ 25 - 9
gencpp.ml

@@ -835,6 +835,30 @@ let implement_dynamic_here class_def =
    ( (implements_dynamic class_def) && (not (super_implements_dynamic class_def) ) );;
 
 
+let gen_hash32 seed str =
+   let h = ref (Int32.of_int seed) in
+   let cycle = Int32.of_int 223 in
+   for i = 0 to String.length str - 1 do
+      h := Int32.add (Int32.mul !h cycle) (Int32.of_int (int_of_char (String.unsafe_get str i)));
+   done;
+   !h
+;;
+
+let gen_hash seed str =
+   Printf.sprintf "0x%08lx" (gen_hash32 seed str)
+;;
+
+let gen_string_hash str =
+   let h = gen_hash32 0 str in
+   Printf.sprintf "\"\\x%02lx\",\"\\x%02lx\",\"\\x%02lx\",\"\\x%02lx\""
+       (Int32.shift_right_logical (Int32.shift_left h 24) 24)
+       (Int32.shift_right_logical (Int32.shift_left h 16) 24)
+       (Int32.shift_right_logical (Int32.shift_left h 8) 24)
+       (Int32.shift_right_logical h 24)
+;;
+
+
+
 
 (* Make string printable for c++ code *)
 (* Here we know there are no utf8 characters, so use the L"" notation to avoid conversion *)
@@ -910,7 +934,7 @@ let str s =
    let escaped = Ast.s_escape ~hex:false s in
    let hexed = (special_to_hex escaped) in
    if (String.length hexed <= 16000 ) then
-      "HX_CSTRING(\"" ^ hexed ^ "\")"
+      "HX_HCSTRING(\"" ^ hexed ^ "\"," ^ (gen_string_hash s) ^ ")"
    else
       "(" ^ (split s "" ) ^ ")"
 ;;
@@ -1349,14 +1373,6 @@ let has_default_values args =
 
 exception PathFound of string;;
 
-let gen_hash seed str =
-   let h = ref (Int32.of_int seed) in
-   let cycle = Int32.of_int 223 in
-   for i = 0 to String.length str - 1 do
-      h := Int32.add (Int32.mul !h cycle) (Int32.of_int (int_of_char (String.unsafe_get str i)));
-   done;
-   Printf.sprintf "0x%08lx" !h
-;;
 
 let strip_file ctx file = (match Common.defined ctx Common.Define.AbsolutePath with
    | true -> file

+ 7 - 7
optimizer.ml

@@ -1142,7 +1142,7 @@ let rec make_constant_expression ctx ?(concat_strings=false) e =
 *)
 
 type inline_kind =
-	| IKCtor of tfunc * tclass_field * tclass * texpr list * texpr list
+	| IKCtor of tfunc * tclass_field * tclass * texpr list * texpr list * t
 	| IKArray of texpr list * t
 	| IKStructure of (string * texpr) list
 	| IKNone
@@ -1167,8 +1167,8 @@ let inline_constructors ctx e =
 			false
 	in
 	let rec get_inline_ctor_info e = match e.eexpr with
-		| TNew ({ cl_constructor = Some ({ cf_kind = Method MethInline; cf_expr = Some { eexpr = TFunction f } } as cst) } as c,_,pl) ->
-			IKCtor (f,cst,c,pl,[])
+		| TNew ({ cl_constructor = Some ({ cf_kind = Method MethInline; cf_expr = Some { eexpr = TFunction f } } as cst) } as c,tl,pl) ->
+			IKCtor (f,cst,c,pl,[],TInst(c,tl))
 		| TObjectDecl [] | TArrayDecl [] ->
 			IKNone
 		| TArrayDecl el ->
@@ -1189,8 +1189,8 @@ let inline_constructors ctx e =
 			begin match List.rev el with
 				| e :: el ->
 					begin match get_inline_ctor_info e with
-						| IKCtor(f,cst,c,pl,e_init) ->
-							IKCtor(f,cst,c,pl,(List.rev el) @ e_init)
+						| IKCtor(f,cst,c,pl,e_init,t) ->
+							IKCtor(f,cst,c,pl,(List.rev el) @ e_init,t)
 						| _ ->
 							IKNone
 					end
@@ -1222,9 +1222,9 @@ let inline_constructors ctx e =
 			begin match eo with
 				| Some n ->
 					begin match get_inline_ctor_info n with
-					| IKCtor (f,cst,c,pl,el_init) ->
+					| IKCtor (f,cst,c,pl,el_init,t) ->
 						(* inline the constructor *)
-						(match (try type_inline ctx cst f (mk (TLocal v) v.v_type n.epos) pl ctx.t.tvoid None n.epos true with Error (Custom _,_) -> None) with
+						(match (try type_inline ctx cst f (mk (TLocal v) t n.epos) pl ctx.t.tvoid None n.epos true with Error (Custom _,_) -> None) with
 						| None -> ()
 						| Some ecst ->
 							let assigns = ref [] in

+ 4 - 3
std/cs/Lib.hx

@@ -59,15 +59,16 @@ class Lib
 	**/
 	inline public static function nativeArray<T>(arr:Array<T>, equalLengthRequired:Bool):NativeArray<T>
 	{
-		return p_nativeArray(arr,new cs.NativeArray(arr.length));
+		var ret = new cs.NativeArray(arr.length);
+		p_nativeArray(arr,ret);
+		return ret;
 	}
 
-	static function p_nativeArray<T>(arr:Array<T>, ret:NativeArray<T>):NativeArray<T>
+	static function p_nativeArray<T>(arr:Array<T>, ret:cs.system.Array):Void
 	{
 		var native:NativeArray<T> = untyped arr.__a;
 		var len = arr.length;
 		cs.system.Array.Copy(native, 0, ret, 0, len);
-		return ret;
 	}
 
 	/**

+ 1 - 1
std/cs/internal/Runtime.hx

@@ -426,7 +426,7 @@ import cs.system.Object;
 					{
 						var param = params[i].ParameterType;
 						var strParam = param + "";
-						if (param.IsAssignableFrom(ts[i]))
+						if (param.IsAssignableFrom(ts[i]) || (ts[i] == null && !param.IsValueType))
 						{
 							//if it is directly assignable, we'll give it top rate
 							continue;

+ 1 - 1
tests/RunCi.hx

@@ -516,7 +516,7 @@ class RunCi {
 				case Cs:
 					getCsDependencies();
 
-					runCommand("haxe", ["compile-cs.hxml"]);
+					runCommand("haxe", ["compile-cs-travis.hxml"]);
 					runCommand("mono", ["bin/cs/bin/Test-Debug.exe"]);
 
 					runCommand("haxe", ["compile-cs-unsafe.hxml"]);

+ 7 - 0
tests/unit/compile-cs-travis.hxml

@@ -0,0 +1,7 @@
+compile-cs.hxml
+
+-net-lib cs_drivers/System.Data.dll
+-net-lib cs_drivers/System.Xml.dll
+-net-lib cs_drivers/Mono.Data.Sqlite.dll
+
+-D travis

+ 0 - 3
tests/unit/compile-cs.hxml

@@ -7,6 +7,3 @@ compile-each.hxml
 -main unit.Test
 -cs bin/cs
 -net-lib native_cs/bin/native_cs.dll
--net-lib cs_drivers/System.Data.dll
--net-lib cs_drivers/System.Xml.dll
--net-lib cs_drivers/Mono.Data.Sqlite.dll

+ 2 - 0
tests/unit/native_cs/hxcs_build.txt

@@ -18,6 +18,8 @@ M haxe.test.GenericHelper
 C haxe.test.GenericHelper
 M haxe.test.StaticAndInstanceClash
 C haxe.test.StaticAndInstanceClash
+M NoPackage
+C NoPackage
 end modules
 begin defines
 dll

+ 21 - 0
tests/unit/native_cs/src/NoPackage.cs

@@ -0,0 +1,21 @@
+public class NoPackage
+{
+	public NoPackInner b;
+	public bool isWorking;
+
+	public NoPackage()
+	{
+		isWorking = true;
+		b = new NoPackInner();
+	}
+
+	public class NoPackInner
+	{
+		public bool isReallyWorking;
+
+		public NoPackInner()
+		{
+			isReallyWorking = true;
+		}
+	}
+}

+ 1 - 1
tests/unit/src/unit/Test.hx

@@ -300,7 +300,7 @@ class Test #if swf_mark implements mt.Protect #end {
 			//new TestRemoting(),
 		];
 		// SPOD tests
-		#if ( (neko || php || java || cpp || cs) && !macro && !interp)
+		#if ( (neko || php || java || cpp || (cs && travis)) && !macro && !interp)
 		#if !(cpp || cs)
 		if (Sys.getEnv("CI") != null && Sys.systemName() == "Linux")
 		{

+ 9 - 8
tests/unit/src/unit/TestCSharp.hx

@@ -4,6 +4,7 @@ import haxe.test.Base;
 import haxe.test.Base.Base_InnerClass;
 import haxe.test.TEnum;
 import haxe.test.TEnumWithValue;
+import NoPackage;
 #if unsafe
 import cs.Pointer;
 #end
@@ -130,6 +131,14 @@ class TestCSharp extends Test
 
 		var i2 = new Base_InnerClass_InnerInnerClass();
 		t(true);
+
+		var noPack:NoPackage = new NoPackage();
+		t(noPack.isWorking);
+		t(noPack.b != null);
+		t(noPack.b.isReallyWorking);
+
+		var noPack2 = new NoPackage.NoPackage_NoPackInner();
+		t(noPack2.isReallyWorking);
 	}
 
 	function testGenerics()
@@ -261,14 +270,6 @@ class TestCSharp extends Test
 		checkEnum(TEnumWithValue,0,TEnumWithValue.TVB);
 		checkEnum(TEnumWithValue,2,TEnumWithValue.TVC);
 		checkEnum(TEnumWithValue,1,TEnumWithValue.TVD);
-		// trace( getArray(cs.system.Enum.GetValues(untyped TEnum)) );
-		// trace( getArray(cs.system.Enum.GetNames(untyped TEnum)) );
-		// trace( getArray(cs.system.Enum.GetValues(untyped TEnumWithValue)) );
-		// trace( getArray(cs.system.Enum.GetNames(untyped TEnumWithValue)) );
-		// trace( Type.getEnumConstructs(TEnum) );
-		// trace( Type.getEnumConstructs(TEnumWithValue) );
-		// trace( Type.allEnums(TEnum) );
-		// trace( Type.allEnums(TEnumWithValue) );
 	}
 
 	private static function getArray(arr:cs.system.Array)

+ 32 - 0
tests/unit/src/unit/issues/Issue3513.hx

@@ -0,0 +1,32 @@
+package unit.issues;
+
+private enum Either<L, R> {
+    Left(l:L);
+    Right(r:R);
+}
+
+private abstract LazyGenerator<Data, End>(Void->Either<Data, End>) from Void->Either<Data, End> {
+	public function next():Either<Data, End>
+		return (this)();
+
+	@:from static function infinite<Data, End>(f:Void->Data):LazyGenerator<Data, End>
+		return function () return Left(f());
+}
+
+class Issue3513 extends Test {
+	function test() {
+        var count = 0;
+        function counter() return count++;
+        var gen:LazyGenerator<Int, Int> = counter;
+        var gen:LazyGenerator<Int, Int> = function ():Int return count++;
+		eq(0, getValue(gen.next()));
+		eq(1, getValue(gen.next()));
+	}
+
+	static function getValue(e:Either<Int, Int>) {
+		return switch (e) {
+			case Left(v): v;
+			case Right(v): v;
+		}
+	}
+}

+ 14 - 0
tests/unit/src/unit/issues/Issue3545.hx

@@ -0,0 +1,14 @@
+package unit.issues;
+
+typedef Constraint = { }
+
+typedef T1<T:Constraint> = { }
+
+typedef T2<T:Constraint> = {
+	x:T1<T>
+}
+
+class Issue3545 extends Test {
+	// if it compiles it works
+	function test() { }
+}

+ 20 - 0
tests/unit/src/unit/issues/Issue3554.hx

@@ -0,0 +1,20 @@
+package unit.issues;
+
+private abstract A(Int)
+{
+    public static var a(get,never):Int;
+    private static function get_a()
+        return(1 << x);
+
+    public static var x(get,never):Int;
+    static var _x:Int = 4;
+    inline static function get_x()
+        return _x;
+}
+
+
+class Issue3554 extends Test {
+	function test() {
+		eq(16, A.a);
+	}
+}

+ 17 - 1
tests/unit/src/unit/issues/Issue3575.hx

@@ -10,18 +10,32 @@ class Issue3575 extends Test {
 
 @:nativeGen private class Base
 {
+#if (cs || java) @:overload #end
 	public function getName()
 	{
 		return "Base!";
 	}
+
+#if (cs || java)
+	@:overload public function getName(s:String)
+	{
+		return 'Base!:$s';
+	}
+#end
 }
 
-class Child extends Base
+class DirectDescendant extends Base
+{
+
+}
+
+class Child extends DirectDescendant
 {
 	public function new()
 	{
 	}
 
+#if (cs || java) @:overload #end
 	override public function getName()
 	{
 		return "Something Else";
@@ -32,3 +46,5 @@ class Child extends Base
 		return 'Child' + super.getName();
 	}
 }
+
+

+ 16 - 0
tests/unit/src/unit/issues/Issue3577.hx

@@ -0,0 +1,16 @@
+package unit.issues;
+
+class Issue3577 extends Test {
+    function test() {
+        eq(testNull(2), 4);
+    }
+
+    function testNull(?x:Int=0) : Int {
+        var y:Int = x;
+        function anon() {
+            y *= 2;
+        }
+        anon();
+        return y;
+    }
+}

+ 27 - 0
tests/unit/src/unit/issues/Issue3578.hx

@@ -0,0 +1,27 @@
+package unit.issues;
+
+class Issue3578 extends Test
+{
+	function test()
+	{
+		var i = 0;
+		var t = new TestG(function() i++);
+		eq(i,1);
+		t.func();
+		eq(i,2);
+	}
+}
+
+private class TestG
+{
+	public var func:Void->Void;
+	public function new(callback:Void->Void)
+	{
+		function x()
+		{
+			callback();
+		}
+		x();
+		this.func = x;
+	}
+}

+ 36 - 0
tests/unit/src/unit/issues/Issue3579.hx

@@ -0,0 +1,36 @@
+package unit.issues;
+import haxe.ds.Vector;
+
+class Issue3579 extends Test
+{
+	function test()
+	{
+		var a = ["a","b"],
+				b = [1,2,3,4],
+				c:Array<Single> = [1.1,1.2,1.3,1.4],
+				d = [new SomeClass(),new SomeClass()];
+		var a1 = Vector.fromArrayCopy(a),
+				b1 = Vector.fromArrayCopy(b),
+				c1 = Vector.fromArrayCopy(c),
+				d1 = Vector.fromArrayCopy(d);
+		eq(a[0],a1[0]);
+		eq(b[0],b1[0]);
+		eq(c[0],c1[0]);
+		eq(d[0],d1[0]);
+		eq("a",a1[0]);
+		eq(1,b1[0]);
+		eq(11,Std.int(c1[0]*10));
+		t(d1[0] != null);
+	}
+}
+
+private class SomeClass
+{
+	public function new()
+	{
+	}
+}
+
+#if (!java && !cs)
+private typedef Single = Float
+#end

+ 16 - 0
tests/unit/src/unit/issues/Issue3586.hx

@@ -0,0 +1,16 @@
+package unit.issues;
+
+private class C<T> {
+    public var f:Array<T>;
+    public inline function new(v) f = [v];
+}
+
+@:forward(f)
+private abstract A(C<Int>) from C<Int> {}
+
+class Issue3586 extends unit.Test {
+    function test() {
+        var a:A = new C(15);
+        eq(a.f[0], 15);
+    }
+}

+ 1 - 1
type.ml

@@ -1379,7 +1379,7 @@ let rec unify a b =
 		if PMap.is_empty an.a_fields then (match c.cl_kind with
 			| KTypeParameter pl ->
 				(* one of the constraints must unify with { } *)
-				if not (List.exists (fun t -> match t with TInst _ | TAnon _ -> true | _ -> false) pl) then error [cannot_unify a b]
+				if not (List.exists (fun t -> match follow t with TInst _ | TAnon _ -> true | _ -> false) pl) then error [cannot_unify a b]
 			| _ -> ());
 		(try
 			PMap.iter (fun n f2 ->

+ 12 - 5
typer.ml

@@ -1163,6 +1163,12 @@ let field_access ctx mode f fmode t e p =
 				normal()
 		| AccCall ->
 			let m = (match mode with MSet -> "set_" | _ -> "get_") ^ f.cf_name in
+			let is_abstract_this_access () = match e.eexpr,ctx.curfun with
+				| TTypeExpr (TClassDecl ({cl_kind = KAbstractImpl _} as c)),(FunMemberAbstract | FunMemberAbstractLocal) ->
+					c == ctx.curclass
+				| _ ->
+					false
+			in
 			if m = ctx.curfield.cf_name && (match e.eexpr with TConst TThis -> true | TTypeExpr (TClassDecl c) when c == ctx.curclass -> true | _ -> false) then
 				let prefix = (match ctx.com.platform with Flash when Common.defined ctx.com Define.As3 -> "$" | _ -> "") in
 				if is_extern_field f then begin
@@ -1170,7 +1176,7 @@ let field_access ctx mode f fmode t e p =
 					display_error ctx "Add @:isVar here to enable it" f.cf_pos;
 				end;
 				AKExpr (mk (TField (e,if prefix = "" then fmode else FDynamic (prefix ^ f.cf_name))) t p)
-			else if (match e.eexpr with TTypeExpr (TClassDecl ({cl_kind = KAbstractImpl _} as c)) when c == ctx.curclass -> true | _ -> false) then begin
+			else if is_abstract_this_access() then begin
 				let this = get_this ctx p in
 				if mode = MSet then begin
 					let c,a = match ctx.curclass with {cl_kind = KAbstractImpl a} as c -> c,a | _ -> assert false in
@@ -1795,7 +1801,7 @@ let type_generic_function ctx (e,cf) el ?(using_param=None) with_type p =
 			end;
 			ignore(follow cf.cf_type);
 			cf2.cf_expr <- (match cf.cf_expr with
-				| None -> None
+				| None -> error "Recursive @:generic function" p
 				| Some e -> Some (Codegen.generic_substitute_expr gctx e));
 			cf2.cf_kind <- cf.cf_kind;
 			cf2.cf_public <- cf.cf_public;
@@ -3330,9 +3336,10 @@ and type_expr ctx (e,p) (with_type:with_type) =
 						| _ -> ()
 					) args args2;
 					(* unify for top-down inference unless we are expecting Void *)
-					begin match follow tr with
-						| TAbstract({a_path = [],"Void"},_) -> ()
-						| _ -> unify ctx rt tr p
+					begin match follow tr,follow rt with
+						| TAbstract({a_path = [],"Void"},_),_ -> ()
+						| _,TMono _ -> unify ctx rt tr p
+						| _ -> ()
 					end
 				| TAbstract(a,tl) ->
 					loop (Abstract.get_underlying_type a tl)