Browse Source

removed === and !==
fixes in reflection

Nicolas Cannasse 17 years ago
parent
commit
8bda9b4e54

+ 0 - 4
ast.ml

@@ -69,9 +69,7 @@ type binop =
 	| OpSub
 	| OpAssign
 	| OpEq
-	| OpPhysEq
 	| OpNotEq
-	| OpPhysNotEq
 	| OpGt
 	| OpGte
 	| OpLt
@@ -332,9 +330,7 @@ let rec s_binop = function
 	| OpSub -> "-"
 	| OpAssign -> "="
 	| OpEq -> "=="
-	| OpPhysEq -> "==="
 	| OpNotEq -> "!="
-	| OpPhysNotEq -> "!=="
 	| OpGte -> ">="
 	| OpLte -> "<="
 	| OpGt -> ">"

+ 7 - 0
doc/CHANGES.txt

@@ -35,6 +35,13 @@ TODO inlining : substitute class+function type parameters in order to have fully
 	fixed big bug in js/flash8 debug stack handling
 	complete rewrite of haxe.remoting package
 	haxe.io.Bytes serialization support
+	removed === and !==
+	removed Std.bool
+	fixed : Reflect.field(null) in flash9 doesn't throw an error anymore
+	removed Type.toClass and Type.toEnum
+	Dynamic type is now a class and not an enum
+	moved reflection support for core types from Boot to Type
+	fixed Type.getClassName/getEnumName/resolve for core flash9 types
 
 2008-04-05: 1.19
 	fixed flash9 Array.toString

+ 1 - 7
genneko.ml

@@ -200,13 +200,7 @@ let gen_constant ctx pe c =
 	| TSuper -> assert false
 
 let rec gen_binop ctx p op e1 e2 =
-	let gen_op str =
-		(EBinop (str,gen_expr ctx e1,gen_expr ctx e2),p)
-	in
-	match op with
-	| OpPhysEq -> (EBinop ("==", call p (builtin p "pcompare") [gen_expr ctx e1; gen_expr ctx e2], int p 0),p)
-	| OpPhysNotEq ->  (EBinop ("!=", call p (builtin p "pcompare") [gen_expr ctx e1; gen_expr ctx e2], int p 0),p)
-	| _ -> gen_op (Ast.s_binop op)
+	(EBinop (Ast.s_binop op,gen_expr ctx e1,gen_expr ctx e2),p)
 
 and gen_unop ctx p op flag e =
 	match op with

+ 4 - 4
genswf8.ml

@@ -747,10 +747,6 @@ and gen_binop ctx retval op e1 e2 =
 	| OpDiv -> gen ADivide
 	| OpSub -> gen ASubtract
 	| OpEq -> gen AEqual
-	| OpPhysEq -> gen APhysEqual
-	| OpPhysNotEq ->
-		gen APhysEqual;
-		write ctx ANot
 	| OpNotEq ->
 		gen AEqual;
 		write ctx ANot
@@ -877,6 +873,10 @@ and gen_call ctx e el =
 		jump_end();
 		get_tmp ctx r;
 		free_tmp ctx r e2.epos;
+	| TLocal "__physeq__" ,  [e1;e2] ->
+		gen_expr ctx true e1;
+		gen_expr ctx true e2;
+		write ctx APhysEqual;
 	| TLocal "__unprotect__", [{ eexpr = TConst (TString s) }] ->
 		push ctx [VStr (s,false)]
 	| _ , _ ->

+ 2 - 9
genswf9.ml

@@ -1254,14 +1254,9 @@ and gen_binop ctx retval op e1 e2 t =
 		gen_op ~iop:A3OISub A3OSub
 	| OpEq ->
 		gen_op A3OEq
-	| OpPhysEq ->
-		gen_op A3OPhysEq
 	| OpNotEq ->
 		gen_op A3OEq;
 		write ctx (HOp A3ONot)
-	| OpPhysNotEq ->
-		gen_op A3OPhysEq;
-		write ctx (HOp A3ONot)
 	| OpGt ->
 		gen_op A3OGt
 	| OpGte ->
