Bläddra i källkod

[cs/java] use native arrays for dynamic function invokation (#6125)

Dan Korostelev 8 år sedan
förälder
incheckning
8e17262833

+ 12 - 10
src/generators/gencommon/closuresToClass.ml

@@ -615,7 +615,7 @@ struct
 		let args_real_to_func args =
 			let arity = List.length args in
 			if arity >= max_arity then
-				[ alloc_var (mk_internal_name "fn" "dynargs") (basic.tarray t_dynamic), None ]
+				[ alloc_var (mk_internal_name "fn" "dynargs") (gen.gclasses.nativearray t_dynamic), None ]
 			else func_args_i arity
 		in
 
@@ -634,7 +634,7 @@ struct
 		let args_real_to_func_sig args =
 			let arity = List.length args in
 			if arity >= max_arity then
-				[mk_internal_name "fn" "dynargs", false, basic.tarray t_dynamic]
+				[mk_internal_name "fn" "dynargs", false, gen.gclasses.nativearray t_dynamic]
 			else begin
 				func_sig_i arity
 			end
@@ -651,7 +651,7 @@ struct
 
 		let args_real_to_func_call el (pos:pos) =
 			if List.length el >= max_arity then
-				[{ eexpr = TArrayDecl el; etype = basic.tarray t_dynamic; epos = pos }]
+				[mk_nativearray_decl gen t_dynamic el pos]
 			else begin
 				List.fold_left (fun acc e ->
 					if like_float (gen.greal_type e.etype) && not (like_i64 (gen.greal_type e.etype)) then
@@ -679,11 +679,13 @@ struct
 			if arity >= max_arity then begin
 				let varray = match changed_args with | [v,_] -> v | _ -> assert false in
 				let varray_local = mk_local varray pos in
-				let mk_varray i = { eexpr = TArray(varray_local, { eexpr = TConst(TInt(Int32.of_int i)); etype = basic.tint; epos = pos }); etype = t_dynamic; epos = pos } in
-
-				snd (List.fold_left (fun (count,acc) (v,const) ->
-					(count + 1, (mk (TVar(v, Some(mk_const const (mk_varray count) v.v_type))) basic.tvoid pos) :: acc)
-				) (0,[]) args)
+				let mk_varray i = { eexpr = TArray(varray_local, ExprBuilder.make_int gen.gcon i pos); etype = t_dynamic; epos = pos } in
+				let el =
+					snd (List.fold_left (fun (count,acc) (v,const) ->
+						(count + 1, (mk (TVar(v, Some(mk_const const (mk_varray count) v.v_type))) basic.tvoid pos) :: acc)
+					) (0, []) args)
+				in
+				List.rev el
 			end else begin
 				let _, dyn_args, float_args = List.fold_left (fun (count,fargs, dargs) arg ->
 					if count land 1 = 0 then
@@ -844,7 +846,7 @@ struct
 			in
 
 			let type_name = mk_internal_name "fn" "type" in
-			let dynamic_arg = alloc_var (mk_internal_name "fn" "dynargs") (basic.tarray t_dynamic) in
+			let dynamic_arg = alloc_var (mk_internal_name "fn" "dynargs") (gen.gclasses.nativearray t_dynamic) in
 
 			let mk_invoke_complete_i i is_float =
 
@@ -1076,7 +1078,7 @@ struct
 						eexpr = TIf(
 							mk (TBinop (OpEq, dynargs, null dynargs.etype pos)) basic.tbool pos,
 							mk (TConst (TInt Int32.zero)) basic.tint pos,
-							Some (mk_field_access gen dynargs "length" pos));
+							Some (gen.gclasses.nativearray_len dynargs pos));
 						etype = basic.tint;
 						epos = pos;
 					} in

+ 6 - 6
src/generators/gencommon/reflectionCFs.ml

@@ -1297,7 +1297,7 @@ let implement_invokeField ctx slow_invoke cl =
 	let field_args, switch_var = field_type_args ctx cl.cl_pos in
 	let field_args_exprs = List.map (fun (v,_) -> mk_local v pos) field_args in
 
-	let dynamic_arg = alloc_var "dynargs" (basic.tarray t_dynamic) in
+	let dynamic_arg = alloc_var "dynargs" (gen.gclasses.nativearray t_dynamic) in
 	let all_args = field_args @ [ dynamic_arg, None ] in
 	let fun_t = TFun(fun_args all_args, t_dynamic) in
 
@@ -1434,7 +1434,7 @@ let implement_varargs_cl ctx cl =
 	let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in
 
 	let invokedyn = mk_internal_name "hx" "invokeDynamic" in
-	let idyn_t = TFun([mk_internal_name "fn" "dynargs", false, basic.tarray t_dynamic], t_dynamic) in
+	let idyn_t = TFun([mk_internal_name "fn" "dynargs", false, gen.gclasses.nativearray t_dynamic], t_dynamic) in
 	let this_idyn = mk_this invokedyn idyn_t in
 
 	let map_fn arity ret vars api =
@@ -1450,9 +1450,9 @@ let implement_varargs_cl ctx cl =
 		let call_arg = if arity = (-1) then
 			api (-1) t_dynamic None
 		else if arity = 0 then
-			null (basic.tarray t_empty) pos
+			null (gen.gclasses.nativearray t_empty) pos
 		else
-			{ eexpr = TArrayDecl(loop (arity - 1) []); etype = basic.tarray t_empty; epos = pos }
+			mk_nativearray_decl gen t_empty (loop (arity - 1) []) pos
 		in
 
 		let expr = {
@@ -1513,9 +1513,9 @@ let implement_closure_cl ctx cl =
 		let call_arg = if arity = (-1) then
 			api (-1) t_dynamic None
 		else if arity = 0 then
-			null (basic.tarray t_empty) pos
+			null (gen.gclasses.nativearray t_empty) pos
 		else
-			{ eexpr = TArrayDecl(loop (arity - 1) []); etype = basic.tarray t_empty; epos = pos }
+			mk_nativearray_decl gen t_empty  (loop (arity - 1) []) pos
 		in
 
 		let expr = {

+ 2 - 2
src/generators/gencs.ml

@@ -2797,9 +2797,9 @@ let generate con =
 			in
 
 			let arr_call = if args <> [] then
-				{ eexpr = TArrayDecl args; etype = basic.tarray t_dynamic; epos = ecall.epos }
+				mk_nativearray_decl gen t_dynamic args ecall.epos
 			else
-				null (basic.tarray t_dynamic) ecall.epos
+				null (gen.gclasses.nativearray t_dynamic) ecall.epos
 			in
 
 			let call_args =

+ 2 - 2
src/generators/genjava.ml

@@ -2167,9 +2167,9 @@ let generate con =
 		in
 
 		let arr_call = if args <> [] then
-			{ eexpr = TArrayDecl args; etype = basic.tarray t_dynamic; epos = ecall.epos }
+			mk_nativearray_decl gen t_dynamic args ecall.epos
 		else
-			null (basic.tarray t_dynamic) ecall.epos
+			null (gen.gclasses.nativearray t_dynamic) ecall.epos
 		in
 
 

+ 2 - 1
std/cs/_std/Reflect.hx

@@ -76,13 +76,14 @@ import cs.system.reflection.*;
 		if (ihx != null)
 			untyped ihx.__hx_setField(field, FieldLookup.hash(field), value, true);
 		else if (Runtime.slowHasField(o, 'set_$field'))
-			Runtime.slowCallField(o, 'set_$field', [value]);
+			Runtime.slowCallField(o, 'set_$field', cs.NativeArray.make(value));
 		else
 			Runtime.slowSetField(o,field,value);
 	}
 
 	public static function callMethod( o : Dynamic, func : haxe.Constraints.Function, args : Array<Dynamic> ) : Dynamic
 	{
+		var args = cs.Lib.nativeArray(args,true);
 		return untyped cast(func, Function).__hx_invokeDynamic(args);
 	}
 

+ 2 - 2
std/cs/_std/Type.hx

@@ -165,7 +165,7 @@ enum ValueType {
 			t = Lib.toNativeType(resolveClass(getClassName(cl)));
 		}
 		var ctors = t.GetConstructors();
-		return Runtime.callMethod(null, cast ctors, ctors.Length, args);
+		return Runtime.callMethod(null, cast ctors, ctors.Length, cs.Lib.nativeArray(args,true));
 	}
 
 	// cache empty constructor arguments so we don't allocate it on each createEmptyInstance call
@@ -202,7 +202,7 @@ enum ValueType {
 				throw 'Constructor $constr needs parameters';
 			return ret;
 		} else {
-			return cs.internal.Runtime.slowCallField(e,constr,params);
+			return cs.internal.Runtime.slowCallField(e,constr,cs.Lib.nativeArray(params,true));
 		}
 	}
 

