Merge pull request #3320 from lambdageek/dev/reflection-in-managed
[mono.git] / mono / metadata / icall.c
index eb1ca5958dd0779dc6d1cfddb3859b335e80d206..165cdd39d8fb39480187deee89e1c49e3ea89892 100644 (file)
@@ -1536,9 +1536,24 @@ ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
 }
 
 ICALL_EXPORT void
-ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array, MonoBoolean freeSeg)
+ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
 {
-       g_ptr_array_free (ptr_array, freeSeg);
+       g_ptr_array_free (ptr_array, TRUE);
+}
+
+ICALL_EXPORT void
+ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
+{
+       g_free (c_str);
+}
+
+ICALL_EXPORT char*
+ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
+{
+       MonoError error;
+       char *res = mono_string_to_utf8_checked (s, &error);
+       mono_error_set_pending_exception (&error);
+       return res;
 }
 
 /* System.TypeCode */
@@ -1765,7 +1780,6 @@ ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField
        MonoError error;
        gboolean found = FALSE;
        MonoClass *klass;
-       MonoClass *k;
 
        g_assert (handle);
 
@@ -1774,13 +1788,7 @@ ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField
        } else {
                klass = mono_class_from_mono_type (type);
 
-               /* Check that the field belongs to the class */
-               for (k = klass; k; k = k->parent) {
-                       if (k == handle->parent) {
-                               found = TRUE;
-                               break;
-                       }
-               }
+               found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
 
                if (!found)
                        /* The managed code will throw the exception */
@@ -1792,6 +1800,55 @@ ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField
        return result;
 }
 
+ICALL_EXPORT MonoReflectionEvent*
+ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type)
+{
+       MonoError error;
+       MonoClass *klass;
+
+       g_assert (handle);
+
+       if (!type) {
+               klass = handle->parent;
+       } else {
+               klass = mono_class_from_mono_type (type);
+
+               gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
+               if (!found)
+                       /* Managed code will throw an exception */
+                       return NULL;
+       }
+
+       MonoReflectionEvent *result = mono_event_get_object_checked (mono_domain_get (), klass, handle, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
+
+ICALL_EXPORT MonoReflectionProperty*
+ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type)
+{
+       MonoError error;
+       MonoClass *klass;
+
+       g_assert (handle);
+
+       if (!type) {
+               klass = handle->parent;
+       } else {
+               klass = mono_class_from_mono_type (type);
+
+               gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
+               if (!found)
+                       /* Managed code will throw an exception */
+                       return NULL;
+       }
+
+       MonoReflectionProperty *result = mono_property_get_object_checked (mono_domain_get (), klass, handle, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
 ICALL_EXPORT MonoArray*
 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
 {
@@ -3748,29 +3805,29 @@ enum {
 };
 
 ICALL_EXPORT GPtrArray*
-ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, MonoString *name, guint32 bflags)
+ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
 {
        MonoError error;
-       MonoDomain *domain; 
        MonoClass *startklass, *klass;
        int match;
        gpointer iter;
-       char *utf8_name = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;    
        MonoClassField *field;
 
-       domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref) {
                return g_ptr_array_new ();
        }
 
+       mono_error_init (&error);
+
+       compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
+
        klass = startklass = mono_class_from_mono_type (type->type);
 
        GPtrArray *ptr_array = g_ptr_array_sized_new (16);
        
 handle_parent: 
        if (mono_class_has_failure (klass)) {
-               mono_error_init (&error);
                mono_error_set_for_class_failure (&error, klass);
                goto fail;
        }
@@ -3804,29 +3861,18 @@ handle_parent:
                if (!match)
                        continue;
 
-               if (name != NULL) {
-                       if (utf8_name == NULL) {
-                               utf8_name = mono_string_to_utf8_checked (name, &error);
-                               if (!is_ok (&error))
-                                       goto fail;
-                               compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
-                       }
-
-                       if (compare_func (mono_field_get_name (field), utf8_name))
+               if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
                                continue;
-               }
 
                g_ptr_array_add (ptr_array, field);
        }
        if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
                goto handle_parent;
 
-       if (utf8_name != NULL)
-               g_free (utf8_name);
        return ptr_array;
 
 fail:
-       g_ptr_array_free (ptr_array, FALSE);
+       g_ptr_array_free (ptr_array, TRUE);
        mono_error_set_pending_exception (&error);
        return NULL;
 }
@@ -3847,7 +3893,7 @@ method_nonpublic (MonoMethod* method, gboolean start_klass)
 }
 
 GPtrArray*
-mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoException **ex)
+mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
 {
        GPtrArray *array;
        MonoClass *startklass;
@@ -3861,7 +3907,7 @@ mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bfla
 
        array = g_ptr_array_new ();
        startklass = klass;
-       *ex = NULL;
+       mono_error_init (error);
 
        if (name != NULL)
                compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
@@ -3950,117 +3996,54 @@ loader_error:
                g_free (method_slots);
        g_ptr_array_free (array, TRUE);
 
-       if (mono_class_has_failure (klass)) {
-               *ex = mono_class_get_exception_for_failure (klass);
-       } else {
-               *ex = mono_get_exception_execution_engine ("Unknown error");
-       }
+       g_assert (mono_class_has_failure (klass));
+       mono_error_set_for_class_failure (error, klass);
        return NULL;
 }
 
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
+ICALL_EXPORT GPtrArray*
+ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
 {
-       static MonoClass *MethodInfo_array;
        MonoError error;
-       MonoDomain *domain; 
-       MonoArray *res;
-       MonoVTable *array_vtable;
-       MonoException *ex = NULL;
-       const char *mname = NULL;
        GPtrArray *method_array;
-       MonoClass *klass, *refklass;
-       int i;
-
-       mono_error_init (&error);
-
-       if (!MethodInfo_array) {
-               MonoClass *klass = mono_array_class_get (mono_defaults.method_info_class, 1);
-               mono_memory_barrier ();
-               MethodInfo_array = klass;
-       }
+       MonoClass *klass;
 
        klass = mono_class_from_mono_type (type->type);
-       refklass = mono_class_from_mono_type (reftype->type);
-       domain = ((MonoObject *)type)->vtable->domain;
-       array_vtable = mono_class_vtable_full (domain, MethodInfo_array, &error);
-       if (!is_ok (&error)) {
-               mono_error_set_pending_exception (&error);
-               return NULL;
-       }
        if (type->type->byref) {
-               res = mono_array_new_specific_checked (array_vtable, 0, &error);
-               mono_error_set_pending_exception (&error);
-
-               return res;
-       }
-
-       if (name) {
-               mname = mono_string_to_utf8_checked (name, &error);
-               if (mono_error_set_pending_exception (&error))
-                   return NULL;
-       }
-
-       method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &ex);
-       g_free ((char*)mname);
-       if (ex) {
-               mono_set_pending_exception (ex);
-               return NULL;
-       }
-
-       res = mono_array_new_specific_checked (array_vtable, method_array->len, &error);
-       if (!mono_error_ok (&error)) {
-               mono_error_set_pending_exception (&error);
-               return NULL;
-       }
-
-       for (i = 0; i < method_array->len; ++i) {
-               MonoMethod *method = (MonoMethod *)g_ptr_array_index (method_array, i);
-               MonoReflectionMethod *rm = mono_method_get_object_checked (domain, method, refklass, &error);
-               if (!mono_error_ok (&error))
-                       goto failure;
-               mono_array_setref (res, i, rm);
+               return g_ptr_array_new ();
        }
 
-failure:
-       g_ptr_array_free (method_array, TRUE);
-       if (!mono_error_ok (&error))
-               mono_set_pending_exception (mono_error_convert_to_exception (&error));
-       return res;
+       method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
+       mono_error_set_pending_exception (&error);
+       return method_array;
 }
 
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
+ICALL_EXPORT GPtrArray*
+ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
 {
-       MonoDomain *domain; 
-       MonoClass *startklass, *klass, *refklass;
-       MonoArray *res = NULL;
+       MonoClass *startklass, *klass;
        MonoMethod *method;
-       MonoObject *member;
-       int i, match;
+       int match;
        gpointer iter = NULL;
-       MonoPtrArray tmp_array;
+       GPtrArray *res_array;
        MonoError error;
        
-       domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref) {
-               res = mono_array_new_cached (domain, mono_defaults.method_info_class, 0, &error);
-               mono_error_set_pending_exception (&error);
-               return res;
+               return g_ptr_array_new ();
        }
 
-       mono_ptr_array_init (tmp_array, 4, MONO_ROOT_SOURCE_REFLECTION, "temporary reflection constructors list"); /*FIXME, guestimating*/
-
-
        klass = startklass = mono_class_from_mono_type (type->type);
-       refklass = mono_class_from_mono_type (reftype->type);
 
        mono_class_setup_methods (klass);
        if (mono_class_has_failure (klass)) {
-               mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
-               goto leave;
+               mono_error_init (&error);
+               mono_error_set_for_class_failure (&error, klass);
+               mono_error_set_pending_exception (&error);
+               return NULL;
        }
 
