From: Jay Krell Date: Tue, 3 Sep 2019 22:18:21 +0000 (-0700) Subject: [Coop] ves_icall_InternalInvoke. (mono/mono#16625) X-Git-Tag: submit/tizen/20210909.063632~10331^2~5^2~605 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=35542cf86e79e2056af0bac5fa7650330b7b6336;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [Coop] ves_icall_InternalInvoke. (mono/mono#16625) * [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 --- diff --git a/src/mono/mono/metadata/boehm-gc.c b/src/mono/mono/metadata/boehm-gc.c index de572f6..06b0388 100644 --- a/src/mono/mono/metadata/boehm-gc.c +++ b/src/mono/mono/metadata/boehm-gc.c @@ -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; } diff --git a/src/mono/mono/metadata/handle-decl.h b/src/mono/mono/metadata/handle-decl.h index a6085be..931824c 100644 --- a/src/mono/mono/metadata/handle-decl.h +++ b/src/mono/mono/metadata/handle-decl.h @@ -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), \ diff --git a/src/mono/mono/metadata/handle.h b/src/mono/mono/metadata/handle.h index f08fe6c..1e6dea9 100644 --- a/src/mono/mono/metadata/handle.h +++ b/src/mono/mono/metadata/handle.h @@ -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) { diff --git a/src/mono/mono/metadata/icall-decl.h b/src/mono/mono/metadata/icall-decl.h index 30f7720..b2a022f 100644 --- a/src/mono/mono/metadata/icall-decl.h +++ b/src/mono/mono/metadata/icall-decl.h @@ -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*); diff --git a/src/mono/mono/metadata/icall-def-netcore.h b/src/mono/mono/metadata/icall-def-netcore.h index 41624ca..45b7c43 100644 --- a/src/mono/mono/metadata/icall-def-netcore.h +++ b/src/mono/mono/metadata/icall-def-netcore.h @@ -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)) diff --git a/src/mono/mono/metadata/icall-def.h b/src/mono/mono/metadata/icall-def.h index 23ac8bc..23ffc77 100644 --- a/src/mono/mono/metadata/icall-def.h +++ b/src/mono/mono/metadata/icall-def.h @@ -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 diff --git a/src/mono/mono/metadata/icall-table.h b/src/mono/mono/metadata/icall-table.h index e27caf1..af253b3 100644 --- a/src/mono/mono/metadata/icall-table.h +++ b/src/mono/mono/metadata/icall-table.h @@ -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 diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index def985d..449ed2a 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -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 diff --git a/src/mono/mono/metadata/null-gc.c b/src/mono/mono/metadata/null-gc.c index 6354da9..e3af02f 100644 --- a/src/mono/mono/metadata/null-gc.c +++ b/src/mono/mono/metadata/null-gc.c @@ -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; } diff --git a/src/mono/mono/metadata/object-internals.h b/src/mono/mono/metadata/object-internals.h index eb5bda7..231dde9 100644 --- a/src/mono/mono/metadata/object-internals.h +++ b/src/mono/mono/metadata/object-internals.h @@ -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); diff --git a/src/mono/mono/sgen/sgen-gc.c b/src/mono/mono/sgen/sgen-gc.c index 5ac0a3d..4697689 100644 --- a/src/mono/mono/sgen/sgen-gc.c +++ b/src/mono/mono/sgen/sgen-gc.c @@ -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); }