Browse Source

wrapped arrays into objects (haXe/PHP)
several bugs fixed

Franco Ponticelli 17 years ago
parent
commit
d6517a977a

+ 5 - 7
doc/CHANGES.txt

@@ -1,3 +1,7 @@
+xxxx-xx-xx: 2.02 CVS
+	Std.is(MyInterface, Class) now returns true (haXe/PHP)
+	php arrays are wrapped into _hx_array instances, fixes issues with references (array cast, access out of bounds ...)
+
 2008-10-04: 2.01
 	fixed php.Sys
 	added neko.NativeString and neko.NativeArray
@@ -41,18 +45,12 @@
 	fixed binary resources for Flash, JS and PHP outputs
 	fixed compiler bug with inline + optional arguments
 	fixed Type.createInstance and createEmptyInstance with Array for flash6-8
-	added "c".code for compiletime UTF8 charcodes
-	completed flash10 support
-	fixed ~64K resource limit for SWF8
-	fixed double-evaluations for array and field acesses with binary and unary ops
-	fixed bug when using protected AS3 classes in swf-lib
-	using -lib also define the conditional variable
 
 2008-07-28: 2.0
 	fixed current package bug in inherited constructor type
 	delayed type-parameter constraints check (allow mutual rec extends for SPOD)
 	improved unclosed macro error reporting
-	haxe/PHP integration
+	haXe/PHP integration
 	renamed NekoSocketConnection to SyncSocketConnection (php support)
 	fixes in genAs3
 	fix for flash9 : always coerce call return type

+ 101 - 243
genphp.ml

@@ -136,27 +136,6 @@ let rec is_unknown_type t =
 
 let is_unknown_expr e =	is_unknown_type e.etype
 
-let rec is_array_type t =
-	match follow t with
-	| TInst ({cl_path = ([], "Array")}, _) -> true
-	| TAnon a ->
-	   (match !(a.a_status) with
-	   | Statics ({cl_path = ([], "Array")}) -> true
-	   | _ -> false)
-	| _ -> false
-
-let is_array_expr e =  is_array_type e.etype
-
-
-let rec is_array_ref e =
-	match e.eexpr with
-	| TNew (c,_,_) when c.cl_path = ([], "Array") -> false
-	| TArrayDecl _
-	| TIf (_,_,_)
-	| TConst _ -> false
-	| TParenthesis e -> is_array_ref e
-	| _ -> is_array_expr e
-
 let rec is_string_type t =
 	match follow t with
 	| TInst ({cl_path = ([], "String")}, _) -> true
@@ -395,7 +374,7 @@ let gen_constant ctx p = function
 	| TSuper -> spr ctx "ERROR /* unexpected call to super in gen_constant */"
 
 let s_funarg ctx arg t p c =
