2
0
Эх сурвалжийг харах

fixed Array.reverse() in PHP
fixed php.Lib.getClasses()

Franco Ponticelli 17 жил өмнө
parent
commit
341c22223a

+ 2 - 1
doc/CHANGES.txt

@@ -41,7 +41,8 @@ TODO inlining : substitute class+function type parameters in order to have fully
 	Enum is no longer defined inside Type but is standalone class
 	Enum is no longer defined inside Type but is standalone class
 	fixed Date.getDay on Neko/Windows (use %w instead of %u)
 	fixed Date.getDay on Neko/Windows (use %w instead of %u)
 	fixed memory leak with PHP closures
 	fixed memory leak with PHP closures
-	fixed wrong scope in closures
+	fixed wrong scope in PHP closures
+	fixed Array.reverse() in PHP
 2008-07-28: 2.0
 2008-07-28: 2.0
 	fixed current package bug in inherited constructor type
 	fixed current package bug in inherited constructor type
 	delayed type-parameter constraints check (allow mutual rec extends for SPOD)
 	delayed type-parameter constraints check (allow mutual rec extends for SPOD)

+ 6 - 5
genphp.ml

@@ -565,7 +565,7 @@ and could_be_string_or_array_var s =
 and gen_uncertain_string_or_array_var ctx s e =
 and gen_uncertain_string_or_array_var ctx s e =
 	match s with
 	match s with
 	| "length" ->
 	| "length" ->
-		spr ctx "php_Boot::__len(";
+		spr ctx "_hx_len(";
 		gen_value ctx e;
 		gen_value ctx e;
 		spr ctx ")"
 		spr ctx ")"
 	| _ ->
 	| _ ->
@@ -712,7 +712,7 @@ and gen_array_call ctx s e el =
 		gen_value ctx e;
 		gen_value ctx e;
 		spr ctx ")"
 		spr ctx ")"
 	| "reverse" ->
 	| "reverse" ->
-		spr ctx "array_reverse(";
+		spr ctx "_hx_array_reverse(";
 		gen_value ctx e;
 		gen_value ctx e;
 		spr ctx ")"
 		spr ctx ")"
 	| "shift" ->
 	| "shift" ->
@@ -902,7 +902,7 @@ and gen_inline_function ctx f params p =
 	let old_t = ctx.local_types in
 	let old_t = ctx.local_types in
 	ctx.in_value <- Some "closure";
 	ctx.in_value <- Some "closure";
 	ctx.local_types <- List.map snd params @ ctx.local_types;
 	ctx.local_types <- List.map snd params @ ctx.local_types;
-	spr ctx "php_Boot::__closure(array(";
+	spr ctx "_hx_closure(array(";
 
 
 	let pq = escphp ctx.quotes in
 	let pq = escphp ctx.quotes in
 	let c = ref 0 in
 	let c = ref 0 in
@@ -1206,7 +1206,7 @@ and gen_expr ctx e =
 				let name = f.cf_name in
 				let name = f.cf_name in
 				match f.cf_expr with
 				match f.cf_expr with
 				| Some { eexpr = TFunction fd } ->
 				| Some { eexpr = TFunction fd } ->