+ 4 - 4
std/cs/internal/Function.hx

@@ -37,7 +37,7 @@ package cs.internal;
 
 @:keep @:nativeGen @:native("haxe.lang.VarArgsBase") private class VarArgsBase extends Function
 {
-	public function __hx_invokeDynamic(dynArgs:Array<Dynamic>):Dynamic
+	public function __hx_invokeDynamic(dynArgs:cs.NativeArray<Dynamic>):Dynamic
 	{
 		throw "Abstract implementation";
 	}
@@ -53,9 +53,9 @@ package cs.internal;
 		this.fun = fun;
 	}
 
-	override public function __hx_invokeDynamic(dynArgs:Array<Dynamic>):Dynamic
+	override public function __hx_invokeDynamic(dynArgs:cs.NativeArray<Dynamic>):Dynamic
 	{
-		return fun(dynArgs);
+		return fun(cs.Lib.array(dynArgs));
 	}
 }
 
@@ -73,7 +73,7 @@ package cs.internal;
 		this.hash = hash;
 	}
 
-	override public function __hx_invokeDynamic(dynArgs:Array<Dynamic>):Dynamic
+	override public function __hx_invokeDynamic(dynArgs:cs.NativeArray<Dynamic>):Dynamic
 	{
 		return Runtime.callField(obj, field, hash, dynArgs);
 	}