-	let byref = if is_array_type t || (String.length arg > 7 && String.sub arg 0 7 = "byref__") then "&" else "" in
+	let byref = if (String.length arg > 7 && String.sub arg 0 7 = "byref__") then "&" else "" in
 	(match t with
 	| TInst (cl,_) ->
 		(match cl.cl_path with
@@ -456,7 +435,7 @@ let gen_function_header ctx name f params p =
 		) f.tf_args;
 		print ctx "', '') "
 	| Some n ->
-		let byref = if is_array_expr f.tf_expr || (String.length n > 9 && String.sub n 0 9 = "__byref__") then "&" else "" in
+		let byref = if (String.length n > 9 && String.sub n 0 9 = "__byref__") then "&" else "" in
 		print ctx "function %s%s(" byref n;
 		concat ctx ", " (fun (arg,o,t) ->
 		let arg = define_local ctx arg in
@@ -472,15 +451,24 @@ let gen_function_header ctx name f params p =
 
 let s_escape_php_vars ctx code =
 	String.concat ((escphp ctx.quotes) ^ "$") (ExtString.String.nsplit code "$")
-	
-let rec gen_call ctx e el =
+
+let rec gen_array_args ctx lst =
+	match lst with
+	| [] -> ()
+	| h :: t ->
+		spr ctx "[";
+		gen_value ctx h;
+		spr ctx "]";				
+		gen_array_args ctx t
+		
+and gen_call ctx e el =
 	match e.eexpr , el with
 	| TConst TSuper , params ->
 		(match ctx.curclass.cl_super with
 		| None -> assert false
 		| Some (c,_) ->
 			spr ctx "parent::__construct(";
-			concat ctx "," (gen_call_value ctx) params;
+			concat ctx "," (gen_value ctx) params;
 			spr ctx ")";
 		);
 	| TField ({ eexpr = TConst TSuper },name) , params ->
@@ -488,35 +476,50 @@ let rec gen_call ctx e el =
 		| None -> assert false
 		| Some (c,_) ->
 			print ctx "parent::%s(" (name);
-			concat ctx "," (gen_call_value ctx) params;
+			concat ctx "," (gen_value ctx) params;
 			spr ctx ")";
 		);
-	| TLocal "__set__" , { eexpr = TConst (TString code) } :: [] ->
-		unsupported e.epos;
-	| TLocal "__set__" , { eexpr = TConst (TString code) } :: [el] ->
-		print ctx "%s$%s = " (escphp ctx.quotes) code;
-		gen_value ctx el;
 	| TLocal "__set__" , { eexpr = TConst (TString code) } :: el ->
 		let rec genargs lst =
 			(match lst with
 			| [] -> ()
-			| h :: [t] ->
+			| h :: [] ->
+				spr ctx " = ";
 				gen_value ctx h;
-				spr ctx "] = ";
-				gen_value ctx t
 			| h :: t ->
+				spr ctx "[";
 				gen_value ctx h;
-				spr ctx "][";
+				spr ctx "]";
 				genargs t)
 		in
-		print ctx "%s$%s[" (escphp ctx.quotes) code;
-		genargs el;
-	| TLocal "__var__" , { eexpr = TConst (TString code) } :: [] ->
 		print ctx "%s$%s" (escphp ctx.quotes) code;
+		genargs el;
+	| TLocal "__set__" , e :: el ->
+		let rec genargs lst =
+			(match lst with
+			| [] -> ()
+			| h :: [] ->
+				spr ctx " = ";
+				gen_value ctx h;
+			| h :: t ->
+				spr ctx "[";
+				gen_value ctx h;
+				spr ctx "]";
+				genargs t)
+		in
+		gen_value ctx e;
+		genargs el;
+	| TLocal "__field__" , e :: (f :: el) ->
+		gen_value ctx e;
+		spr ctx "->";
+		gen_value ctx f;
+		gen_array_args ctx el;
 	| TLocal "__var__" , { eexpr = TConst (TString code) } :: el ->
-		print ctx "%s$%s[" (escphp ctx.quotes) code;
-		concat ctx "][" (gen_value ctx) el;
-		spr ctx "]";
+		print ctx "%s$%s" (escphp ctx.quotes) code;
+		gen_array_args ctx el;
+	| TLocal "__var__" , e :: el ->
+		gen_value ctx e;
+		gen_array_args ctx el;
 	| TLocal "__call__" , { eexpr = TConst (TString code) } :: el ->
 		spr ctx code;
 		spr ctx "(";
@@ -535,7 +538,7 @@ let rec gen_call ctx e el =
 		gen_value ctx e;
 		ctx.is_call <- false;
 		spr ctx ", array(";
-		concat ctx ", " (gen_call_ref ctx) el;
+		concat ctx ", " (gen_value ctx) el;
 		spr ctx "))"
 	| TCall (x,_), el when (match x.eexpr with | TLocal _ -> false | _ -> true) ->
 		ctx.is_call <- true;
@@ -543,29 +546,20 @@ let rec gen_call ctx e el =
 		gen_value ctx e;
 		ctx.is_call <- false;
 		spr ctx ", array(";
-		concat ctx ", " (gen_call_ref ctx) el;
+		concat ctx ", " (gen_value ctx) el;
 		spr ctx "))"
 	| _ ->
 		ctx.is_call <- true;
 		gen_value ctx e;
 		ctx.is_call <- false;
 		spr ctx "(";
-		concat ctx ", " (gen_call_value ctx) el;
+		concat ctx ", " (gen_value ctx) el;
 		spr ctx ")";
 
-and gen_call_value ctx e =
-	match e.eexpr with
-	| TConst TNull -> spr ctx "_hx_null()";
-	| _ -> gen_value ctx e
-
-and gen_call_ref ctx e =
-	if is_array_ref e then spr ctx "&";
-	gen_call_value ctx e
-
-and could_be_string_or_array_var s =
+and could_be_string_var s =
 	s = "length"
 
-and gen_uncertain_string_or_array_var ctx s e =
+and gen_uncertain_string_var ctx s e =
 	match s with
 	| "length" ->
 		spr ctx "_hx_len(";
@@ -600,12 +594,9 @@ and gen_string_static_call ctx s e el =
 		spr ctx ")";
 	| _ -> unsupported e.epos;
 
-and could_be_string_or_array_call s =
-	s = "toString"
-
 and could_be_string_call s =
 	s = "substr" || s = "charAt" || s = "charCodeAt" || s = "indexOf" ||
-	s = "lastIndexOf" || s = "split" || s = "toLowerCase" || s = "toUpperCase"
+	s = "lastIndexOf" || s = "split" || s = "toLowerCase" || s = "toString" || s = "toUpperCase"
 
 and gen_string_call ctx s e el =
 	match s with
@@ -646,7 +637,7 @@ and gen_string_call ctx s e el =
 		concat ctx ", " (gen_value ctx) el;
 		spr ctx ")"
 	| "split" ->
-		spr ctx "explode(";
+		spr ctx "_hx_explode(";
 		concat ctx ", " (gen_value ctx) el;
 		spr ctx ", ";
 		gen_value ctx e;
@@ -664,16 +655,6 @@ and gen_string_call ctx s e el =
 	| _ ->
 		unsupported e.epos;
 
-and could_be_array_call s =
-	s = "push" || s = "concat" || s = "join" || s = "pop" || s = "reverse" ||
-	s = "shift" || s = "slice" || s = "sort" || s = "splice" ||
-	s = "copy" || s = "unshift" || s = "insert" || s = "remove" || s = "iterator"
-
-and gen_uncertain_string_or_array_call ctx s e el =
-	spr ctx "_hx_string_rec(";
-	gen_value ctx e;
-	print ctx ", null)"
-
 and gen_uncertain_string_call ctx s e el =
 	let p = escphp ctx.quotes in
 	spr ctx "_hx_string_call(";
@@ -682,97 +663,6 @@ and gen_uncertain_string_call ctx s e el =
 	concat ctx ", " (gen_value ctx) el;
 	spr ctx "))"
 
-and gen_uncertain_array_call ctx s e el =
-	let p = escphp ctx.quotes in
-	spr ctx "_hx_array_call(";
-	gen_value ctx e;
-	print ctx ", %s\"%s%s\", array(" p s p;
-	concat ctx ", " (gen_value ctx) el;
-	spr ctx "))"
-
-and gen_array_call ctx s e el =
-	match s with
-	| "push" ->
-		spr ctx "array_push(";
-		gen_value ctx e;
-		spr ctx ", ";
-		concat ctx ", " (gen_value ctx) el;
-		spr ctx ")"
-	| "concat" ->
-		spr ctx "array_merge(";
-		gen_value ctx e;
-		spr ctx ", ";
-		concat ctx ", " (gen_value ctx) el;
-		spr ctx ")"
-	| "join" ->
-		spr ctx "join(";
-		concat ctx ", " (gen_value ctx) el;
-		spr ctx ", ";
-		gen_value ctx e;
-		spr ctx ")"
-	| "pop" ->
-		spr ctx "array_pop(";
-		gen_value ctx e;
-		spr ctx ")"
-	| "reverse" ->
-		spr ctx "_hx_array_reverse(";
-		gen_value ctx e;
-		spr ctx ")"
-	| "shift" ->
-		spr ctx "array_shift(";
-		gen_value ctx e;
-		spr ctx ")"
-	| "slice" ->
-		spr ctx "_hx_array_slice(";
-		gen_value ctx e;
-		spr ctx ", ";
-		concat ctx ", " (gen_value ctx) el;
-		spr ctx ")"
-	| "sort" ->
-		spr ctx "_hx_array_sort(";
-		gen_value ctx e;
-		spr ctx ", ";
-		concat ctx ", " (gen_value ctx) el;
-		spr ctx ")"
-	| "splice" ->
-		spr ctx "_hx_array_splice(";
-		gen_value ctx e;
-		spr ctx ", ";
-		concat ctx ", " (gen_value ctx) el;
-		spr ctx ")"
-	| "toString" ->
-		spr ctx "'['.join(', ', ";
-		gen_value ctx e;
-		spr ctx ").']'"
-	| "copy" ->
-		spr ctx "_hx_array_copy(";
-		gen_value ctx e;
-		spr ctx ")"
-	| "unshift" ->
-		spr ctx "array_unshift(";
-		gen_value ctx e;
-		spr ctx ", ";
-		concat ctx ", " (gen_value ctx) el;
-		spr ctx ")"
-	| "insert" ->
-		spr ctx "_hx_array_insert(";
-		gen_value ctx e;
-		spr ctx ", ";
-		concat ctx ", " (gen_value ctx) el;
-		spr ctx ")"
-	| "remove" ->
-		spr ctx "_hx_array_remove(";
-		gen_value ctx e;
-		spr ctx ", ";
-		concat ctx ", " (gen_value ctx) el;
-		spr ctx ")"
-	| "iterator" ->
-		spr ctx "new _hx_array_iterator(";
-		gen_value ctx e;
-		spr ctx ")"
-	| _ ->
-		unsupported e.epos;
-
 and gen_field_op ctx e =
 	match e.eexpr with
 	| TField (f,s) ->
@@ -818,7 +708,7 @@ and gen_field_access ctx isvar e s =
 		gen_expr ctx e;
 		print ctx "->%s" (s_ident s)
 	| TArray (e1,e2) ->
-		spr ctx "_hx_array_get_ref(";
+		spr ctx "_hx_array_get(";
 		gen_value ctx e1;
 		spr ctx ", ";
 		gen_value ctx e2;
@@ -826,6 +716,8 @@ and gen_field_access ctx isvar e s =
 		gen_member_access ctx isvar e s
 	| TBlock _
 	| TParenthesis _
+	| TObjectDecl _
+	| TArrayDecl _
 	| TNew _ ->
 		spr ctx "_hx_deref(";
 		ctx.is_call <- true;
@@ -844,7 +736,7 @@ and gen_dynamic_function ctx isstatic name f params p =
 	let old_t = ctx.local_types in
 	ctx.in_value <- None;
 	ctx.local_types <- List.map snd params @ ctx.local_types;
-	let byref = if is_array_expr f.tf_expr || (String.length name > 9 && String.sub name 0 9 = "__byref__") then "&" else "" in
+	let byref = if (String.length name > 9 && String.sub name 0 9 = "__byref__") then "&" else "" in
 	print ctx "function %s%s(" byref name;
 	concat ctx ", " (fun (arg,o,t) ->
 	let arg = define_local ctx arg in
@@ -858,7 +750,6 @@ and gen_dynamic_function ctx isstatic name f params p =
 		else
 			print ctx " return call_user_func_array($this->%s, array("  name;
 		concat ctx ", " (fun (arg,o,t) ->
-			if is_array_type t then spr ctx "&";
 			spr ctx ((escphp ctx.quotes) ^ "$" ^ arg)
 		) f.tf_args;
 		print ctx ")); }";
@@ -884,7 +775,7 @@ and gen_function ctx name f params p =
 	let old_t = ctx.local_types in
 	ctx.in_value <- None;
 	ctx.local_types <- List.map snd params @ ctx.local_types;
-	let byref = if is_array_type f.tf_type || (String.length name > 9 && String.sub name 0 9 = "__byref__") then "&" else "" in
+	let byref = if (String.length name > 9 && String.sub name 0 9 = "__byref__") then "&" else "" in
 	print ctx "function %s%s(" byref name;
 	concat ctx ", " (fun (arg,o,t) ->
 		let arg = define_local ctx arg in
@@ -905,7 +796,8 @@ and gen_inline_function ctx f params p =
 	let old_t = ctx.local_types in
 	ctx.in_value <- Some "closure";
 	ctx.local_types <- List.map snd params @ ctx.local_types;
-	spr ctx "_hx_closure(array(";
+
+	spr ctx "array(new _hx_lambda(array(";
 
 	let pq = escphp ctx.quotes in
 	let c = ref 0 in
@@ -917,15 +809,17 @@ and gen_inline_function ctx f params p =
 	) old_li;
 
 	print ctx "), null, array(";
+	let cargs = ref 0 in
 	concat ctx "," (fun (arg,o,t) ->
 		let arg = define_local ctx arg in
 		print ctx "'%s'" arg;
+		incr cargs;
 	) f.tf_args;
 	print ctx "), %s\"" pq;
 	ctx.quotes <- ctx.quotes + 1;
 	gen_expr ctx (fun_block ctx f p);
 	ctx.quotes <- ctx.quotes - 1;
-	print ctx "%s\")" pq;
+	print ctx "%s\"), 'execute%d')" pq !cargs;
 	ctx.in_value <- old;
 	ctx.locals <- old_l;
 	ctx.inv_locals <- old_li;
@@ -966,16 +860,9 @@ and gen_expr ctx e =
 		| TFun (args,_) -> print ctx "%s::%s" (s_path ctx en.e_path en.e_extern e.epos) (s_ident s)
 		| _ -> print ctx "%s::%s$%s" (s_path ctx en.e_path en.e_extern e.epos) (escphp ctx.quotes) (s_ident s))
 	| TArray (e1,e2) ->
-		(*
-		spr ctx "_hx_array_get_ref(";
-		gen_value ctx e1;
-		spr ctx ", ";
-		gen_value ctx e2;
-		spr ctx ")";
-		*)
 		(match e1.eexpr with
 		| TCall _ ->
-			spr ctx "_hx_array_get_ref(";
+			spr ctx "_hx_array_get(";
 			gen_value ctx e1;
 			spr ctx ", ";
 			gen_value ctx e2;
@@ -986,26 +873,22 @@ and gen_expr ctx e =
 			gen_value ctx e2;
 			spr ctx "]");
 	| TBinop (op,e1,e2) ->
-		(match op with
-		| Ast.OpAssign ->
-			(match e1.eexpr with
+		let leftside e =
+			(match e.eexpr with
 			| TArray(te1, te2) ->
-				spr ctx "_hx_array_set(";
 				gen_value ctx te1;
-				spr ctx ", ";
+				spr ctx "[";
 				gen_value ctx te2;
-				spr ctx ", ";
-				gen_value ctx e2;
-				spr ctx ")";
+				spr ctx "]";
 			| _ ->
-				gen_field_op ctx e1;
-				if is_array_ref e2 then
-					spr ctx " =& "
-				else
-					spr ctx " = ";
-				gen_value_op ctx e2;)
+				gen_field_op ctx e1;) in
+		(match op with
+		| Ast.OpAssign ->
+			leftside e1;
+			spr ctx " = ";
+			gen_value_op ctx e2;
 		| Ast.OpAssignOp(Ast.OpAdd) when (is_string_expr e1 || is_string_expr e2) ->
-			gen_value_op ctx e1;
+			leftside e1;
 			spr ctx " .= ";
 			gen_value_op ctx e2;
 		| Ast.OpAdd when (is_string_expr e1 || is_string_expr e2) ->
@@ -1013,7 +896,7 @@ and gen_expr ctx e =
 			spr ctx " . ";
 			gen_value_op ctx e2;
 		| Ast.OpAssignOp(Ast.OpShl) ->
-			gen_value_op ctx e1;
+			leftside e1;
 			spr ctx " <<= ";
 			gen_value_op ctx e2;
 		| Ast.OpShl ->
@@ -1021,7 +904,7 @@ and gen_expr ctx e =
 			spr ctx " << ";
 			gen_value_op ctx e2;
 		| Ast.OpAssignOp(Ast.OpUShr) ->
-			gen_value_op ctx e1;
+			leftside e1;
 			spr ctx " = ";
 			spr ctx "_hx_shift_right(";
 			gen_value_op ctx e1;
@@ -1094,8 +977,6 @@ and gen_expr ctx e =
 				|| (match e2.eexpr with | TConst _ | TLocal _ | TArray _  | TNew _ -> true | _ -> false)
 				|| is_string_expr e1
 				|| is_string_expr e2
-				|| is_array_expr e1
-				|| is_array_expr e2
 				|| is_anonym_expr e1
 				|| is_anonym_expr e2
 				|| is_unknown_expr e1
@@ -1110,7 +991,7 @@ and gen_expr ctx e =
 				gen_field_op ctx e2;
 			end
 		| _ ->
-			gen_value_op ctx e1;
+			leftside e1;
 			print ctx " %s " (Ast.s_binop op);
 			gen_value_op ctx e2;
 		);
@@ -1145,14 +1026,12 @@ and gen_expr ctx e =
 			if ctx.is_call then
 				gen_field_access ctx false e1 s
 			else
-				gen_uncertain_string_or_array_var ctx s e1
+				gen_uncertain_string_var ctx s e1
 		| _ ->
 			if is_string_expr e1 then
 				gen_string_var ctx s e1
-			else if is_array_expr e1 then
-				gen_array_var ctx s e1
 			else if is_uncertain_expr e1 then
-				gen_uncertain_string_or_array_var ctx s e1
+				gen_uncertain_string_var ctx s e1
 			else
 				gen_field_access ctx true e1 s
 		)
@@ -1172,17 +1051,6 @@ and gen_expr ctx e =
 			gen_value ctx e;
 			newline ctx;
 			spr ctx "return"
-		| Some e when (is_array_expr e && (match e.eexpr with TLocal _ -> false | _ -> true)) ->
-			spr ctx "{";
-			newline ctx;
-			let tmp = define_local ctx "__r__" in
-			let byref = if is_array_ref e then "&" else "" in
-			print ctx "%s$%s =%s " (escphp ctx.quotes) tmp byref;
-			gen_value ctx e;
-			newline ctx;
-			print ctx "return %s$%s" (escphp ctx.quotes) tmp;
-			newline ctx;
-			spr ctx "}"
 		| Some e ->
 			spr ctx "return ";
 			gen_value ctx e;
@@ -1209,10 +1077,12 @@ and gen_expr ctx e =
 				let name = f.cf_name in
 				match f.cf_expr with
 				| Some { eexpr = TFunction fd } ->
-					print ctx "$this->%s = _hx_closure(array(), $this, array(" name;
+					print ctx "$this->%s = array(new _hx_lambda(array(), $this, array(" name;
+					let cargs = ref 0 in
 					concat ctx "," (fun (arg,o,t) ->
 						let arg = define_local ctx arg in
 						print ctx "'%s'" arg;
+						incr cargs;
 					) fd.tf_args;
 					print ctx "), \"";
 					let old = ctx.in_value in
@@ -1221,7 +1091,7 @@ and gen_expr ctx e =
 					gen_expr ctx (fun_block ctx fd e.epos);
 					ctx.quotes <- ctx.quotes - 1;
 					ctx.in_value <- old;
-					print ctx "\")";
+					print ctx "\"), 'execute%d')" !cargs;
 					newline ctx;
 				| _ -> ()
 			) ctx.dynamic_methods;
