浏览代码

fixed Std.string({ toString : function() return foo }) on flash9/neko

Nicolas Cannasse 14 年之前
父节点
当前提交
6bb3d3bf6c
共有 3 个文件被更改,包括 17 次插入7 次删除
  1. 9 7
      genneko.ml
  2. 2 0
      std/flash9/Boot.hx
  3. 6 0
      tests/unit/TestMisc.hx

+ 9 - 7
genneko.ml

@@ -240,7 +240,9 @@ and gen_expr ctx e =
 	| TParenthesis e ->
 		(EParenthesis (gen_expr ctx e),p)
 	| TObjectDecl fl ->
-		(EObject (List.map (fun (f,e) -> f , gen_expr ctx e) fl),p)
+		let hasToString = ref false in
+		let fl = List.map (fun (f,e) -> if f = "toString" then hasToString := (match follow e.etype with TFun ([],_) -> true | _ -> false); f , gen_expr ctx e) fl in
+		(EObject (if !hasToString then ("__string",ident p "@default__string") :: fl else fl),p)
 	| TArrayDecl el ->
 		call p (field p (ident p "Array") "new1") [array p (List.map (gen_expr ctx) el); int p (List.length el)]
 	| TCall (e,el) ->
@@ -473,12 +475,7 @@ let gen_class ctx c =
 	let fstring = (try
 		let f = PMap.find "toString" c.cl_fields in
 		match follow f.cf_type with
-		| TFun ([],_) ->
-			["__string",(EFunction ([],(EBlock [
-				EVars ["@s",Some (call p (field p (this p) "toString") [])] ,p;
-				EIf ((EBinop ("!=",call p (builtin p "typeof") [ident p "@s"],builtin p "tobject"),p),(EReturn (Some (null p)),p),None),p;
-				EReturn (Some (field p (ident p "@s") "__s")),p;
-			],p)),p)]
+		| TFun ([],_) -> ["__string",ident p "@default__string"]
 		| _ -> []
 	with Not_found ->
 		[]
@@ -721,6 +718,11 @@ let header() =
 		"@serialize",func [] (call p (fields ["neko";"Boot";"__serialize"]) [this p]);
 		"@tag_serialize",func [] (call p (fields ["neko";"Boot";"__tagserialize"]) [this p]);
 		"@lazy_error",func ["e"] (call p (builtin p "varargs") [func ["_"] (call p (builtin p "throw") [ident p "e"])]);
+		"@default__string",func [] (EBlock [
+			EVars ["@s",Some (call p (field p (this p) "toString") [])] ,p;
+			EIf ((EBinop ("!=",call p (builtin p "typeof") [ident p "@s"],builtin p "tobject"),p),(EReturn (Some (null p)),p),None),p;
+			EReturn (Some (field p (ident p "@s") "__s")),p;
+		],p)
 	] in
 	let inits = inits @ List.map (fun nargs ->
 		let args = Array.to_list (Array.init nargs (fun i -> Printf.sprintf "%c" (char_of_int (int_of_char 'a' + i)))) in

+ 2 - 0
std/flash9/Boot.hx

@@ -155,6 +155,8 @@ class Boot extends flash.display.MovieClip {
 			var first = true;
 			for( i in 0...k.length ) {
 				var key = k[i];
+				if( key == "toString" )
+					try return v.toString() catch( e : Dynamic ) {}
 				if( first )
 					first = false;
 				else

+ 6 - 0
tests/unit/TestMisc.hx

@@ -312,6 +312,12 @@ class TestMisc extends Test {
 		eq(b.toString(), "-451.456nulltruefalseHello!laR");
 	}
 	
+	function testToString():Void
+	{
+		var x = { toString : function() return "foo" };
+		eq( Std.string(x), "foo" );
+	}
+	
 	#if !macro
 	function testFormat()
 	{