[Coop] ves_icall_InternalInvoke. (mono/mono#16625)
authorJay Krell <jaykrell@microsoft.com>
Tue, 3 Sep 2019 22:18:21 +0000 (15:18 -0700)
committerLarry Ewing <lewing@xamarin.com>
Tue, 3 Sep 2019 22:18:21 +0000 (17:18 -0500)
* [Coop] ves_icall_InternalInvoke.

(Part taken from ves_icall_InternalExecute https://github.com/mono/mono/pull/16622.)

* error_init_reuse.

* Remove stars from types.

Commit migrated from https://github.com/mono/mono/commit/651eb7696e7887597df0eb149cd7eb222ea807b4

src/mono/mono/metadata/boehm-gc.c
src/mono/mono/metadata/handle-decl.h
src/mono/mono/metadata/handle.h
src/mono/mono/metadata/icall-decl.h
src/mono/mono/metadata/icall-def-netcore.h
src/mono/mono/metadata/icall-def.h
src/mono/mono/metadata/icall-table.h
src/mono/mono/metadata/icall.c
src/mono/mono/metadata/null-gc.c
src/mono/mono/metadata/object-internals.h
src/mono/mono/sgen/sgen-gc.c

index de572f6..06b0388 100644 (file)
@@ -906,7 +906,7 @@ mono_gc_wbarrier_arrayref_copy_internal (gpointer dest_ptr, gconstpointer src_pt
 }
 
 void
-mono_gc_wbarrier_generic_store_internal (gpointer ptr, MonoObject* value)
+mono_gc_wbarrier_generic_store_internal (void volatile* ptr, MonoObject* value)
 {
        *(void**)ptr = value;
 }
index a6085be..931824c 100644 (file)
@@ -67,6 +67,7 @@ Handle macros/functions
                MONO_IF_CPLUSPLUS (                                             \
                        MONO_ALWAYS_INLINE                                      \
                        TYPE * GetRaw () const { return __raw ? *__raw : NULL; } \
+                       TYPE * volatile * Ref () { g_assert (__raw); return __raw; } \
                )                                                               \
                TYPE * volatile *__raw;                                         \
        } TYPED_HANDLE_NAME (TYPE),                                             \
index f08fe6c..1e6dea9 100644 (file)
@@ -557,6 +557,29 @@ mono_null_value_handle (void)
 #define NULL_HANDLE_ARRAY              (MONO_HANDLE_CAST (MonoArray,  NULL_HANDLE))
 #define NULL_HANDLE_STRING_BUILDER     (MONO_HANDLE_CAST (MonoStringBuilder, NULL_HANDLE))
 
+#if __cplusplus
+
+// Use this to convert a THandle to a raw T** such as for a ref or out parameter, without
+// copying back and forth through an intermediate. The handle must already be allocated,
+// such as icall marshaling does for out and ref parameters.
+#define MONO_HANDLE_REF(h) (h.Ref ())
+
+#else
+
+static inline void volatile*
+mono_handle_ref (void volatile* p)
+{
+       g_assert (p);
+       return p;
+}
+
+// Use this to convert a THandle to a raw T** such as for a ref or out parameter, without
+// copying back and forth through an intermediate. The handle must already be allocated,
+// such as icall marshaling does for out and ref parameters.
+#define MONO_HANDLE_REF(handle) (MONO_TYPEOF_CAST ((handle).__raw, mono_handle_ref ((handle).__raw)))
+
+#endif
+
 static inline MonoObjectHandle
 mono_handle_assign_raw (MonoObjectHandleOut dest, void *src)
 {
index 30f7720..b2a022f 100644 (file)
@@ -84,7 +84,6 @@ ICALL_EXPORT MonoBoolean ves_icall_System_Reflection_AssemblyName_ParseAssemblyN
 ICALL_EXPORT MonoBoolean ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void);
 ICALL_EXPORT MonoBoolean ves_icall_System_Threading_Thread_YieldInternal (void);
 ICALL_EXPORT MonoObject* ves_icall_InternalExecute (MonoReflectionMethod*, MonoObject*, MonoArray*, MonoArray**);
-ICALL_EXPORT MonoObject* ves_icall_InternalInvoke (MonoReflectionMethod*, MonoObject*, MonoArray*, MonoException**);
 ICALL_EXPORT MonoObject* ves_icall_RuntimeFieldInfo_GetValueInternal (MonoReflectionField* field, MonoObject* obj);
 ICALL_EXPORT MonoObject* ves_icall_property_info_get_default_value (MonoReflectionProperty*);
 ICALL_EXPORT void ves_icall_System_ArgIterator_Setup (MonoArgIterator*, char*, char*);
index 41624ca..45b7c43 100644 (file)
@@ -257,7 +257,7 @@ HANDLES(RASSEM_12, "get_location", ves_icall_System_Reflection_RuntimeAssembly_g
 
 ICALL_TYPE(MCMETH, "System.Reflection.RuntimeConstructorInfo", MCMETH_1)
 HANDLES(MCMETH_1, "GetGenericMethodDefinition_impl", ves_icall_RuntimeMethodInfo_GetGenericMethodDefinition, MonoReflectionMethod, 1, (MonoReflectionMethod))
-ICALL(MCMETH_2, "InternalInvoke", ves_icall_InternalInvoke)
+HANDLES(MCMETH_2, "InternalInvoke", ves_icall_InternalInvoke, MonoObject, 4, (MonoReflectionMethod, MonoObject, MonoArray, MonoExceptionOut))
 HANDLES(MCMETH_3, "get_core_clr_security_level", ves_icall_RuntimeMethodInfo_get_core_clr_security_level, int, 1, (MonoReflectionMethod))
 HANDLES_REUSE_WRAPPER(MCMETH_4, "get_metadata_token", ves_icall_reflection_get_token)
 
@@ -284,7 +284,7 @@ HANDLES_REUSE_WRAPPER(RMETHODINFO_2, "GetGenericMethodDefinition_impl", ves_ical
 HANDLES(RMETHODINFO_3, "GetMethodBodyInternal", ves_icall_System_Reflection_RuntimeMethodInfo_GetMethodBodyInternal, MonoReflectionMethodBody, 1, (MonoMethod_ptr))
 HANDLES(RMETHODINFO_4, "GetMethodFromHandleInternalType_native", ves_icall_System_Reflection_RuntimeMethodInfo_GetMethodFromHandleInternalType_native, MonoReflectionMethod, 3, (MonoMethod_ptr, MonoType_ptr, MonoBoolean))
 HANDLES(RMETHODINFO_5, "GetPInvoke", ves_icall_RuntimeMethodInfo_GetPInvoke, void, 4, (MonoReflectionMethod, int_ref, MonoStringOut, MonoStringOut))
-ICALL(RMETHODINFO_6, "InternalInvoke", ves_icall_InternalInvoke)
+HANDLES_REUSE_WRAPPER(RMETHODINFO_6, "InternalInvoke", ves_icall_InternalInvoke)
 HANDLES(RMETHODINFO_7, "MakeGenericMethod_impl", ves_icall_RuntimeMethodInfo_MakeGenericMethod_impl, MonoReflectionMethod, 2, (MonoReflectionMethod, MonoArray))
 HANDLES(RMETHODINFO_8, "get_IsGenericMethod", ves_icall_RuntimeMethodInfo_get_IsGenericMethod, MonoBoolean, 1, (MonoReflectionMethod))
 HANDLES(RMETHODINFO_9, "get_IsGenericMethodDefinition", ves_icall_RuntimeMethodInfo_get_IsGenericMethodDefinition, MonoBoolean, 1, (MonoReflectionMethod))
index 23ac8bc..23ffc77 100644 (file)
@@ -674,7 +674,7 @@ HANDLES(RASSEM_15, "get_location", ves_icall_System_Reflection_RuntimeAssembly_g
 
 ICALL_TYPE(MCMETH, "System.Reflection.RuntimeConstructorInfo", MCMETH_1)
 HANDLES(MCMETH_1, "GetGenericMethodDefinition_impl", ves_icall_RuntimeMethodInfo_GetGenericMethodDefinition, MonoReflectionMethod, 1, (MonoReflectionMethod))
-ICALL(MCMETH_2, "InternalInvoke", ves_icall_InternalInvoke)
+HANDLES(MCMETH_2, "InternalInvoke", ves_icall_InternalInvoke, MonoObject, 4, (MonoReflectionMethod, MonoObject, MonoArray, MonoExceptionOut))
 HANDLES(MCMETH_3, "get_core_clr_security_level", ves_icall_RuntimeMethodInfo_get_core_clr_security_level, int, 1, (MonoReflectionMethod))
 HANDLES_REUSE_WRAPPER(MCMETH_4, "get_metadata_token", ves_icall_reflection_get_token)
 
@@ -700,7 +700,7 @@ HANDLES_REUSE_WRAPPER(RMETHODINFO_2, "GetGenericMethodDefinition_impl", ves_ical
 HANDLES(RMETHODINFO_3, "GetMethodBodyInternal", ves_icall_System_Reflection_RuntimeMethodInfo_GetMethodBodyInternal, MonoReflectionMethodBody, 1, (MonoMethod_ptr))
 HANDLES(RMETHODINFO_4, "GetMethodFromHandleInternalType_native", ves_icall_System_Reflection_RuntimeMethodInfo_GetMethodFromHandleInternalType_native, MonoReflectionMethod, 3, (MonoMethod_ptr, MonoType_ptr, MonoBoolean))
 HANDLES(RMETHODINFO_5, "GetPInvoke", ves_icall_RuntimeMethodInfo_GetPInvoke, void, 4, (MonoReflectionMethod, int_ref, MonoStringOut, MonoStringOut))
-ICALL(RMETHODINFO_6, "InternalInvoke", ves_icall_InternalInvoke)
+HANDLES_REUSE_WRAPPER(RMETHODINFO_6, "InternalInvoke", ves_icall_InternalInvoke)
 HANDLES(RMETHODINFO_7, "MakeGenericMethod_impl", ves_icall_RuntimeMethodInfo_MakeGenericMethod_impl, MonoReflectionMethod, 2, (MonoReflectionMethod, MonoArray))
 HANDLES(RMETHODINFO_8, "get_IsGenericMethod", ves_icall_RuntimeMethodInfo_get_IsGenericMethod, MonoBoolean, 1, (MonoReflectionMethod))
 HANDLES(RMETHODINFO_9, "get_IsGenericMethodDefinition", ves_icall_RuntimeMethodInfo_get_IsGenericMethodDefinition, MonoBoolean, 1, (MonoReflectionMethod))
@@ -846,7 +846,6 @@ HANDLES(REALP_2, "InternalGetTransparentProxy", ves_icall_Remoting_RealProxy_Get
 
 ICALL_TYPE(REMSER, "System.Runtime.Remoting.RemotingServices", REMSER_0)
 HANDLES(REMSER_0, "GetVirtualMethod", ves_icall_Remoting_RemotingServices_GetVirtualMethod, MonoReflectionMethod, 2, (MonoReflectionType, MonoReflectionMethod))
-
 ICALL(REMSER_1, "InternalExecute", ves_icall_InternalExecute)
 HANDLES(REMSER_2, "IsTransparentProxy", ves_icall_IsTransparentProxy, MonoBoolean, 1, (MonoObject))
 #endif
index e27caf1..af253b3 100644 (file)
@@ -90,16 +90,18 @@ typedef MonoW32ProcessInfo *MonoW32ProcessInfo_ref;
 // Maybe do this in TYPED_HANDLE_DECL.
 typedef MonoArray MonoArrayOut;
 typedef MonoArray MonoArrayInOut;
+typedef MonoArrayHandle MonoArrayOutHandle;
+typedef MonoArrayHandle MonoArrayInOutHandle;
+typedef MonoException MonoExceptionOut;
+typedef MonoExceptionHandle MonoExceptionOutHandle;
 typedef MonoObject MonoObjectOut;
 typedef MonoObject MonoObjectInOut;
 typedef MonoObjectHandle MonoObjectOutHandle;
 typedef MonoObjectHandle MonoObjectInOutHandle;
-typedef MonoArrayHandle MonoArrayOutHandle;
-typedef MonoArrayHandle MonoArrayInOutHandle;
-typedef MonoString MonoStringOut;
-typedef MonoStringHandle MonoStringOutHandle;
 typedef MonoReflectionModule MonoReflectionModuleOut;
 typedef MonoReflectionModuleHandle MonoReflectionModuleOutHandle;
+typedef MonoString MonoStringOut;
+typedef MonoStringHandle MonoStringOutHandle;
 
 // How the arguments and return value of an icall should be wrapped.
 // The names and meanings are from marshal-ilgen.c.
@@ -224,6 +226,7 @@ typedef MonoReflectionModuleHandle MonoReflectionModuleOutHandle;
 #define MONO_HANDLE_TYPE_WRAP_MonoTransparentProxy                     ICALL_HANDLES_WRAP_OBJ
 #define MONO_HANDLE_TYPE_WRAP_MonoW32ProcessStartInfo          ICALL_HANDLES_WRAP_OBJ
 
+#define MONO_HANDLE_TYPE_WRAP_MonoExceptionOut         ICALL_HANDLES_WRAP_OBJ_OUT
 #define MONO_HANDLE_TYPE_WRAP_MonoObjectOut            ICALL_HANDLES_WRAP_OBJ_OUT
 #define MONO_HANDLE_TYPE_WRAP_MonoStringOut            ICALL_HANDLES_WRAP_OBJ_OUT
 #define MONO_HANDLE_TYPE_WRAP_MonoArrayOut             ICALL_HANDLES_WRAP_OBJ_OUT
index def985d..449ed2a 100644 (file)
@@ -3582,113 +3582,119 @@ ves_icall_RuntimeMethodInfo_GetGenericArguments (MonoReflectionMethodHandle ref_
        return res;
 }
 
-MonoObject *
-ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc) 
+MonoObjectHandle
+ves_icall_InternalInvoke (MonoReflectionMethodHandle method_handle, MonoObjectHandle this_arg_handle,
+                         MonoArrayHandle params_handle, MonoExceptionHandleOut exception_out, MonoError *error)
 {
-       ERROR_DECL (error);
+       MonoReflectionMethod* const method = MONO_HANDLE_RAW (method_handle);
+       MonoObject* const this_arg = MONO_HANDLE_RAW (this_arg_handle);
+       MonoArray* const params = MONO_HANDLE_RAW (params_handle);
+
        /* 
         * Invoke from reflection is supposed to always be a virtual call (the API
         * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
         * greater flexibility.
         */
        MonoMethod *m = method->method;
-       MonoMethodSignature *sig = mono_method_signature_internal (m);
-       MonoImage *image;
-       int pcount;
+       MonoMethodSignature* const sig = mono_method_signature_internal (m);
+       MonoImage *image = NULL;
+       int pcount = 0;
        void *obj = this_arg;
+       char *this_name = NULL;
+       char *target_name = NULL;
+       char *msg = NULL;
+       MonoObject *result = NULL;
+       MonoArray *arr = NULL;
+       MonoException *exception = NULL;
 
-       *exc = NULL;
+       *MONO_HANDLE_REF (exception_out) = NULL;
 
        if (mono_security_core_clr_enabled () &&
            !mono_security_core_clr_ensure_reflection_access_method (m, error)) {
-               mono_error_set_pending_exception (error);
-               return NULL;
+               goto return_null;
        }
 
        if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
                if (!mono_class_vtable_checked (mono_object_domain (method), m->klass, error)) {
                        mono_error_cleanup (error); /* FIXME does this make sense? */
-                       mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
-                       return NULL;
+                       error_init_reuse (error);
+                       exception = mono_class_get_exception_for_failure (m->klass);
+                       goto return_null;
                }
 
                if (this_arg) {
                        if (!mono_object_isinst_checked (this_arg, m->klass, error)) {
                                if (!is_ok (error)) {
-                                       mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_error_convert_to_exception (error));
-                                       return NULL;
+                                       exception = mono_error_convert_to_exception (error);
+                                       goto return_null;
                                }
-                               char *this_name = mono_type_get_full_name (mono_object_class (this_arg));
-                               char *target_name = mono_type_get_full_name (m->klass);
-                               char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
-                               mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
-                               g_free (msg);
-                               g_free (target_name);
-                               g_free (this_name);
-                               return NULL;
+                               this_name = mono_type_get_full_name (mono_object_class (this_arg));
+                               target_name = mono_type_get_full_name (m->klass);
+                               msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
+                               exception = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg);
+                               goto return_null;
                        }
                        m = mono_object_get_virtual_method_internal (this_arg, m);
                        /* must pass the pointer to the value for valuetype methods */
-                       if (m_class_is_valuetype (m->klass))
+                       if (m_class_is_valuetype (m->klass)) {
                                obj = mono_object_unbox_internal (this_arg);
+                               // FIXMEcoop? Does obj need to be put into a handle?
+                       }
                } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
-                       mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
-                       return NULL;
+                       exception = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target.");
+                       goto return_null;
                }
        }
 
        if ((m->klass != NULL && m_class_is_byreflike (m->klass)) || m_class_is_byreflike (mono_class_from_mono_type_internal (sig->ret))) {
-               mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System", "NotSupportedException", "Cannot invoke method with stack pointers via reflection"));
-               return NULL;
+               exception = mono_exception_from_name_msg (mono_defaults.corlib, "System", "NotSupportedException", "Cannot invoke method with stack pointers via reflection");
+               goto return_null;
        }
 #if ENABLE_NETCORE
        if (sig->ret->byref) {
                MonoType* ret_byval = m_class_get_byval_arg (mono_class_from_mono_type_internal (sig->ret));
                if (ret_byval->type == MONO_TYPE_VOID) {
-                       mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System", "NotSupportedException", "ByRef to void return values are not supported in reflection invocation"));
-                       return NULL;
+                       exception = mono_exception_from_name_msg (mono_defaults.corlib, "System", "NotSupportedException", "ByRef to void return values are not supported in reflection invocation");
+                       goto return_null;
                }       
                if (m_class_is_byreflike (mono_class_from_mono_type_internal (ret_byval))) {
-                       mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System", "NotSupportedException", "Cannot invoke method returning ByRef to ByRefLike type via reflection"));
-                       return NULL;
+                       exception = mono_exception_from_name_msg (mono_defaults.corlib, "System", "NotSupportedException", "Cannot invoke method returning ByRef to ByRefLike type via reflection");
+                       goto return_null;
                }
        }
 #else
        if (sig->ret->byref) {
-               mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System", "NotSupportedException", "Cannot invoke method returning ByRef type via reflection"));
-               return NULL;
+               exception = mono_exception_from_name_msg (mono_defaults.corlib, "System", "NotSupportedException", "Cannot invoke method returning ByRef type via reflection");
+               goto return_null;
        }
 #endif
 
        pcount = params? mono_array_length_internal (params): 0;
        if (pcount != sig->param_count) {
-               mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
-               return NULL;
+               exception = mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException");
+               goto return_null;
        }
 
        if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
-               mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class."));
-               return NULL;
+               exception = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class.");
+               goto return_null;
        }
 
        image = m_class_get_image (m->klass);
        if (mono_asmctx_get_kind (&image->assembly->context) == MONO_ASMCTX_REFONLY) {
-               mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
-               return NULL;
+               exception = mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api.");
+               goto return_null;
        }
 
        if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
-               mono_gc_wbarrier_generic_store_internal (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
-               return NULL;
+               exception = mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access.");
+               goto return_null;
        }
        
        if (m_class_get_rank (m->klass) && !strcmp (m->name, ".ctor")) {
-               MonoArray *arr;
                int i;
-               uintptr_t *lengths;
-               intptr_t *lower_bounds;
                pcount = mono_array_length_internal (params);
-               lengths = g_newa (uintptr_t, pcount);
+               uintptr_t * const lengths = g_newa (uintptr_t, pcount);
                /* Note: the synthetized array .ctors have int32 as argument type */
                for (i = 0; i < pcount; ++i)
                        lengths [i] = *(int32_t*) ((char*)mono_array_get_internal (params, gpointer, i) + sizeof (MonoObject));
@@ -3696,35 +3702,28 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, Mo
                if (m_class_get_rank (m->klass) == 1 && sig->param_count == 2 && m_class_get_rank (m_class_get_element_class (m->klass))) {
                        /* This is a ctor for jagged arrays. MS creates an array of arrays. */
                        arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, error);
-                       if (!is_ok (error)) {
-                               mono_error_set_pending_exception (error);
-                               return NULL;
-                       }
+                       goto_if_nok (error, return_null);
+
+                       MonoArrayHandle subarray_handle = MONO_HANDLE_NEW (MonoArray, NULL);
 
                        for (i = 0; i < mono_array_length_internal (arr); ++i) {
                                MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m_class_get_element_class (m->klass), &lengths [1], NULL, error);
-                               if (!is_ok (error)) {
-                                       mono_error_set_pending_exception (error);
-                                       return NULL;
-                               }
+                               goto_if_nok (error, return_null);
+                               MONO_HANDLE_ASSIGN_RAW (subarray_handle, subarray); // FIXME? Overkill?
                                mono_array_setref_fast (arr, i, subarray);
                        }
-                       return (MonoObject*)arr;
+                       goto exit;
                }
 
                if (m_class_get_rank (m->klass) == pcount) {
                        /* Only lengths provided. */
                        arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, error);
