Bläddra i källkod

removed String.cca (replaced by StringTools.fastCodeAt + StringTools.isEOF)

Nicolas Cannasse 14 år sedan
förälder
incheckning
88037a099d

+ 9 - 3
genswf9.ml

@@ -281,7 +281,7 @@ let property ctx p t =
 		(match p with
 		| "length" (* Int in AS3/haXe *) -> ident p, None, false
 		| "charCodeAt" (* use haXe version *) -> ident p, None, true
-		| "cca" -> as3 "charCodeAt", Some KInt, false
+		| "cca" -> as3 "charCodeAt", None, false
 		| _ -> as3 p, None, false);
 	| TAnon a ->
 		(match !(a.a_status) with
@@ -1751,9 +1751,15 @@ let generate_class_init ctx c hc =
 	write ctx (HInitProp (type_path ctx c.cl_path));
 	(match c.cl_init with
 	| None -> ()
-	| Some e -> gen_expr ctx false e);
+	| Some e ->
+		gen_expr ctx false e;
+		if ctx.block_vars <> [] then error "You can't have a local variable referenced from a closure inside __init__ (FP 10.1.53 crash)" e.epos;
+	);
 	generate_class_statics ctx c true;
-	if ctx.swc then generate_class_statics ctx c false
+	if ctx.swc then begin
+		generate_class_statics ctx c false;
+		if ctx.block_vars <> [] then error "You can't have a local variable referenced from a closure inside a static (FP 10.1.53 crash)" c.cl_pos;
+	end
 
 let generate_enum_init ctx e hc meta =
 	let path = ([],"Object") in

+ 0 - 4
std/String.hx

@@ -91,8 +91,4 @@ extern class String {
 
 	static function fromCharCode( code : Int ) : String;
 
-	#if !neko
-	private function cca( pos : Int ) : Int;
-	#end
-
 }

+ 31 - 0
std/StringTools.hx

@@ -246,6 +246,37 @@ class StringTools {
 		return s;
 	}
 
+	/**
+		Provides a fast native string charCodeAt access. Since the EOF value might vary depending on the platforms, always test with StringTools.isEOF.
+		Only guaranteed to work if index in [0,s.length] range. Might not work with strings containing \0 char.
+	**/
+	public static inline function fastCodeAt( s : String, index : Int ) : Int untyped {
+		#if neko
+		return untyped __dollar__sget(s.__s, index);
+		#elseif cpp
+		return (s == null) ? 0 : s.cca(index);
+		#else
+		return s.cca(index);
+		#end
+	}
+
+	/*
+		Only to use together with fastCodeAt.
+	*/
+	public static inline function isEOF( c : Int ) : Bool {
+		#if (flash9 || cpp)
+		return c == 0;
+		#elseif flash8
+		return c <= 0; // fast NaN
+		#elseif js
+		return c != c; // fast NaN
+		#elseif neko
+		return c == null;
+		#else
+		return false;
+		#end
+	}
+
 	#if neko
 	private static var _urlEncode = neko.Lib.load("std","url_encode",1);
 	private static var _urlDecode = neko.Lib.load("std","url_decode",1);

+ 1 - 1
std/flash/Boot.hx

