From: Aleksey Kliger (λgeek) Date: Thu, 14 Jul 2016 15:32:58 +0000 (-0400) Subject: Merge pull request #3281 from lambdageek/dev/g-ptr-array X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=26c3cfa0c5cbd09c59ec18a1a6041930ca7bc784;hp=c75dcf579fc29bb003bbfd9e0922bd1d9780ed28;p=mono.git Merge pull request #3281 from lambdageek/dev/g-ptr-array [reflection] RuntimeType Field and Method search partly in managed --- diff --git a/mcs/class/corlib/Mono/RuntimeHandles.cs b/mcs/class/corlib/Mono/RuntimeHandles.cs index b83ff68550b..e916332db32 100644 --- a/mcs/class/corlib/Mono/RuntimeHandles.cs +++ b/mcs/class/corlib/Mono/RuntimeHandles.cs @@ -141,4 +141,48 @@ namespace Mono { return i; } } + + internal struct RuntimeGPtrArrayHandle { + unsafe RuntimeStructs.GPtrArray* value; + + internal unsafe RuntimeGPtrArrayHandle (RuntimeStructs.GPtrArray* value) + { + this.value = value; + } + + internal unsafe RuntimeGPtrArrayHandle (IntPtr ptr) + { + this.value = (RuntimeStructs.GPtrArray*) ptr; + } + + internal int Length { + get { + unsafe { + return value->len; + } + } + } + + internal IntPtr this[int i] => Lookup (i); + + internal IntPtr Lookup (int i) + { + if (i >= 0 && i < Length) { + unsafe { + return value->data[i]; + } + } else + throw new IndexOutOfRangeException (); + } + + [MethodImpl(MethodImplOptions.InternalCall)] + unsafe extern static void GPtrArrayFree (RuntimeStructs.GPtrArray* value, bool freeSeg); + + internal static void DestroyAndFree (ref RuntimeGPtrArrayHandle h, bool freeSeg) { + unsafe { + GPtrArrayFree (h.value, freeSeg); + h.value = null; + } + } + } } diff --git a/mcs/class/corlib/Mono/RuntimeStructs.cs b/mcs/class/corlib/Mono/RuntimeStructs.cs index 29b75c077d3..20cd93fdaec 100644 --- a/mcs/class/corlib/Mono/RuntimeStructs.cs +++ b/mcs/class/corlib/Mono/RuntimeStructs.cs @@ -37,6 +37,12 @@ namespace Mono { internal uint token; internal MonoClass** constraints; /* NULL terminated */ } + + // glib.h GPtrArray + internal unsafe struct GPtrArray { + internal IntPtr* data; + internal int len; + } } } diff --git a/mcs/class/corlib/Mono/SafeGPtrArrayHandle.cs b/mcs/class/corlib/Mono/SafeGPtrArrayHandle.cs new file mode 100644 index 00000000000..e681ff4b8d8 --- /dev/null +++ b/mcs/class/corlib/Mono/SafeGPtrArrayHandle.cs @@ -0,0 +1,42 @@ +// +// Safe handle class for Mono.RuntimeGPtrArrayHandle +// +// Authors: +// Aleksey Kliger +// Rodrigo Kumpera +// +// Copyright 2016 Dot net foundation. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Runtime.CompilerServices; + +namespace Mono { + internal sealed class SafeGPtrArrayHandle : IDisposable { + RuntimeGPtrArrayHandle handle; + bool freeSeg; + + internal SafeGPtrArrayHandle (IntPtr ptr, bool freeSeg) + { + handle = new RuntimeGPtrArrayHandle (ptr); + this.freeSeg = freeSeg; + } + + public void Dispose () + { + RuntimeGPtrArrayHandle.DestroyAndFree (ref handle, freeSeg); + GC.SuppressFinalize (this); + } + + internal int Length { + get { + return handle.Length; + } + } + + internal IntPtr this[int i] => handle[i]; + } + + +} diff --git a/mcs/class/corlib/ReferenceSources/MethodBase.cs b/mcs/class/corlib/ReferenceSources/MethodBase.cs index 2fb847a6ef9..8cd00056328 100644 --- a/mcs/class/corlib/ReferenceSources/MethodBase.cs +++ b/mcs/class/corlib/ReferenceSources/MethodBase.cs @@ -46,7 +46,12 @@ namespace System.Reflection internal static MethodBase GetMethodFromHandleNoGenericCheck (RuntimeMethodHandle handle) { - return GetMethodFromHandleInternalType (handle.Value, IntPtr.Zero); + return GetMethodFromHandleInternalType_native (handle.Value, IntPtr.Zero, false); + } + + internal static MethodBase GetMethodFromHandleNoGenericCheck (RuntimeMethodHandle handle, RuntimeTypeHandle reflectedType) + { + return GetMethodFromHandleInternalType_native (handle.Value, reflectedType.Value, false); } [MethodImplAttribute (MethodImplOptions.InternalCall)] @@ -57,7 +62,12 @@ namespace System.Reflection return GetMethodBodyInternal (handle); } + static MethodBase GetMethodFromHandleInternalType (IntPtr method_handle, IntPtr type_handle) { + return GetMethodFromHandleInternalType_native (method_handle, type_handle, true); + } + [MethodImplAttribute (MethodImplOptions.InternalCall)] - extern static MethodBase GetMethodFromHandleInternalType (IntPtr method_handle, IntPtr type_handle); + internal extern static MethodBase GetMethodFromHandleInternalType_native (IntPtr method_handle, IntPtr type_handle, bool genericCheck); + } -} \ No newline at end of file +} diff --git a/mcs/class/corlib/ReferenceSources/RuntimeType.cs b/mcs/class/corlib/ReferenceSources/RuntimeType.cs index 4981f4175a1..3710350e09e 100644 --- a/mcs/class/corlib/ReferenceSources/RuntimeType.cs +++ b/mcs/class/corlib/ReferenceSources/RuntimeType.cs @@ -472,13 +472,42 @@ namespace System static extern Type MakeGenericType (Type gt, Type [] types); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal extern RuntimeMethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type); + internal extern IntPtr GetMethodsByName_native (string name, BindingFlags bindingAttr, bool ignoreCase); + + internal RuntimeMethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, RuntimeType reflectedType) + { + var refh = new RuntimeTypeHandle (reflectedType); + using (var h = new Mono.SafeGPtrArrayHandle (GetMethodsByName_native (name, bindingAttr, ignoreCase), false)) { + var n = h.Length; + var a = new RuntimeMethodInfo [n]; + for (int i = 0; i < n; i++) { + var mh = new RuntimeMethodHandle (h[i]); + a[i] = (RuntimeMethodInfo) MethodBase.GetMethodFromHandleNoGenericCheck (mh, refh); + } + return a; + } + } [MethodImplAttribute(MethodImplOptions.InternalCall)] extern RuntimePropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, Type reflected_type); [MethodImplAttribute(MethodImplOptions.InternalCall)] - extern RuntimeConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, Type reflected_type); + extern IntPtr GetConstructors_native (BindingFlags bindingAttr); + + RuntimeConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, RuntimeType reflectedType) + { + var refh = new RuntimeTypeHandle (reflectedType); + using (var h = new Mono.SafeGPtrArrayHandle (GetConstructors_native (bindingAttr), false)) { + var n = h.Length; + var a = new RuntimeConstructorInfo [n]; + for (int i = 0; i < n; i++) { + var mh = new RuntimeMethodHandle (h[i]); + a[i] = (RuntimeConstructorInfo) MethodBase.GetMethodFromHandleNoGenericCheck (mh, refh); + } + return a; + } + } + public override InterfaceMapping GetInterfaceMap (Type ifaceType) { @@ -630,7 +659,21 @@ namespace System extern RuntimeEventInfo[] GetEvents_internal (string name, BindingFlags bindingAttr, Type reflected_type); [MethodImplAttribute(MethodImplOptions.InternalCall)] - extern RuntimeFieldInfo[] GetFields_internal (string name, BindingFlags bindingAttr, Type reflected_type); + extern IntPtr GetFields_native (string name, BindingFlags bindingAttr); + + RuntimeFieldInfo[] GetFields_internal (string name, BindingFlags bindingAttr, RuntimeType reflectedType) + { + var refh = new RuntimeTypeHandle (reflectedType); + using (var h = new Mono.SafeGPtrArrayHandle (GetFields_native (name, bindingAttr), false)) { + int n = h.Length; + var a = new RuntimeFieldInfo[n]; + for (int i = 0; i < n; i++) { + var fh = new RuntimeFieldHandle (h[i]); + a[i] = (RuntimeFieldInfo) FieldInfo.GetFieldFromHandle (fh, refh); + } + return a; + } + } [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern override Type[] GetInterfaces(); diff --git a/mcs/class/corlib/corlib.dll.sources b/mcs/class/corlib/corlib.dll.sources index 199eb737b89..b36d3d446bc 100644 --- a/mcs/class/corlib/corlib.dll.sources +++ b/mcs/class/corlib/corlib.dll.sources @@ -25,6 +25,7 @@ Mono.Globalization.Unicode/NormalizationTableUtil.cs Mono/Runtime.cs Mono/RuntimeStructs.cs Mono/RuntimeHandles.cs +Mono/SafeGPtrArrayHandle.cs Mono/DataConverter.cs Mono.Interop/ComInteropProxy.cs Mono.Interop/IDispatch.cs diff --git a/mono/metadata/class-internals.h b/mono/metadata/class-internals.h index 3ce27a7119e..f51c979a50f 100644 --- a/mono/metadata/class-internals.h +++ b/mono/metadata/class-internals.h @@ -1403,7 +1403,7 @@ void mono_unload_interface_id (MonoClass *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); char* mono_class_full_name (MonoClass *klass); diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 19985061661..f27705f3218 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -65,6 +65,9 @@ ICALL(RUNTIME_12, "GetNativeStackTrace", ves_icall_Mono_Runtime_GetNativeStackTr ICALL_TYPE(RTCLASS, "Mono.RuntimeClassHandle", RTCLASS_1) ICALL(RTCLASS_1, "GetTypeFromClass", ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass) +ICALL_TYPE(RTPTRARRAY, "Mono.RuntimeGPtrArrayHandle", RTPTRARRAY_1) +ICALL(RTPTRARRAY_1, "GPtrArrayFree", ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree) + #ifndef PLATFORM_RO_FS ICALL_TYPE(KPAIR, "Mono.Security.Cryptography.KeyPairPersistence", KPAIR_1) ICALL(KPAIR_1, "_CanSecure", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_CanSecure) @@ -556,7 +559,7 @@ ICALL(MEMBERI_1, "get_MetadataToken", ves_icall_reflection_get_token) ICALL_TYPE(MBASE, "System.Reflection.MethodBase", MBASE_1) ICALL(MBASE_1, "GetCurrentMethod", ves_icall_GetCurrentMethod) ICALL(MBASE_2, "GetMethodBodyInternal", ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal) -ICALL(MBASE_4, "GetMethodFromHandleInternalType", ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType) +ICALL(MBASE_4, "GetMethodFromHandleInternalType_native", ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native) ICALL_TYPE(MODULE, "System.Reflection.Module", MODULE_1) ICALL(MODULE_1, "Close", ves_icall_System_Reflection_Module_Close) @@ -733,16 +736,16 @@ ICALL(MHAN_1, "GetFunctionPointer", ves_icall_RuntimeMethodHandle_GetFunctionPoi ICALL_TYPE(RT, "System.RuntimeType", RT_1) ICALL(RT_1, "CreateInstanceInternal", ves_icall_System_Activator_CreateInstanceInternal) -ICALL(RT_2, "GetConstructors_internal", ves_icall_RuntimeType_GetConstructors_internal) +ICALL(RT_2, "GetConstructors_native", ves_icall_RuntimeType_GetConstructors_native) ICALL(RT_30, "GetCorrespondingInflatedConstructor", ves_icall_RuntimeType_GetCorrespondingInflatedMethod) ICALL(RT_31, "GetCorrespondingInflatedMethod", ves_icall_RuntimeType_GetCorrespondingInflatedMethod) ICALL(RT_3, "GetEvents_internal", ves_icall_RuntimeType_GetEvents_internal) -ICALL(RT_5, "GetFields_internal", ves_icall_RuntimeType_GetFields_internal) +ICALL(RT_5, "GetFields_native", ves_icall_RuntimeType_GetFields_native) ICALL(RT_6, "GetGenericArgumentsInternal", ves_icall_RuntimeType_GetGenericArguments) ICALL(RT_9, "GetGenericParameterPosition", ves_icall_RuntimeType_GetGenericParameterPosition) ICALL(RT_10, "GetInterfaceMapData", ves_icall_RuntimeType_GetInterfaceMapData) ICALL(RT_11, "GetInterfaces", ves_icall_RuntimeType_GetInterfaces) -ICALL(RT_12, "GetMethodsByName", ves_icall_RuntimeType_GetMethodsByName) +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) diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index 94081c73fd3..c3dd869958e 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -1535,6 +1535,12 @@ ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass) return mono_class_get_type (klass); } +ICALL_EXPORT void +ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array, MonoBoolean freeSeg) +{ + g_ptr_array_free (ptr_array, freeSeg); +} + /* System.TypeCode */ typedef enum { TYPECODE_EMPTY, @@ -3741,38 +3747,32 @@ enum { BFLAGS_OptionalParamBinding = 0x40000 }; -ICALL_EXPORT MonoArray* -ves_icall_RuntimeType_GetFields_internal (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoReflectionType *reftype) +ICALL_EXPORT GPtrArray* +ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, MonoString *name, guint32 bflags) { MonoError error; MonoDomain *domain; - MonoClass *startklass, *klass, *refklass; - MonoArray *res; - MonoObject *member; - int i, match; + MonoClass *startklass, *klass; + int match; gpointer iter; char *utf8_name = NULL; int (*compare_func) (const char *s1, const char *s2) = NULL; MonoClassField *field; - MonoPtrArray tmp_array; domain = ((MonoObject *)type)->vtable->domain; if (type->type->byref) { - MonoArray *result = mono_array_new_checked (domain, mono_defaults.field_info_class, 0, &error); - mono_error_set_pending_exception (&error); - return result; + return g_ptr_array_new (); } klass = startklass = mono_class_from_mono_type (type->type); - refklass = mono_class_from_mono_type (reftype->type); - mono_ptr_array_init (tmp_array, 2, MONO_ROOT_SOURCE_REFLECTION, "temporary reflection fields list"); + GPtrArray *ptr_array = g_ptr_array_sized_new (16); handle_parent: if (mono_class_has_failure (klass)) { - mono_ptr_array_destroy (tmp_array); - mono_set_pending_exception (mono_class_get_exception_for_failure (klass)); - return NULL; + mono_error_init (&error); + mono_error_set_for_class_failure (&error, klass); + goto fail; } iter = NULL; @@ -3816,29 +3816,17 @@ handle_parent: continue; } - member = (MonoObject*)mono_field_get_object_checked (domain, refklass, field, &error); - if (!mono_error_ok (&error)) - goto fail; - mono_ptr_array_append (tmp_array, member); + g_ptr_array_add (ptr_array, field); } if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)) goto handle_parent; - res = mono_array_new_cached (domain, mono_defaults.field_info_class, mono_ptr_array_size (tmp_array), &error); - if (!is_ok (&error)) - goto fail; - - 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 ptr_array; - return res; fail: - mono_ptr_array_destroy (tmp_array); + g_ptr_array_free (ptr_array, FALSE); mono_error_set_pending_exception (&error); return NULL; } @@ -3859,7 +3847,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; @@ -3873,7 +3861,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; @@ -3962,49 +3950,24 @@ 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, MonoString *name, 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; + return g_ptr_array_new (); } if (name) { @@ -4013,66 +3976,38 @@ ves_icall_RuntimeType_GetMethodsByName (MonoReflectionType *type, MonoString *na return NULL; } - method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &ex); + method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error); 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); - } - -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; + 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; @@ -4099,24 +4034,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 @@ -5349,21 +5270,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);