+ 6 - 13
std/cs/internal/Runtime.hx

@@ -64,7 +64,7 @@ import cs.system.Object;
 		return obj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false);
 	}
 
-	public static object callField(haxe.lang.HxObject obj, string field, int fieldHash, Array args)
+	public static object callField(haxe.lang.HxObject obj, string field, int fieldHash, object[] args)
 	{
 		return obj.__hx_invokeField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, args);
 	}
@@ -429,7 +429,7 @@ import cs.system.Object;
 		}
 	}
 
-	public static function callMethod(obj:Dynamic, methods:NativeArray<MethodBase>, methodLength:Int, args:Array<Dynamic>):Dynamic
+	public static function callMethod(obj:Dynamic, methods:NativeArray<MethodBase>, methodLength:Int, args:cs.NativeArray<Dynamic>):Dynamic
 	{
 		if (methodLength == 0) throw "No available methods";
 		var length = args.length;
@@ -578,13 +578,13 @@ import cs.system.Object;
 	}
 #end
 
-	public static function slowCallField(obj:Dynamic, field:String, args:Array<Dynamic>):Dynamic
+	public static function slowCallField(obj:Dynamic, field:String, args:cs.NativeArray<Dynamic>):Dynamic
 	{
 		if (field == "toString" && (args == null || args.length == 0))
 		{
 			return obj.ToString();
 		}
-		if (args == null) args = [];
+		if (args == null) args = new cs.NativeArray(0);
 
 		var bf:BindingFlags;
 		var t = Lib.as(obj,cs.system.Type);
@@ -625,14 +625,7 @@ import cs.system.Object;
 		}
 
 		if (last == 0 && t.IsCOMObject)
-		{
-			var oargs = new NativeArray(args.length);
-			for (i in 0...oargs.Length)
-			{
-				oargs[i] = args[i];
-			}
-			return t.InvokeMember(field, BindingFlags.InvokeMethod, null, obj, oargs);
-		}
+			return t.InvokeMember(field, BindingFlags.InvokeMethod, null, obj, args);
 
 		if (last == 0)
 		{
@@ -642,7 +635,7 @@ import cs.system.Object;
 		return Runtime.callMethod(obj, mis, last, args);
 	}
 