@@ -1243,31 +1113,23 @@ and gen_expr ctx e =
 		ctx.in_loop <- snd old;
 	| TCall (ec,el) ->
 		(match ec.eexpr with
-		| TField (ef,s) when is_array_expr ef ->
-			gen_array_call ctx s ef el
 		| TField (ef,s) when is_static ef.etype && is_string_expr ef ->
 			gen_string_static_call ctx s ef el
 		| TField (ef,s) when is_string_expr ef ->
 			gen_string_call ctx s ef el
 		| TField (ef,s) when is_anonym_expr ef ->
-			if could_be_string_or_array_call s then begin
-				gen_uncertain_string_or_array_call ctx s ef el
-			end else if could_be_string_call s then begin
+			if could_be_string_call s then begin
 				gen_uncertain_string_call ctx s ef el
-			end else if could_be_array_call s then begin
-				gen_uncertain_array_call ctx s ef el
 			end else
 				gen_call ctx ec el
 		| TCall _ ->
 			gen_call ctx ec el
 		| _ ->
 			gen_call ctx ec el);
-	| TArrayDecl [] ->
-		spr ctx "_hx_array_empty()";
 	| TArrayDecl el ->
-		spr ctx "_hx_array(";
+		spr ctx "new _hx_array(array(";
 		concat ctx ", " (gen_value ctx) el;
-		spr ctx ")";
+		spr ctx "))";
 	| TThrow e ->
 		spr ctx "throw new HException(";
 		gen_value ctx e;
@@ -1279,21 +1141,20 @@ and gen_expr ctx e =
 		concat ctx ("; " ^ (escphp ctx.quotes) ^ "$") (fun (n,t,v) ->
 			let n = define_local ctx n in
 			match v with
-			| None -> print ctx "%s = null" n
+			| None -> 
+				print ctx "%s = null" n
 			| Some e ->
-				print ctx "%s %s " n (if is_array_ref e then "=&" else "=");
+				print ctx "%s = " n;
 				gen_value ctx e
 		) vl;
 	| TNew (c,_,el) ->
 		(match c.cl_path, el with
 		| ([], "String"), _ ->
 			concat ctx "" (gen_value ctx) el
-		| ([], "Array"), [] ->
-			spr ctx "_hx_array_empty()";
 		| ([], "Array"), el ->
-			spr ctx "_hx_array(";
+			spr ctx "new _hx_array(array(";
 			concat ctx ", " (gen_value ctx) el;
-			spr ctx ")"
+			spr ctx "))"
 		| (_, _), _ ->
 			print ctx "new %s(" (s_path ctx c.cl_path c.cl_extern e.epos);
 			let count = ref (-1) in
@@ -1301,14 +1162,7 @@ and gen_expr ctx e =
 				incr count;
 				match c.cl_constructor with
 				| Some f ->
-					(match follow f.cf_type with
-					| TFun (al, _) ->
-						let _, _, t = List.nth al !count in
-						if (try is_array_type t with Failure _ -> false) then
-							gen_call_value ctx e
-						else
-							gen_value ctx e;
-					| _ -> ())
+					gen_value ctx e;
 				| _ -> ();
 			) el;
 			spr ctx ")")
@@ -1345,7 +1199,6 @@ and gen_expr ctx e =
 		gen_value ctx (parent cond);
 		handle_break();
 	| TObjectDecl fields ->
-(*TODO: optimization, call the constructor directly when fields is void *)
 		spr ctx "_hx_anonymous(array(";
 		let p = escphp ctx.quotes in
 		concat ctx ", " (fun (f,e) -> print ctx "%s\"%s%s\" => " p f p; gen_value ctx e) fields;
@@ -1395,7 +1248,7 @@ and gen_expr ctx e =
 				| "Int"	-> print ctx "if(is_int(%s$%s = %s$%s))"		p ev p evar
 				| "Float"  -> print ctx "if(is_numeric(%s$%s = %s$%s))"	p ev p evar
 				| "String" -> print ctx "if(is_string(%s$%s = %s$%s))"	p ev p evar
-				| "Array"  -> print ctx "if(is_array(%s$%s = %s$%s))"	p ev p evar
+				| "Array"  -> print ctx "if((%s$%s = %s$%s) instanceof _hx_array)"	p ev p evar
 				| _ -> print ctx "if((%s$%s = %s$%s) instanceof %s)"    p ev p evar (s_path ctx tc.cl_path tc.cl_extern e.epos));
 				gen_expr ctx (mk_block e);
 			| TFun _
@@ -1784,9 +1637,14 @@ let generate_class ctx c =
 	cl();
 	newline ctx;
 	
-	if PMap.exists "toString" c.cl_fields then begin
-			print ctx "\tfunction __toString() { return $this->toString(); }";
-			newline ctx;
+	if PMap.exists "__toString" c.cl_fields then
+		()
+	else if PMap.exists "toString" c.cl_fields then begin
+		print ctx "\tfunction __toString() { return $this->toString(); }";
+		newline ctx
+	end else if (not c.cl_interface) && (not c.cl_extern) then begin
+		print ctx "\tfunction __toString() { return '%s'; }" ((s_path_haxe c.cl_path)) ;
+		newline ctx
 	end;
 	
 	print ctx "}"

+ 1 - 1
std/DateTools.hx

