[runtime] Use coop handles in mono_delegate_ctor_with_method
authorAleksey Kliger <aleksey@xamarin.com>
Wed, 10 May 2017 22:18:44 +0000 (18:18 -0400)
committerAleksey Kliger <aleksey@xamarin.com>
Tue, 23 May 2017 15:30:48 +0000 (11:30 -0400)
Use coop handles in icall System.Delegate.CreateDelegate_internal

TODO: change callsites fo mono_delegate_ctor_with_method_fixme to use handles

mono/metadata/icall-def.h
mono/metadata/icall.c
mono/metadata/marshal.c
mono/metadata/object-internals.h
mono/metadata/object.c

index f4bb94d2ea67f28845c55db975e143344ed802c8..df017b5f7943117fab8bb6550b3ccca8476cfdaa 100644 (file)
@@ -208,7 +208,7 @@ ICALL(DECIMAL_13, "ToSingle", mono_decimal_to_float)
 
 ICALL_TYPE(DELEGATE, "System.Delegate", DELEGATE_1)
 ICALL(DELEGATE_1, "AllocDelegateLike_internal", ves_icall_System_Delegate_AllocDelegateLike_internal)
-ICALL(DELEGATE_2, "CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal)
+HANDLES(ICALL(DELEGATE_2, "CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal))
 ICALL(DELEGATE_3, "GetVirtualMethod_internal", ves_icall_System_Delegate_GetVirtualMethod_internal)
 
 ICALL_TYPE(DEBUGR, "System.Diagnostics.Debugger", DEBUGR_1)
index 32f78c27c26245914f3682eac1ad80954bfe9866..176b754f1bdee3186518a54fa6c6435f9aeca238 100644 (file)
@@ -6170,68 +6170,64 @@ ves_icall_RuntimeType_MakePointerType (MonoReflectionTypeHandle ref_type, MonoEr
        return mono_type_get_object_handle (domain, &pklass->byval_arg, error);
 }
 
-ICALL_EXPORT MonoObject *
-ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
-                                                  MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
+ICALL_EXPORT MonoObjectHandle
+ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionTypeHandle ref_type, MonoObjectHandle target,
+                                                  MonoReflectionMethodHandle info, MonoBoolean throwOnBindFailure, MonoError *error)
 {
-       MonoError error;
-       MonoClass *delegate_class = mono_class_from_mono_type (type->type);
-       MonoObject *delegate;
+       MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
+       MonoClass *delegate_class = mono_class_from_mono_type (type);
        gpointer func;
-       MonoMethod *method = info->method;
+       MonoMethod *method = MONO_HANDLE_GETVAL (info, method);
        MonoMethodSignature *sig = mono_method_signature(method);
 
-       mono_class_init_checked (delegate_class, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+       mono_class_init_checked (delegate_class, error);
+       return_val_if_nok (error, NULL_HANDLE);
 
        if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
                /* FIXME improve this exception message */
-               mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
+               mono_error_set_execution_engine (error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
                                                 __func__,
                                                 "delegate_class->parent == mono_defaults.multicastdelegate_class");
-               mono_error_set_pending_exception (&error);
-               return NULL;
+               return NULL_HANDLE;
        }
 
        if (mono_security_core_clr_enabled ()) {
-               if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
+               MonoError security_error;
+               if (!mono_security_core_clr_ensure_delegate_creation (method, &security_error)) {
                        if (throwOnBindFailure)
-                               mono_error_set_pending_exception (&error);
+                               mono_error_move (error, &security_error);
                        else
-                               mono_error_cleanup (&error);
-                       return NULL;
+                               mono_error_cleanup (&security_error);
+                       return NULL_HANDLE;
                }
        }
 
        if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
                if (!method->is_inflated) {
-                       mono_set_pending_exception(mono_get_exception_argument("method", " Cannot bind to the target method because its signature differs from that of the delegate type"));
-                       return NULL;
+                       mono_error_set_argument (error, "method", " Cannot bind to the target method because its signature differs from that of the delegate type");
+                       return NULL_HANDLE;
                }
        }
 
-       delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+       MonoObjectHandle delegate = MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (MONO_HANDLE_DOMAIN (ref_type), delegate_class, error));
+       return_val_if_nok (error, NULL_HANDLE);
 
        if (method_is_dynamic (method)) {
                /* Creating a trampoline would leak memory */
-               func = mono_compile_method_checked (method, &error);
-               if (mono_error_set_pending_exception (&error))
-                       return NULL;
+               func = mono_compile_method_checked (method, error);
+               return_val_if_nok (error, NULL_HANDLE);
        } else {
-               if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
-                       method = mono_object_get_virtual_method (target, method);
-               gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
-               if (mono_error_set_pending_exception (&error))
-                       return NULL;
+               if (!MONO_HANDLE_IS_NULL (target) && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_handle_class (target)) {
+                       method = mono_object_handle_get_virtual_method (target, method, error);
+                       return_val_if_nok (error, NULL_HANDLE);
+               }
+               gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, error);
+               return_val_if_nok (error, NULL_HANDLE);
                func = mono_create_ftnptr (mono_domain_get (), trampoline);
        }
 