-	public static function callField(obj:Dynamic, field:String, fieldHash:Int, args:Array<Dynamic>):Dynamic
+	public static function callField(obj:Dynamic, field:String, fieldHash:Int, args:cs.NativeArray<Dynamic>):Dynamic
 	{
 		var hxObj = Lib.as(obj, HxObject);
 		if (hxObj != null)

+ 11 - 8
std/cs/internal/StringExt.hx

@@ -205,14 +205,17 @@ private typedef NativeString = cs.system.String;
 		}
 	}
 
-	public static function handleCallField(str:NativeString, f:String, args:Array<Dynamic>):Dynamic
+	public static function handleCallField(str:NativeString, f:String, args:cs.NativeArray<Dynamic>):Dynamic
 	{
-		var _args:Array<Dynamic> = [str];
-		if (args == null)
-			args = _args;
-		else
-			args = _args.concat(args);
-
-		return Runtime.slowCallField(StringExt, f, args);
+		var _args:cs.NativeArray<Dynamic>;
+		if (args == null) {
+			_args = cs.NativeArray.make(str);
+		} else {
+			_args = new cs.NativeArray(args.length + 1);
+			for (i in 0...args.length)
+				_args[i + 1] = args[i];
+			_args[0] = str;
+		}
+		return Runtime.slowCallField(StringExt, f, _args);
 	}
 }

+ 2 - 1
std/java/_std/Reflect.hx

@@ -70,7 +70,7 @@ import java.Boot;
 		if (Std.is(o, IHxObject)) {
 			untyped (o : IHxObject).__hx_setField(field, value, true);
 		} else if (Runtime.slowHasField(o, "set_" + field)) {
-			Runtime.slowCallField(o, "set_" + field, [value]);
+			Runtime.slowCallField(o, "set_" + field, java.NativeArray.make(value));
 		} else {
 			Runtime.slowSetField(o, field, value);
 		}
@@ -78,6 +78,7 @@ import java.Boot;
 
 	public static function callMethod( o : Dynamic, func : haxe.Constraints.Function, args : Array<Dynamic> ) : Dynamic
 	{
+		var args = java.Lib.nativeArray(args, true);
 		return untyped (func : Function).__hx_invokeDynamic(args);
 	}
 

+ 9 - 12
std/java/_std/Type.hx

@@ -257,20 +257,17 @@ enum ValueType {
 		}
 	}
 
