[runtime] Use coop handles for System.Runtime.Remoting.RemotingServices.GetVirtualMethod
authorAleksey Kliger <aleksey@xamarin.com>
Thu, 25 May 2017 15:31:29 +0000 (11:31 -0400)
committerAleksey Kliger <aleksey@xamarin.com>
Thu, 25 May 2017 15:31:29 +0000 (11:31 -0400)
mono/metadata/icall-def.h
mono/metadata/icall.c

index 51b333dce30ef07cdbf32d762525d9698e32770e..775ce508d1d403c15768ac1ba197add7fb4d1290 100644 (file)
@@ -753,7 +753,7 @@ ICALL(REALP_1, "InternalGetProxyType", ves_icall_Remoting_RealProxy_InternalGetP
 HANDLES(ICALL(REALP_2, "InternalGetTransparentProxy", ves_icall_Remoting_RealProxy_GetTransparentProxy))
 
 ICALL_TYPE(REMSER, "System.Runtime.Remoting.RemotingServices", REMSER_0)
-ICALL(REMSER_0, "GetVirtualMethod", ves_icall_Remoting_RemotingServices_GetVirtualMethod)
+HANDLES(ICALL(REMSER_0, "GetVirtualMethod", ves_icall_Remoting_RemotingServices_GetVirtualMethod))
 ICALL(REMSER_1, "InternalExecute", ves_icall_InternalExecute)
 ICALL(REMSER_2, "IsTransparentProxy", ves_icall_IsTransparentProxy)
 #endif
index 79329f935382f75dd2d2ba9e3be1e2825d17d45e..cb362e1015946a86eb309832f830ab8c29a7f394 100644 (file)
@@ -6922,43 +6922,44 @@ ves_icall_IsTransparentProxy (MonoObject *proxy)
        return 0;
 }
 
-ICALL_EXPORT MonoReflectionMethod *
+ICALL_EXPORT MonoReflectionMethodHandle
 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
-       MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
+       MonoReflectionTypeHandle rtype, MonoReflectionMethodHandle rmethod, MonoError *error)
 {
-       MonoReflectionMethod *ret = NULL;
-       MonoError error;
-
-       MonoClass *klass;
-       MonoMethod *method;
-       MonoMethod **vtable;
-       MonoMethod *res = NULL;
+       MonoReflectionMethodHandle ret = MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
 
-       MONO_CHECK_ARG_NULL (rtype, NULL);
-       MONO_CHECK_ARG_NULL (rmethod, NULL);
+       error_init (error);
+       if (MONO_HANDLE_IS_NULL (rtype)) {
+               mono_error_set_argument_null (error, "type", "");
+               return ret;
+       }
+       if (MONO_HANDLE_IS_NULL (rmethod)) {
+               mono_error_set_argument_null (error, "method", "");
+               return ret;
+       }
 
-       method = rmethod->method;
-       klass = mono_class_from_mono_type (rtype->type);
-       mono_class_init_checked (klass, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+       MonoMethod *method = MONO_HANDLE_GETVAL (rmethod, method);
+       MonoType *type = MONO_HANDLE_GETVAL (rtype, type);
+       MonoClass *klass = mono_class_from_mono_type (type);
+       mono_class_init_checked (klass, error);
+       return_val_if_nok (error, ret);
 
        if (MONO_CLASS_IS_INTERFACE (klass))
-               return NULL;
+               return ret;
 
        if (method->flags & METHOD_ATTRIBUTE_STATIC)
-               return NULL;
+               return ret;
 
        if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
                if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
-                       return rmethod;
-               else
-                       return NULL;
+                       ret = rmethod;
+               return ret;
        }
 
        mono_class_setup_vtable (klass);
-       vtable = klass->vtable;
+       MonoMethod **vtable = klass->vtable;
 
+       MonoMethod *res = NULL;
        if (mono_class_is_interface (method->klass)) {
                gboolean variance_used = FALSE;
                /*MS fails with variant interfaces but it's the right thing to do anyway.*/
@@ -6967,17 +6968,16 @@ ves_icall_Remoting_RemotingServices_GetVirtualMethod (
                        res = vtable [offs + method->slot];
        } else {
                if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
-                       return NULL;
+                       return ret;
 
                if (method->slot != -1)
                        res = vtable [method->slot];
        }
 
        if (!res)
-               return NULL;
+               return ret;
 
-       ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
-       mono_error_set_pending_exception (&error);
+       ret = mono_method_get_object_handle (mono_domain_get (), res, NULL, error);
        return ret;
 }