-					print ctx "$this->%s = php_Boot::__closure(array(), $this, array(" name;
+					print ctx "$this->%s = _hx_closure(array(), $this, array(" name;
 					concat ctx "," (fun (arg,o,t) ->
 					concat ctx "," (fun (arg,o,t) ->
 						let arg = define_local ctx arg in
 						let arg = define_local ctx arg in
 						print ctx "'%s'" arg;
 						print ctx "'%s'" arg;
@@ -1342,7 +1342,8 @@ and gen_expr ctx e =
 		gen_value ctx (parent cond);
 		gen_value ctx (parent cond);
 		handle_break();
 		handle_break();
 	| TObjectDecl fields ->
 	| TObjectDecl fields ->
-		spr ctx "php_Boot::__anonymous(array(";
+(*TODO: optimization, call the constructor directly when fields is void *)
+		spr ctx "_hx_anonymous(array(";
 		let p = escphp ctx.quotes in
 		let p = escphp ctx.quotes in
 		concat ctx ", " (fun (f,e) -> print ctx "%s\"%s%s\" => " p f p; gen_value ctx e) fields;
 		concat ctx ", " (fun (f,e) -> print ctx "%s\"%s%s\" => " p f p; gen_value ctx e) fields;
 		spr ctx "))"
 		spr ctx "))"

+ 1 - 1
std/haxe/Log.hx

@@ -34,7 +34,7 @@ class Log {
 		#elseif js
 		#elseif js
 		untyped js.Boot.__trace(v,infos);
 		untyped js.Boot.__trace(v,infos);
 		#elseif php
 		#elseif php
-		untyped php.Boot.__trace(v,infos);
+		untyped __call__('_hx_trace', v,infos);
 		#end
 		#end
 	}
 	}
 
 

+ 126 - 123
std/php/Boot.hx

@@ -1,25 +1,6 @@
 package php;
 package php;
 
 
 class Boot {
 class Boot {
-	public static function __trace(v,i : haxe.PosInfos) {
-		var msg = if( i != null ) i.fileName+":"+i.lineNumber+": " else "";
-		untyped __call__("echo", msg+ __string_rec(v, '')+"\n"); // TODO: __unhtml
-	}
-
-	static public function __anonymous(?p : Dynamic) : Dynamic {
-		untyped __php__("$o = new _hx_anonymous();
-		if(is_array($p))
-			foreach($p as $k => $v)
-				$o->$k = $v;
-		return $o");
-	}
-
-	static private var __cid = 0;
-
-	static public function __closure(locals : ArrayAccess<Dynamic>, scope : Dynamic, params : Dynamic, body : String) : Void {
-		untyped __php__("return array(new _hx_lambda($locals, $scope, $params, $body), 'execute'.count($params))");
-	}
-
 	static public function __is_lambda(s : Dynamic) : Bool {
 	static public function __is_lambda(s : Dynamic) : Bool {
 		return untyped (__call__("is_string", s) && s.substr(0, 8) == __call__("chr", 0) + "lambda_") || (__call__("is_array", s) && __call__("count", s) > 0 && __call__("is_a", s[0], "php_Lambda"));
 		return untyped (__call__("is_string", s) && s.substr(0, 8) == __call__("chr", 0) + "lambda_") || (__call__("is_array", s) && __call__("count", s) > 0 && __call__("is_a", s[0], "php_Lambda"));
 	}
 	}
@@ -224,65 +205,65 @@ class Boot {
 				}
 				}
 			} else if(__call__("is_string", o)) {
 			} else if(__call__("is_string", o)) {
 				if(field == 'length')
 				if(field == 'length')
-					return php.Boot.__len(o);
+					return __call__("_hx_len",o);
 				else {
 				else {
 					switch(field) {
 					switch(field) {
 						case 'charAt':
 						case 'charAt':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('index'), 'return substr($o,$index,1);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('index'), 'return substr($o,$index,1);')");
 						case 'charCodeAt':
 						case 'charCodeAt':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('index'), 'return ord(substr($o, $index, 1));')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('index'), 'return ord(substr($o, $index, 1));')");
 						case 'indexOf':
 						case 'indexOf':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('value','startIndex'), 'return php_Boot::__index_of($o, $value, $startIndex);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('value','startIndex'), 'return php_Boot::__index_of($o, $value, $startIndex);')");
 						case 'lastIndexOf':
 						case 'lastIndexOf':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('value','startIndex'), 'return php_Boot::__last_index_of($o, $value, $startIndex);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('value','startIndex'), 'return php_Boot::__last_index_of($o, $value, $startIndex);')");
 						case 'split':
 						case 'split':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('delimiter'), 'return explode($delimiter, $o);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('delimiter'), 'return explode($delimiter, $o);')");
 						case 'substr':
 						case 'substr':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('pos','len'), 'return php_Boot::__substr($o, $pos, $len);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('pos','len'), 'return php_Boot::__substr($o, $pos, $len);')");
 						case 'toUpperCase':
 						case 'toUpperCase':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array(), 'return strtoupper($o);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array(), 'return strtoupper($o);')");
 						case 'toLowerCase':
 						case 'toLowerCase':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array(), 'return strtolower($o);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array(), 'return strtolower($o);')");
 						case 'toString':
 						case 'toString':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array(), 'return $o;')");
+							__php__("return _hx_closure(array('o' => &$o), null, array(), 'return $o;')");
 					}
 					}
 					return null;
 					return null;
 				}
 				}
 			} else if(__call__("is_array", o)) {
 			} else if(__call__("is_array", o)) {
 				if(field == 'length')
 				if(field == 'length')
-					return php.Boot.__len(o);
+					return __call__("_hx_len",o);
 				else
 				else
 					switch(field) {
 					switch(field) {
 						case 'concat':
 						case 'concat':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('a'), 'return array_merge($o, $a);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('a'), 'return array_merge($o, $a);')");
 						case 'join':
 						case 'join':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('sep'), 'return join($sep,$o);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('sep'), 'return join($sep,$o);')");
 						case 'pop':
 						case 'pop':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array(), 'return array_pop($o);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array(), 'return array_pop($o);')");
 						case 'push':
 						case 'push':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('x'), 'return array_push($o,$x);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('x'), 'return array_push($o,$x);')");
 						case 'reverse':
 						case 'reverse':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array(), 'return array_reverse($o);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array(), 'return  _hx_reverse($o);')");
 						case 'shift':
 						case 'shift':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array(), 'return array_shift($o);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array(), 'return array_shift($o);')");
 						case 'slice':
 						case 'slice':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('pos','end'), 'return php_Boot::__array_slice(array(&$o), $pos, $end);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('pos','end'), 'return php_Boot::__array_slice(array(&$o), $pos, $end);')");
 						case 'sort':
 						case 'sort':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('f'), 'return php_Boot::__array_sort($o,$f);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('f'), 'return php_Boot::__array_sort($o,$f);')");
 						case 'splice':
 						case 'splice':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('pos','len'), 'return php_Boot::__array_splice(array(&$o), $pos, $len);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('pos','len'), 'return php_Boot::__array_splice(array(&$o), $pos, $len);')");
 						case 'toString':
 						case 'toString':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array(), 'return \"[\".join(\", \", $o).\"]\";')");
+							__php__("return _hx_closure(array('o' => &$o), null, array(), 'return \"[\".join(\", \", $o).\"]\";')");
 						case 'unshift':
 						case 'unshift':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('x'), 'return array_unshift($o,$x);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('x'), 'return array_unshift($o,$x);')");
 						case 'insert':
 						case 'insert':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('pos','x'), 'return php_Boot::__array_insert(array(&$o), $pos, $x);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('pos','x'), 'return php_Boot::__array_insert(array(&$o), $pos, $x);')");
 						case 'remove':
 						case 'remove':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array('x'), 'return php_Boot::__array_remove(array(&$o), $x);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array('x'), 'return php_Boot::__array_remove(array(&$o), $x);')");
 						case 'iterator':
 						case 'iterator':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array(), 'return new _hx_array_iterator($o);')");
+							__php__("return _hx_closure(array('o' => &$o), null, array(), 'return new _hx_array_iterator($o);')");
 						case 'copy':
 						case 'copy':
-							__php__("return php_Boot::__closure(array('o' => &$o), null, array(), 'return $o;')");
+							__php__("return _hx_closure(array('o' => &$o), null, array(), 'return $o;')");
 					}
 					}
 				return null;
 				return null;
 			} else if(__php__("property_exists($o, $field)")) {
 			} else if(__php__("property_exists($o, $field)")) {
@@ -384,15 +365,107 @@ class Boot {
 		}
 		}
 	}
 	}
 
 
