[reflection] Move System.RuntimeType.GetPropertiesByName to managed
authorAleksey Kliger <aleksey@xamarin.com>
Thu, 14 Jul 2016 23:15:35 +0000 (19:15 -0400)
committerAleksey Kliger <aleksey@xamarin.com>
Thu, 14 Jul 2016 23:15:35 +0000 (19:15 -0400)
mcs/class/corlib/ReferenceSources/RuntimeType.cs
mono/metadata/icall-def.h
mono/metadata/icall.c

index 881cc66939ce5b3fe7ae9d74a8e6c1ba6e14bcf3..08159216f565de940787de6b3441daf5875ce092 100644 (file)
@@ -489,7 +489,7 @@ namespace System
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               extern RuntimePropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, Type reflected_type);              
+               extern IntPtr GetPropertiesByName_native (string name, BindingFlags bindingAttr, bool icase);           
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern IntPtr GetConstructors_native (BindingFlags bindingAttr);
@@ -508,6 +508,19 @@ namespace System
                        }
                }
 
+               RuntimePropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, RuntimeType reflectedType)
+               {
+                       var refh = new RuntimeTypeHandle (reflectedType);
+                       using (var h = new Mono.SafeGPtrArrayHandle (GetPropertiesByName_native (name, bindingAttr, icase), false)) {
+                               var n = h.Length;
+                               var a = new RuntimePropertyInfo [n];
+                               for (int i = 0; i < n; i++) {
+                                       var ph = new Mono.RuntimePropertyHandle (h[i]);
+                                       a[i] = (RuntimePropertyInfo) PropertyInfo.GetPropertyFromHandle (ph, refh);
+                               }
+                               return a;
+                       }
+               }
 
                public override InterfaceMapping GetInterfaceMap (Type ifaceType)
                {
index 0eb418d783732aacee0ab8cad7e6188a63c4d007..757ed8c5be79f0dbc270a476f5eb2c9c359d997a 100644 (file)
@@ -754,7 +754,7 @@ ICALL(RT_11, "GetInterfaces", ves_icall_RuntimeType_GetInterfaces)
 ICALL(RT_12, "GetMethodsByName_native", ves_icall_RuntimeType_GetMethodsByName_native)
 ICALL(RT_13, "GetNestedTypes_internal", ves_icall_RuntimeType_GetNestedTypes)
 ICALL(RT_14, "GetPacking", ves_icall_RuntimeType_GetPacking)
-ICALL(RT_15, "GetPropertiesByName", ves_icall_RuntimeType_GetPropertiesByName)
+ICALL(RT_15, "GetPropertiesByName_native", ves_icall_RuntimeType_GetPropertiesByName_native)
 ICALL(RT_16, "GetTypeCodeImplInternal", ves_icall_type_GetTypeCodeInternal)
 ICALL(RT_28, "IsTypeExportedToWindowsRuntime", ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime)
 ICALL(RT_29, "IsWindowsRuntimeObjectType", ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType)
index 3231dcdde6205733f3d494e882fbf878a6a023d9..a0b84c1da89dc6d25d3dc60f4f7c3e217705844c 100644 (file)
@@ -4145,34 +4145,27 @@ property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
        return method_nonpublic (accessor, start_klass);
 }
 
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
+ICALL_EXPORT GPtrArray*
+ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case)
 {
        MonoError error;
-       MonoDomain *domain; 
        MonoClass *startklass, *klass;
-       MonoArray *res;
        MonoMethod *method;
        MonoProperty *prop;
-       int i, match;
+       int match;
        guint32 flags;
        gchar *propname = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;
        gpointer iter;
        GHashTable *properties = NULL;
-       MonoPtrArray tmp_array;
+       GPtrArray *res_array;
 
-       mono_error_init (&error);
-       
-       domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref) {
-               res = mono_array_new_cached (domain, mono_class_get_property_info_class (), 0, &error);
-               mono_error_set_pending_exception (&error);
-               return res;
+               return g_ptr_array_new ();
        }
 
-       mono_ptr_array_init (tmp_array, 8, MONO_ROOT_SOURCE_REFLECTION, "temporary reflection properties list"); /*This the average for ASP.NET types*/
-
+       mono_error_init (&error);
+       
        klass = startklass = mono_class_from_mono_type (type->type);
 
        if (name != NULL) {
@@ -4182,6 +4175,8 @@ ves_icall_RuntimeType_GetPropertiesByName (MonoReflectionType *type, MonoString
                compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
        }
 
+       res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
+
        properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
 handle_parent:
        mono_class_setup_methods (klass);
@@ -4233,10 +4228,7 @@ handle_parent:
                if (g_hash_table_lookup (properties, prop))
                        continue;
 
-               MonoReflectionProperty *pr = mono_property_get_object_checked (domain, startklass, prop, &error);
-               if (!pr)
-                       goto failure;
-               mono_ptr_array_append (tmp_array, pr);
+               g_ptr_array_add (res_array, prop);
                
                g_hash_table_insert (properties, prop, prop);
        }
@@ -4246,28 +4238,18 @@ handle_parent:
        g_hash_table_destroy (properties);
        g_free (propname);
 
-       res = mono_array_new_cached (domain, mono_class_get_property_info_class (), mono_ptr_array_size (tmp_array), &error);
-       if (!is_ok (&error))
-               goto failure;
-       for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
-               mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
-
-       mono_ptr_array_destroy (tmp_array);
-
-       return res;
-
+       return res_array;
 
 
 loader_error:
        if (mono_class_has_failure (klass))
                mono_error_set_for_class_failure (&error, klass);
 
-failure:
        if (properties)
                g_hash_table_destroy (properties);
        if (name)
                g_free (propname);
-       mono_ptr_array_destroy (tmp_array);
+       g_ptr_array_free (res_array, FALSE);
 
        mono_error_set_pending_exception (&error);