@@ -254,7 +254,7 @@ package flash;
 			var cca = String.prototype["charCodeAt"];
 			String.prototype["cca"] = cca;
 			String.prototype["charCodeAt"] = function(i) {
-				var x = cca["call"](this,i);
+				var x = this["cca"](i);
 				if( x <= 0 ) // fast NaN
 					return null;
 				return x;

+ 6 - 6
std/flash9/Boot.hx

@@ -25,7 +25,7 @@
 package flash;
 
 #if !as3
-@:keep private class RealBoot extends Boot {
+@:keep private class RealBoot extends Boot, implements Dynamic {
 	#if swc
 	public function new() {
 		super();
@@ -44,7 +44,7 @@ package flash;
 }
 #end
 
-@:keep class Boot extends flash.display.MovieClip, implements Dynamic {
+@:keep class Boot extends flash.display.MovieClip {
 
 	static var tf : flash.text.TextField;
 	static var lines : Array<String>;
@@ -223,12 +223,12 @@ package flash;
 		aproto.setPropertyIsEnumerable("insert", false);
 		aproto.setPropertyIsEnumerable("remove", false);
 		aproto.setPropertyIsEnumerable("iterator", false);
-		var cca = String.prototype.charCodeAt;
-		String.prototype.charCodeAt = function(i) {
-			var x = cca.call(this,i);
+		String.prototype.charCodeAt = function(i) : Null<Int> {
+			var s : String = this;
+			var x : Float = s.cca(i);
 			if( __global__["isNaN"](x) )
 				return null;
-			return x;
+			return Std.int(x);
 		};
 	}
 

+ 10 - 23
std/haxe/Unserializer.hx

@@ -46,7 +46,7 @@ class Unserializer {
 				new Array();
 			#end
 		for( i in 0...BASE64.length )
-			codes[untyped BASE64.cca(i)] = i;
+			codes[StringTools.fastCodeAt(BASE64,i)] = i;
 		return codes;
 	}
 	#end
@@ -88,13 +88,7 @@ class Unserializer {
 	}
 
 	inline function get(p) : Int {
-		#if (flash || js)
-		return untyped buf.cca(p);
-		#elseif neko
-		return untyped __dollar__sget(buf.__s,p);
-		#else
-		return buf.charCodeAt(p);
-		#end
+		return StringTools.fastCodeAt(buf, p);
 	}
 
  	function readDigits() {
@@ -103,15 +97,8 @@ class Unserializer {
  		var fpos = pos;
  		while( true ) {
  			var c = get(pos);
-			#if flash9
-			// if flash9, it returns 0 so we will break later
-			#elseif (flash || js)
-			if( Math.isNaN(c) )
+			if( StringTools.isEOF(c) )
 				break;
-			#else
- 			if( c == null )
- 				break;
-			#end
  			if( c == "-".code ) {
  				if( pos != fpos )
  					break;
@@ -320,20 +307,20 @@ class Unserializer {
 			var bytes = haxe.io.Bytes.alloc(size);
 			var bpos = 0;
 			while( i < max ) {
-				var c1 = codes[untyped buf.cca(i++)];
-				var c2 = codes[untyped buf.cca(i++)];
+				var c1 = codes[StringTools.fastCodeAt(buf,i++)];
+				var c2 = codes[StringTools.fastCodeAt(buf,i++)];
 				bytes.set(bpos++,(c1 << 2) | (c2 >> 4));
-				var c3 = codes[untyped buf.cca(i++)];
+				var c3 = codes[StringTools.fastCodeAt(buf,i++)];
 				bytes.set(bpos++,(c2 << 4) | (c3 >> 2));
-				var c4 = codes[untyped buf.cca(i++)];
+				var c4 = codes[StringTools.fastCodeAt(buf,i++)];
 				bytes.set(bpos++,(c3 << 6) | c4);
 			}
 			if( rest >= 2 ) {
-				var c1 = codes[untyped buf.cca(i++)];
-				var c2 = codes[untyped buf.cca(i++)];
+				var c1 = codes[StringTools.fastCodeAt(buf,i++)];
+				var c2 = codes[StringTools.fastCodeAt(buf,i++)];
 				bytes.set(bpos++,(c1 << 2) | (c2 >> 4));
 				if( rest == 3 ) {
-					var c3 = codes[untyped buf.cca(i++)];
+					var c3 = codes[StringTools.fastCodeAt(buf,i++)];
 					bytes.set(bpos++,(c2 << 4) | (c3 >> 2));
 				}
 			}

+ 1 - 1
std/haxe/io/Bytes.hx

@@ -254,7 +254,7 @@ class Bytes {
 		var a = new Array();
 		// utf8-decode
 		for( i in 0...s.length ) {
-			var c : Int = untyped s["cca"](i);
+			var c : Int = StringTools.fastCodeAt(s,i);
 			if( c <= 0x7F )
 				a.push(c);
 			else if( c <= 0x7FF ) {

+ 3 - 4
std/js/Boot.hx

@@ -234,11 +234,10 @@ package js;
 					}
 				}
 			};
-			var cca = String.prototype.charCodeAt;
-			String.prototype.cca = cca;
+			String.prototype.cca = String.prototype.charCodeAt;
 			String.prototype.charCodeAt = function(i) {
-				var x = cca.call(this,i);
-				if( isNaN(x) )
+				var x = this.cca(i);
+				if( x != x ) // fast isNaN
 					return null;
 				return x;
 			};

+ 9 - 0
std/php/_std/StringTools.hx

@@ -86,4 +86,13 @@
 			s = lpad(s, '0', digits);
 		return s.toUpperCase();
 	}
+
+	public static inline function fastCodeAt( s : String, index : Int ) : Int {
+		return s.charCodeAt(index);
+	}
+
+	public static inline function isEOF( c : Int ) : Bool {
+		return c == null;
+	}
+
 }

+ 18 - 0
tests/unit/TestBasetypes.hx

@@ -44,6 +44,13 @@ class TestBasetypes extends Test {
 		eq( abc[0], "a" );
 		eq( abc[1], "b" );
 		eq( abc[2], "c" );
+		
+		var str = "abc";
+		eq( str.charCodeAt(0), "a".code );
+		eq( str.charCodeAt(1), "b".code );
+		eq( str.charCodeAt(2), "c".code );
+		eq( str.charCodeAt(-1), null );
+		eq( str.charCodeAt(3), null );
 	}
 
 	function testMath() {
@@ -120,5 +127,16 @@ class TestBasetypes extends Test {
 		eq( StringTools.hex(-1,8), "FFFFFFFF" );
 		eq( StringTools.hex(-481400000,8), "E34E6B40" );
 	}
+	
+	function testCCA() {
+		var str = "abc";
+		eq( StringTools.fastCodeAt(str, 0), "a".code );
+		eq( StringTools.fastCodeAt(str, 1), "b".code );
+		eq( StringTools.fastCodeAt(str, 2), "c".code );
+		f( StringTools.isEOF(StringTools.fastCodeAt(str, 2)) );
+		t( StringTools.isEOF(StringTools.fastCodeAt(str, 3)) );
+		
+		t( StringTools.isEOF(StringTools.fastCodeAt("", 0)) );
+	}
 
 }