-	public static function __len(o : Dynamic) {
-		return untyped __php__("is_array($o) ? count($o) : (is_string($o) ? strlen($o) : $o->length)");
+	static public function __string_rec(o : Dynamic, s : String) {
+		if( o == null )
+			return "null";
+		if( s.length >= 5 )
+			return "<...>"; // too much deep recursion
+
+		if(untyped __call__("is_int", o) || __call__("is_float", o))
+			return o;
+
+		if(untyped __call__("is_bool", o))
+			return o ? "true" : "false";
+
+		if(untyped __call__("is_object", o)) {
+			var c = untyped __call__("get_class", o);
+			if(untyped __php__("$o instanceof Enum")) {
+				var b : String = o.tag;
+				if(!untyped __call__("empty", o.params)) {
+					s += "\t";
+					b += '(';
+					for( i in 0...untyped __call__("count", o.params) ) {
+						if(i > 0)
+							b += ', ' + __string_rec(o.params[i],s);
+						else
+							b += __string_rec(o.params[i],s);
+					}
+					b += ')';
+				}
+				return b;
+			} else if(untyped __php__("$o instanceof _hx_anonymous")) {
+				var rfl = untyped __php__("new ReflectionObject($o)");
+				var b = "{\n";
+				s += "\t";
+				var properties : Array<Dynamic> = rfl.getProperties();
+				for(prop in properties) {
+					var f : String = prop.getName();
+					if(b.length != 2)
+						b += ", \n";
+					b += s + f + " : " + __string_rec(prop.getValue(o), s);
+				}
+				s = s.substr(1);
+				b += "\n" + s + "}";
+				return b;
+			} else if(untyped __php__("$o instanceof _hx_type")) {
+				return untyped o.__qname__;
+			} else {
+				if(untyped __call__("is_callable", [o, "toString"]))
+					return untyped __php__("$o->toString()");
+				else if(untyped __call__("is_callable", [o, "__toString"]))
+					return o.__toString();
+				else
+					return "[" + __ttype(c) + "]";
+			}
+		}
+
+		if(untyped __call__("is_string", o)) {
+			if(__is_lambda(o)) return "«function»";
+			if(s.length > 0)
+				return '"'+untyped __call__("str_replace", '"', '\\"', o)+'"';
+			else
+				return o;
+		}
+
+		if(untyped __call__("is_array", o)) {
+			if(untyped __call__("is_callable", o)) return "«function»";
+			var str = "[";
+			s += "\t";
+			for( i in 0...untyped __call__("count", o) )
+				str += (if (i > 0) ", " else "")+__string_rec(untyped o[i],s);
+			str += "]";
+			return str;
+		}
+
+		return '';
 	}
 	}