-	@:functionCode('
-		if (params == null || params.length == 0)
-		{
-			java.lang.Object ret = haxe.lang.Runtime.slowGetField(e, constr, true);
-			if (ret instanceof haxe.lang.Function)
-				throw haxe.lang.HaxeException.wrap("Constructor " + constr + " needs parameters");
-			return (T) ret;
+	public static function createEnum<T>( e : Enum<T>, constr : String, ?params : Array<Dynamic> ) : T {
+		if (params == null || params.length == 0) {
+			var ret:Dynamic = java.internal.Runtime.slowGetField(e, constr, true);
+			if (Std.is(ret, java.internal.Function)) {
+				throw "Constructor " + constr + " needs parameters";
+			}
+			return ret;
 		} else {
-			return (T) haxe.lang.Runtime.slowCallField(e, constr, params);
+			var params = java.Lib.nativeArray(params, true);
+			return java.internal.Runtime.slowCallField(e, constr, params);
 		}
-	')
-	public static function createEnum<T>( e : Enum<T>, constr : String, ?params : Array<Dynamic> ) : T
-	{
-		return null;
 	}
 
 	public static function createEnumIndex<T>( e : Enum<T>, index : Int, ?params : Array<Dynamic> ) : T {

+ 4 - 4
std/java/internal/Function.hx

@@ -39,7 +39,7 @@ import java.internal.Runtime;
 
 @:nativeGen @:native("haxe.lang.VarArgsBase") @:keep private class VarArgsBase extends Function
 {
-	public function __hx_invokeDynamic(dynArgs:Array<Dynamic>):Dynamic
+	public function __hx_invokeDynamic(dynArgs:java.NativeArray<Dynamic>):Dynamic
 	{
 		throw "Abstract implementation";
 	}
@@ -55,9 +55,9 @@ import java.internal.Runtime;
 		this.fun = fun;
 	}
 
-	override public function __hx_invokeDynamic(dynArgs:Array<Dynamic>):Dynamic
+	override public function __hx_invokeDynamic(dynArgs:java.NativeArray<Dynamic>):Dynamic
 	{
-		return fun(dynArgs);
+		return fun(@:privateAccess Array.ofNative(dynArgs));
 	}
 }
 
@@ -73,7 +73,7 @@ import java.internal.Runtime;
 		this.field = field;
 	}
 
-	override public function __hx_invokeDynamic(dynArgs:Array<Dynamic>):Dynamic
+	override public function __hx_invokeDynamic(dynArgs:java.NativeArray<Dynamic>):Dynamic
 	{
 		return Runtime.callField(obj, field, dynArgs);
 	}

+ 6 - 6
std/java/internal/Runtime.hx

@@ -51,7 +51,7 @@ package java.internal;
 		return obj.__hx_setField_f(field, value, false);
 	}
 
-	public static java.lang.Object callField(haxe.lang.IHxObject obj, java.lang.String field, Array<?> args)
+	public static java.lang.Object callField(haxe.lang.IHxObject obj, java.lang.String field, java.lang.Object[] args)
 	{
 		return obj.__hx_invokeField(field, args);
 	}
@@ -362,7 +362,7 @@ package java.internal;
 		if (obj instanceof java.lang.Class)
 		{
 			if (obj == java.lang.String.class && field.equals("fromCharCode"))
-				return haxe.lang.StringExt.fromCharCode(toInt(args.__get(0)));
+				return haxe.lang.StringExt.fromCharCode(toInt(args[0]));
 
 			cl = (java.lang.Class) obj;
 			obj = null;
@@ -372,7 +372,7 @@ package java.internal;
 			cl = obj.getClass();
 		}
 
-		if (args == null) args = new Array();
+		if (args == null) args = new java.lang.Object[0];
 
 		int len = args.length;
 		java.lang.Class[] cls = new java.lang.Class[len];
@@ -398,7 +398,7 @@ package java.internal;
 
 		for (int i = 0; i < len; i++)
 		{
-			Object o = args.__get(i);
+			Object o = args[i];
 			if (o == null)
 			{
 				continue; //can be anything
@@ -498,7 +498,7 @@ package java.internal;
 			throw haxe.lang.HaxeException.wrap(t);
 		}
 	')
-	public static function slowCallField(obj:Dynamic, field:String, args:Array<Dynamic>):Dynamic
+	public static function slowCallField(obj:Dynamic, field:String, args:java.NativeArray<Dynamic>):Dynamic
 	{
 		return null;
 	}
@@ -511,7 +511,7 @@ package java.internal;
 
 		return slowCallField(obj, field, args);
 	')
-	public static function callField(obj:Dynamic, field:String, args:Array<Dynamic>):Dynamic
+	public static function callField(obj:Dynamic, field:String, args:java.NativeArray<Dynamic>):Dynamic
 	{
 		return null;
 	}

+ 11 - 8
std/java/internal/StringExt.hx

@@ -223,15 +223,18 @@ private typedef NativeString = String;
 		}
 	}
 
-	public static function handleCallField(str:NativeString, f:NativeString, args:Array<Dynamic>):Dynamic
+	public static function handleCallField(str:NativeString, f:NativeString, args:java.NativeArray<Dynamic>):Dynamic
 	{
-		var _args:Array<Dynamic> = [str];
-		if (args == null)
-			args = _args;
-		else
-			args = _args.concat(args);
-
-		return Runtime.slowCallField(StringExt, f, args);
+		var _args:java.NativeArray<Dynamic>;
+		if (args == null) {
+			_args = java.NativeArray.make(str);
+		} else {
+			_args = new java.NativeArray(args.length + 1);
+			_args[0] = str;
+			for (i in 0...args.length)
+				_args[i + 1] = args[i];
+		}
+		return Runtime.slowCallField(StringExt, f, _args);
 	}
 }