-       mono_delegate_ctor_with_method (delegate, target, func, method, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+       mono_delegate_ctor_with_method (delegate, target, func, method, error);
+       return_val_if_nok (error, NULL_HANDLE);
        return delegate;
 }
 
index 0886efa1ec5b235e32fe87eda969e2f03307159c..9b0f090eea59c8bf6e4c74a6fe1d93d6074741b1 100644 (file)
@@ -653,7 +653,7 @@ mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn)
                gpointer compiled_ptr = mono_compile_method_checked (wrapper, &error);
                if (mono_error_set_pending_exception (&error))
                        return NULL;
-               mono_delegate_ctor_with_method ((MonoObject*)d, this_obj, compiled_ptr, wrapper, &error);
+               mono_delegate_ctor_with_method_fixme ((MonoObject*)d, this_obj, compiled_ptr, wrapper, &error);
                if (mono_error_set_pending_exception (&error))
                        return NULL;
        }
index 59b1cc558995810ce60a38bd480b4515d0c5ccbc..933adf218ff461109306d42dd32adad8793918cc 100644 (file)
@@ -655,7 +655,10 @@ void
 mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoArray *out_args, MonoError *error);
 
 gboolean
-mono_delegate_ctor_with_method (MonoObject *this_obj, MonoObject *target, gpointer addr, MonoMethod *method, MonoError *error);
+mono_delegate_ctor_with_method (MonoObjectHandle this_obj, MonoObjectHandle target, gpointer addr, MonoMethod *method, MonoError *error);
+
+gboolean
+mono_delegate_ctor_with_method_fixme (MonoObject *this_obj, MonoObject *target, gpointer addr, MonoMethod *method, MonoError *error);
 
 gboolean
 mono_delegate_ctor         (MonoObject *this_obj, MonoObject *target, gpointer addr, MonoError *error);
@@ -768,12 +771,18 @@ struct _MonoDelegate {
        MonoBoolean method_is_virtual;
 };
 
+/* Safely access System.Delegate from native code */
+TYPED_HANDLE_DECL (MonoDelegate);
+
 typedef struct _MonoMulticastDelegate MonoMulticastDelegate;
 struct _MonoMulticastDelegate {
        MonoDelegate delegate;
        MonoArray *delegates;
 };
 
+/* Safely access System.MulticastDelegate from native code */
+TYPED_HANDLE_DECL (MonoMulticastDelegate);
+
 struct _MonoReflectionField {
        MonoObject object;
        MonoClass *klass;
index 92aa723f20a73f61c7ffec75631e46b6ee77ec94..e0712a91b240d9148254e2e93cbd3d8dd39ed384 100644 (file)
@@ -7803,6 +7803,17 @@ mono_print_unhandled_exception (MonoObject *exc)
                g_free (message);
 }
 