+	static public var skip_constructor = false;
 
 
 	static function __init__() untyped {
 	static function __init__() untyped {
 		__php__("//error_reporting(0);
 		__php__("//error_reporting(0);
 set_error_handler(array('php_Boot', '__error_handler'), E_ALL);
 set_error_handler(array('php_Boot', '__error_handler'), E_ALL);
 set_exception_handler(array('php_Boot', '__exception_handler'));
 set_exception_handler(array('php_Boot', '__exception_handler'));
 
 
+function _hx_anonymous($p = array()) {
+	$o = new _hx_anonymous();
+	foreach($p as $k => $v)
+		$o->$k = $v;
+	return $o;
+}
+
+function _hx_trace($v, $i) {
+	$msg = $i !== null ? $i->fileName.':'.$i->lineNumber.': ' : '';
+	echo $msg.php_Boot::__string_rec($v, '').\"\n\";
+}
+
+function _hx_len($o) {
+	return is_array($o) ? count($o) : (is_string($o) ? strlen($o) : $o->length);
+}
+
+function _hx_array_reverse(&$a) {
+	$a = array_reverse($a, false);
+}
+
 class _hx_anonymous extends stdClass {
 class _hx_anonymous extends stdClass {
 	public function __call($m, $a) {
 	public function __call($m, $a) {
 		$v = $this->$m;
 		$v = $this->$m;
@@ -529,6 +602,11 @@ class HException extends Exception {
 	}
 	}
 }
 }
 
 
+// TODO: optimization, remove as much as possible the calls to this function
+function _hx_closure($locals, $scope, $params, $body) {
+	return array(new _hx_lambda($locals, $scope, $params, $body), 'execute'.count($params));
+}
+
 class _hx_lambda {
 class _hx_lambda {
 	public function __construct($locals, $scope, $args, $body) {
 	public function __construct($locals, $scope, $args, $body) {
 		$this->locals = $locals;
 		$this->locals = $locals;
@@ -706,82 +784,7 @@ function _hx_autoload($name) {
 	require_once php_Boot::$__tpaths[$name];
 	require_once php_Boot::$__tpaths[$name];
 	return true;
 	return true;
 }
 }
-spl_autoload_register('_hx_autoload')");
-	}
-
-	static public function __string_rec(o : Dynamic, s : String) {
-		if( o == null )
-			return "null";
-		if( s.length >= 5 )
-			return "<...>"; // too much deep recursion
-
-		if(untyped __call__("is_int", o) || __call__("is_float", o))
-			return o;
-
-		if(untyped __call__("is_bool", o))
-			return o ? "true" : "false";
-
-		if(untyped __call__("is_object", o)) {
-			var c = untyped __call__("get_class", o);
-			if(untyped __php__("$o instanceof Enum")) {
-				var b : String = o.tag;
-				if(!untyped __call__("empty", o.params)) {
-					s += "\t";
-					b += '(';
-					for( i in 0...untyped __call__("count", o.params) ) {
-						if(i > 0)
-							b += ', ' + __string_rec(o.params[i],s);
-						else
-							b += __string_rec(o.params[i],s);
-					}
-					b += ')';
-				}
-				return b;
-			} else if(untyped __php__("$o instanceof _hx_anonymous")) {
-				var rfl = untyped __php__("new ReflectionObject($o)");
-				var b = "{\n";
-				s += "\t";
-				var properties : Array<Dynamic> = rfl.getProperties();
-				for(prop in properties) {
-					var f : String = prop.getName();
-					if(b.length != 2)
-						b += ", \n";
-					b += s + f + " : " + __string_rec(prop.getValue(o), s);
-				}
-				s = s.substr(1);
-				b += "\n" + s + "}";
-				return b;
-			} else if(untyped __php__("$o instanceof _hx_type")) {
-				return untyped o.__qname__;
-			} else {
-				if(untyped __call__("is_callable", [o, "toString"]))
-					return untyped __php__("$o->toString()");
-				else if(untyped __call__("is_callable", [o, "__toString"]))
-					return o.__toString();
-				else
-					return "[" + __ttype(c) + "]";
-			}
-		}
 
 
-		if(untyped __call__("is_string", o)) {
-			if(__is_lambda(o)) return "«function»";
-			if(s.length > 0)
-				return '"'+untyped __call__("str_replace", '"', '\\"', o)+'"';
-			else
-				return o;
-		}
-
-		if(untyped __call__("is_array", o)) {
-			if(untyped __call__("is_callable", o)) return "«function»";
-			var str = "[";
-			s += "\t";
-			for( i in 0...untyped __call__("count", o) )
-				str += (if (i > 0) ", " else "")+__string_rec(untyped o[i],s);
-			str += "]";
-			return str;
-		}
-
-		return '';
+spl_autoload_register('_hx_autoload')");
 	}
 	}
-	static public var skip_constructor = false;
 }
 }

+ 1 - 1
std/php/Lib.hx

@@ -74,7 +74,7 @@ class Lib {
 		if(path.length == 0)
 		if(path.length == 0)
 			untyped __php__("$o->$name = $t");
 			untyped __php__("$o->$name = $t");
 		else {
 		else {
-			var so = {};
+			var so = untyped __call__("isset", __php__("$o->$name")) ? __php__("$o->$name") : {};
 			appendType(so, path, t);
 			appendType(so, path, t);
 			untyped __php__("$o->$name = $so");
 			untyped __php__("$o->$name = $so");
 		}
 		}

+ 1 - 1
std/php/Session.hx

@@ -96,7 +96,7 @@ class Session {
 	}
 	}
 	
 	
 	public static function getCookieParams() : { lifetime : Int, path : String, domain : String, secure : Bool, httponly : Bool} {
 	public static function getCookieParams() : { lifetime : Int, path : String, domain : String, secure : Bool, httponly : Bool} {
-		return php.Boot.__anonymous(untyped __call__("session_get_cookie_params"));
+		return untyped __call__("_hx_anonymous", untyped __call__("session_get_cookie_params"));
 	}
 	}
 	
 	
 	// TODO: completely untested
 	// TODO: completely untested

+ 1 - 1
std/php/db/Sqlite.hx

@@ -136,7 +136,7 @@ private class SqliteResultSet implements ResultSet {
 		var c = untyped __call__("sqlite_fetch_array", r, __php__("SQLITE_BOTH"));
 		var c = untyped __call__("sqlite_fetch_array", r, __php__("SQLITE_BOTH"));
 		if(untyped __physeq__(c, false))
 		if(untyped __physeq__(c, false))
 			return null;
 			return null;
-		return php.Boot.__anonymous(c);
+		return untyped __call__("_hx_anonymous", c);
 	}
 	}
 
 
 	public function results() : List<Dynamic> {
 	public function results() : List<Dynamic> {