-                       if (!is_ok (error)) {
-                               mono_error_set_pending_exception (error);
-                               return NULL;
-                       }
-
-                       return (MonoObject*)arr;
+                       goto_if_nok (error, return_null);
+                       goto exit;
                } else {
                        g_assert (pcount == (m_class_get_rank (m->klass) * 2));
                        /* The arguments are lower-bound-length pairs */
-                       lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
+                       intptr_t * const lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
 
                        for (i = 0; i < pcount / 2; ++i) {
                                lower_bounds [i] = *(int32_t*) ((char*)mono_array_get_internal (params, gpointer, (i * 2)) + sizeof (MonoObject));
@@ -3732,17 +3731,25 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, Mo
                        }
 
                        arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, error);
-                       if (!is_ok (error)) {
-                               mono_error_set_pending_exception (error);
-                               return NULL;
-                       }
-
-                       return (MonoObject*)arr;
+                       goto_if_nok (error, return_null);
+                       goto exit;
                }
        }
-       MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, error);
-       mono_error_set_pending_exception (error);
-       return result;
+       result = mono_runtime_invoke_array_checked (m, obj, params, error);
+       goto exit;
+return_null:
+       result = NULL;
+       arr = NULL;
+exit:
+       if (exception) {
+               MONO_HANDLE_NEW (MonoException, exception); // FIXME? overkill?
+               mono_gc_wbarrier_generic_store_internal (MONO_HANDLE_REF (exception_out), (MonoObject*)exception);
+       }
+       g_free (target_name);
+       g_free (this_name);
+       g_free (msg);
+       g_assert (!result || !arr); // only one, or neither, should be set
+       return result ? MONO_HANDLE_NEW (MonoObject, result) : arr ? MONO_HANDLE_NEW (MonoObject, (MonoObject*)arr) : NULL_HANDLE;
 }
 
 #ifndef DISABLE_REMOTING
