소스 검색

[cs] use native arrays instead of Array for dynamic method calls

Dan Korostelev 8 년 전
부모
커밋
8c07e26c2e
7개의 변경된 파일42개의 추가작업 그리고 108개의 파일을 삭제
  1. 16 14
      src/generators/gencommon.ml
  2. 2 2
      src/generators/gencs.ml
  3. 2 1
      std/cs/_std/Reflect.hx
  4. 2 2
      std/cs/_std/Type.hx
  5. 4 4
      std/cs/internal/Function.hx
  6. 6 79
      std/cs/internal/Runtime.hx
  7. 10 6
      std/cs/internal/StringExt.hx

+ 16 - 14
src/generators/gencommon.ml

@@ -3200,7 +3200,7 @@ struct
 			let args_real_to_func args =
 				let arity = List.length args in
 				if arity >= max_arity then
-					[ alloc_var (gen.gmk_internal_name "fn" "dynargs") (basic.tarray t_dynamic), None ]
+					[ alloc_var (gen.gmk_internal_name "fn" "dynargs") (gen.gclasses.nativearray t_dynamic), None ]
 				else func_args_i arity
 			in
 
@@ -3219,7 +3219,7 @@ struct
 			let args_real_to_func_sig args =
 				let arity = List.length args in
 				if arity >= max_arity then
-					[gen.gmk_internal_name "fn" "dynargs", false, basic.tarray t_dynamic]
+					[gen.gmk_internal_name "fn" "dynargs", false, gen.gclasses.nativearray t_dynamic]
 				else begin
 					func_sig_i arity
 				end
@@ -3236,7 +3236,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
@@ -3438,7 +3438,7 @@ struct
 				in
 
 				let type_name = gen.gmk_internal_name "fn" "type" in
-				let dynamic_arg = alloc_var (gen.gmk_internal_name "fn" "dynargs") (basic.tarray t_dynamic) in
+				let dynamic_arg = alloc_var (gen.gmk_internal_name "fn" "dynargs") (gen.gclasses.nativearray t_dynamic) in
 
 				let mk_invoke_complete_i i is_float =
 
@@ -3670,7 +3670,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
@@ -7773,7 +7773,7 @@ struct
 		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
 
@@ -7826,9 +7826,12 @@ struct
 				let cases = List.map (switch_case ctx pos) names in
 				(cases,
 					{ eexpr = TReturn(Some (mk_this_call cf (List.map (fun (name,_,t) ->
-							let ret = { eexpr = TArray(dyn_arg_local, ExprBuilder.make_int ctx.rcf_gen.gcon !i pos); etype = t_dynamic; epos = pos } in
+							let eidx = ExprBuilder.make_int ctx.rcf_gen.gcon !i pos in
 							incr i;
-							ret
+							let ret = mk (TArray (dyn_arg_local, eidx)) t_dynamic pos in
+							let elen = gen.gclasses.nativearray_len dyn_arg_local pos in
+							let egt = mk (TBinop (OpGt,elen,eidx)) basic.tbool pos in
+							mk (TIf (egt,ret,Some (ExprBuilder.make_null t_dynamic pos))) t_dynamic pos
 						) (fst (get_args (cf.cf_type))) ) ));
 						etype = basic.tvoid;
 						epos = pos
@@ -7918,14 +7921,13 @@ struct
 	let implement_varargs_cl ctx cl =
 		let pos = cl.cl_pos in
 		let gen = ctx.rcf_gen in
-		let basic = gen.gcon.basic in
 
 		let this_t = TInst(cl, List.map snd cl.cl_params) in
 		let this = { eexpr = TConst(TThis); etype = this_t ; epos = pos } in
 		let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in
 
 		let invokedyn = gen.gmk_internal_name "hx" "invokeDynamic" in
-		let idyn_t = TFun([gen.gmk_internal_name "fn" "dynargs", false, basic.tarray t_dynamic], t_dynamic) in
+		let idyn_t = TFun([gen.gmk_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 =
@@ -7941,9 +7943,9 @@ struct
 			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 = {
@@ -8004,9 +8006,9 @@ struct
 			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

@@ -2838,9 +2838,9 @@ let configure gen =
 		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 - 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

@@ -163,7 +163,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
@@ -200,7 +200,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(new 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 - 79
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,79 +578,13 @@ import cs.system.Object;
 	}
 #end
 
-	// @:functionCode('
-	// 	if (field == "toString")
-	// 	{
-	// 		if (args == null)
-	// 			return obj.ToString();
-	// 		field = "ToString";
-	// 	}
-	// 	if (args == null) args = new Array<object>();
-
-	// 	System.Reflection.BindingFlags bf;
-	// 	System.Type t = obj as System.Type;
-	// 	if (t == null)
-	// 	{
-	// 		string s = obj as string;
-	// 		if (s != null)
-	// 			return haxe.lang.StringRefl.handleCallField(s, field, args);
-	// 		t = obj.GetType();
-	// 		bf = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
-	// 	} else {
-	// 		if (t == typeof(string) && field.Equals("fromCharCode"))
-	// 			return haxe.lang.StringExt.fromCharCode(toInt(args[0]));
-	// 		obj = null;
-	// 		bf = System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public;
-	// 	}
-
-	// 	System.Reflection.MethodInfo[] mis = t.GetMethods(bf);
-	// 	int last = 0;
-	// 	for (int i = 0; i < mis.Length; i++)
-	// 	{
-	// 		string name = mis[i].Name;
-	// 		if (name.Equals(field))
-	// 		{
-	// 			mis[last++] = mis[i];
-	// 		}
-	// 	}
-
-	// 	if (last == 0 && (field == "__get" || field == "__set"))
-	// 	{
-	// 		field = field == "__get" ? "get_Item" : "set_Item";
-	// 		for (int i = 0; i < mis.Length; i++)
-	// 		{
-	// 			string name = mis[i].Name;
-	// 			if (name.Equals(field))
-	// 			{
-	// 				mis[last++] = mis[i];
-	// 			}
-	// 		}
-	// 	}
-
-	// 	if (last == 0 && t.IsCOMObject)
-	// 	{
-	// 		object[] oargs = new object[arrLen(args)];
-	// 		for (int i = 0; i < oargs.Length; i++)
-	// 		{
-	// 			oargs[i] = args[i];
-	// 		}
-	// 		return t.InvokeMember(field, System.Reflection.BindingFlags.InvokeMethod, null, obj, oargs);
-	// 	}
-
-	// 	if (last == 0)
-	// 	{
-	// 		throw haxe.lang.HaxeException.wrap("Method \'" + field + "\' not found on type " + t);
-	// 	}
-
-	// 	return haxe.lang.Runtime.callMethod(obj, mis, last, args);
-	// ')
-	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);
@@ -691,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)
 		{
@@ -708,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)

+ 10 - 6
std/cs/internal/StringExt.hx

@@ -205,14 +205,18 @@ 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];
+		var _args;
 		if (args == null)
-			args = _args;
-		else
-			args = _args.concat(args);
+			_args = cs.NativeArray.make(str);
+		else {
+			_args = new cs.NativeArray(args.length + 1);
+			for (i in 0...args.length)
+				_args[i] = args[i];
+			_args[args.length] = str;
+		}
 
-		return Runtime.slowCallField(StringExt, f, args);
+		return Runtime.slowCallField(StringExt, f, _args);
 	}
 }