@@ -1339,8 +1334,6 @@ and jump_expr_gen ctx e jif jfun =
 		(match op with
 		| OpEq -> j J3Eq J3Neq
 		| OpNotEq -> j J3Neq J3Eq
-		| OpPhysEq -> j J3PhysEq J3PhysNeq
-		| OpPhysNotEq -> j J3PhysNeq J3PhysEq
 		| OpGt -> j J3Gt J3NotGt
 		| OpGte -> j J3Gte J3NotGte
 		| OpLt -> j J3Lt J3NotLt
@@ -1659,12 +1652,12 @@ let generate_enum ctx e =
 let generate_type ctx t =
 	match t with
 	| TClassDecl c ->
-		if c.cl_extern then
+		if c.cl_extern && c.cl_path <> ([],"Dynamic") then
 			None
 		else
 			Some (generate_class ctx c)
 	| TEnumDecl e ->
-		if e.e_extern then
+		if e.e_extern && e.e_path <> ([],"Void") then
 			None
 		else
 			Some (generate_enum ctx e)

+ 0 - 2
lexer.mll

@@ -165,8 +165,6 @@ rule token = parse
 	| "<<=" { mk lexbuf (Binop (OpAssignOp OpShl)) }
 (*//| ">>=" { mk lexbuf (Binop (OpAssignOp OpShr)) } *)
 (*//| ">>>=" { mk lexbuf (Binop (OpAssignOp OpUShr)) } *)
-	| "===" { mk lexbuf (Binop OpPhysEq) }
-	| "!==" { mk lexbuf (Binop OpPhysNotEq) }
 	| "==" { mk lexbuf (Binop OpEq) }
 	| "!=" { mk lexbuf (Binop OpNotEq) }
 	| "<=" { mk lexbuf (Binop OpLte) }

+ 1 - 1
parser.ml

@@ -65,7 +65,7 @@ let priority = function
 	| OpBoolOr -> -3
 	| OpBoolAnd -> -2
 	| OpInterval -> -2
-	| OpEq | OpNotEq | OpGt | OpLt | OpGte | OpLte | OpPhysEq | OpPhysNotEq -> -1
+	| OpEq | OpNotEq | OpGt | OpLt | OpGte | OpLte -> -1
 	| OpOr | OpAnd | OpXor -> 0
 	| OpShl | OpShr | OpUShr -> 1
 	| OpAdd | OpSub -> 2

+ 4 - 0
std/Math.hx

@@ -58,6 +58,7 @@ extern class Math
 	private static function __init__() : Void untyped {
 	#if neko
 		Math = neko.NekoMath__;
+		neko.Boot.__classes.Math = Math;
 	#else
 		#if flash9
 		NaN = __global__["Number"].NaN;
@@ -93,6 +94,9 @@ extern class Math
 			#end
 		};
 	#end
+	#if !flash9
+		Math.__name__ = ["Math"];
+	#end
 	}
 
 }

+ 3 - 1
std/Reflect.hx

@@ -55,7 +55,9 @@ class Reflect {
 		Returns the field of an object, or null if [o] is not an object or doesn't have this field.
 	**/
 	public inline static function field( o : Dynamic, field : String ) : Dynamic untyped {
-		#if flash
+		#if flash9
+			return (o == null) ? null : o[field];
+		#elseif flash
 			return o[field];
 		#elseif js
 			var v = null;

+ 0 - 9
std/Std.hx

@@ -72,13 +72,6 @@ class Std {
 		#end
 	}
 
-	/**
-		Convert any value to a Bool. Only 0, null and false are false, other values are true.
-	**/
-	public static function bool( x : Dynamic ) : Bool {
-		return (x !== 0 && x != null && x !== false);
-	}
-
 	/**
 		Convert a String to an Int, parsing different possible representations. Returns [null] if could not be parsed.
 	**/
@@ -191,8 +184,6 @@ class Std {
 		return untyped
 		#if as3gen
 		throw "Not supported in AS3";
-		#elseif flash9
-		flash.Boot.__res[name];
 		#elseif flash
 		flash.Boot.__res[name];
 		#elseif neko

+ 1 - 1
std/StdTypes.hx

@@ -68,7 +68,7 @@ extern enum Bool {
 	Dynamic is an internal compiler type which has special behavior.
 	See the haXe language reference for more informations.
 **/
-extern enum Dynamic<T> {
+extern class Dynamic<T> {
 }
 
 /**

+ 68 - 36
std/Type.hx

@@ -28,40 +28,6 @@ enum ValueType {
 **/
 class Type {
 
-	/**
-		Converts a value to an Enum or returns [null] if the value is not an Enum.
-	**/
-	public static function toEnum( t : Dynamic ) : Enum untyped {
-		try {
-			#if flash9
-				if( !t.__isenum ) return null;
-			#else
-				if( t.__ename__ == null ) return null;
-			#end
-			return t;
-		} catch( e : Dynamic ) {
-		}
-		return null;
-	}
-
-	/**
-		Converts a value to a Class or returns [null] if the value is not a Class.
-	**/
-	public static function toClass( t : Dynamic ) : Class<Dynamic> untyped {
-		try {
-			#if flash9
-				if( !t.hasOwnProperty("prototype") )
-					return null;
-			#else
-				if( t.__name__ == null )
-					return null;
-			#end
-			return t;
-		} catch( e : Dynamic ) {
-		}
-		return null;
-	}
-
 	/**
 		Returns the class of a value or [null] if this value is not a Class instance.
 	**/
@@ -152,6 +118,12 @@ class Type {
 			return null;
 		#if flash9
 			var str : String = untyped __global__["flash.utils.getQualifiedClassName"](c);
+			switch( str ) {
+			case "int": return "Int";
+			case "Number": return "Float";
+			case "Boolean": return "Bool";
+			default:
+			}
 			return str.split("::").join(".");
 		#else
 			var a : Array<String> = untyped c.__name__;
@@ -164,8 +136,7 @@ class Type {
 	**/
 	public static function getEnumName( e : Enum ) : String {
 		#if flash9
-			var n = untyped __global__["flash.utils.getQualifiedClassName"](e);
-			return n;
+			return getClassName(cast e);
 		#else
 			var a : Array<String> = untyped e.__ename__;
 			return a.join(".");
@@ -185,6 +156,10 @@ class Type {
 					return null;
 				return cl; // skip test below
 			} catch( e : Dynamic ) {
+				switch( name ) {
+				case "Int": return Int;
+				case "Float": return Float;
+				}
 				return null;
 			}
 		#elseif flash
@@ -224,6 +199,7 @@ class Type {
 					return null;
 				return e;
 			} catch( e : Dynamic ) {
+				if( name == "Bool" ) return Bool;
 				return null;
 			}
 		#elseif flash
@@ -549,5 +525,61 @@ class Type {
 		#end
 	}
 
+	static function __init__() untyped {
+		#if js
+			String.prototype.__class__ = String;
+			String.__name__ = ["String"];
+			Array.prototype.__class__ = Array;
+			Array.__name__ = ["Array"];
+			Int = { __name__ : ["Int"] };
+			Dynamic = { __name__ : ["Dynamic"] };
+			Float = __js__("Number");
+			Float.__name__ = ["Float"];
+			Bool = { __ename__ : ["Bool"] };
+			Class = { __name__ : ["Class"] };
+			Enum = {};
+			Void = { __ename__ : ["Void"] };
+		#elseif flash9
+			#if !as3gen
+			Bool = __global__["Boolean"];
+			Int = __global__["int"];
+			Float = __global__["Number"];
+			#end
+		#elseif flash
+			var g = _global;
+			g.Int = { __name__ : ["Int"] };
+			g.Bool = { __ename__ : ["Bool"] };
+			g.Dynamic = { __name__ : ["Dynamic"] };
+			g.Class = { __name__ : ["Class"] };
+			g.Enum = {};
+			g.Void = { __ename__ : ["Void"] };
+			g.Float = _global["Number"];
+			g.Float[__unprotect__("__name__")] = ["Float"];
+			Array.prototype[__unprotect__("__class__")] = Array;
+			Array[__unprotect__("__name__")] = ["Array"];
+			String.prototype[__unprotect__("__class__")] = String;
+			String[__unprotect__("__name__")] = ["String"];
+			g["ASSetPropFlags"](Array.prototype,null,7);
+		#elseif neko
+			Int = { __name__ : ["Int"] };
+			Float = { __name__ : ["Float"] };
+			Bool = { __ename__ : ["Bool"] };
+			Dynamic = { __name__ : ["Dynamic"] };
+			Class = { __name__ : ["Class"] };
+			Enum = {};
+			Void = { __ename__ : ["Void"] };
+			var cl = neko.Boot.__classes;
+			cl.String = String;
+			cl.Array = Array;
+			cl.Int = Int;
+			cl.Float = Float;
+			cl.Bool = Bool;
+			cl.Dynamic = Dynamic;
+			cl.Class = Class;
+			cl.Enum = Enum;
+			cl.Void = Void;
+		#end
+	}
+
 }
 

+ 6 - 18
std/flash/Boot.hx

@@ -137,19 +137,19 @@ class Boot {
 			#end
 			switch( cast cl ) {
 			case Int:
-				return (Math.ceil(o) === o) && isFinite(o) && (o !== true) && (o !== false);
+				return __physeq__(Math.ceil(o),o) && isFinite(o) && !(__physeq__(o,true) || __physeq__(o,false));
 			case Float:
 				return __typeof__(o) == "number";
 			case Bool:
-				return (o === true || o === false);
+				return __physeq__(o,true) || __physeq__(o,false);
 			case String:
 				return __typeof__(o) == "string";
 			case Dynamic:
 				return true;
 			default:
-				if( o[__unprotect__("__enum__")] == cl )
-					return true;
-				return false;
+				return o[__unprotect__("__enum__")] == cl ||
+					(cl == Class && o[__unprotect__("__name__")] != null) ||
+					(cl == Enum && o[__unprotect__("__ename__")] != null);
 			}
 		}
 	}
@@ -217,15 +217,7 @@ class Boot {
 		// only if not set yet
 		var g : Dynamic = _global;
 		if( !g.haxeInitDone ) {
-			var obj = _global["Object"];
 			g.haxeInitDone = true;
-			g.Int = __new__(obj);
-			g.Bool = __new__(obj);
-			g.Dynamic = __new__(obj);
-			g.Bool = __new__(obj);
-			g.Bool[__unprotect__("true")] = true;
-			g.Bool[__unprotect__("false")] = false;
-			g.Float = _global["Number"];
 			Array.prototype["copy"] = Array.prototype["slice"];
 			Array.prototype["insert"] = function(i,x) {
 				this["splice"](i,0,x);
@@ -254,11 +246,7 @@ class Boot {
 					}
 				}
 			};
-			Array.prototype[__unprotect__("__class__")] = Array;
-			Array[__unprotect__("__name__")] = ["Array"];
 			_global["ASSetPropFlags"](Array.prototype,null,7);
-			String.prototype[__unprotect__("__class__")] = String;
-			String[__unprotect__("__name__")] = ["String"];
 			var cca = String.prototype["charCodeAt"];
 			String.prototype["cca"] = cca;
 			String.prototype["charCodeAt"] = function(i) {
@@ -269,7 +257,7 @@ class Boot {
 			};
 			// create flash package (in for FP7 mark support)
 			if( _global["flash"] == null )
-				_global["flash"] = __new__(obj);
+				_global["flash"] = {};
 		}
 		// set the Lib variables
 		current.flash.Lib._global = _global;

+ 1 - 7
std/flash9/Boot.hx

@@ -72,12 +72,6 @@ class Boot extends flash.display.MovieClip, implements Dynamic {
 			aproto.setPropertyIsEnumerable("insert", false);
 			aproto.setPropertyIsEnumerable("remove", false);
 			aproto.setPropertyIsEnumerable("iterator", false);
-			#if !as3gen
-			Bool = __global__["Boolean"];
-			Int = __global__["int"];
-			Float = __global__["Number"];
-			Dynamic = { toString : function(){ return "Dynamic"; } };
-			#end
 			var cca = String.prototype.charCodeAt;
 			String.prototype.charCodeAt = function(i) {
 				var x = cca.call(this,i);
@@ -107,7 +101,7 @@ class Boot extends flash.display.MovieClip, implements Dynamic {
 
 	public static function __instanceof( v : Dynamic, t : Dynamic ) {
 		try {
-			if( t === untyped __global__["Dynamic"] )
+			if( t == Dynamic )
 				return true;
 			return untyped __is__(v,t);
 		} catch( e : Dynamic ) {

+ 3 - 10
std/flash9/Lib.hx

@@ -45,17 +45,10 @@ class Lib {
 			if( o != null )
 				break;
 		}
-		if( o == null ) {
-			#if !as3gen
-			// this is a small hack for a "api" global
-			// which can be used by some MT libraries
-			if( path == "api" )
-				return untyped __global__["api"];
-			#end
-			return null;
-		}
-		for( f in fields )
+		for( f in fields ) {
+			if( o == null ) return null;
 			o = untyped o[f];
+		}
 		return o;
 	}
 

+ 1 - 1
std/haxe/remoting/Context.hx

@@ -40,7 +40,7 @@ class Context {
 		if( path.length < 2 ) throw "Invalid path '"+path.join(".")+"'";
 		var inf = objects.get(path[0]);
 		if( inf == null )
-			throw "No such object "+path.join(".");
+			throw "No such object "+path[0];
 		var o = inf.obj;
 		var m = Reflect.field(o,path[1]);
 		if( path.length > 2 ) {

+ 57 - 0
std/haxe/remoting/ContextAll.hx

@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2005-2008, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package haxe.remoting;
+
+class ContextAll extends Context {
+
+	public override function call( path : Array<String>, params : Array<Dynamic> ) : Dynamic {
+		#if neko
+		var o : Dynamic = null;
+		var m : Dynamic = neko.Lib.getClasses();
+		for( p in path ) {
+			o = m;
+			m = Reflect.field(o,p);
+		}
+		#elseif js
+		var path2 = path.copy();
+		var f = path2.pop();
+		var o;
+		try {
+			o = js.Lib.eval(path2.join("."));
+		} catch( e : Dynamic ) {
+		}
+		var m = Reflect.field(o,f);
+		#elseif flash
+		var path2 = path.copy();
+		var f = path2.pop();
+		var o = flash.Lib.eval(path2.join("."));
+		var m = Reflect.field(o,f);
+		#end
+		if( m == null )
+			return super.call(path,params);
+		return Reflect.callMethod(o,m,params);
+	}
+
+}

+ 5 - 15
std/js/Boot.hx

@@ -174,19 +174,19 @@ class Boot {
 			}
 			switch( cl ) {
 			case Int:
-				return (Math.ceil(o) === o) && isFinite(o);
+				return __js__("Math.ceil(o) === o") && isFinite(o);
 			case Float:
 				return __js__("typeof(o)") == "number";
 			case Bool:
-				return (o === true || o === false);
+				return __js__("o === true || o === false");
 			case String:
 				return __js__("typeof(o)") == "string";
 			case Dynamic:
 				return true;
 			default:
-				if( o != null && o.__enum__ == cl )
-					return true;
-				return false;
+				if( o == null )
+					return false;
+				return o.__enum__ == cl || ( cl == Class && o.__name__ != null ) || ( cl == Enum && o.__ename__ != null );
 			}
 		}
 	}
@@ -223,10 +223,6 @@ class Boot {
 					}
 				}
 			};
-			String.prototype.__class__ = String;
-			String.__name__ = ["String"];
-			Array.prototype.__class__ = Array;
-			Array.__name__ = ["Array"];
 			var cca = String.prototype.charCodeAt;
 			String.prototype.cca = cca;
 			String.prototype.charCodeAt = function(i) {
@@ -247,12 +243,6 @@ class Boot {
 				}
 				return oldsub.apply(this,[pos,len]);
 			};
-			Int = __new__("Object");
-			Dynamic = __new__("Object");
-			Float = __js__("Number");
-			Bool = __new__("Object");
-			Bool["true"] = true;
-			Bool["false"] = false;
 			__js__("$closure = js.Boot.__closure");
 		}
 	}

+ 1 - 9
std/neko/Boot.hx

@@ -78,7 +78,7 @@ class Boot {
 			case __dollar__tobject:
 				if( cl == null )
 					return false;
-				return __interfLoop(o.__class__,cl) || ( o.__enum__ == cl );
+				return __interfLoop(o.__class__,cl) || ( o.__enum__ == cl ) || (cl == Class && o.__name__ != null) || (cl == Enum && o.__ename__ != null );
 			default:
 				return false;
 			}
@@ -140,15 +140,7 @@ class Boot {
 	private static function __init() {
 		untyped {
 			String = NekoString__;
-			neko.Boot.__classes.String = String;
 			Array = NekoArray__;
-			neko.Boot.__classes.Array = Array;
-			Int = __dollar__new(null);
-			Float = __dollar__new(null);
-			Bool = __dollar__new(null);
-			Dynamic = __dollar__new(null);
-			__dollar__objset(Bool,__dollar__hash("true".__s),true);
-			__dollar__objset(Bool,__dollar__hash("false".__s),false);
 			__dollar__exports.__unserialize = __unserialize;
 			__dollar__exports.__classes = neko.Boot.__classes;
 		}

+ 9 - 0
tests/unit/MySubClass.hx

@@ -0,0 +1,9 @@
+package unit;
+
+class MySubClass extends MyClass {
+
+	public override function get() {
+		return val * 2;
+	}
+
+}

+ 15 - 6
tests/unit/Test.hx

@@ -5,7 +5,7 @@ class Test {
 	public function new() {
 	}
 
-	function eq<T>( v : T, v2 : T, ?pos : haxe.PosInfos ) {
+	function eq<T>( v : T, v2 : T, ?pos ) {
 		count++;
 		if( v != v2 ) report(v+" should be "+v2,pos);
 	}
@@ -18,7 +18,7 @@ class Test {
 		eq(v,false,pos);
 	}
 
-	function exc( f : Void -> Void, ?pos : haxe.PosInfos ) {
+	function exc( f : Void -> Void, ?pos ) {
 		count++;
 		try {
 			f();
@@ -27,7 +27,7 @@ class Test {
 		}
 	}
 
-	function unspec( f : Void -> Void, ?pos : haxe.PosInfos ) {
+	function unspec( f : Void -> Void, ?pos ) {
 		count++;
 		try {
 			f();
@@ -35,7 +35,7 @@ class Test {
 		}
 	}
 
-	function allow<T>( v : T, values : Array<T>, ?pos : haxe.PosInfos ) {
+	function allow<T>( v : T, values : Array<T>, ?pos ) {
 		count++;
 		for( v2 in values )
 			if( v == v2 )
@@ -148,7 +148,16 @@ class Test {
 			neko.Lib.print("<pre>");
 		#end
 		resetTimer();
+		trace("START");
+		#if flash
+		var tf = untyped flash.Boot.getTrace();
+		tf.selectable = true;
+		#if flash9
+			tf.mouseEnabled = true;
+		#end
+		#end
 		var classes = [
+			new TestReflect(),
 			new TestBytes(),
 			new TestInt32(),
 			new TestIO(),
@@ -168,14 +177,14 @@ class Test {
 			}
 			asyncWaits.remove(null);
 			checkDone();
-		} catch( e : Dynamic ) {
+		} catch( e : Int ) {
 			asyncWaits.remove(null);
-			reportInfos = null;
 			var msg = "???";
 			var stack = haxe.Stack.toString(haxe.Stack.exceptionStack());
 			try msg = Std.string(e) catch( e : Dynamic ) {};
 			reportCount = 0;
 			report("ABORTED : "+msg+" in "+Type.getClassName(current),here);
+			reportInfos = null;
 			trace("STACK :\n"+stack);
 		}
 	}

+ 142 - 0
tests/unit/TestReflect.hx

@@ -0,0 +1,142 @@
+package unit;
+import Type;
+
+class TestReflect extends Test {
+
+	static var TYPES = [
+		null,Int,String,Bool,Float,
+		Array,Hash,List,Date,Xml,Math,
+		unit.MyEnum,unit.MyClass,unit.MySubClass,
+		Class,Enum,Void,Dynamic,
+	];
+
+	static var TNAMES = [
+		"null","Int","String","Bool","Float",
+		"Array","Hash","List","Date","Xml","Math",
+		"unit.MyEnum","unit.MyClass","unit.MySubClass",
+		"Class","Enum","Void","Dynamic",
+	];
+
+	public function testTypes() {
+		for( i in 1...TYPES.length ) {
+			var t : Dynamic = TYPES[i];
+			var name = TNAMES[i];
+			infos("type "+name);
+			f( t == null );
+			if( name == "Enum" ) {
+				// neither an enum or a class
+			} else if( t == MyEnum || t == Void || t == Bool ) {
+				eq( Type.getEnumName(t), name );
+				eq( Type.resolveEnum(name), t );
+			} else {
+				eq( Type.getClassName(t), name );
+				eq( Type.resolveClass(name), t );
+			}
+		}
+		infos(null);
+		// we allow to have a common object class
+		allow( Class == Enum, [true,false] );
+		// these are very specific cases since we can't allow reflection on core type
+		unspec( function() Type.getEnumConstructs(Void) );
+		unspec( function() Type.getEnumConstructs(Bool) );
+	}
+
+	public function testIs() {
+		is(null,null);
+		is(0,Int,Float);
+		is(1,Int,Float);
+		is(-1,Int,Float);
+		is(1.2,Float);
+		is(Math.NaN,Float);
+		is(Math.POSITIVE_INFINITY,Float);
+		is(Math.NEGATIVE_INFINITY,Float);
+		is(true,Bool);
+		is(false,Bool);
+		is("Hello",String);
+		is("",String);
+		is([],Array);
+		is(new List(),List);
+		is(new Hash(),Hash);
+		is(new MyClass(0),MyClass);
+		is(new MySubClass(0),MyClass,MySubClass);
+		is(MyEnum.A,MyEnum);
+		is(MyEnum.C(0,""),MyEnum);
+		is(Date.now(),Date);
+		is({ x : 0 },null);
+		is(function() { },null);
+		is(MyClass,Class);
+		is(MyEnum,Enum);
+		is(Void,Enum);
+		is(Class,Class);
+		// it is allowed to have Class==Enum
+		if( Class == Enum ) is(Enum,Enum) else is(Enum,null);
+	}
+
+	function is( v : Dynamic, t1 : Dynamic, ?t2 : Dynamic, ?pos : haxe.PosInfos ){
+		for( i in 0...TYPES.length ) {
+			var c = TYPES[i];
+			infos(v+" is "+TNAMES[i]);
+			eq( Std.is(v,c), c != null && (c == t1 || c == t2) || (c == Dynamic), pos );
+		}
+		infos(null);
+		t( Std.is(v,Dynamic), pos );
+	}
+
+	public function testTypeof() {
+		typeof(null,TNull);
+		typeof(0,TInt);
+		typeof(1,TInt);
+		typeof(-1,TInt);
+		typeof(1.2,TFloat);
+		typeof(Math.NaN,TFloat);
+		typeof(Math.POSITIVE_INFINITY,TFloat);
+		typeof(Math.NEGATIVE_INFINITY,TFloat);
+		typeof(true,TBool);
+		typeof(false,TBool);
+		typeof("Hello",TClass(String));
+		typeof("",TClass(String));
+		typeof([],TClass(Array));
+		typeof(new List(),TClass(List));
+		typeof(new Hash(),TClass(Hash));
+		typeof(new MyClass(0),TClass(MyClass));
+		typeof(new MySubClass(0),TClass(MySubClass));
+		typeof(MyEnum.A,TEnum(MyEnum));
+		typeof(MyEnum.C(0,""),TEnum(MyEnum));
+		typeof(Date.now(),TClass(Date));
+		typeof({ x : 0 },TObject);
+		typeof(function() {},TFunction);
+		typeof(MyClass,TObject);
+		typeof(MyEnum,TObject);
+		typeof(Void,TObject);
+		#if !flash9
+		// on flash9, Type.typeof(Class) is crashing the player
+		typeof(Class,TObject);
+		typeof(Enum,TObject);
+		#end
+	}
+
+	function typeof( v : Dynamic, rt : ValueType, ?pos : haxe.PosInfos ) {
+		var vt = Type.typeof(v);
+		infos("typeof("+v+") = "+vt);
+		t( Type.enumEq(vt,rt), pos );
+	}
+
+	function testConv() {
+		eq( Std.chr(65), "A" );
+		eq( Std.ord("A"), 65 );
+		eq( Std.int(65), 65 );
+		eq( Std.int(65.456), 65 );
+		eq( Std.int(-65.456), -65 );
+		eq( Std.int(1.5), 1 );
+		eq( Std.int(-1.5), -1 );
+		eq( Std.int(1.7), 1 );
+		eq( Std.int(-1.7), -1 );
+		eq( Std.parseInt("65"), 65 );
+		eq( Std.parseInt("65.3"), 65 );
+		eq( Std.parseFloat("65"), 65.0 );
+		eq( Std.parseFloat("65.3"), 65.3 );
+		eq( Std.parseFloat("-1e10"), -1e10 );
+		eq( Std.parseInt("0xFF"), 255 );
+	}
+
+}

+ 12 - 0
tests/unit/TestRemoting.hx

@@ -16,6 +16,10 @@ class TestRemoting extends Test {
 	static var lcnx : haxe.remoting.LocalConnection;
 	static var fjscnx : haxe.remoting.FlashJsConnection;
 
+	static function staticMethod( a : Int, b : Int ) {
+		return a + b;
+	}
+
 	static function init() {
 		var ctx = RemotingApi.context();
 		#if flash
@@ -72,6 +76,14 @@ class TestRemoting extends Test {
 		async( doConnect, new Socket("haxeFlash8"), true );
 		async( doConnect, new Socket("haxeFlash9"), true );
 		#end
+
+		var actx = new haxe.remoting.ContextAll();
+		actx.addObject("fake",{ TestRemoting : TestRemoting },true);
+		eq( actx.call(["unit","TestRemoting","staticMethod"],[2,3]), 5 );
+		exc( function() actx.call(["unit2","TestRemoting","staticMethod"],[2,3]) );
+		exc( function() actx.call(["unit","TestRemoting2","staticMethod"],[2,3]) );
+		exc( function() actx.call(["unit","TestRemoting","staticMethod2"],[2,3]) );
+		eq( actx.call(["fake","TestRemoting","staticMethod"],[2,3]), 5 );
 	}
 
 	function doConnect( s : Socket, onResult : Bool -> Void ) {

+ 1 - 1
tests/unit/unit.html

@@ -18,7 +18,7 @@
 
 <p>JS :</p>
 
-<pre id="haxe:trace" style="{ background-color : white; height : 290px; width : 390px; padding : 5px; overflow : auto auto; }">
+<pre id="haxe:trace" style="{ background-color : white; height : 290px; width : 390px; padding : 5px; overflow : auto; }">
 </pre>
 
 </td>

+ 2 - 0
tests/unit/unit.hxp

@@ -7,12 +7,14 @@
   <files path="/">
     <file path="MyClass.hx" />
     <file path="MyEnum.hx" />
+    <file path="MySubClass.hx" />
     <file path="RemotingApi.hx" />
     <file path="RemotingServer.hx" />
     <file path="Test.hx" />
     <file path="TestBytes.hx" />
     <file path="TestInt32.hx" />
     <file path="TestIO.hx" />
+    <file path="TestReflect.hx" />
     <file path="TestRemoting.hx" />
     <file path="TestSerialize.hx" />
   </files>

+ 2 - 2
typer.ml

@@ -923,6 +923,8 @@ let unify_call_params ctx name el args p =
 				is_pos_infos (!f())
 			| TType ({ t_path = ["haxe"] , "PosInfos" },[]) ->
 				true
+			| TType (t,tl) ->
+				is_pos_infos (apply_params t.t_types tl t.t_type)
 			| _ ->
 				false
 		in
@@ -1439,8 +1441,6 @@ let rec type_binop ctx op e1 e2 p =
 			unify ctx e2.etype i e2.epos);
 		mk_op !result
 	| OpEq
-	| OpPhysEq
-	| OpPhysNotEq
 	| OpNotEq ->
 		(try
 			unify_raise ctx e1.etype e2.etype p