+       res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
+
        iter = NULL;
        while ((method = mono_class_get_methods (klass, &iter))) {
                match = 0;
@@ -4087,24 +4070,10 @@ ves_icall_RuntimeType_GetConstructors_internal (MonoReflectionType *type, guint3
 
                if (!match)
                        continue;
-               member = (MonoObject*)mono_method_get_object_checked (domain, method, refklass, &error);
-               if (mono_error_set_pending_exception (&error))
-                       goto leave;
-
-               mono_ptr_array_append (tmp_array, member);
+               g_ptr_array_add (res_array, method);
        }
 
-       res = mono_array_new_cached (domain, mono_class_get_constructor_info_class (), mono_ptr_array_size (tmp_array), &error);
-       if (mono_error_set_pending_exception (&error))
-               goto leave;
-
-       for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
-               mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
-
-leave:
-       mono_ptr_array_destroy (tmp_array);
-
-       return res;
+       return res_array;
 }
 
 static guint
@@ -4170,49 +4139,40 @@ 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, gchar *propname, 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) {
-               propname = mono_string_to_utf8_checked (name, &error);
-               if (mono_error_set_pending_exception (&error))
-                       return NULL;
-               compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
-       }
+       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);
        mono_class_setup_vtable (klass);
-       if (mono_class_has_failure (klass))
+       if (mono_class_has_failure (klass)) {
+               mono_error_set_for_class_failure (&error, klass);
                goto loader_error;
+       }
 
        iter = NULL;
        while ((prop = mono_class_get_properties (klass, &iter))) {
@@ -4250,49 +4210,28 @@ handle_parent:
                        continue;
                match = 0;
 
-               if (name != NULL) {
-                       if (compare_func (propname, prop->name))
-                               continue;
-               }
+               if (propname != NULL && compare_func (propname, prop->name))
+                       continue;
                
                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);
        }
-       if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
+       if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
                goto 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, TRUE);
 
        mono_error_set_pending_exception (&error);
 