+gboolean
+mono_delegate_ctor_with_method_fixme (MonoObject *this_obj_raw, MonoObject *target_raw, gpointer addr, MonoMethod *method, MonoError *error)
+{
+       HANDLE_FUNCTION_ENTER ();
+       error_init (error);
+       MONO_HANDLE_DCL (MonoObject, this_obj);
+       MONO_HANDLE_DCL (MonoObject, target);
+       gboolean res = mono_delegate_ctor_with_method (this_obj, target, addr, method, error);
+       HANDLE_FUNCTION_RETURN_VAL (res);
+}
+
 /**
  * mono_delegate_ctor_with_method:
  * \param this pointer to an uninitialized delegate object
@@ -7817,43 +7828,44 @@ mono_print_unhandled_exception (MonoObject *exc)
  * On failure returns FALSE and sets \p error.
  */
 gboolean
-mono_delegate_ctor_with_method (MonoObject *this_obj, MonoObject *target, gpointer addr, MonoMethod *method, MonoError *error)
+mono_delegate_ctor_with_method (MonoObjectHandle this_obj, MonoObjectHandle target, gpointer addr, MonoMethod *method, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
        error_init (error);
-       MonoDelegate *delegate = (MonoDelegate *)this_obj;
+       MonoDelegateHandle delegate = MONO_HANDLE_CAST (MonoDelegate, this_obj);
 
-       g_assert (this_obj);
+       g_assert (!MONO_HANDLE_IS_NULL (this_obj));
        g_assert (addr);
 
-       g_assert (mono_class_has_parent (mono_object_class (this_obj), mono_defaults.multicastdelegate_class));
+       MonoClass *klass = mono_handle_class (this_obj);
+       g_assert (mono_class_has_parent (klass, mono_defaults.multicastdelegate_class));
 
        if (method)
-               delegate->method = method;
+               MONO_HANDLE_SETVAL (delegate, method, MonoMethod*, method);
 
        mono_stats.delegate_creations++;
 
 #ifndef DISABLE_REMOTING
-       if (target && mono_object_is_transparent_proxy (target)) {
+       if (!MONO_HANDLE_IS_NULL (target) && mono_class_is_transparent_proxy (mono_handle_class (target))) {
                g_assert (method);
                method = mono_marshal_get_remoting_invoke (method);
 #ifdef ENABLE_INTERPRETER
                //g_error ("need RuntimeMethod in method_ptr when using interpreter");
 #endif
-               delegate->method_ptr = mono_compile_method_checked (method, error);
+               MONO_HANDLE_SETVAL (delegate, method_ptr, gpointer, mono_compile_method_checked (method, error));
                return_val_if_nok (error, FALSE);
-               MONO_OBJECT_SETREF (delegate, target, target);
+               MONO_HANDLE_SET (delegate, target, target);
        } else
 #endif
        {
-               delegate->method_ptr = addr;
-               MONO_OBJECT_SETREF (delegate, target, target);
+               MONO_HANDLE_SETVAL (delegate, method_ptr, gpointer, addr);
+               MONO_HANDLE_SET (delegate, target, target);
        }
 
-       delegate->invoke_impl = callbacks.create_delegate_trampoline (delegate->object.vtable->domain, delegate->object.vtable->klass);
+       MONO_HANDLE_SETVAL (delegate, invoke_impl, gpointer, callbacks.create_delegate_trampoline (MONO_HANDLE_DOMAIN (delegate), mono_handle_class (delegate)));
        if (callbacks.init_delegate)
-               callbacks.init_delegate (delegate);
+               callbacks.init_delegate (MONO_HANDLE_RAW (delegate)); /* FIXME: update init_delegate callback to take a MonoDelegateHandle */
        return TRUE;
 }
 
@@ -7887,7 +7899,7 @@ mono_delegate_ctor (MonoObject *this_obj, MonoObject *target, gpointer addr, Mon
                g_assert (!mono_class_is_gtd (method->klass));
        }
 
-       return mono_delegate_ctor_with_method (this_obj, target, addr, method, error);
+       return mono_delegate_ctor_with_method_fixme (this_obj, target, addr, method, error);
 }
 
 /**