Browse Source

[js] also check typeof(o) == "number" for Std.is(o, Int)

closes #4962
kaikoga 9 years ago
parent
commit
8b95f8fcc8
3 changed files with 19 additions and 3 deletions
  1. 3 2
      src/optimization/optimizer.ml
  2. 1 1
      std/js/Boot.hx
  3. 15 0
      tests/unit/src/unit/issues/Issue4962.hx

+ 3 - 2
src/optimization/optimizer.ml

@@ -179,10 +179,11 @@ let api_inline ctx c field params p = match c.cl_path, field, params with
 		| TTypeExpr (TAbstractDecl ({ a_path = [],"Bool" })) -> Some (typeof "boolean")
 		| TTypeExpr (TAbstractDecl ({ a_path = [],"Float" })) -> Some (typeof "number")
 		| TTypeExpr (TAbstractDecl ({ a_path = [],"Int" })) when is_trivial o ->
-			(* generate (o|0) === o check *)
+			(* generate typeof(o) == "number" && (o|0) === o check *)
 			let teq = mk_local ctx "__strict_eq__" (tfun [tint; tint] tbool) p in
 			let lhs = mk (TBinop (Ast.OpOr, o, mk (TConst (TInt Int32.zero)) tint p)) tint p in
-			Some (mk (TCall (teq, [lhs; o])) tbool p)
+			let jscheck = mk (TCall (teq, [lhs; o])) tbool p in
+			Some(mk (TBinop (Ast.OpBoolAnd, typeof "number", jscheck)) tbool p)
 		| TTypeExpr (TClassDecl ({ cl_path = [],"Array" })) ->
 			(* generate (o instanceof Array) && o.__enum__ == null check *)
 			let iof = mk_local ctx "__instanceof__" (tfun [o.etype;t.etype] tbool) p in

+ 1 - 1
std/js/Boot.hx

@@ -191,7 +191,7 @@ class Boot {
 			return false;
 		switch( cl ) {
 		case Int:
-			return (untyped __js__("(o|0) === o"));
+			return (untyped __js__("typeof"))(o) == "number" && untyped __js__("(o|0) === o");
 		case Float:
 			return (untyped __js__("typeof"))(o) == "number";
 		case Bool:

+ 15 - 0
tests/unit/src/unit/issues/Issue4962.hx

@@ -0,0 +1,15 @@
+package unit.issues;
+
+private class C {
+	public function new() { }
+	@:keep function toString() return toString();
+}
+
+class Issue4962 extends Test {
+	function test() {
+		var int:Dynamic = Int;
+		f(Std.is(new C(), int));
+
+		f(Std.is(new C(), Int));
+	}
+}