index 6354da9..e3af02f 100644 (file)
@@ -271,7 +271,7 @@ mono_gc_wbarrier_arrayref_copy_internal (gpointer dest_ptr, gconstpointer src_pt
 }
 
 void
-mono_gc_wbarrier_generic_store_internal (gpointer ptr, MonoObject* value)
+mono_gc_wbarrier_generic_store_internal (void volatile* ptr, MonoObject* value)
 {
        *(void**)ptr = value;
 }
index eb5bda7..231dde9 100644 (file)
@@ -2401,7 +2401,7 @@ void
 mono_gc_wbarrier_arrayref_copy_internal (void* dest_ptr, const void* src_ptr, int count);
 
 void
-mono_gc_wbarrier_generic_store_internal (void* ptr, MonoObject* value);
+mono_gc_wbarrier_generic_store_internal (void volatile* ptr, MonoObject* value);
 
 void
 mono_gc_wbarrier_generic_store_atomic_internal (void *ptr, MonoObject *value);
index 5ac0a3d..4697689 100644 (file)
@@ -3045,12 +3045,12 @@ mono_gc_wbarrier_generic_nostore_internal (gpointer ptr)
  * mono_gc_wbarrier_generic_store_internal:
  */
 void
-mono_gc_wbarrier_generic_store_internal (gpointer ptr, GCObject* value)
+mono_gc_wbarrier_generic_store_internal (void volatile* ptr, GCObject* value)
 {
        SGEN_LOG (8, "Wbarrier store at %p to %p (%s)", ptr, value, value ? sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (value)) : "null");
-       SGEN_UPDATE_REFERENCE_ALLOW_NULL (ptr, value);
+       SGEN_UPDATE_REFERENCE_ALLOW_NULL ((void*)ptr, value); // FIXME volatile
        if (ptr_in_nursery (value) || sgen_concurrent_collection_in_progress)
-               mono_gc_wbarrier_generic_nostore_internal (ptr);
+               mono_gc_wbarrier_generic_nostore_internal ((void*)ptr); // FIXME volatile
        sgen_dummy_use (value);
 }