/* Declare all shared lazy type lookup functions */
GENERATE_TRY_GET_CLASS_WITH_CACHE (safehandle, System.Runtime.InteropServices, SafeHandle)
+
+/**
+ * mono_method_get_base_method:
+ * @method: a method
+ * @definition: if true, get the definition
+ * @error: set on failure
+ *
+ * Given a virtual method associated with a subclass, return the corresponding
+ * method from an ancestor. If @definition is FALSE, returns the method in the
+ * superclass of the given method. If @definition is TRUE, return the method
+ * in the ancestor class where it was first declared. The type arguments will
+ * be inflated in the ancestor classes. If the method is not associated with a
+ * class, or isn't virtual, returns the method itself. On failure returns NULL
+ * and sets @error.
+ */
+MonoMethod*
+mono_method_get_base_method (MonoMethod *method, gboolean definition, MonoError *error)
+{
+ MonoClass *klass, *parent;
+ MonoGenericContext *generic_inst = NULL;
+ MonoMethod *result = NULL;
+ int slot;
+
+ if (method->klass == NULL)
+ return method;
+
+ if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
+ MONO_CLASS_IS_INTERFACE (method->klass) ||
+ method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
+ return method;
+
+ slot = mono_method_get_vtable_slot (method);
+ if (slot == -1)
+ return method;
+
+ klass = method->klass;
+ if (mono_class_is_ginst (klass)) {
+ generic_inst = mono_class_get_context (klass);
+ klass = mono_class_get_generic_class (klass)->container_class;
+ }
+
+retry:
+ if (definition) {
+ /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
+ for (parent = klass->parent; parent != NULL; parent = parent->parent) {
+ /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
+ or klass is the generic container class and generic_inst is the instantiation.
+
+ when we go to the parent, if the parent is an open constructed type, we need to
+ replace the type parameters by the definitions from the generic_inst, and then take it
+ apart again into the klass and the generic_inst.
+
+ For cases like this:
+ class C<T> : B<T, int> {
+ public override void Foo () { ... }
+ }
+ class B<U,V> : A<HashMap<U,V>> {
+ public override void Foo () { ... }
+ }
+ class A<X> {
+ public virtual void Foo () { ... }
+ }
+
+ if at each iteration the parent isn't open, we can skip inflating it. if at some
+ iteration the parent isn't generic (after possible inflation), we set generic_inst to
+ NULL;
+ */
+ MonoGenericContext *parent_inst = NULL;
+ if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
+ parent = mono_class_inflate_generic_class_checked (parent, generic_inst, error);
+ return_val_if_nok (error, NULL);
+ }
+ if (mono_class_is_ginst (parent)) {
+ parent_inst = mono_class_get_context (parent);
+ parent = mono_class_get_generic_class (parent)->container_class;
+ }
+
+ mono_class_setup_vtable (parent);
+ if (parent->vtable_size <= slot)
+ break;
+ klass = parent;
+ generic_inst = parent_inst;
+ }
+ } else {
+ klass = klass->parent;
+ if (!klass)
+ return method;
+ if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
+ klass = mono_class_inflate_generic_class_checked (klass, generic_inst, error);
+ return_val_if_nok (error, NULL);
+
+ generic_inst = NULL;
+ }
+ if (mono_class_is_ginst (klass)) {
+ generic_inst = mono_class_get_context (klass);
+ klass = mono_class_get_generic_class (klass)->container_class;
+ }
+
+ }
+
+ if (generic_inst) {
+ klass = mono_class_inflate_generic_class_checked (klass, generic_inst, error);
+ return_val_if_nok (error, NULL);
+ }
+
+ if (klass == method->klass)
+ return method;
+
+ /*This is possible if definition == FALSE.
+ * Do it here to be really sure we don't read invalid memory.
+ */
+ if (slot >= klass->vtable_size)
+ return method;
+
+ mono_class_setup_vtable (klass);
+
+ result = klass->vtable [slot];
+ if (result == NULL) {
+ /* It is an abstract method */
+ gboolean found = FALSE;
+ gpointer iter = NULL;
+ while ((result = mono_class_get_methods (klass, &iter))) {
+ if (result->slot == slot) {
+ found = TRUE;
+ break;
+ }
+ }
+ /* found might be FALSE if we looked in an abstract class
+ * that doesn't override an abstract method of its
+ * parent:
+ * abstract class Base {
+ * public abstract void Foo ();
+ * }
+ * abstract class Derived : Base { }
+ * class Child : Derived {
+ * public override void Foo () { }
+ * }
+ *
+ * if m was Child.Foo and we ask for the base method,
+ * then we get here with klass == Derived and found == FALSE
+ */
+ /* but it shouldn't be the case that if we're looking
+ * for the definition and didn't find a result; the
+ * loop above should've taken us as far as we could
+ * go! */
+ g_assert (!(definition && !found));
+ if (!found)
+ goto retry;
+ }
+
+ g_assert (result != NULL);
+ return result;
+}
HANDLES(ICALL(MODULE_13, "get_MetadataToken", ves_icall_reflection_get_token))
ICALL_TYPE(MCMETH, "System.Reflection.MonoCMethod", MCMETH_1)
-ICALL(MCMETH_1, "GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition)
+HANDLES(ICALL(MCMETH_1, "GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition))
ICALL(MCMETH_2, "InternalInvoke", ves_icall_InternalInvoke)
-ICALL(MCMETH_3, "get_core_clr_security_level", ves_icall_MonoMethod_get_core_clr_security_level)
+HANDLES(ICALL(MCMETH_3, "get_core_clr_security_level", ves_icall_MonoMethod_get_core_clr_security_level))
ICALL_TYPE(MEVIN, "System.Reflection.MonoEventInfo", MEVIN_1)
ICALL(MEVIN_1, "get_event_info", ves_icall_MonoEventInfo_get_event_info)
ICALL(MFIELD_7, "get_core_clr_security_level", ves_icall_MonoField_get_core_clr_security_level)
ICALL_TYPE(MMETH, "System.Reflection.MonoMethod", MMETH_2)
-ICALL(MMETH_2, "GetGenericArguments", ves_icall_MonoMethod_GetGenericArguments)
-ICALL(MMETH_3, "GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition)
-ICALL(MMETH_11, "GetPInvoke", ves_icall_MonoMethod_GetPInvoke)
+HANDLES(ICALL(MMETH_2, "GetGenericArguments", ves_icall_MonoMethod_GetGenericArguments))
+HANDLES(ICALL(MMETH_3, "GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition))
+HANDLES(ICALL(MMETH_11, "GetPInvoke", ves_icall_MonoMethod_GetPInvoke))
ICALL(MMETH_4, "InternalInvoke", ves_icall_InternalInvoke)
-ICALL(MMETH_5, "MakeGenericMethod_impl", ves_icall_MonoMethod_MakeGenericMethod_impl)
-ICALL(MMETH_6, "get_IsGenericMethod", ves_icall_MonoMethod_get_IsGenericMethod)
-ICALL(MMETH_7, "get_IsGenericMethodDefinition", ves_icall_MonoMethod_get_IsGenericMethodDefinition)
-ICALL(MMETH_8, "get_base_method", ves_icall_MonoMethod_get_base_method)
-ICALL(MMETH_10, "get_core_clr_security_level", ves_icall_MonoMethod_get_core_clr_security_level)
-ICALL(MMETH_9, "get_name", ves_icall_MonoMethod_get_name)
+HANDLES(ICALL(MMETH_5, "MakeGenericMethod_impl", ves_icall_MonoMethod_MakeGenericMethod_impl))
+HANDLES(ICALL(MMETH_6, "get_IsGenericMethod", ves_icall_MonoMethod_get_IsGenericMethod))
+HANDLES(ICALL(MMETH_7, "get_IsGenericMethodDefinition", ves_icall_MonoMethod_get_IsGenericMethodDefinition))
+HANDLES(ICALL(MMETH_8, "get_base_method", ves_icall_MonoMethod_get_base_method))
+HANDLES(ICALL(MMETH_10, "get_core_clr_security_level", ves_icall_MonoMethod_get_core_clr_security_level))
+HANDLES(ICALL(MMETH_9, "get_name", ves_icall_MonoMethod_get_name))
ICALL_TYPE(MMETHI, "System.Reflection.MonoMethodInfo", MMETHI_4)
ICALL(MMETHI_4, "get_method_attributes", vell_icall_get_method_attributes)
}
ICALL_EXPORT void
-ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
+ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethodHandle ref_method, int* flags, MonoStringHandleOut entry_point, MonoStringHandleOut dll_name, MonoError *error)
{
MonoDomain *domain = mono_domain_get ();
- MonoImage *image = method->method->klass->image;
- MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
+ MonoMethod *method = MONO_HANDLE_GETVAL (ref_method, method);
+ MonoImage *image = method->klass->image;
+ MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
MonoTableInfo *tables = image->tables;
MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
const char *import = NULL;
const char *scope = NULL;
+ mono_error_init (error);
+
if (image_is_dynamic (image)) {
MonoReflectionMethodAux *method_aux =
- (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
+ (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method);
if (method_aux) {
import = method_aux->dllentry;
scope = method_aux->dll;
}
if (!import || !scope) {
- mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
+ mono_error_set_argument (error, "method", "System.Refleciton.Emit method with invalid pinvoke information");
return;
}
}
}
*flags = piinfo->piflags;
- *entry_point = mono_string_new (domain, import);
- *dll_name = mono_string_new (domain, scope);
+ MONO_HANDLE_ASSIGN (entry_point, mono_string_new_handle (domain, import, error));
+ return_if_nok (error);
+ MONO_HANDLE_ASSIGN (dll_name, mono_string_new_handle (domain, scope, error));
}
-ICALL_EXPORT MonoReflectionMethod *
-ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
+ICALL_EXPORT MonoReflectionMethodHandle
+ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethodHandle ref_method, MonoError *error)
{
- MonoMethodInflated *imethod;
- MonoMethod *result;
- MonoReflectionMethod *ret = NULL;
- MonoError error;
+ mono_error_init (error);
+ MonoMethod *method = MONO_HANDLE_GETVAL (ref_method, method);
- if (method->method->is_generic)
- return method;
+ if (method->is_generic)
+ return ref_method;
- if (!method->method->is_inflated)
- return NULL;
+ if (!method->is_inflated)
+ return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
- imethod = (MonoMethodInflated *) method->method;
+ MonoMethodInflated *imethod = (MonoMethodInflated *) method;
- result = imethod->declaring;
+ MonoMethod *result = imethod->declaring;
/* Not a generic method. */
if (!result->is_generic)
- return NULL;
+ return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
- if (image_is_dynamic (method->method->klass->image)) {
- MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
- MonoReflectionMethod *res;
+ if (image_is_dynamic (method->klass->image)) {
+ MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
/*
* FIXME: Why is this stuff needed at all ? Why can't the code below work for
* the dynamic case as well ?
*/
mono_image_lock ((MonoImage*)image);
- res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
+ MonoReflectionMethodHandle res = MONO_HANDLE_NEW (MonoReflectionMethod, mono_g_hash_table_lookup (image->generic_def_objects, imethod));
mono_image_unlock ((MonoImage*)image);
- if (res)
+ if (!MONO_HANDLE_IS_NULL (res))
return res;
}
MonoClass *klass = ((MonoMethod *) imethod)->klass;
/*Generic methods gets the context of the GTD.*/
if (mono_class_get_context (klass)) {
- result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
- if (!mono_error_ok (&error))
- goto leave;
+ result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), error);
+ return_val_if_nok (error, MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE));
}
}
- ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
-leave:
- if (!mono_error_ok (&error))
- mono_error_set_pending_exception (&error);
- return ret;
+ return mono_method_get_object_handle (MONO_HANDLE_DOMAIN (ref_method), result, NULL, error);
}
ICALL_EXPORT gboolean
-ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
+ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethodHandle ref_method, MonoError *erro)
{
- return mono_method_signature (method->method)->generic_param_count != 0;
+ MonoMethod *method = MONO_HANDLE_GETVAL (ref_method, method);
+ return mono_method_signature (method)->generic_param_count != 0;
}
ICALL_EXPORT gboolean
-ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
+ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethodHandle ref_method, MonoError *Error)
{
- return method->method->is_generic;
+ MonoMethod *method = MONO_HANDLE_GETVAL (ref_method, method);
+ return method->is_generic;
}
-ICALL_EXPORT MonoArray*
-ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
+static gboolean
+set_array_generic_argument_handle_inflated (MonoDomain *domain, MonoGenericInst *inst, int i, MonoArrayHandle arr, MonoError *error)
{
- MonoError error;
- MonoReflectionType *rt;
- MonoArray *res;
- MonoDomain *domain;
- int count, i;
+ HANDLE_FUNCTION_ENTER ();
+ mono_error_init (error);
+ MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, inst->type_argv [i], error);
+ if (!is_ok (error))
+ goto leave;
+ MONO_HANDLE_ARRAY_SETREF (arr, i, rt);
+leave:
+ HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
+}
+
+static gboolean
+set_array_generic_argument_handle_gparam (MonoDomain *domain, MonoGenericContainer *container, int i, MonoArrayHandle arr, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER ();
+ mono_error_init (error);
+ MonoGenericParam *param = mono_generic_container_get_param (container, i);
+ MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
+ MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &pklass->byval_arg, error);
+ if (!is_ok (error))
+ goto leave;
+ MONO_HANDLE_ARRAY_SETREF (arr, i, rt);
+leave:
+ HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
+}
- domain = mono_object_domain (method);
+ICALL_EXPORT MonoArrayHandle
+ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethodHandle ref_method, MonoError *error)
+{
+ mono_error_init (error);
+ MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_method);
+ MonoMethod *method = MONO_HANDLE_GETVAL (ref_method, method);
- if (method->method->is_inflated) {
- MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
+ if (method->is_inflated) {
+ MonoGenericInst *inst = mono_method_get_context (method)->method_inst;
if (inst) {
- count = inst->type_argc;
- res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
- if (mono_error_set_pending_exception (&error))
- return NULL;
-
- for (i = 0; i < count; i++) {
- rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
- if (mono_error_set_pending_exception (&error))
- return NULL;
+ int count = inst->type_argc;
+ MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.systemtype_class, count, error);
+ return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
- mono_array_setref (res, i, rt);
+ for (int i = 0; i < count; i++) {
+ if (!set_array_generic_argument_handle_inflated (domain, inst, i, res, error))
+ break;
}
-
+ return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
return res;
}
}
- count = mono_method_signature (method->method)->generic_param_count;
- res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
- if (mono_error_set_pending_exception (&error))
- return NULL;
-
- for (i = 0; i < count; i++) {
- MonoGenericContainer *container = mono_method_get_generic_container (method->method);
- MonoGenericParam *param = mono_generic_container_get_param (container, i);
- MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
-
- rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
- if (mono_error_set_pending_exception (&error))
- return NULL;
+ int count = mono_method_signature (method)->generic_param_count;
+ MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.systemtype_class, count, error);
+ return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
- mono_array_setref (res, i, rt);
+ MonoGenericContainer *container = mono_method_get_generic_container (method);
+ for (int i = 0; i < count; i++) {
+ if (!set_array_generic_argument_handle_gparam (domain, container, i, res, error))
+ break;
}
-
+ return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
return res;
}
}
ICALL_EXPORT int
-ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
+ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethodHandle rfield, MonoError *error)
{
- MonoMethod *method = rfield->method;
+ mono_error_init (error);
+ MonoMethod *method = MONO_HANDLE_GETVAL (rfield, method);
return mono_security_core_clr_method_level (method, TRUE);
}
return MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (domain, klass, error));
}
-ICALL_EXPORT MonoReflectionMethod *
-ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
+ICALL_EXPORT MonoReflectionMethodHandle
+ves_icall_MonoMethod_get_base_method (MonoReflectionMethodHandle m, gboolean definition, MonoError *error)
{
- MonoReflectionMethod *ret = NULL;
- MonoError error;
-
- MonoClass *klass, *parent;
- MonoGenericContext *generic_inst = NULL;
- MonoMethod *method = m->method;
- MonoMethod *result = NULL;
- int slot;
-
- if (method->klass == NULL)
- return m;
-
- if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
- MONO_CLASS_IS_INTERFACE (method->klass) ||
- method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
- return m;
-
- slot = mono_method_get_vtable_slot (method);
- if (slot == -1)
- return m;
-
- klass = method->klass;
- if (mono_class_is_ginst (klass)) {
- generic_inst = mono_class_get_context (klass);
- klass = mono_class_get_generic_class (klass)->container_class;
- }
-
-retry:
- if (definition) {
- /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
- for (parent = klass->parent; parent != NULL; parent = parent->parent) {
- /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
- or klass is the generic container class and generic_inst is the instantiation.
-
- when we go to the parent, if the parent is an open constructed type, we need to
- replace the type parameters by the definitions from the generic_inst, and then take it
- apart again into the klass and the generic_inst.
-
- For cases like this:
- class C<T> : B<T, int> {
- public override void Foo () { ... }
- }
- class B<U,V> : A<HashMap<U,V>> {
- public override void Foo () { ... }
- }
- class A<X> {
- public virtual void Foo () { ... }
- }
-
- if at each iteration the parent isn't open, we can skip inflating it. if at some
- iteration the parent isn't generic (after possible inflation), we set generic_inst to
- NULL;
- */
- MonoGenericContext *parent_inst = NULL;
- if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
- parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
- if (!mono_error_ok (&error)) {
- mono_error_set_pending_exception (&error);
- return NULL;
- }
- }
- if (mono_class_is_ginst (parent)) {
- parent_inst = mono_class_get_context (parent);
- parent = mono_class_get_generic_class (parent)->container_class;
- }
-
- mono_class_setup_vtable (parent);
- if (parent->vtable_size <= slot)
- break;
- klass = parent;
- generic_inst = parent_inst;
- }
- } else {
- klass = klass->parent;
- if (!klass)
- return m;
- if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
- klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
- if (!mono_error_ok (&error)) {
- mono_error_set_pending_exception (&error);
- return NULL;
- }
-
- generic_inst = NULL;
- }
- if (mono_class_is_ginst (klass)) {
- generic_inst = mono_class_get_context (klass);
- klass = mono_class_get_generic_class (klass)->container_class;
- }
-
- }
-
- if (generic_inst) {
- klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
- if (!mono_error_ok (&error)) {
- mono_error_set_pending_exception (&error);
- return NULL;
- }
- }
-
- if (klass == method->klass)
- return m;
+ mono_error_init (error);
+ MonoMethod *method = MONO_HANDLE_GETVAL (m, method);
- /*This is possible if definition == FALSE.
- * Do it here to be really sure we don't read invalid memory.
- */
- if (slot >= klass->vtable_size)
+ MonoMethod *base = mono_method_get_base_method (method, definition, error);
+ return_val_if_nok (error, MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE));
+ if (base == method)
return m;
-
- mono_class_setup_vtable (klass);
-
- result = klass->vtable [slot];
- if (result == NULL) {
- /* It is an abstract method */
- gboolean found = FALSE;
- gpointer iter = NULL;
- while ((result = mono_class_get_methods (klass, &iter))) {
- if (result->slot == slot) {
- found = TRUE;
- break;
- }
- }
- /* found might be FALSE if we looked in an abstract class
- * that doesn't override an abstract method of its
- * parent:
- * abstract class Base {
- * public abstract void Foo ();
- * }
- * abstract class Derived : Base { }
- * class Child : Derived {
- * public override void Foo () { }
- * }
- *
- * if m was Child.Foo and we ask for the base method,
- * then we get here with klass == Derived and found == FALSE
- */
- /* but it shouldn't be the case that if we're looking
- * for the definition and didn't find a result; the
- * loop above should've taken us as far as we could
- * go! */
- g_assert (!(definition && !found));
- if (!found)
- goto retry;
- }
-
- g_assert (result != NULL);
-
- ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
- mono_error_set_pending_exception (&error);
- return ret;
+ else
+ return mono_method_get_object_handle (mono_domain_get (), base, NULL, error);
}
-ICALL_EXPORT MonoString*
-ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
+ICALL_EXPORT MonoStringHandle
+ves_icall_MonoMethod_get_name (MonoReflectionMethodHandle m, MonoError *error)
{
- MonoMethod *method = m->method;
+ mono_error_init (error);
+ MonoMethod *method = MONO_HANDLE_GETVAL (m, method);
- MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
- return m->name;
+ MonoStringHandle s = mono_string_new_handle (MONO_HANDLE_DOMAIN (m), method->name, error);
+ if (!is_ok (error))
+ return NULL_HANDLE_STRING;
+ MONO_HANDLE_SET (m, name, s);
+ return s;
}
ICALL_EXPORT void
return mono_generic_class_get_class (gclass);
}
-static MonoReflectionMethod*
-reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types, MonoError *error)
+static MonoGenericInst*
+generic_inst_from_type_array_handle (MonoArrayHandle types, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER ();
+ mono_error_init (error);
+ MonoGenericInst *ginst = NULL;
+ int count = mono_array_handle_length (types);
+ MonoType **type_argv = g_new0 (MonoType *, count);
+ MonoReflectionTypeHandle garg = MONO_HANDLE_NEW (MonoReflectionType, NULL);
+ for (int i = 0; i < count; i++) {
+ MONO_HANDLE_ARRAY_GETREF (garg, types, i);
+ type_argv [i] = mono_reflection_type_handle_mono_type (garg, error);
+ if (!is_ok (error))
+ goto leave;
+
+ }
+ ginst = mono_metadata_get_generic_inst (count, type_argv);
+leave:
+ g_free (type_argv);
+ HANDLE_FUNCTION_RETURN_VAL (ginst);
+}
+
+static MonoMethod*
+reflection_bind_generic_method_parameters (MonoMethod *method, MonoArrayHandle types, MonoError *error)
{
MonoClass *klass;
- MonoMethod *method, *inflated;
- MonoMethodInflated *imethod;
+ MonoMethod *inflated;
MonoGenericContext tmp_context;
- MonoGenericInst *ginst;
- MonoType **type_argv;
- int count, i;
mono_error_init (error);
- g_assert (strcmp (rmethod->object.vtable->klass->name, "MethodBuilder"));
-
- method = rmethod->method;
-
klass = method->klass;
if (method->is_inflated)
method = ((MonoMethodInflated *) method)->declaring;
- count = mono_method_signature (method)->generic_param_count;
- if (count != mono_array_length (types))
+ int count = mono_method_signature (method)->generic_param_count;
+ if (count != mono_array_handle_length (types)) {
+ mono_error_set_argument (error, "typeArguments", "Incorrect number of generic arguments");
return NULL;
-
- type_argv = g_new0 (MonoType *, count);
- for (i = 0; i < count; i++) {
- MonoReflectionType *garg = (MonoReflectionType *)mono_array_get (types, gpointer, i);
- type_argv [i] = mono_reflection_type_get_handle (garg, error);
- if (!is_ok (error)) {
- g_free (type_argv);
- return NULL;
- }
}
- ginst = mono_metadata_get_generic_inst (count, type_argv);
- g_free (type_argv);
+
+ MonoGenericInst *ginst = generic_inst_from_type_array_handle (types, error);
+ return_val_if_nok (error, NULL);
tmp_context.class_inst = mono_class_is_ginst (klass) ? mono_class_get_generic_class (klass)->context.class_inst : NULL;
tmp_context.method_inst = ginst;
inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error);
mono_error_assert_ok (error);
- imethod = (MonoMethodInflated *) inflated;
+
+ if (!mono_verifier_is_method_valid_generic_instantiation (inflated)) {
+ mono_error_set_argument (error, "typeArguments", "Invalid generic arguments");
+ return NULL;
+ }
+
+ return inflated;
+}
+
+MonoReflectionMethodHandle
+ves_icall_MonoMethod_MakeGenericMethod_impl (MonoReflectionMethodHandle rmethod, MonoArrayHandle types, MonoError *error)
+{
+ mono_error_init (error);
+ g_assert (0 != strcmp (mono_handle_class (rmethod)->name, "MethodBuilder"));
+
+ MonoMethod *method = MONO_HANDLE_GETVAL (rmethod, method);
+ MonoMethod *imethod = reflection_bind_generic_method_parameters (method, types, error);
+ return_val_if_nok (error, MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE));
/*FIXME but I think this is no longer necessary*/
if (image_is_dynamic (method->klass->image)) {
* to the reflection objects representing their generic definitions.
*/
mono_image_lock ((MonoImage*)image);
- mono_g_hash_table_insert (image->generic_def_objects, imethod, rmethod);
+ mono_g_hash_table_insert (image->generic_def_objects, imethod, MONO_HANDLE_RAW (rmethod));
mono_image_unlock ((MonoImage*)image);
}
- if (!mono_verifier_is_method_valid_generic_instantiation (inflated)) {
- mono_error_set_argument (error, "typeArguments", "Invalid generic arguments");
- return NULL;
- }
-
- return mono_method_get_object_checked (mono_object_domain (rmethod), inflated, NULL, error);
-}
-
-MonoReflectionMethod*
-ves_icall_MonoMethod_MakeGenericMethod_impl (MonoReflectionMethod *rmethod, MonoArray *types)
-{
- MonoError error;
- MonoReflectionMethod *result = reflection_bind_generic_method_parameters (rmethod, types, &error);
- mono_error_set_pending_exception (&error);
- return result;
+ return mono_method_get_object_handle (MONO_HANDLE_DOMAIN (rmethod), imethod, NULL, error);
}