@@ -117,7 +117,7 @@ class DateTools {
 		#if neko
 			return new String(untyped date_format(d.__t, f.__s));
 		#elseif php
-			return untyped __php__("strftime($f,$d->__t)");
+			return untyped __call__("strftime",f,d.__t);
 		#else
 			return __format(d,f);
 		#end

+ 10 - 10
std/EReg.hx

@@ -42,7 +42,7 @@ class EReg {
 	var pattern : String;
 	var options : String;
 	var re : String;
-	var matches : Array<Dynamic>;
+	var matches : ArrayAccess<Dynamic>;
 	#end
 
 	/**
@@ -126,9 +126,9 @@ class EReg {
 			if( n < 0 ) throw "EReg::matched";
 			// we can't differenciate between optional groups at the end of a match
 			// that have not been matched and invalid groups
-			if( n >= matches.length ) return null;
-			if(matches[n][1] < 0) return null;
-			return matches[n][0];
+			if( n >= untyped __call__("count", matches)) return null;
+			if(untyped __php__("$this->matches[$n][1] < 0")) return null;
+			return untyped __php__("$this->matches[$n][0]");
 		#else
 			return null;
 		#end
@@ -153,8 +153,8 @@ class EReg {
 			var s = result.input;
 			return s.substr(0,result.index);
 		#elseif php
-			if( matches.length == 0 ) throw "No string matched";
-			return last.substr(0, matches[0][1]);
+			if( untyped __call__("count", matches) == 0 ) throw "No string matched";
+			return last.substr(0, untyped __php__("$this->matches[0][1]"));
 		#else
 			return null;
 		#end
@@ -184,8 +184,8 @@ class EReg {
 			var s = result.input;
 			return s.substr(rl,s.length - rl);
 		#elseif php
-			if( matches.length == 0 ) throw "No string matched";
-			return untyped last.substr(matches[0][1] + __php__("strlen")(matches[0][0]));
+			if( untyped __call__("count", matches) == 0 ) throw "No string matched";
+			return untyped last.substr(__php__("$this->matches[0][1]") + __php__("strlen")(__php__("$this->matches[0][0]")));
 		#else
 			return null;
 		#end
@@ -205,7 +205,7 @@ class EReg {
 			if( result == null ) throw "No string matched";
 			return { pos : result.index, len : result[0].length };
 		#elseif php
-			return untyped { pos : matches[0][1], len : __php__("strlen")(matches[0][0]) };
+			return untyped { pos : __php__("$this->matches[0][1]"), len : __php__("strlen")(__php__("$this->matches[0][0]")) };
 		#else
 			return null;
 		#end
@@ -243,7 +243,7 @@ class EReg {
 			var d = "#__delim__#";
 			return untyped s.replace(r,d).split(d);
 		#elseif php
-			return untyped __php__("preg_split")(re, s, global ? -1 : 2);
+			return untyped __php__("new _hx_array(preg_split($this->re, $s, $this->hglobal ? -1 : 2))");
 		#else
 			return null;
 		#end

+ 8 - 6
std/Hash.hx

@@ -66,7 +66,7 @@ class Hash<T> {
 		#elseif neko
 		untyped __dollar__hset(h,key.__s,value,null);
 		#elseif php
-		untyped __php__("$this->h[$key] = $value");
+		untyped h[key] = value;
 		#end
 	}
 
@@ -81,7 +81,7 @@ class Hash<T> {
 		#elseif neko
 		return untyped __dollar__hget(h,key.__s,null);
 		#elseif php
-		if(!exists(key)) return null;
+		untyped __php__("if(!isset($this->h[$key])) return null");
 		return untyped h[key];
 		#else
 		return null;
@@ -112,7 +112,7 @@ class Hash<T> {
 		#elseif neko
 		return untyped __dollar__hmem(h,key.__s,null);
 		#elseif php
-		return untyped __php__("array_key_exists")(key, h);
+		return untyped __call__("isset", h[key]);
 		#else
 		return false;
 		#end
@@ -141,7 +141,9 @@ class Hash<T> {
 		#elseif neko
 		return untyped __dollar__hremove(h,key.__s,null);
 		#elseif php
-		return untyped __call__("_hx_array_remove_at", h, key);
+		if(!untyped __call__("isset", h[key])) return false;
+		untyped __call__("unset", h[key]);
+		return true;
 		#else
 		return false;
 		#end
@@ -167,7 +169,7 @@ class Hash<T> {
 		untyped __dollar__hiter(h,function(k,_) { l.push(new String(k)); });
 		return l.iterator();
 		#elseif php
-		return untyped __call__("_hx_array_iterator", __call__("array_keys", h));
+		return untyped __call__("new _hx_array_iterator", __call__("array_keys", h));
 		#else
 		return null;
 		#end
@@ -203,7 +205,7 @@ class Hash<T> {
 		untyped __dollar__hiter(h,function(_,v) { l.push(v); });
 		return l.iterator();
 		#elseif php
-		return untyped __call__("_hx_array_iterator", __call__("array_values", h));
+		return untyped __call__("new _hx_array_iterator", __call__("array_values", h));
 		#else
 		return null;
 		#end

+ 8 - 8
std/IntHash.hx

@@ -56,14 +56,12 @@ class IntHash<T> {
 		Set a value for the given key.
 	**/
 	public function set( key : Int, value : T ) : Void {
-		#if flash
+		#if (flash || php)
 		untyped h[key] = value;
 		#elseif js
 		untyped h[key] = value;
 		#elseif neko
 		untyped __dollar__hset(h,key,value,null);
-		#elseif php
-		untyped __php__("$this->h[$key] = $value");
 		#end
 	}
 
@@ -78,7 +76,7 @@ class IntHash<T> {
 		#elseif neko
 		return untyped __dollar__hget(h,key,null);
 		#elseif php
-		if(!exists(key)) return null;
+		untyped __php__("if(!isset($this->h[$key])) return null");
 		return untyped h[key];
 		#else
 		return null;
@@ -100,7 +98,7 @@ class IntHash<T> {
 		#elseif neko
 		return untyped __dollar__hmem(h,key,null);
 		#elseif php
-		return untyped __php__("array_key_exists")(key, h);
+		return untyped __call__("isset", h[key]);
 		#else
 		return false;
 		#end
@@ -126,7 +124,9 @@ class IntHash<T> {
 		#elseif neko
 		return untyped __dollar__hremove(h,key,null);
 		#elseif php
-		return untyped __call__("_hx_array_remove_at", h, key);
+		if(!untyped __call__("isset", h[key])) return false;
+		untyped __call__("unset", h[key]);
+		return true;
 		#else
 		return false;
 		#end
@@ -155,7 +155,7 @@ class IntHash<T> {
 		untyped __dollar__hiter(h,function(k,_) { l.push(k); });
 		return l.iterator();
 		#elseif php
-		return untyped __call__("_hx_array_iterator", __call__("array_keys", h));
+		return untyped __call__("new _hx_array_iterator", __call__("array_keys", h));
 		#else
 		return null;
 		#end
@@ -191,7 +191,7 @@ class IntHash<T> {
 		untyped __dollar__hiter(h,function(_,v) { l.push(v); });
 		return l.iterator();
 		#elseif php
-		return untyped __call__("_hx_array_iterator", __call__("array_values", h));
+		return untyped __call__("new _hx_array_iterator", __call__("array_values", h));
 		#else
 		return null;
 		#end

+ 5 - 6
std/List.hx

@@ -152,7 +152,7 @@ class List<T> {
 		var l = null;
 		untyped __php__("$l =& $this->h");
 		while( l != null ) {
-			if( l[0] == v ) {
+			if(untyped __php__("$l[0] == $v")) {
 				if( prev == null )
 					untyped __php__("$this->h =& $l[1]");
 				else
@@ -194,13 +194,13 @@ class List<T> {
 		it = untyped {
 			h : h,
 			hasNext : function() {
-				return it.h != null;
+				return __php__("$it->h != null");
 			},
 			next : function() {
-				if( it.h == null )
+				if(__php__("$it->h == null"))
 					return null;
-				var x = it.h[0];
-				it.h = it.h[1];
+				var x = __php__("$it->h[0]");
+				it.h = __php__("$it->h[1]");
 				return x;
 			}
 		};
@@ -292,5 +292,4 @@ class List<T> {
 		}
 		return b;
 	}
-
 }

+ 10 - 11
std/Reflect.hx

@@ -106,12 +106,12 @@ class Reflect {
 		#elseif neko
 			return __dollar__call(func,o,args.__neko());
 		#elseif php
-			if(__call__("is_string", o) || __call__("is_array", o)) {
+			if(__call__("is_string", o)) {
 				if(args.length == 0) return __call__("call_user_func", field(o, func));
 				else if(args.length == 1) return __call__("call_user_func", field(o, func), args[0]);
 				else return __call__("call_user_func", field(o, func), args[0], args[1]);
 			}
-			return __php__("call_user_func_array(is_callable($func) ? $func : array($o, $func) , $args)");
+			return __php__("call_user_func_array(is_callable($func) ? $func : array($o, $func) , $args->a)");
 		#else
 			return null;
 		#end
@@ -178,11 +178,11 @@ class Reflect {
 				return Array.new1(a,l);
 			}
 		#elseif php
-			return __call__('is_array', o)
-					? __call__('array', 'concat', 'copy', 'insert', 'iterator', 'length', 'join', 'pop', 'push', 'remove', 'reverse', 'shift', 'slice', 'sort', 'splice', 'toString', 'unshift')
+			return __php__('$o instanceof _hx_array')
+					? __php__("new _hx_array(array('concat','copy','insert','iterator','length','join','pop','push','remove','reverse','shift','slice','sort','splice','toString','unshift'))")
 					: (__call__('is_string', o)
-						? __call__('array', 'charAt', 'charCodeAt', 'indexOf', 'lastIndexOf', 'length', 'split', 'substr', 'toLowerCase', 'toString', 'toUpperCase')
-						: __call__('array_keys', __call__('get_object_vars', o)));
+						? __php__("new _hx_array(array('charAt','charCodeAt','indexOf','lastIndexOf','length','split','substr','toLowerCase','toString','toUpperCase'))")
+						: __php__("new _hx_array(array_keys(get_object_vars($o)))"));
 		#else
 			return new Array();
 		#end
@@ -201,7 +201,7 @@ class Reflect {
 		#elseif neko
 			return __dollar__typeof(f) == __dollar__tfunction;
 		#elseif php
-			return __php__("(is_array($f) && is_callable($f)) || _hx_is_lambda($f)") || (__php__("is_array($f)") && hasField(f[0], f[1]) && f[1] != "length");
+			return __php__("(is_array($f) && is_callable($f)) || _hx_is_lambda($f)") || (__php__("is_array($f)") && hasField(__php__("$f[0]"), __php__("$f[1]")) && __php__("$f[1]") != "length");
 		#else
 			return false;
 		#end
@@ -239,7 +239,7 @@ class Reflect {
 			return f1.scope == f2.scope && f1.method == f2.method && f1.method != null;
 		#elseif php
 			if(untyped __call__("is_array", f1) && untyped __call__("is_array", f1))
-				return f1[0] == f2[0] && f1[1] == f2[1];
+				return untyped __php__("$f1[0] === $f2[0] && $f1[1] == $f2[1]");
 			if(untyped __call__("is_string", f1) && untyped __call__("is_string", f2))
 				return f1 == f2;
 			return false;
@@ -282,7 +282,6 @@ class Reflect {
 			if(__call__("is_object", v))
 				return __php__("$v instanceof _hx_anonymous") || Type.getClass(v) != null;
 			if(__php__("is_string($v) && !_hx_is_lambda($v)")) return true;
-			if(__php__("is_array($v) && !is_callable($v)")) return true;
 			return false;
 		#else
 			return false;
@@ -324,7 +323,7 @@ class Reflect {
 			return untyped __dollar__new(o);
 		#else
 			#if php
-				if(untyped __call__("is_string", o) || untyped __call__("is_array", o)) return o;
+				if(untyped __call__("is_string", o)) return o;
 			#end
 			var o2 : Dynamic = {};
 			for( f in Reflect.fields(o) )
@@ -352,7 +351,7 @@ class Reflect {
 		#elseif flash
 			return function() { return f(untyped __arguments__); };
 		#elseif php
-			untyped __php__("return array(new _hx_lambda(array('f' => &$f), null, array('args'), 'return call_user_func_array($f, array($args));'), 'makeArgs')");
+			untyped __php__("return array(new _hx_lambda(array('f' => &$f), null, array('args'), 'return call_user_func($f, new _hx_array($args));'), 'makeArgs')");
 		#else
 			return null;
 		#end

+ 14 - 11
std/Type.hx

@@ -171,7 +171,6 @@ class Type {
 	**/
 	public static function resolveClass( name : String ) : Class<Dynamic> untyped {
 		#if php
-//			php.Boot.__require_once(StringTools.replace(name, '.', '/'));
 			var c = untyped __call__("_hx_qtype", name);
 			if(__php__("$c instanceof _hx_class"))
 				return c;
@@ -303,7 +302,7 @@ class Type {
 			if(cl.__qname__ == 'String') return args[0];
 			var c = cl.__rfl__();
 			if(c == null) return null;
-			return __php__("$inst = $c->getConstructor() ? $c->newInstanceArgs($args) : $c->newInstanceArgs()");
+			return __php__("$inst = $c->getConstructor() ? $c->newInstanceArgs($args->a) : $c->newInstanceArgs()");
 		#else
 			return null;
 		#end
@@ -372,7 +371,11 @@ class Type {
 		if( f == null ) throw "No such constructor "+constr;
 		if( Reflect.isFunction(f) ) {
 			if( params == null ) throw "Constructor "+constr+" need parameters";
+#if php
+			return Reflect.callMethod(e,f,untyped params.a);
+#else
 			return Reflect.callMethod(e,f,params);
+#end
 		}
 		if( params != null && params.length != 0 )
 			throw "Constructor "+constr+" does not need parameters";
@@ -418,7 +421,7 @@ class Type {
 			foreach($ps as $p)
 				if(!$p->isStatic()) $r[] = $p->getName();
 			");
-			return untyped __php__("array_values(array_unique($r))");
+			return untyped __php__("new _hx_array(array_values(array_unique($r)))");
 		#else
 			var a = Reflect.fields(untyped c.prototype);
 			#if js
@@ -464,7 +467,7 @@ class Type {
 			foreach($ps as $p)
 				if($p->isStatic()) $r[] = $p->getName();
 			");
-			return untyped __php__("$r");
+			return untyped __php__("new _hx_array($r)");
 		#else
 			var a = Reflect.fields(c);
 			a.remove(__unprotect__("__name__"));
@@ -491,11 +494,11 @@ class Type {
 			if(__php__("$e->__tname__ == 'Void'")) return [];
 			var rfl = __php__("new ReflectionClass($e->__tname__)");
 			var sps : ArrayAccess<Dynamic> = rfl.getStaticProperties();
-			var r : ArrayAccess<String> = __call__('array');
-			__php__("foreach($sps as $k => $v) $r[] = $k");
+//			var r : ArrayAccess<String> = __call__('array');
+			__php__("$r = array(); foreach($sps as $k => $v) $r[] = $k");
 			sps = rfl.getMethods();
 			__php__("foreach($sps as $m) { $n = $m->getName(); if($n != '__construct' && $n != '__toString') $r[] = $n; }");
-			return r;
+			return __php__("new _hx_array($r)");
 		#else
 			return untyped e.__constructs__;
 		#end
@@ -642,11 +645,11 @@ class Type {
 				if( a.tag != b.tag )
 					return false;
 				for( i in 0...__call__("count", a.params))
-					if(getEnum(a.params[i]) != null) {
-						if(!enumEq(a.params[i],b.params[i]))
+					if(getEnum(untyped __php__("$a->params[$i]")) != null) {
+						if(!untyped enumEq(__php__("$a->params[$i]"),__php__("$b->params[$i]")))
 							return false;
 					} else {
-						if(!untyped __call__("_hx_equal", a.params[i],b.params[i]))
+						if(!untyped __call__("_hx_equal", __php__("$a->params[$i]"),__php__("$b->params[$i]")))
 							return false;
 					}
 			} catch( e : Dynamic ) {
@@ -690,7 +693,7 @@ class Type {
 			if(e.params == null)
 				return [];
 			else
-				return e.params;
+				return untyped __php__("new _hx_array($e->params)");
 		#else
 			return e.slice(2);
 		#end

+ 2 - 2
std/haxe/Serializer.hx

@@ -190,7 +190,7 @@ class Serializer {
 				#if flash9
 				var v : Array<Dynamic> = v;
 				#end
-				var l = #if (neko || flash9) v.length #elseif php untyped __call__("count", v) #else v[untyped "length"] #end;
+				var l = #if (neko || flash9 || php) v.length #else v[untyped "length"] #end;
 				for( i in 0...l ) {
 					if( v[i] == null )
 						ucount++;
@@ -341,7 +341,7 @@ class Serializer {
 			else {
 				buf.add(l);
 				for( i in 0...l )
-					serialize(v.params[i]);
+					serialize(untyped __field__(v, __php__("params"), i));
 			}
 			#else
 			if( useEnumIndex ) {

+ 7 - 4
std/haxe/io/Bytes.hx

@@ -90,6 +90,8 @@ class Bytes {
 		var b2 = new flash.utils.ByteArray();
 		b.readBytes(b2,0,len);
 		return new Bytes(len,b2);
+		#elseif php
+		return new Bytes(len,untyped __call__("new _hx_array", __call__("array_slice", b, pos, len)));
 		#else
 		return new Bytes(len,b.slice(pos,pos+len));
 		#end
@@ -135,7 +137,7 @@ class Bytes {
 		b.position = pos;
 		return b.readUTFBytes(len);
 		#elseif php
-		return untyped __call__("call_user_func_array", "pack", __call__("array_merge", ["C*"], __call__("array_slice", b, pos, len)));
+		return untyped __call__("call_user_func_array", "pack", __call__("array_merge", __call__("array", "C*"), __call__("array_slice", b.a, pos, len)));
 		#else
 		var s = "";
 		var b = b;
@@ -170,7 +172,7 @@ class Bytes {
 		b.position = 0;
 		return b.readUTFBytes(length);
 		#elseif php
-		return untyped __call__("call_user_func_array", "pack", __call__("array_merge", ["C*"], b));
+		return untyped __call__("call_user_func_array", "pack", __call__("array_merge", __call__("array", "C*"), b.a));
 		#else
 		return readString(0,length);
 		#end
@@ -187,6 +189,8 @@ class Bytes {
 		var b = new flash.utils.ByteArray();
 		b.length = length;
 		return new Bytes(length,b);
+		#elseif php
+		return new Bytes(length, untyped __call__("new _hx_array", __call__("array_fill", 0, length, 0)));
 		#else
 		var a = new Array();
 		for( i in 0...length )
@@ -203,8 +207,7 @@ class Bytes {
 		b.writeUTFBytes(s);
 		return new Bytes(b.length,b);
 		#elseif php
-		var a : Array<Int> = untyped __call__("array_values", __call__("unpack", "C*",  s));
-		return new Bytes(a.length,a);
+		return ofData(untyped __call__("new _hx_array", __call__("array_values", __call__("unpack", "C*",  s))));
 		#else
 		var a = new Array();
 		// utf8-decode

+ 10 - 4
std/haxe/io/BytesBuffer.hx

@@ -59,6 +59,8 @@ class BytesBuffer {
 		untyped StringBuf.__add(b,src.getData());
 		#elseif flash9
 		b.writeBytes(src.getData());
+		#elseif php
+		b = untyped __call__("new _hx_array", __call__("array_merge", b.a, src.getData().a));
 		#else
 		var b1 = b;
 		var b2 = src.getData();
@@ -75,6 +77,12 @@ class BytesBuffer {
 		try untyped StringBuf.__add_sub(b,src.getData(),pos,len) catch( e : Dynamic ) throw Error.OutsideBounds;
 		#elseif flash9
 		b.writeBytes(src.getData(),pos,len);
+		#elseif php
+		try {
+			b = untyped __call__("new _hx_array", __call__("array_merge", b.a, __call__("array_slice", src.getData().a, pos, len)));
+		} catch(e : Dynamic) {
+			throw Error.OutsideBounds;
+		}
 		#else
 		var b1 = b;
 		var b2 = src.getData();
@@ -94,14 +102,12 @@ class BytesBuffer {
 		#elseif flash9
 		var bytes = new Bytes(b.length,b);
 		b.position = 0;
+		#elseif php
+		var bytes = Bytes.ofData(b);
 		#else
 		var bytes = new Bytes(b.length,b);
 		#end
-		#if php
-		untyped __call__('unset', b);
-		#else
 		b = null;
-		#end
 		return bytes;
 	}
 

+ 4 - 2
std/haxe/io/Input.hx

@@ -133,7 +133,8 @@ class Input {
 		#if neko
 			return _float_of_bytes(untyped read(4).b,bigEndian);
 		#elseif php
-			return untyped __call__('unpack', 'f', readString(4))[1];
+			var a = untyped __call__('unpack', 'f', readString(4));
+			return a[1];
 		#else
 			throw "Not implemented";
 			return 0;
@@ -144,7 +145,8 @@ class Input {
 		#if neko
 			return _double_of_bytes(untyped read(8).b,bigEndian);
 		#elseif php
-			return untyped __call__('unpack', 'd', readString(8))[1];
+			var a = untyped __call__('unpack', 'd', readString(8));
+			return a[1];
 		#else
 			throw "Not implemented";
 			return 0;

+ 168 - 152
std/php/Boot.hx

@@ -14,116 +14,161 @@ function _hx_anonymous($p = array()) {
 	return $o;
 }
 
+class _hx_array implements ArrayAccess {
+	var $a;
+	var $length;
+	function __construct($a = array()) {
+		$this->a = $a;
+		$this->length = count($a);
+	}
 
-function _hx_array() {
-	return func_get_args();
-}
+	function concat($a) {
+		return new _hx_array(array_merge($this->a, $a->a));
+	}
 
-function _hx_array_call(&$arr, $method, $params) {
-	if(!is_array($arr)) return call_user_func_array(array($arr, $method), $params);
-	switch($method) {
-		case 'concat'  : return array_merge($arr, $params[0]);
-		case 'copy'    : return _hx_array_copy($arr);
-		case 'insert'  : return _hx_array_insert($arr, $params[0], $params[1]);
-		case 'iterator': return new _hx_array_iterator($arr);
-		case 'join'    : return join($params[0], $arr);
-		case 'pop'     : return array_pop($arr);
-		case 'push'    : return array_push($arr, $params[0]);
-		case 'remove'  : return _hx_array_remove($arr, $params[0]);
-		case 'reverse' : return _hx_array_reverse($arr);
-		case 'shift'   : return array_shift($arr);
-		case 'slice'   : return _hx_array_slice($arr, $params[0], (_hx_len($params) > 1 ? $params[1] : null));
-		case 'sort'    : return _hx_array_sort($arr, $params[0]);
-		case 'splice'  : return _hx_array_splice($arr, $params[0], $params[1]);
-		case 'unshift' : return array_unshift($arr, $params[0]);
-		default        : throw new HException('Invalid Operation: ' . $method);
+	function copy() {
+		return new _hx_array($this->a);
+	}
+/*
+	function get($index) {
+		if(isset($this->a[$index])) return $this->a[$index];
+		return null;
+	}
+*/
+	function insert($pos, $x) {
+		array_splice($this->a, $pos, 0, array($x));
+		$this->length++;
 	}
-}
 
-function _hx_array_copy($a) {
-	return $a;
-}
+	function iterator() {
+		return new _hx_array_iterator($this->a);
+	}
 
-function _hx_array_empty() {
-	return array();
-}
+	function join($sep) {
+		return implode($this->a, $sep);
+	}
 
-function &_hx_array_get_ref(&$o, $index) {
-	$r = null;
-	if(isset($o[$index])) $r =& $o[$index];
-	return $r;
-}
+	function pop() {
+		$r = array_pop($this->a);
+		$this->length = count($this->a);
+		return $r;
+	}
 
-function _hx_array_insert(&$arr, $pos, $x) {
-	array_splice($arr, $pos, 0, array($x));
-}
+	function push($x) {
+		$this->a[] = $x;
+		$this->length++;
+	}
 
-function _hx_array_iterator($arr) {
-	return new _hx_array_iterator($arr);
-}
+	function remove($x) {
+		for($i = 0; $i < count($this->a); $i++)
+			if($this->a[$i] === $x) {
+				unset($this->a[$i]);
+				$this->a = array_values($this->a);
+				$this->length--;
+				return true;
+			}
+		return false;
+	}
 
-function _hx_array_remove(&$arr, $x) {
-	for($i = 0; $i < count($arr); $i++)
-		if($arr[$i] === $x) {
-			unset($arr[$i]);
-			$arr = array_values($arr);
+	function removeAt($pos) {
+		if(array_key_exists($pos, $this->a)) {
+			unset($this->a[$pos]);
+			$this->length--;
 			return true;
+		} else
+			return false;
+	}
+
+	function reverse() {
+		$this->a = array_reverse($this->a, false);
+	}
+/*
+	function set($pos, $v) {
+		if($this->length <= $pos) {
+			$this->a = array_merge($this->a, array_fill(0, $pos+1-$this->length, null));
+			$this->length = $pos+1;
 		}
-	return false;
-}
+		return $this->a[$pos] = $v;
+	}
+*/
+	function shift() {
+		$r = array_shift($this->a);
+		$this->length = count($this->a);
+		return $r;
+	}
 
-function _hx_array_remove_at(&$arr, $pos) {
-	if(array_key_exists($pos, $arr)) {
-		unset($arr[$pos]);
-		return true;
-	} else
-		return false;
-}
+	function slice($pos, $end) {
+		if($end == null)
+			return new _hx_array(array_slice($this->a, $pos));
+		else
+			return new _hx_array(array_slice($this->a, $pos, $end-$pos));
+	}
+
+	function sort($f) {
+		$i = 0;
+		while($i < $this->length) {
+			$swap = false;
+			$j = 0;
+			$max = $this->length - $i - 1;
+			while($j < $max) {
+				if(call_user_func($f, $this->a[$j], $this->a[$j+1]) > 0 ) {
+					$tmp = $this->a[$j+1];
+					$this->a[$j+1] = $this->a[$j];
+					$this->a[$j] = $tmp;
+					$swap = true;
+				}
+				$j += 1;
+			}
+			if(!$swap) break;
+			$i += 1;
+		}
+	}
 
-function _hx_array_reverse(&$a) {
-	$a = array_reverse($a, false);
-}
+	function splice($pos, $len) {
+		if($len < 0) $len = 0;
+		$nh = new _hx_array(array_splice($this->a, $pos, $len));
+		$this->length = count($this->a);
+		return $nh;
+	}
 
-function _hx_array_set(&$arr, $pos, $v) {
-	if(is_int($pos)) {
-		$l = count($arr);
-		if($l < $pos)
-			array_splice($arr, $l, 0, array_fill($l, $pos-$l, null));
+	function toString() {
+		return '['.implode($this->a, ', ').']';
 	}
-	return $arr[$pos] = $v;
-}
 
-function _hx_array_slice(&$arr, $pos, $end) {
-	if($end == null)
-		return array_slice($arr, $pos);
-	else
-		return array_slice($arr, $pos, $end-$pos);
-}
-
-function _hx_array_sort(&$arr, $f) {
-	$i = 0;
-	$l = count($arr);
-	while($i < $l) {
-		$swap = false;
-		$j = 0;
-		$max = $l - $i - 1;
-		while($j < $max) {
-			if(call_user_func($f, $arr[$j], $arr[$j+1]) > 0 ) {
-				$tmp = $arr[$j+1];
-				$arr[$j+1] = $arr[$j];
-				$arr[$j] = $tmp;
-				$swap = true;
-			}
-			$j += 1;
+	function __toString() {
+		return $this->toString();
+	}
+
+	function unshift($x) {
+		array_unshift($this->a, $x);
+		$this->length++;
+	}
+
+	// ArrayAccess methods:
+	function offsetExists($offset) {
+		return isset($this->a[$offset]);
+	}
+
+	function offsetGet($offset) {
+		if(isset($this->a[$offset])) return $this->a[$offset];
+		return null;
+	}
+
+	function offsetSet($offset, $value) {
+		if($this->length <= $offset) {
+			$this->a = array_merge($this->a, array_fill(0, $offset+1-$this->length, null));
+			$this->length = $offset+1;
 		}
-		if(!$swap) break;
-		$i += 1;
+		return $this->a[$offset] = $value;
+	}
+
+	function offsetUnset($offset) {
+		return $this->removeAt($offset);
 	}
 }
 
-function _hx_array_splice(&$arr, $pos, $len) {
-	if($len < 0) $len = 0;
-	return array_splice($arr, $pos, $len);
+function _hx_array_get($a, $pos) {
+	return $a[$pos];
 }
 
 function _hx_char_code_at($s, $pos) {
@@ -131,12 +176,7 @@ function _hx_char_code_at($s, $pos) {
 	return ord($s{$pos});
 }
 
-// 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));
-}
-
-function _hx_deref(&$o) {
+function _hx_deref($o) {
 	return $o;
 }
 
@@ -170,6 +210,10 @@ function _hx_exception_handler($e) {
 	die($msg);
 }
 
+function _hx_explode($delimiter, $s) {
+	return new _hx_array(explode($delimiter, $s));
+}
+
 function _hx_field($o, $field) {
 	if(_hx_has_field($o, $field)) {
 		if($o instanceof _hx_type) {
@@ -181,60 +225,34 @@ function _hx_field($o, $field) {
 		} else {
 			if(is_string($o)) {
 				if($field == 'length') {
-					return _hx_len($o);
+					return strlen($o);
 				} else {
 					switch($field) {
-						case 'charAt'     : return _hx_closure(array('o' => &$o), null, array('index'), 'return substr($o,$index,1);');
-						case 'charCodeAt' : return _hx_closure(array('o' => &$o), null, array('index'), 'return ord(substr($o, $index, 1));');
-						case 'indexOf'    : return _hx_closure(array('o' => &$o), null, array('value','startIndex'), 'return _hx_index_of($o, $value, $startIndex);');
-						case 'lastIndexOf': return _hx_closure(array('o' => &$o), null, array('value','startIndex'), 'return _hx_last_index_of($o, $value, $startIndex);');
-						case 'split'      : return _hx_closure(array('o' => &$o), null, array('delimiter'), 'return explode($delimiter, $o);');
-						case 'substr'     : return _hx_closure(array('o' => &$o), null, array('pos','len'), 'return _hx_substr($o, $pos, $len);');
-						case 'toUpperCase': return _hx_closure(array('o' => &$o), null, array(), 'return strtoupper($o);');
-						case 'toLowerCase': return _hx_closure(array('o' => &$o), null, array(), 'return strtolower($o);');
-						case 'toString'   : return _hx_closure(array('o' => &$o), null, array(), 'return $o;');
+						case 'charAt'     : return array(new _hx_lambda(array('o' => &$o), null, array('index'), 'return substr($o,$index,1);'), 'execute1');
+						case 'charCodeAt' : return array(new _hx_lambda(array('o' => &$o), null, array('index'), 'return ord(substr($o, $index, 1));'), 'execute1');
+						case 'indexOf'    : return array(new _hx_lambda(array('o' => &$o), null, array('value','startIndex'), 'return _hx_index_of($o, $value, $startIndex);'), 'execute1');
+						case 'lastIndexOf': return array(new _hx_lambda(array('o' => &$o), null, array('value','startIndex'), 'return _hx_last_index_of($o, $value, $startIndex);'), 'execute1');
+						case 'split'      : return array(new _hx_lambda(array('o' => &$o), null, array('delimiter'), 'return _hx_explode($delimiter, $o);'), 'execute1');
+						case 'substr'     : return array(new _hx_lambda(array('o' => &$o), null, array('pos','len'), 'return _hx_substr($o, $pos, $len);'), 'execute2');
+						case 'toUpperCase': return array(new _hx_lambda(array('o' => &$o), null, array(), 'return strtoupper($o);'), 'execute0');
+						case 'toLowerCase': return array(new _hx_lambda(array('o' => &$o), null, array(), 'return strtolower($o);'), 'execute0');
+						case 'toString'   : return array(new _hx_lambda(array('o' => &$o), null, array(), 'return $o;'), 'execute0');
 					}
 					return null;
 				}
-			}
-			else {
-				if(is_array($o)) {
-					if($field == 'length') {
-						return _hx_len($o);
+			} else {
+				if(property_exists($o, $field)) {
+					if(is_array($o->$field) && is_callable($o->$field)) {
+						return $o->$field;
 					} else {
-						switch($field) {
-							case 'concat'  : return _hx_closure(array('o' => &$o), null, array('a'), 'return array_merge($o, $a);');
-							case 'join'    : return _hx_closure(array('o' => &$o), null, array('sep'), 'return join($sep,$o);');
-							case 'pop'     : return _hx_closure(array('o' => &$o), null, array(), 'return array_pop($o);');
-							case 'push'    : return _hx_closure(array('o' => &$o), null, array('x'), 'return array_push($o,$x);');
-							case 'reverse' : return _hx_closure(array('o' => &$o), null, array(), 'return _hx_reverse($o);');
-							case 'shift'   : return _hx_closure(array('o' => &$o), null, array(), 'return array_shift($o);');
-							case 'slice'   : return _hx_closure(array('o' => &$o), null, array('pos','end'), 'return _hx_array_slice($o, $pos, $end);');
-							case 'sort'    : return _hx_closure(array('o' => &$o), null, array('f'), 'return _hx_array_sort($o,$f);');
-							case 'splice'  : return _hx_closure(array('o' => &$o), null, array('pos','len'), 'return _hx_array_splice($o, $pos, $len);');
-							case 'toString': return _hx_closure(array('o' => &$o), null, array(), 'return \"[\".join(\", \", $o).\"]\";');
-							case 'unshift' : return _hx_closure(array('o' => &$o), null, array('x'), 'return array_unshift($o,$x);');
-							case 'insert'  : return _hx_closure(array('o' => &$o), null, array('pos','x'), 'return _hx_array_insert($o, $pos, $x);');
-							case 'remove'  : return _hx_closure(array('o' => &$o), null, array('x'), '_hx_array_remove($o, $x);');
-							case 'iterator': return _hx_closure(array('o' => &$o), null, array(), 'return new _hx_array_iterator($o);');
-							case 'copy'    : return _hx_closure(array('o' => &$o), null, array(), 'return $o;');
-						}
-					}
-					return null;
-				} else {
-					if(property_exists($o, $field)) {
-						if(is_array($o->$field) && is_callable($o->$field)) {
-							return $o->$field;
+						if(is_string($o->$field) && _hx_is_lambda($o->$field)) {
+							return array($o, $field);
 						} else {
-							if(is_string($o->$field) && _hx_is_lambda($o->$field)) {
-								return array($o, $field);
-							} else {
-								return $o->$field;
-							}
+							return $o->$field;
 						}
-					} else {
-						return array($o, $field);
 					}
+				} else {
+					return array($o, $field);
 				}
 			}
 		}
@@ -248,8 +266,6 @@ function _hx_has_field($o, $field) {
 		(is_object($o) && (method_exists($o, $field) || isset($o->$field) || property_exists($o, $field)))
 		||
 		(is_string($o) && (in_array($field, array('toUpperCase', 'toLowerCase', 'charAt', 'charCodeAt', 'indexOf', 'lastIndexOf', 'split', 'substr', 'toString', 'length'))))
-		||
-		(is_array($o)  && (in_array($field, array('concat', 'copy', 'insert', 'iterator', 'join', 'pop', 'push', 'remove', 'reverse', 'shift', 'slice', 'sort', 'splice', 'unshift', 'toString', 'length'))))
 	;
 }
 
@@ -272,7 +288,7 @@ function _hx_instanceof($v, $t) {
 		case 'Int'    : return is_int($v);
 		case 'Float'  : return is_float($v) || is_int($v);
 		case 'Dynamic': return true;
-		case 'Class'  : return $v instanceof _hx_class && $v->__tname__ != 'Enum';
+		case 'Class'  : return ($v instanceof _hx_class || $v instanceof _hx_interface) && $v->__tname__ != 'Enum';
 		case 'Enum'   : return $v instanceof _hx_enum;
 		default       : return is_a($v, $t->__tname__);
 	}
@@ -291,7 +307,7 @@ function _hx_last_index_of($s, $value, $startIndex) {
 }
 
 function _hx_len($o) {
-	return is_array($o) ? count($o) : (is_string($o) ? strlen($o) : $o->length);
+	return is_string($o) ? strlen($o) : $o->length;
 }
 
 function _hx_null() {
@@ -327,10 +343,10 @@ function _hx_string_call($s, $method, $params) {
 		case 'toLowerCase': return strtolower($s);
 		case 'charAt'     : return substr($s, $params[0], 1);
 		case 'charCodeAt' : return _hx_char_code_at($s, $params[0]);
-		case 'indexOf'    : return _hx_index_of($s, $params[0], (_hx_len($params) > 1 ? $params[1] : null));
-		case 'lastIndexOf': return _hx_last_index_of($s, (_hx_len($params) > 1 ? $params[1] : null), null);
-		case 'split'      : return explode($params[0], $s);
-		case 'substr'     : return _hx_substr($s, $params[0], (_hx_len($params) > 1 ? $params[1] : null));
+		case 'indexOf'    : return _hx_index_of($s, $params[0], (count($params) > 1 ? $params[1] : null));
+		case 'lastIndexOf': return _hx_last_index_of($s, (count($params) > 1 ? $params[1] : null), null);
+		case 'split'      : return _hx_explode($params[0], $s);
+		case 'substr'     : return _hx_substr($s, $params[0], (count($params) > 1 ? $params[1] : null));
 		default           : throw new HException('Invalid Operation: ' . $method);
 	}
 }
@@ -377,10 +393,10 @@ function _hx_string_rec($o, $s) {
 				if($o instanceof _hx_type)
 					return $o->__qname__;
 				else {
-					if(is_callable(_hx_array($o, 'toString')))
+					if(is_callable(array($o, 'toString')))
 						return $o->toString();
 					else {
-						if(is_callable(_hx_array($o, '__toString')))
+						if(is_callable(array($o, '__toString')))
 							return $o->__toString();
 						else
 							return '[' . _hx_ttype($c) . ']';
@@ -664,7 +680,7 @@ php_Boot::$ttypes = array();
 php_Boot::$tpaths = array();
 
 _hx_register_type(new _hx_class('String',  'String'));
-_hx_register_type(new _hx_class('Array',   'Array'));
+_hx_register_type(new _hx_class('_hx_array', 'Array'));
 _hx_register_type(new _hx_class('Int',     'Int'));
 _hx_register_type(new _hx_class('Float',   'Float'));
 _hx_register_type(new _hx_class('Class',   'Class'));

+ 2 - 2
std/php/FileSystem.hx

@@ -103,10 +103,10 @@ class FileSystem {
 	}
 
 	public static function readDirectory( path : String ) : Array<String> {
-		var l : Array<String> =  [];
+		var l = untyped __call__("array");
 		untyped __php__('$dh = opendir($path);
         while (($file = readdir($dh)) !== false) $l[] = $file;
         closedir($dh);');
-		return l;
+		return untyped __call__("new _hx_array", l);
 	}
 }

+ 11 - 3
std/php/Lib.hx

@@ -8,9 +8,9 @@ class Lib {
 		untyped __call__("echo", Std.string(v));
 	}
 
-	/*
+	/**
 		Print the specified value on the default output followed by a newline character.
-	*/
+	**/
 	public static function println( v : Dynamic ) : Void {
 		print(v);
 		print("\n");
@@ -56,7 +56,15 @@ class Lib {
 		return untyped __call__("fpassthru", h);
 	}
 
-	public static function hashOfAssociativeArray<T>(arr : Dynamic) : Hash<T> {
+	public static inline function haxeToNativeArray(a : Array<Dynamic>) : NativeArray {
+		return untyped a.a;
+	}
+
+	public static inline function nativeArrayToHaxe(a : NativeArray) : Array<Dynamic> {
+		return untyped __call__("new _hx_array", a);
+	}
+
+	public static function hashOfAssociativeArray<T>(arr : NativeArray) : Hash<T> {
 		var h = new Hash<T>();
 		untyped __php__("foreach($arr as $k => $v) $h->set($k, $v)");
 		return h;

+ 7 - 7
std/php/PhpXml__.hx

@@ -47,7 +47,7 @@ class PhpXml__ {
 	public var _parent : PhpXml__;
 
 	private static var build : PhpXml__;
-	private static function __start_element_handler(parser : Dynamic, name : String, attribs : Array<String>) {
+	private static function __start_element_handler(parser : Dynamic, name : String, attribs : ArrayAccess<String>) {
 		var node = createElement(name);
 		untyped __php__("foreach($attribs as $key => $value) $node->set($key, $value)");
 		build.addChild(node);
@@ -60,7 +60,7 @@ class PhpXml__ {
 
 	private static function __character_data_handler(parser : Dynamic, data : String) {
 		// TODO: this function can probably be simplified
-		var lc : PhpXml__ = (build._children == null || untyped __call__("count", build._children) == 0) ? null : build._children[untyped __call__("count", build._children) -1];
+		var lc : PhpXml__ = (build._children == null || build._children.length == 0) ? null : build._children[build._children.length-1];
 		if(lc != null && Xml.PCData == lc.nodeType) {
 			lc.nodeValue = lc.nodeValue + untyped __call__("htmlentities", data);
 		} else if((untyped __call__("strlen", data) == 1 && __call__("htmlentities", data) != data) || untyped __call__("htmlentities", data) == data) {
@@ -226,7 +226,7 @@ class PhpXml__ {
 			cur: 0,
 			x: me._children,
 			hasNext : function(){
-				return it.cur < __call__("count", it.x);
+				return it.cur < it.x.length;
 			},
 			next : function(){
 				return it.x[it.cur++];
@@ -244,7 +244,7 @@ class PhpXml__ {
 			x: me._children,
 			hasNext : function() {
 				var k = it.cur;
-				var l = __call__("count", it.x);
+				var l = it.x.length;
 				while( k < l ) {
 
 					if( it.x[k].nodeType == Xml.Element )
@@ -256,7 +256,7 @@ class PhpXml__ {
 			},
 			next : function() {
 				var k = it.cur;
-				var l = __call__("count", it.x);
+				var l = it.x.length;
 				while( k < l ) {
 					var n = it.x[k];
 					k += 1;
@@ -281,7 +281,7 @@ class PhpXml__ {
 			x: me._children,
 			hasNext : function() {
 				var k = it.cur;
-				var l = __call__("count", it.x);
+				var l = it.x.length;
 				while( k < l ) {
 					var n = it.x[k];
 					if( n.nodeType == Xml.Element && n._nodeName == name )
@@ -293,7 +293,7 @@ class PhpXml__ {
 			},
 			next : function() {
 				var k = it.cur;
-				var l = __call__("count", it.x);
+				var l = it.x.length;
 				while( k < l ) {
 					var n = it.x[k];
 					k++;

+ 1 - 1
std/php/Sys.hx

@@ -3,7 +3,7 @@ package php;
 
 class Sys {
 	public static function args() : Array<String> {
-		return untyped __call__('array_key_exists', 'argv', __var__('_SERVER')) ? __call__('array_slice', __var__('_SERVER', 'argv'), 1) : [];
+		return untyped __call__('array_key_exists', 'argv', __var__('_SERVER')) ? __call__('new _hx_array', __call__('array_slice', __var__('_SERVER', 'argv'), 1)) : [];
 	}
 
 	public static function getEnv( s : String ) : String {

+ 2 - 5
std/php/Web.hx

@@ -11,7 +11,7 @@ class Web {
 	**/
 	public static function getParams() {
 		#if force_std_separator
-		var a : Array<String> = untyped __php__("$_POST");
+		var a : NativeArray = untyped __php__("$_POST");
 		if(untyped __call__("get_magic_quotes_gpc"))
 			untyped __php__("foreach($a as $k => $v) $a[$k] = stripslashes($v)");
 		var h = Lib.hashOfAssociativeArray(a);
@@ -22,7 +22,7 @@ class Web {
 		}
 		return h;
 		#else
-		var a : Array<String> = untyped __php__("array_merge($_GET, $_POST)");
+		var a : NativeArray = untyped __php__("array_merge($_GET, $_POST)");
 		if(untyped __call__("get_magic_quotes_gpc"))
 			untyped __php__("foreach($a as $k => $v) $a[$k] = stripslashes($v)");
 		return Lib.hashOfAssociativeArray(a);
@@ -307,14 +307,11 @@ class Web {
 			}
 			onPart(part, file);
 			var h = untyped __call__("fopen", tmp, "r");
-//			var pos = 0;
 			var bsize = 8192;
 			while (!untyped __call__("feof", h)) {
 				var buf : String = untyped __call__("fread", h, bsize);
 				var size : Int = untyped __call__("strlen", buf);
 				onData(buf, 0, size);
-//				onData(buf, pos, size);
-//				pos += size;
 			}
 			untyped __call__("fclose", h);
 		}

+ 12 - 12
std/php/db/DBase.hx

@@ -28,15 +28,15 @@ private class DBaseConnection {
 
 	var c : Void;
 	var fields : Array<Field>;
-	
+
 	public function new( file : String, mode : Int) {
 		c = untyped __call__("dbase_open", file, mode);
 		if(c == null) throw "Invalid dBase file: " + file;
-		var infos : Array<Dynamic> = untyped __call__("dbase_get_header_info", c);
+		var infos : ArrayAccess<Dynamic> = untyped __call__("dbase_get_header_info", c);
 		fields = [];
 		for(info in infos) {
 			fields.push({
-				name : info[untyped 'name'],
+				name : info['name'],
 				type : getType(info)
 			});
 		}
@@ -54,37 +54,37 @@ private class DBaseConnection {
 	public function insert(values : Array<Dynamic>) : Bool {
 		return untyped __call__("dbase_add_record", c, values);
 	}
-	
+
 	public function replace(index : Int, values : Array<Dynamic>) {
 		return untyped __call__("dbase_replace_record", c, values, index);
 	}
-	
+
 	public function delete(index : Int) : Bool {
 		return untyped __call__("dbase_delete_record", c, index);
 	}
-	
+
 	public function records() : Array<Dynamic> {
 		var arr = [];
 		for(i in 1...count()+1)
 			arr.push(record(i));
 		return arr;
 	}
-	
+
 	public function rows() : Array<Array<Dynamic>> {
 		var arr = [];
 		for(i in 1...count()+1)
 			arr.push(row(i));
 		return arr;
 	}
-	
+
 	public function row(index : Int) : Array<Dynamic> {
 		var r = untyped __call__("dbase_get_record", c, index);
 		if(untyped __php__("isset($r['deleted'])")) {
 			untyped __php__("unset($r['deleted'])");
 		}
-		return r;
+		return untyped __call__("new _hx_array", r);
 	}
-	
+
 	public function record(index : Int) : Dynamic {
 		var row = row(index);
 		var record = {};
@@ -92,7 +92,7 @@ private class DBaseConnection {
 			Reflect.setField(record, fields[j].name, row[j]);
 		return record;
 	}
-	
+
 	private function getType(info : Array<Dynamic>) {
 		switch(info[untyped 'type']) {
 			case 'D': return DateField;
@@ -114,7 +114,7 @@ class DBase {
 	public static function openReadOnly( file : String ) : DBaseConnection {
 		return new DBaseConnection(file, 0);
 	}
-	
+
 	public static function create(file : String, fields : Array<Field>) : Void {
 		var flds : Array<Array<Dynamic>> = [];
 		for(field in fields) {

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

@@ -156,7 +156,7 @@ private class MysqlResultSet implements ResultSet {
 	}
 
 	public function getResult( n : Int ) : String {
-		var a : Array<String> = untyped __call__("mysql_fetch_row", __r);
+		var a = untyped __call__("mysql_fetch_row", __r);
 		return a[n];
 	}
 

+ 1 - 2
std/php/io/FileInput.hx

@@ -47,7 +47,6 @@ class FileInput extends haxe.io.Input {
 		if(untyped __call__('feof', __f)) return throw new haxe.io.Eof();
 		var r : String = untyped __call__('fread', __f, l);
 		if(untyped __physeq__(r, false)) return throw haxe.io.Error.Custom('An error occurred');
-		
 		var b = haxe.io.Bytes.ofString(r);
 		s.blit(p, b, 0, r.length);
 		return r.length;
@@ -60,7 +59,7 @@ class FileInput extends haxe.io.Input {
 
 	public function seek( p : Int, pos : FileSeek ) {
 		var w;
-		switch( pos ) { 
+		switch( pos ) {
 			case SeekBegin: w = untyped __php__('SEEK_SET');
 			case SeekCur  : w = untyped __php__('SEEK_CUR');
 			case SeekEnd  : w = untyped __php__('SEEK_END');

+ 12 - 11
std/php/io/Process.hx

@@ -85,15 +85,15 @@ class Process {
 	public var stdin(default,null) : haxe.io.Output;
 
 	public function new( cmd : String, args : Array<String> ) {
-		var pipes = new Array<Dynamic>();
-		var descriptorspec = [
-			['pipe', 'r'],
-			['pipe', 'w'],
-			['pipe', 'w']
-		];
+		var pipes = untyped __call__("array");
+		var descriptorspec = untyped __php__("array(
+			array('pipe', 'r'),
+			array('pipe', 'w'),
+			array('pipe', 'w')
+		)");
 		p = untyped __call__('proc_open', cmd+sargs(args), descriptorspec, pipes);
 		if(untyped __physeq__(p, false)) throw "Process creation failure : "+cmd;
-		stdin  = new Stdin(pipes[0]);
+		stdin  = new Stdin( pipes[0]);
 		stdout = new Stdout(pipes[1]);
 		stderr = new Stdout(pipes[2]);
 	}
@@ -110,7 +110,8 @@ class Process {
 	}
 
 	public function getPid() : Int {
-		return untyped __call__('proc_get_status', p)['pid'];
+		var r = untyped __call__('proc_get_status', p);
+		return r[untyped 'pid'];
 	}
 
 	function replaceStream(input : haxe.io.Input) {
@@ -125,15 +126,15 @@ class Process {
 	}
 
 	public function exitCode() : Int {
-		var status : Array<Dynamic> = untyped __call__('proc_get_status', p);
+		var status = untyped __call__('proc_get_status', p);
 		while(status[untyped 'running']) {
 			php.Sys.sleep(0.01);
 			status = untyped __call__('proc_get_status', p);
 		}
 		replaceStream(stderr);
 		replaceStream(stdout);
-		var cl = untyped __call__('proc_close', p);
-		return (status[untyped 'exitcode'] < 0) ? cl : status[untyped 'exitcode'];
+		var cl : Int = untyped __call__('proc_close', p);
+		return (cast status[untyped 'exitcode']) < 0 ? cl : cast status[untyped 'exitcode'];
 
 	}
 }

+ 1 - 36
std/php/net/SocketInput.hx

@@ -24,39 +24,4 @@
  */
 package php.net;
 
-typedef SocketInput = php.io.FileInput;
-
-/*
-import php.net.Socket;
-import haxe.io.Error;
-class SocketInput extends haxe.io.Input {
-
-	var __s : SocketHandle;
-
-	public function new(s) {
-		__s = s;
-	}
-
-	public override function readByte() {
-		var r = untyped __call__('socket_read', __s, 1);
-		untyped Socket.checkError(r);
-		if(r == 0) return throw new haxe.io.Eof();
-		return untyped __call__('ord', r);
-	}
-
-	public override function readBytes( buf : haxe.io.Bytes, pos : Int, len : Int ) : Int {
-		var r : String = untyped __call__('socket_read', __s, len);
-		untyped Socket.checkError(r);
-		var b = haxe.io.Bytes.ofString(r);
-		if(r.length == 0) return throw new haxe.io.Eof();
-		s.blit(pos, b, 0, r.length);
-		return r.length;
-	}
-
-	public override function close() {
-		super.close();
-		if( __s != null ) untyped __call__('socket_close', __s);
-	}
-}
-
-*/
+typedef SocketInput = php.io.FileInput;

+ 1 - 31
std/php/net/SocketOutput.hx

@@ -24,34 +24,4 @@
  */
 package php.net;
 
-typedef SocketOutput = php.io.FileOutput;
-
-/*
-import php.net.Socket;
-import haxe.io.Error;
-class SocketOutput extends haxe.io.Output {
-
-	var __s : SocketHandle;
-
-	public function new(s) {
-		__s = s;
-	}
-
-	public override function writeByte( c : Int ) {
-		var r = __call__('socket_write', __s, __call__('chr', c), 1);
-		untyped Socket.checkError(r);
-	}
-
-	public override function writeBytes( buf : haxe.io.Bytes, pos : Int, len : Int) : Int {
-		var s = b.readString(p, l);
-		var r = untyped __call__('socket_write', __f, s, len);
-		untyped Socket.checkError(r);
-		return cast r;
-	}
-
-	public override function close() {
-		super.close();
-		if( __s != null ) untyped __call__('socket_close', __s);
-	}
-}
-*/
+typedef SocketOutput = php.io.FileOutput;