@@ -4314,32 +4253,28 @@ event_equal (MonoEvent *event1, MonoEvent *event2)
        return g_str_equal (event1->name, event2->name);
 }
 
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetEvents_internal (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoReflectionType *reftype)
+ICALL_EXPORT GPtrArray*
+ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
 {
        MonoError error;
-       MonoDomain *domain; 
        MonoClass *startklass, *klass;
-       MonoArray *res;
        MonoMethod *method;
        MonoEvent *event;
-       int i, match;
+       int match;
        gpointer iter;
-       char *utf8_name = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;    
        GHashTable *events = NULL;
-       MonoPtrArray tmp_array;
+       GPtrArray *res_array;
 
-       mono_error_init (&error);
-       
-       domain = mono_object_domain (type);
        if (type->type->byref) {
-               res = mono_array_new_cached (domain, mono_class_get_event_info_class (), 0, &error);
-               mono_error_set_pending_exception (&error);
-               return res;
+               return g_ptr_array_new ();
        }
 
-       mono_ptr_array_init (tmp_array, 4, MONO_ROOT_SOURCE_REFLECTION, "temporary reflection events list");
+       mono_error_init (&error);
+
+       compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
+
+       res_array = g_ptr_array_sized_new (4);
 
        klass = startklass = mono_class_from_mono_type (type->type);
 
@@ -4347,8 +4282,10 @@ ves_icall_RuntimeType_GetEvents_internal (MonoReflectionType *type, MonoString *
 handle_parent:
        mono_class_setup_methods (klass);
        mono_class_setup_vtable (klass);
-       if (mono_class_has_failure (klass))
-               goto loader_error;
+       if (mono_class_has_failure (klass)) {
+               mono_error_set_for_class_failure (&error, klass);
+               goto failure;
+       }
 
        iter = NULL;
        while ((event = mono_class_get_events (klass, &iter))) {
@@ -4389,26 +4326,13 @@ handle_parent:
                if (!match)
                        continue;
 
-               if (name != NULL) {
-                       if (utf8_name == NULL) {
-                               utf8_name = mono_string_to_utf8_checked (name, &error);
-                               if (!is_ok (&error))
-                                       goto failure;
-                               compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
-                       }
-
-                       if (compare_func (event->name, utf8_name))
-                               continue;
-               }               
+               if (utf8_name != NULL && compare_func (event->name, utf8_name))
+                       continue;
 
                if (g_hash_table_lookup (events, event))
                        continue;
 
-               MonoReflectionEvent *ev_obj;
-               ev_obj = mono_event_get_object_checked (domain, startklass, event, &error);
-               if (!ev_obj)
-                       goto failure;
-               mono_ptr_array_append (tmp_array, ev_obj);
+               g_ptr_array_add (res_array, event); 
 
                g_hash_table_insert (events, event, event);
        }
@@ -4417,59 +4341,31 @@ handle_parent:
 
        g_hash_table_destroy (events);
 
-       res = mono_array_new_cached (domain, mono_class_get_event_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);
-
-       if (utf8_name != NULL)
-               g_free (utf8_name);
-
-       return res;
-
-loader_error:
-       if (mono_class_has_failure (klass))
-               mono_error_set_for_class_failure (&error, klass);
+       return res_array;
 
 failure:
-       
        if (events != NULL)
                g_hash_table_destroy (events);
-       if (utf8_name != NULL)
-               g_free (utf8_name);
 
-       mono_ptr_array_destroy (tmp_array);
+       g_ptr_array_free (res_array, TRUE);
 
        mono_error_set_pending_exception (&error);
        return NULL;
 }
 
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetNestedTypes (MonoReflectionType *type, MonoString *name, guint32 bflags)
+ICALL_EXPORT GPtrArray *
+ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
 {
-       MonoError error;
-       MonoReflectionType *rt;
-       MonoDomain *domain; 
        MonoClass *klass;
-       MonoArray *res = NULL;
-       int i, match;
+       int match;
        MonoClass *nested;
        gpointer iter;
-       char *str = NULL;
-       MonoPtrArray tmp_array;
-
-       mono_error_init (&error);
+       GPtrArray *res_array;
 
-       domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref) {
-               MonoArray *result = mono_array_new_cached (domain, mono_defaults.runtimetype_class, 0, &error);
-               mono_error_set_pending_exception (&error);
-               return result;
+               return g_ptr_array_new ();
        }
+
        klass = mono_class_from_mono_type (type->type);
 
        /*
@@ -4484,7 +4380,8 @@ ves_icall_RuntimeType_GetNestedTypes (MonoReflectionType *type, MonoString *name
        if (klass->generic_class)
                klass = klass->generic_class->container_class;
 
-       mono_ptr_array_init (tmp_array, 1, MONO_ROOT_SOURCE_REFLECTION, "temporary reflection nested types list");
+       res_array = g_ptr_array_new ();
+       
        iter = NULL;
        while ((nested = mono_class_get_nested_types (klass, &iter))) {
                match = 0;
@@ -4498,39 +4395,13 @@ ves_icall_RuntimeType_GetNestedTypes (MonoReflectionType *type, MonoString *name
                if (!match)
                        continue;
 
-               if (name != NULL) {
-                       if (str == NULL) {
-                               str = mono_string_to_utf8_checked (name, &error);
-                               if (!is_ok (&error))
-                                       goto leave;
-                               mono_identifier_unescape_type_name_chars (str);
-                       }
-
-                       if (strcmp (nested->name, str))
+               if (str != NULL && strcmp (nested->name, str))
                                continue;
-               }
-
-               rt = mono_type_get_object_checked (domain, &nested->byval_arg, &error);
-               if (!is_ok (&error))
-                       goto leave;
 
-               mono_ptr_array_append (tmp_array, (MonoObject*) rt);
+               g_ptr_array_add (res_array, &nested->byval_arg);
        }
 
-       res = mono_array_new_cached (domain, mono_defaults.runtimetype_class, mono_ptr_array_size (tmp_array), &error);
-       if (!is_ok (&error))
-               goto leave;
-
-       for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
-               mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
-
-leave:
-       mono_ptr_array_destroy (tmp_array);
-
-       g_free (str);
-
-       mono_error_set_pending_exception (&error);
-       return res;
+       return res_array;
 }
 
 ICALL_EXPORT MonoReflectionType*
@@ -5111,7 +4982,7 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflec
                        mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
                        val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
                        MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
-                       if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
+                       if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
                                info->location = 0;
                        else
                                info->location = RESOURCE_LOCATION_EMBEDDED;
@@ -5254,7 +5125,7 @@ ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly
 
        for (i = 0; i < file_count; ++i, ++j) {
                mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
-               if (cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA) {
+               if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
                        MonoReflectionModule *rm = mono_module_file_get_object_checked (domain, image, i, &error);
                        if (mono_error_set_pending_exception (&error))
                                return NULL;
@@ -5337,21 +5208,24 @@ mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
 }
 
 ICALL_EXPORT MonoReflectionMethod*
-ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
+ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
 {
        MonoReflectionMethod *res = NULL;
        MonoError error;
        MonoClass *klass;
-       if (type) {
+       if (type && generic_check) {
                klass = mono_class_from_mono_type (type);
-               if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass)) 
+               if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
                        return NULL;
+
                if (method->klass != klass) {
                        method = mono_method_get_equivalent_method (method, klass);
                        if (!method)
                                return NULL;
                }
-       } else
+       } else if (type)
+               klass = mono_class_from_mono_type (type);
+       else
                klass = method->klass;
        res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
        mono_error_set_pending_exception (&error);