Przeglądaj źródła

[java/cs] Addded support for Reflect.get/setProperty; Tried to eliminate code duplication between reflection helpers but had to revert for now.
[cs] fixed some minor problems with Type API

Caue Waneck 13 lat temu
rodzic
commit
25e9e32eba

+ 98 - 54
gencommon.ml

@@ -5602,7 +5602,7 @@ struct
   
   (*
     Will implement getField / setField which will follow the following rule:
-      function getField(field, isStatic, throwErrors, isCheck):Dynamic
+      function getField(field, isStatic, throwErrors, isCheck, handleProperty, isFirst):Dynamic
       {
         if (isStatic)
         {
@@ -5610,7 +5610,9 @@ struct
           {
             case "aStaticField": return ThisClass.aStaticField;
             case "aDynamicField": return ThisClass.aDynamicField;
-            default: if(throwErrors) throw "Field not found"; else if (isCheck) return __undefined__ else return null;
+            default: 
+              if (isFirst) return getField_d(field, isStatic, throwErrors, handleProperty, false);
+              if(throwErrors) throw "Field not found"; else if (isCheck) return __undefined__ else   return null;
           }
         } else {
           switch(field)
@@ -5623,7 +5625,7 @@ struct
         }
       }
       
-      function getField_d(field, isStatic, throwErrors):Float
+      function getField_d(field, isStatic, throwErrors, handleProperty, isFirst):Float
       {
         if (isStatic)
         {
@@ -5656,6 +5658,9 @@ struct
   
   let mk_int ctx i pos = 
     { eexpr = TConst(TInt(Int32.of_int i)); etype = ctx.rcf_gen.gcon.basic.tint; epos = pos }
+    
+  let mk_bool ctx b pos = 
+    { eexpr = TConst(TBool(b)); etype = ctx.rcf_gen.gcon.basic.tbool; epos = pos }
   
   let mk_throw ctx str pos = { eexpr = TThrow (mk_string ctx str pos); etype = ctx.rcf_gen.gcon.basic.tvoid; epos = pos }
   
@@ -6153,13 +6158,13 @@ struct
   
   (*
     Implements:
-      __hx_lookupField(field:String, throwErrors:Bool, isCheck:Bool):Dynamic
+      __hx_lookupField(field:String, throwErrors:Bool, isCheck:Bool, handleProperties:Bool, isFirst:Bool):Dynamic
       
-      __hx_lookupField_f(field:String, throwErrors:Bool):Float
+      __hx_lookupField_f(field:String, throwErrors:Bool, handleProperties:Bool, isFirst:Bool):Float
       
-      __hx_lookupSetField(field:String, value:Dynamic):Dynamic;
+      __hx_lookupSetField(field:String, value:Dynamic, handleProperties:Bool, isFirst:Bool):Dynamic;
       
-      __hx_lookupSetField(field:String, value:Float):Float;
+      __hx_lookupSetField(field:String, value:Float, handleProperties:Bool, isFirst:Bool):Float;
   *)
   let implement_final_lookup ctx cl =
     let gen = ctx.rcf_gen in
@@ -6167,6 +6172,8 @@ struct
     let pos = cl.cl_pos in
     let is_override = is_override cl in
     
+    let this = { eexpr = TConst(TThis); etype = TInst(cl, List.map snd cl.cl_types); epos = pos } in
+    
     (*
       this function will create the class fields and call callback for each version
       
@@ -6212,18 +6219,23 @@ struct
           } in
           
           let mk_may_check_throw msg = if is_dynamic then mk_return (null ret_t pos) else mk_check_throw msg in
-          if is_float then
-            mk_may_check_throw "Field not found or incompatible field type."
-          else
+          if is_float then begin
+            [
+              mk_may_check_throw "Field not found or incompatible field type.";
+            ]
+          end else begin
             let undefined = alloc_var "__undefined__" t_dynamic in
             let undefined_local = mk_local undefined pos in
             let is_check_local = mk_local (get is_check_opt) pos in
-            {
-              eexpr = TIf(is_check_local, mk_return undefined_local, Some( mk_may_check_throw "Field not found." ));
-              etype = ret_t;
-              epos = pos;
-            }
-        end in block @ [tl] else block in
+            [
+              {
+                eexpr = TIf(is_check_local, mk_return undefined_local, Some( mk_may_check_throw "Field not found." ));
+                etype = ret_t;
+                epos = pos;
+              }
+            ]
+          end
+        end in block @ tl else block in
         cf.cf_expr <- Some(
           {
             eexpr = TFunction({
@@ -6251,7 +6263,6 @@ struct
       ) cfs
     in
     
-    let this = { eexpr = TConst(TThis); etype = TInst(cl, List.map snd cl.cl_types); epos = pos } in
     if is_some cl.cl_dynamic then begin
       (* let abstract_dyn_lookup_implementation ctx this hash_local may_value is_float pos = *)
       (* callback : is_float fields_args switch_var throw_errors_option is_check_option value_option : texpr list *)
@@ -6284,6 +6295,9 @@ struct
       let is_static = alloc_var "isStatic" basic.tbool in
       let is_static_local = { eexpr = TLocal(is_static); etype = basic.tbool; epos = pos } in
       
+      let handle_prop = alloc_var "handleProperties" basic.tbool in
+      let handle_prop_local = mk_local handle_prop pos in
+      
       let mk_this_call_raw name fun_t params =
         { eexpr = TCall( { eexpr = TField({ eexpr = TConst(TThis); etype = TInst(cl, List.map snd cl.cl_types); epos = pos }, name); etype = fun_t; epos = pos  }, params ); etype = snd (get_args fun_t); epos = pos }
       in
@@ -6327,38 +6341,43 @@ struct
       let do_default, do_default_static , do_field, tf_args = if is_set then begin
         let value_var = alloc_var "value" (if is_float then basic.tfloat else t_dynamic) in
         let value_local = { eexpr = TLocal(value_var); etype = value_var.v_type; epos = pos } in
-        let tf_args = tf_args @ [value_var,None] in
+        let tf_args = tf_args @ [value_var,None; handle_prop, None; ] in
         let lookup_name = gen.gmk_internal_name "hx" ("lookupSetField" ^ if is_float then "_f" else "") in
+        
         let do_default = 
-            fun () -> mk_return (mk_this_call_raw lookup_name (TFun(fun_args (field_args @ [value_var,None]),value_var.v_type)) ( List.map (fun (v,_) -> mk_local v pos) field_args @ [ value_local ] ))
+            fun () -> 
+              mk_return (mk_this_call_raw lookup_name (TFun(fun_args (field_args @ [value_var,None]),value_var.v_type)) ( List.map (fun (v,_) -> mk_local v pos) field_args @ [ value_local ] ))
         in
         
         let do_field cf cf_type is_static =
           let get_field ethis name = { eexpr = TField (ethis, name); etype = cf_type; epos = pos } in
           let this = if is_static then mk_classtype_access cl pos else { eexpr = TConst(TThis); etype = t; epos = pos } in
-          match is_float, follow cf_type with
-            | true, TInst( { cl_kind = KTypeParameter }, [] ) -> 
+          
+          let ret = mk_return 
+          { 
+            eexpr = TBinop(Ast.OpAssign, 
+              get_field this cf.cf_name,
+              mk_cast cf_type value_local);
+            etype = cf_type;
+            epos = pos;
+          } in
+          match cf.cf_kind with
+            | Var { v_write = AccCall fn } ->
               let bl = 
               [
-                { 
-                  eexpr = TBinop(Ast.OpAssign, 
-                    get_field this cf.cf_name,
-                    mk_cast cf_type (mk_cast t_dynamic value_local));
-                  etype = cf_type;
-                  epos = pos;
-                };
+                mk_this_call_raw fn (TFun(["value",false,cf.cf_type], cf.cf_type)) [ value_local ];
                 mk_return value_local
               ] in
-              { eexpr = TBlock bl; etype = value_local.etype; epos = pos }
-            | _ ->
-              mk_return 
-              { 
-                eexpr = TBinop(Ast.OpAssign, 
-                  get_field this cf.cf_name,
-                  mk_cast cf_type value_local);
-                etype = cf_type;
+              {
+                eexpr = TIf(
+                  handle_prop_local,
+                  { eexpr = TBlock bl; etype = value_local.etype; epos = pos },
+                  Some ret);
+                etype = value_local.etype;
                 epos = pos;
               }
+            | _ ->
+              ret
         in
         
         (mk_do_default tf_args do_default, do_default, do_field, tf_args)
@@ -6370,24 +6389,40 @@ struct
           let is_check = alloc_var "isCheck" basic.tbool in
           let is_check_local = mk_local is_check pos in
           
+          let tf_args = tf_args @ [ throw_errors,None; ] in
+          
           (* default: if (isCheck) return __undefined__ else if(throwErrors) throw "Field not found"; else return null; *)
           let lookup_name = gen.gmk_internal_name "hx" "lookupField" in
           let do_default = 
-              fun () -> mk_return (mk_this_call_raw lookup_name (TFun(fun_args (field_args @ [throw_errors,None;is_check,None]),t_dynamic)) ( List.map (fun (v,_) -> mk_local v pos) field_args @ [ throw_errors_local; is_check_local ] ) )
+              fun () -> 
+                mk_return (mk_this_call_raw lookup_name (TFun(fun_args (field_args @ [throw_errors,None;is_check,None; ]),t_dynamic)) ( List.map (fun (v,_) -> mk_local v pos) field_args @ [ throw_errors_local; is_check_local; ] ))
           in
           
-          (do_default, tf_args @ [ throw_errors,None; is_check,None ])
+          (do_default, tf_args @ [ is_check,None; handle_prop,None; ])
         end else begin
+          let tf_args = tf_args @ [ throw_errors,None; ] in
+        
           let lookup_name = gen.gmk_internal_name "hx" "lookupField_f" in
           let do_default = 
-              fun () -> mk_return (mk_this_call_raw lookup_name (TFun(fun_args (field_args @ [throw_errors,None]),basic.tfloat)) ( List.map (fun (v,_) -> mk_local v pos) field_args @ [ throw_errors_local ] ))
+              fun () -> 
+                mk_return (mk_this_call_raw lookup_name (TFun(fun_args (field_args @ [throw_errors,None; ]),basic.tfloat)) ( List.map (fun (v,_) -> mk_local v pos) field_args @ [ throw_errors_local; ] ))
           in
           
-          (do_default, tf_args @ [ throw_errors,None ])
+          (do_default, tf_args @ [ handle_prop,None; ])
         end in
         
         let get_field cf cf_type ethis name = 
           match cf.cf_kind with
+            | Var { v_read = AccCall fn } ->
+              {
+                eexpr = TIf(
+                  handle_prop_local,
+                  mk_return (mk_this_call_raw fn (TFun(["value",false,cf.cf_type], cf.cf_type)) [  ]),
+                  Some { eexpr = TField (ethis, name); etype = cf_type; epos = pos }
+                );
+                etype = cf_type;
+                epos = pos;
+              }
             | Var _
             | Method MethDynamic -> { eexpr = TField (ethis, name); etype = cf_type; epos = pos }
             | _ -> { eexpr = TClosure (ethis, name); etype = cf_type; epos = pos }
@@ -6407,14 +6442,18 @@ struct
       let get_fields static =
         let ret = collect_fields cl ( if is_float || is_set then Some (false) else None ) (Some static) in
         let ret = if is_set then List.filter (fun (_,cf) -> not (has_meta ":readonly" cf.cf_meta)) ret else ret in
-        if is_float then List.filter (fun (_,cf) -> (* TODO: maybe really apply_params in cf.cf_type. The benefits would be limited, though *)
-          match follow (ctx.rcf_gen.greal_type (ctx.rcf_gen.gfollow#run_f cf.cf_type)) with
-            | TInst ({ cl_path = ([], "Float") }, [])
-            | TInst ({ cl_path = ([], "Int") }, [])
-            | TDynamic _ 
-            | TInst ({ cl_kind = KTypeParameter },_) -> true
-            | _ -> false
-        ) ret else ret
+        if is_float then 
+          List.filter (fun (_,cf) -> (* TODO: maybe really apply_params in cf.cf_type. The benefits would be limited, though *)
+            match follow (ctx.rcf_gen.greal_type (ctx.rcf_gen.gfollow#run_f cf.cf_type)) with
+              | TDynamic _ | TMono _
+              | TInst ({ cl_kind = KTypeParameter }, _)
+              | TInst ({ cl_path = ([], "Float") }, [])
+              | TInst ({ cl_path = ([], "Int") }, []) -> true
+              | _ -> false
+          ) ret 
+        else
+          (* dynamic will always contain all references *)
+          ret
       in
       
       (* now we have do_default, do_field and tf_args *)
@@ -6483,6 +6522,7 @@ struct
     let tf_args, args = if is_set then tf_args @ [ "setVal", false, rett ], args @ [get set_option] else tf_args, args in
     let tf_args, args = tf_args @ [ "throwErrors",false,basic.tbool ], args @ [throw_errors] in
     let tf_args, args = if is_set || is_float then tf_args, args else tf_args @ [ "isCheck", false, basic.tbool ], args @ [{ eexpr = TConst(TBool false); etype = basic.tbool; epos = pos }] in
+    let tf_args, args = tf_args @ [ "handleProperties",false,basic.tbool; ], args @ [ mk_bool ctx false pos; ] in
     
     {
       eexpr = TCall({
@@ -6581,19 +6621,18 @@ struct
       let tf_args = (v_base_arr,None) :: (if ctx.rcf_handle_statics then [v_is_inst, None] else []) in
       let t = TFun(fun_args tf_args, basic.tvoid) in
       let cf = mk_class_field name t false pos (Method MethNormal) [] in
-      cl.cl_ordered_fields <- cl.cl_ordered_fields @ [cf];
-      cl.cl_fields <- PMap.add cf.cf_name cf cl.cl_fields;
-      (if is_override cl then cl.cl_overrides <- name :: cl.cl_overrides);
       
       let mk_push value =
         { eexpr = TCall({ eexpr = TField(base_arr, "push"); etype = TFun(["x", false, basic.tstring], basic.tint); epos = pos}, [value] ); etype = basic.tint; epos = pos }
       in
       
+      let has_value = ref false in
       let map_fields =
         List.map (fun (_,cf) ->
           match cf.cf_kind with
             | Var _
-            | Method _ when not (List.mem cf.cf_name cl.cl_overrides) ->
+            | Method MethDynamic when not (List.mem cf.cf_name cl.cl_overrides) ->
+              has_value := true;
               mk_push { eexpr = TConst(TString(cf.cf_name)); etype = basic.tstring; epos = pos }
             | _ -> null basic.tvoid pos
         )
@@ -6662,6 +6701,11 @@ struct
         tf_expr = expr
       } in
       
+      (if !has_value || (not (is_override cl)) then begin
+        cl.cl_ordered_fields <- cl.cl_ordered_fields @ [cf];
+        cl.cl_fields <- PMap.add cf.cf_name cf cl.cl_fields;
+        (if is_override cl then cl.cl_overrides <- name :: cl.cl_overrides)
+      end);
       cf.cf_expr <- Some { eexpr = TFunction(fn); etype = t; epos = pos }
     in
     ignore fields
@@ -6801,8 +6845,8 @@ struct
       register_cf (do_proxy "getField_f" (fst_args @ [ alloc_var "isStatic" basic.tbool, None; alloc_var "throwErrors" basic.tbool, None ]) basic.tfloat fst_args_len) true;
       register_cf (do_proxy "setField_f" (fst_args @ [ alloc_var "isStatic" basic.tbool, None; alloc_var "value" basic.tfloat, None ]) basic.tfloat fst_args_len) true
     );
-    register_cf (do_proxy "getField" (fst_args @ [ alloc_var "isStatic" basic.tbool, None; alloc_var "throwErrors" basic.tbool, None; alloc_var "isCheck" basic.tbool, None ]) t_dynamic fst_args_len) true;
-    register_cf (do_proxy "setField" (fst_args @ [ alloc_var "isStatic" basic.tbool, None; alloc_var "value" t_dynamic, None ]) t_dynamic fst_args_len) true;
+    register_cf (do_proxy "getField" (fst_args @ [ alloc_var "isStatic" basic.tbool, None; alloc_var "throwErrors" basic.tbool, None; alloc_var "isCheck" basic.tbool, None; alloc_var "handleProperties" basic.tbool,None; ]) t_dynamic fst_args_len) true;
+    register_cf (do_proxy "setField" (fst_args @ [ alloc_var "isStatic" basic.tbool, None; alloc_var "value" t_dynamic, None; alloc_var "handleProperties" basic.tbool,None; ]) t_dynamic fst_args_len) true;
     
     (* invokeField -> redir the method with static = true *)
     register_cf (do_proxy "invokeField" (fst_args @ [ alloc_var "isStatic" basic.tbool, None; alloc_var "dynArgs" (basic.tarray t_dynamic), None ]) t_dynamic fst_args_len) true;

+ 15 - 3
std/cs/_std/Reflect.hx

@@ -35,7 +35,7 @@ import haxe.lang.Function;
 	**/
 	@:functionBody('
 		if (o is haxe.lang.IHxObject)
-			return ((haxe.lang.IHxObject) o).__hx_getField(field, haxe.lang.FieldLookup.hash(field), false, true) != haxe.lang.Runtime.undefined;
+			return ((haxe.lang.IHxObject) o).__hx_getField(field, haxe.lang.FieldLookup.hash(field), false, true, false) != haxe.lang.Runtime.undefined;
 		
 		return haxe.lang.Runtime.slowHasField(o, field);
 	')
@@ -49,7 +49,7 @@ import haxe.lang.Function;
 	**/
 	@:functionBody('
 		if (o is haxe.lang.IHxObject)
-			return ((haxe.lang.IHxObject) o).__hx_getField(field, haxe.lang.FieldLookup.hash(field), false, false);
+			return ((haxe.lang.IHxObject) o).__hx_getField(field, haxe.lang.FieldLookup.hash(field), false, false, false);
 		
 		return haxe.lang.Runtime.slowGetField(o, field, false);
 	')
@@ -64,7 +64,7 @@ import haxe.lang.Function;
 	**/
 	@:functionBody('
 		if (o is haxe.lang.IHxObject)
-			((haxe.lang.IHxObject) o).__hx_setField(field, haxe.lang.FieldLookup.hash(field), value);
+			((haxe.lang.IHxObject) o).__hx_setField(field, haxe.lang.FieldLookup.hash(field), value, false);
 		else
 			haxe.lang.Runtime.slowSetField(o, field, value);
 	')
@@ -76,6 +76,12 @@ import haxe.lang.Function;
 	/**
 		Similar to field but also supports property (might be slower).
 	**/
+	@:functionBody('
+		if (o is haxe.lang.IHxObject)
+			return ((haxe.lang.IHxObject) o).__hx_getField(field, haxe.lang.FieldLookup.hash(field), false, false, true);
+		
+		return haxe.lang.Runtime.slowGetField(o, field, false);
+	')
 	public static function getProperty( o : Dynamic, field : String ) : Dynamic
 	{
 		return null;
@@ -84,6 +90,12 @@ import haxe.lang.Function;
 	/**
 		Similar to setField but also supports property (might be slower).
 	**/
+	@:functionBody('
+		if (o is haxe.lang.IHxObject)
+			((haxe.lang.IHxObject) o).__hx_setField(field, haxe.lang.FieldLookup.hash(field), value, true);
+		else
+			haxe.lang.Runtime.slowSetField(o, field, value);
+	')
 	public static function setProperty( o : Dynamic, field : String, value : Dynamic ) : Void
 	{
 		

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

@@ -146,7 +146,7 @@ enum ValueType {
 	{
 		var t:system.Type = Lib.toNativeType(cl);
 		var ctors = t.GetConstructors();
-		return Runtime.callMethod(t, cast ctors, ctors.Length, args);
+		return Runtime.callMethod(null, cast ctors, ctors.Length, args);
 	}
 
 	public static function createEmptyInstance<T>( cl : Class<T> ) : T 

+ 16 - 9
std/cs/_std/haxe/lang/Runtime.hx

@@ -18,23 +18,23 @@ import system.Type;
 	public static object getField(haxe.lang.HxObject obj, string field, int fieldHash, bool throwErrors)
 	{
 		if (obj == null && !throwErrors) return null;
-		return obj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false);
+		return obj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false, false);
 	}
 	
 	public static double getField_f(haxe.lang.HxObject obj, string field, int fieldHash, bool throwErrors)
 	{
 		if (obj == null && !throwErrors) return 0.0;
-		return obj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors);
+		return obj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false);
 	}
 	
 	public static object setField(haxe.lang.HxObject obj, string field, int fieldHash, object value)
 	{
-		return obj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value);
+		return obj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false);
 	}
 	
 	public static double setField_f(haxe.lang.HxObject obj, string field, int fieldHash, double value)
 	{
-		return obj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value);
+		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)
@@ -395,7 +395,14 @@ import system.Type;
 			return haxe.lang.Runtime.unbox(retg);
 		}
 		
-		var ret = methods[0].Invoke(obj, oargs);
+		var m = methods[0];
+		if (obj == null && Std.is(m, system.reflection.ConstructorInfo))
+		{
+			var ret = cast(m, system.reflection.ConstructorInfo).Invoke(oargs);
+			return unbox(ret);
+		}
+		
+		var ret = m.Invoke(obj, oargs);
 		return unbox(ret);
 	}
 	
@@ -471,7 +478,7 @@ import system.Type;
 	
 		haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
 		if (hxObj != null)
-			return hxObj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false);
+			return hxObj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false, false);
 		
 		return slowGetField(obj, field, throwErrors);
 	
@@ -485,7 +492,7 @@ import system.Type;
 	
 		haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
 		if (hxObj != null)
-			return hxObj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors);
+			return hxObj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false);
 		
 		return (double)slowGetField(obj, field, throwErrors);
 	
@@ -499,7 +506,7 @@ import system.Type;
 	
 		haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
 		if (hxObj != null)
-			return hxObj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value);
+			return hxObj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false);
 		
 		return slowSetField(obj, field, value);
 	
@@ -513,7 +520,7 @@ import system.Type;
 
 		haxe.lang.HxObject hxObj = obj as haxe.lang.HxObject;
 		if (hxObj != null)
-			return hxObj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value);
+			return hxObj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false);
 		
 		return (double)slowSetField(obj, field, value);
 	

+ 2 - 0
std/cs/_std/system/reflection/ConstructorInfo.hx

@@ -3,4 +3,6 @@ import cs.NativeArray;
 
 @:native('System.Reflection.ConstructorInfo') extern class ConstructorInfo extends MethodBase
 {
+	@:overload(function(args:NativeArray<Dynamic>):Dynamic {})
+	override function Invoke(obj:Dynamic, args:NativeArray<Dynamic>):Dynamic;
 }

+ 1 - 0
std/cs/_std/system/reflection/MethodBase.hx

@@ -7,5 +7,6 @@ import cs.NativeArray;
 	var ContainsGenericParameters(default, null):Bool;
 	function GetParameters():NativeArray<ParameterInfo>;
 	function GetGenericArguments():NativeArray<system.Type>;
+	@:overload(function():Dynamic {})
 	function Invoke(obj:Dynamic, args:NativeArray<Dynamic>):Dynamic;
 }

+ 15 - 3
std/java/_std/Reflect.hx

@@ -36,7 +36,7 @@ import java.Boot;
 	**/
 	@:functionBody('
 		if (o instanceof haxe.lang.IHxObject)
-			return ((haxe.lang.IHxObject) o).__hx_getField(field, false, true) != haxe.lang.Runtime.undefined;
+		return ((haxe.lang.IHxObject) o).__hx_getField(field, false, true, false) != haxe.lang.Runtime.undefined;
 		
 		return haxe.lang.Runtime.slowHasField(o, field);
 	')
@@ -50,7 +50,7 @@ import java.Boot;
 	**/
 	@:functionBody('
 		if (o instanceof haxe.lang.IHxObject)
-			return ((haxe.lang.IHxObject) o).__hx_getField(field, false, false);
+			return ((haxe.lang.IHxObject) o).__hx_getField(field, false, false, false);
 		
 		return haxe.lang.Runtime.slowGetField(o, field, false);
 	')
@@ -65,7 +65,7 @@ import java.Boot;
 	**/
 	@:functionBody('
 		if (o instanceof haxe.lang.IHxObject)
-			((haxe.lang.IHxObject) o).__hx_setField(field, value);
+			((haxe.lang.IHxObject) o).__hx_setField(field, value, false);
 		else
 			haxe.lang.Runtime.slowSetField(o, field, value);
 	')
@@ -77,6 +77,12 @@ import java.Boot;
 	/**
 		Similar to field but also supports property (might be slower).
 	**/
+	@:functionBody('
+		if (o instanceof haxe.lang.IHxObject)
+			return ((haxe.lang.IHxObject) o).__hx_getField(field, false, false, true);
+		
+		return haxe.lang.Runtime.slowGetField(o, field, false);
+	')
 	public static function getProperty( o : Dynamic, field : String ) : Dynamic
 	{
 		return null;
@@ -85,6 +91,12 @@ import java.Boot;
 	/**
 		Similar to setField but also supports property (might be slower).
 	**/
+	@:functionBody('
+		if (o instanceof haxe.lang.IHxObject)
+			((haxe.lang.IHxObject) o).__hx_setField(field, value, true);
+		else
+			haxe.lang.Runtime.slowSetField(o, field, value);
+	')
 	public static function setProperty( o : Dynamic, field : String, value : Dynamic ) : Void
 	{
 		

+ 8 - 8
std/java/_std/haxe/lang/Runtime.hx

@@ -10,23 +10,23 @@ package haxe.lang;
 	public static java.lang.Object getField(haxe.lang.IHxObject obj, java.lang.String field, boolean throwErrors)
 	{
 		if (obj == null && !throwErrors) return null;
-		return obj.__hx_getField(field, throwErrors, false);
+		return obj.__hx_getField(field, throwErrors, false, false);
 	}
 	
 	public static double getField_f(haxe.lang.IHxObject obj, java.lang.String field, boolean throwErrors)
 	{
 		if (obj == null && !throwErrors) return 0.0;
-		return obj.__hx_getField_f(field, throwErrors);
+		return obj.__hx_getField_f(field, throwErrors, false);
 	}
 	
 	public static java.lang.Object setField(haxe.lang.IHxObject obj, java.lang.String field, java.lang.Object value)
 	{
-		return obj.__hx_setField(field, value);
+		return obj.__hx_setField(field, value, false);
 	}
 	
 	public static double setField_f(haxe.lang.IHxObject obj, java.lang.String field, double value)
 	{
-		return obj.__hx_setField_f(field, value);
+		return obj.__hx_setField_f(field, value, false);
 	}
 	
 	public static java.lang.Object callField(haxe.lang.IHxObject obj, java.lang.String field, Array<?> args)
@@ -456,7 +456,7 @@ package haxe.lang;
 	@:functionBody('
 	
 		if (obj instanceof haxe.lang.IHxObject)
-			return ((haxe.lang.IHxObject) obj).__hx_getField(field, throwErrors, false);
+			return ((haxe.lang.IHxObject) obj).__hx_getField(field, throwErrors, false, false);
 		
 		return slowGetField(obj, field, throwErrors);
 	
@@ -469,7 +469,7 @@ package haxe.lang;
 	@:functionBody('
 	
 		if (obj instanceof haxe.lang.IHxObject)
-			return ((haxe.lang.IHxObject) obj).__hx_getField_f(field, throwErrors);
+			return ((haxe.lang.IHxObject) obj).__hx_getField_f(field, throwErrors, false);
 		
 		return toDouble(slowGetField(obj, field, throwErrors));
 	
@@ -482,7 +482,7 @@ package haxe.lang;
 	@:functionBody('
 	
 		if (obj instanceof haxe.lang.IHxObject)
-			return ((haxe.lang.IHxObject) obj).__hx_setField(field, value);
+			return ((haxe.lang.IHxObject) obj).__hx_setField(field, value, false);
 		
 		return slowSetField(obj, field, value);
 	
@@ -495,7 +495,7 @@ package haxe.lang;
 	@:functionBody('
 	
 		if (obj instanceof haxe.lang.IHxObject)
-			return ((haxe.lang.IHxObject) obj).__hx_setField_f(field, value);
+			return ((haxe.lang.IHxObject) obj).__hx_setField_f(field, value, false);
 		
 		return toDouble(slowSetField(obj, field, value));