Mark mono_runtime_invoke external only.
Runtime should use mono_runtime_invoke_checked and mono_runtime_try_invoke.
MonoReflectionAssembly *
mono_domain_try_type_resolve (MonoDomain *domain, char *name, MonoObject *tb)
{
+ MonoError error;
+ MonoReflectionAssembly *ret;
MonoClass *klass;
void *params [1];
static MonoMethod *method = NULL;
*params = (MonoObject*)mono_string_new (mono_domain_get (), name);
else
*params = tb;
- return (MonoReflectionAssembly *) mono_runtime_invoke (method, domain->domain, params, NULL);
+
+ ret = (MonoReflectionAssembly *) mono_runtime_invoke_checked (method, domain->domain, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ return ret;
}
/**
mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, MonoAssembly *requesting, gboolean refonly)
{
MonoError error;
+ MonoReflectionAssembly *ret;
MonoClass *klass;
MonoMethod *method;
MonoBoolean isrefonly;
} else
params [1] = NULL;
params [2] = &isrefonly;
- return (MonoReflectionAssembly *) mono_runtime_invoke (method, domain->domain, params, NULL);
+
+ ret = (MonoReflectionAssembly *) mono_runtime_invoke_checked (method, domain->domain, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ return ret;
}
MonoAssembly *
}
*params = ref_assembly;
- mono_runtime_invoke (assembly_load_method, domain->domain, params, NULL);
+
+ mono_runtime_invoke_checked (assembly_load_method, domain->domain, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
/*
void
mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
{
+ MonoError error;
HANDLE thread_handle;
MonoAppDomainState prev_state;
MonoMethod *method;
method = mono_class_get_method_from_name (domain->domain->mbr.obj.vtable->klass, "DoDomainUnload", -1);
g_assert (method);
- mono_runtime_invoke (method, domain->domain, NULL, exc);
+ mono_runtime_try_invoke (method, domain->domain, NULL, exc, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
if (*exc) {
/* Roll back the state change */
domain->state = MONO_APPDOMAIN_CREATED;
g_free (agent);
pa [0] = main_args;
- mono_runtime_invoke (method, NULL, pa, exc);
+ mono_runtime_try_invoke (method, NULL, pa, exc, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return 0;
}
static void cominterop_raise_hr_exception (int hr)
{
static MonoMethod* throw_exception_for_hr = NULL;
+ MonoError error;
MonoException* ex;
void* params[1] = {&hr};
+
if (!throw_exception_for_hr)
throw_exception_for_hr = mono_class_get_method_from_name (mono_defaults.marshal_class, "GetExceptionForHR", 1);
- ex = (MonoException*)mono_runtime_invoke (throw_exception_for_hr, NULL, params, NULL);
+
+ ex = (MonoException*)mono_runtime_invoke_checked (throw_exception_for_hr, NULL, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
mono_raise_exception (ex);
}
args [0] = a1;
args [1] = a2;
- mono_runtime_invoke (method, o, args, NULL);
+
+ mono_runtime_invoke_checked (method, o, args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
return (MonoException *) o;
}
exc = mono_object_new_checked (mono_domain_get (), klass, &error);
mono_error_assert_ok (&error);
- mono_runtime_invoke (method, exc, args, NULL);
+ mono_runtime_invoke_checked (method, exc, args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return (MonoException *) exc;
}
exc = mono_object_new_checked (mono_domain_get (), klass, &error);
mono_error_assert_ok (&error);
- mono_runtime_invoke (method, exc, args, NULL);
+
+ mono_runtime_invoke_checked (method, exc, args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return (MonoException *) exc;
}
g_assert (method);
params [0] = wrapped_exception;
- mono_runtime_invoke (method, o, params, NULL);
+
+ mono_runtime_invoke_checked (method, o, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return (MonoException *)o;
}
}
/*
- * To avoid the locking plus the other overhead of mono_runtime_invoke (),
+ * To avoid the locking plus the other overhead of mono_runtime_invoke_checked (),
* create and precompile a wrapper which calls the finalize method using
* a CALLVIRT.
*/
args [3] = &revision;
result = mono_object_new_checked (domain, System_Version, &error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
- mono_runtime_invoke (create_version, result, args, NULL);
+
+ mono_runtime_invoke_checked (create_version, result, args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return result;
}
static MonoMethod *create_culture = NULL;
MonoImage *image = assembly->assembly->image;
MonoTableInfo *t;
+ MonoObject *o;
if (!System_Reflection_AssemblyName)
System_Reflection_AssemblyName = mono_class_from_name (
MonoBoolean assembly_ref = 1;
args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
args [1] = &assembly_ref;
- MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
+
+ o = mono_runtime_invoke_checked (create_culture, NULL, args, &error);
+ mono_error_raise_exception (&error);
+
+ MONO_OBJECT_SETREF (aname, cultureInfo, o);
}
if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token)
{
static MonoMethod *create_culture = NULL;
+ MonoError error;
+ MonoObject *obj;
gpointer args [2];
guint32 pkey_len;
const char *pkey_ptr;
if (name->culture) {
args [0] = mono_string_new (domain, name->culture);
args [1] = &assembly_ref;
- MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
+
+ obj = mono_runtime_invoke_checked (create_culture, NULL, args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ MONO_OBJECT_SETREF (aname, cultureInfo, obj);
}
if (name->public_key) {
static MonoStringBuilder *
mono_string_builder_new (int starting_string_length)
{
- MonoError error;
static MonoClass *string_builder_class;
static MonoMethod *sb_ctor;
static void *args [1];
+
+ MonoError error;
int initial_len = starting_string_length;
if (initial_len < 0)
args [0] = &initial_len;
MonoStringBuilder *sb = (MonoStringBuilder*)mono_object_new_checked (mono_domain_get (), string_builder_class, &error);
- MonoObject *exc;
- g_assert (sb && mono_error_ok (&error)); /* FIXME don't swallow the error */
+ mono_error_assert_ok (&error);
- mono_runtime_invoke (sb_ctor, sb, args, &exc);
- g_assert (!exc);
+ MonoObject *exc;
+ mono_runtime_try_invoke (sb_ctor, sb, args, &exc, &error);
+ g_assert (exc == NULL);
+ mono_error_assert_ok (&error);
g_assert (sb->chunkChars->max_length >= initial_len);
void
ves_icall_System_Runtime_InteropServices_Marshal_StructureToPtr (MonoObject *obj, gpointer dst, MonoBoolean delete_old)
{
+ MonoError error;
MonoMethod *method;
gpointer pa [3];
pa [1] = &dst;
pa [2] = &delete_old;
- mono_runtime_invoke (method, NULL, pa, NULL);
+ mono_runtime_invoke_checked (method, NULL, pa, &error);
+ mono_error_raise_exception (&error);
}
static void
ptr_to_structure (gpointer src, MonoObject *dst)
{
+ MonoError error;
MonoMethod *method;
gpointer pa [2];
pa [0] = &src;
pa [1] = dst;
- mono_runtime_invoke (method, NULL, pa, NULL);
+ mono_runtime_invoke_checked (method, NULL, pa, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
void
pa [1] = &res;
pa [2] = &delete_old;
- mono_runtime_invoke (method, NULL, pa, NULL);
+ mono_runtime_invoke_checked (method, NULL, pa, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
return res;
void
mono_marshal_free_asany (MonoObject *o, gpointer ptr, MonoMarshalNative string_encoding, int param_attrs)
{
+ MonoError error;
MonoType *t;
MonoClass *klass;
pa [0] = &ptr;
pa [1] = o;
- mono_runtime_invoke (method, NULL, pa, NULL);
+ mono_runtime_invoke_checked (method, NULL, pa, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
if (!((param_attrs & PARAM_ATTRIBUTE_OUT) && !(param_attrs & PARAM_ATTRIBUTE_IN))) {
void invoke_protected_memory_method (MonoArray *data, MonoObject *scope, gboolean encrypt)
{
+ MonoError error;
MonoClass *klass;
MonoMethod *method;
void *params [2];
method = mono_class_get_method_from_name (klass, encrypt ? "Protect" : "Unprotect", 2);
params [0] = data;
params [1] = scope; /* MemoryProtectionScope.SameProcess */
- mono_runtime_invoke (method, NULL, params, NULL);
+
+ mono_runtime_invoke_checked (method, NULL, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
gboolean (*debug_log_is_enabled) (void);
gboolean (*tls_key_supported) (MonoTlsKey key);
void (*init_delegate) (MonoDelegate *del);
- MonoObject* (*runtime_invoke) (MonoMethod *method, void *obj, void **params, MonoError *error, MonoObject **exc);
+ MonoObject* (*runtime_invoke) (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError *error);
void* (*compile_method) (MonoMethod *method, MonoError *error);
} MonoRuntimeCallbacks;
MonoString *
mono_string_new_utf16_checked (MonoDomain *domain, const guint16 *text, gint32 len, MonoError *error);
+MonoObject*
+mono_runtime_try_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError *error);
+
+MonoObject*
+mono_runtime_invoke_checked (MonoMethod *method, void *obj, void **params, MonoError *error);
+
+
#endif /* __MONO_OBJECT_INTERNALS_H__ */
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoMethod *method = NULL;
MonoClass *klass = this_obj->vtable->klass;
if (method->klass->valuetype)
this_obj = (MonoObject *)mono_object_unbox (this_obj);
- mono_runtime_invoke (method, this_obj, NULL, NULL);
+
+ mono_runtime_invoke_checked (method, this_obj, NULL, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
/* The pseudo algorithm for type initialization from the spec
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoException *exc;
MonoException *exc_to_throw;
MonoMethod *method = NULL;
mono_type_initialization_unlock ();
if (do_initialization) {
- mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc);
+ mono_runtime_try_invoke (method, NULL, NULL, (MonoObject**) &exc, &error);
+ if (exc == NULL && !mono_error_ok (&error))
+ exc = mono_error_convert_to_exception (&error);
/* If the initialization failed, mark the class as unusable. */
/* Avoid infinite loops */
static MonoObject*
do_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *result = NULL;
- MonoError error;
g_assert (callbacks.runtime_invoke);
- result = callbacks.runtime_invoke (method, obj, params, &error, exc);
- if (!mono_error_ok (&error)) {
- if (exc) {
- *exc = (MonoObject*)mono_error_convert_to_exception (&error);
- return NULL;
- } else {
- mono_error_raise_exception (&error);
- }
- }
+
+ mono_error_init (error);
+
+ if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
+ mono_profiler_method_start_invoke (method);
+
+ MONO_PREPARE_RESET_BLOCKING;
+
+ result = callbacks.runtime_invoke (method, obj, params, exc, error);
+
+ MONO_FINISH_RESET_BLOCKING;
+
+ if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
+ mono_profiler_method_end_invoke (method);
+
+ if (!mono_error_ok (error))
+ return NULL;
return result;
}
*/
MonoObject*
mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
+{
+ MonoError error;
+ MonoObject *res;
+ if (exc) {
+ res = mono_runtime_try_invoke (method, obj, params, exc, &error);
+ if (*exc == NULL && !mono_error_ok(&error)) {
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error);
+ }
+ } else {
+ res = mono_runtime_invoke_checked (method, obj, params, &error);
+ mono_error_raise_exception (&error);
+ }
+ return res;
+}
+
+/**
+ * mono_runtime_try_invoke:
+ * @method: method to invoke
+ * @obJ: object instance
+ * @params: arguments to the method
+ * @exc: exception information.
+ * @error: set on error
+ *
+ * Invokes the method represented by @method on the object @obj.
+ *
+ * obj is the 'this' pointer, it should be NULL for static
+ * methods, a MonoObject* for object instances and a pointer to
+ * the value type for value types.
+ *
+ * The params array contains the arguments to the method with the
+ * same convention: MonoObject* pointers for object instances and
+ * pointers to the value type otherwise.
+ *
+ * From unmanaged code you'll usually use the
+ * mono_runtime_invoke() variant.
+ *
+ * Note that this function doesn't handle virtual methods for
+ * you, it will exec the exact method you pass: we still need to
+ * expose a function to lookup the derived class implementation
+ * of a virtual method (there are examples of this in the code,
+ * though).
+ *
+ * For this function, you must not pass NULL as the exc argument if
+ * you don't want to catch exceptions, use
+ * mono_runtime_invoke_checked(). If an exception is thrown, you
+ * can't use the MonoObject* result from the function.
+ *
+ * If this method cannot be invoked, @error will be set and @exc and
+ * the return value must not be used.
+ *
+ * If the method returns a value type, it is boxed in an object
+ * reference.
+ */
+MonoObject*
+mono_runtime_try_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError* error)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoError error;
- MonoObject *result;
+ g_assert (exc != NULL);
if (mono_runtime_get_no_exec ())
g_warning ("Invoking method '%s' when running in no-exec mode.\n", mono_method_full_name (method, TRUE));
- if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
- mono_profiler_method_start_invoke (method);
-
- MONO_PREPARE_RESET_BLOCKING;
-
- result = do_runtime_invoke (method, obj, params, exc, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return do_runtime_invoke (method, obj, params, exc, error);
+}
- MONO_FINISH_RESET_BLOCKING;
+/**
+ * mono_runtime_invoke_checked:
+ * @method: method to invoke
+ * @obJ: object instance
+ * @params: arguments to the method
+ * @error: set on error
+ *
+ * Invokes the method represented by @method on the object @obj.
+ *
+ * obj is the 'this' pointer, it should be NULL for static
+ * methods, a MonoObject* for object instances and a pointer to
+ * the value type for value types.
+ *
+ * The params array contains the arguments to the method with the
+ * same convention: MonoObject* pointers for object instances and
+ * pointers to the value type otherwise.
+ *
+ * From unmanaged code you'll usually use the
+ * mono_runtime_invoke() variant.
+ *
+ * Note that this function doesn't handle virtual methods for
+ * you, it will exec the exact method you pass: we still need to
+ * expose a function to lookup the derived class implementation
+ * of a virtual method (there are examples of this in the code,
+ * though).
+ *
+ * If an exception is thrown, you can't use the MonoObject* result
+ * from the function.
+ *
+ * If this method cannot be invoked, @error will be set. If the
+ * method throws an exception (and we're in coop mode) the exception
+ * will be set in @error.
+ *
+ * If the method returns a value type, it is boxed in an object
+ * reference.
+ */
+MonoObject*
+mono_runtime_invoke_checked (MonoMethod *method, void *obj, void **params, MonoError* error)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
- if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
- mono_profiler_method_end_invoke (method);
+ if (mono_runtime_get_no_exec ())
+ g_warning ("Invoking method '%s' when running in no-exec mode.\n", mono_method_full_name (method, TRUE));
- return result;
+ return do_runtime_invoke (method, obj, params, NULL, error);
}
/**
args [1] = mono_type_get_object_checked (mono_domain_get (), type, &error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
- return mono_runtime_invoke (m, NULL, args, NULL);
+ o = mono_runtime_invoke_checked (m, NULL, args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ return o;
}
/* boxed value type */
MonoError error;
do_runtime_invoke (prop->set, obj, params, exc, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (exc && *exc == NULL && !mono_error_ok (&error)) {
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error);
+ } else {
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
}
/**
MonoError error;
MonoObject *val = do_runtime_invoke (prop->get, obj, params, exc, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (exc && *exc == NULL && !mono_error_ok (&error)) {
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error);
+ } else {
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
return val;
}
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoMethod *im;
MonoClass *klass = delegate->vtable->klass;
+ MonoObject *o;
im = mono_get_delegate_invoke (klass);
if (!im)
g_error ("Could not lookup delegate invoke method for delegate %s", mono_type_get_full_name (klass));
- return mono_runtime_invoke (im, delegate, params, exc);
+ if (exc) {
+ o = mono_runtime_try_invoke (im, delegate, params, exc, &error);
+ if (*exc == NULL && !mono_error_ok (&error))
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error);
+ } else {
+ o = mono_runtime_invoke_checked (im, delegate, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
+
+ return o;
}
static char **main_args = NULL;
{
static MonoMethod *serialize_method;
+ MonoError error;
void *params [1];
MonoObject *array;
params [0] = obj;
*exc = NULL;
- array = mono_runtime_invoke (serialize_method, NULL, params, exc);
+
+ array = mono_runtime_try_invoke (serialize_method, NULL, params, exc, &error);
+ if (*exc == NULL && !mono_error_ok (&error))
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error); /* FIXME convert serialize_object to MonoError */
+
if (*exc)
*failure = TRUE;
static MonoMethod *deserialize_method;
+ MonoError error;
void *params [1];
MonoObject *result;
params [0] = obj;
*exc = NULL;
- result = mono_runtime_invoke (deserialize_method, NULL, params, exc);
+
+ result = mono_runtime_try_invoke (deserialize_method, NULL, params, exc, &error);
+ if (*exc == NULL && !mono_error_ok (&error))
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error); /* FIXME convert deserialize_object to MonoError */
+
if (*exc)
*failure = TRUE;
MONO_OBJECT_SETREF (real_proxy, unwrapped_server, obj);
*exc = NULL;
- transparent_proxy = (MonoTransparentProxy*) mono_runtime_invoke (get_proxy_method, real_proxy, NULL, exc);
+
+ transparent_proxy = (MonoTransparentProxy*) mono_runtime_try_invoke (get_proxy_method, real_proxy, NULL, exc, &error);
+ if (*exc == NULL && !mono_error_ok (&error))
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error); /* FIXME change make_transparent_proxy outarg to MonoError */
if (*exc)
*failure = TRUE;
MonoObject *deserialized = NULL;
gboolean failure = FALSE;
+ g_assert (exc != NULL);
*exc = NULL;
#ifndef DISABLE_REMOTING
obj = mono_object_new_checked (mono_domain_get (), klass, &error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
- mono_runtime_invoke (method, obj, args, NULL);
+
+ mono_runtime_invoke_checked (method, obj, args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return obj;
}
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoDomain *domain;
gpointer pa [1];
int rval;
/* FIXME: check signature of method */
if (mono_method_signature (method)->ret->type == MONO_TYPE_I4) {
MonoObject *res;
- res = mono_runtime_invoke (method, NULL, pa, exc);
+ if (exc) {
+ res = mono_runtime_try_invoke (method, NULL, pa, exc, &error);
+ if (*exc == NULL && !mono_error_ok (&error))
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error);
+ } else {
+ res = mono_runtime_invoke_checked (method, NULL, pa, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
+
if (!exc || !*exc)
rval = *(guint32 *)((char *)res + sizeof (MonoObject));
else
mono_environment_exitcode_set (rval);
} else {
- mono_runtime_invoke (method, NULL, pa, exc);
+ if (exc) {
+ mono_runtime_try_invoke (method, NULL, pa, exc, &error);
+ if (*exc == NULL && !mono_error_ok (&error))
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error);
+ } else {
+ mono_runtime_invoke_checked (method, NULL, pa, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
+
if (!exc || !*exc)
rval = 0;
else {
* respective reference representation.
*
* From unmanaged code you'll usually use the
- * mono_runtime_invoke() variant.
+ * mono_runtime_invoke_checked() variant.
*
* Note that this function doesn't handle virtual methods for
* you, it will exec the exact method you pass: we still need to
obj = mono_value_box (mono_domain_get (), method->klass, obj);
}
- mono_runtime_invoke (method, o, pa, exc);
+ if (exc) {
+ mono_runtime_try_invoke (method, o, pa, exc, &error);
+ if (*exc == NULL && !mono_error_ok (&error))
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error);
+ } else {
+ mono_runtime_invoke_checked (method, o, pa, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
+
return (MonoObject *)obj;
} else {
if (mono_class_is_nullable (method->klass)) {
}
/* obj must be already unboxed if needed */
- res = mono_runtime_invoke (method, obj, pa, exc);
+ if (exc) {
+ res = mono_runtime_try_invoke (method, obj, pa, exc, &error);
+ if (*exc == NULL && !mono_error_ok (&error))
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error);
+ } else {
+ res = mono_runtime_invoke_checked (method, obj, pa, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
if (sig->ret->type == MONO_TYPE_PTR) {
MonoClass *pointer_class;
box_args [1] = mono_type_get_object_checked (mono_domain_get (), sig->ret, &error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
- res = mono_runtime_invoke (box_method, NULL, box_args, &box_exc);
- g_assert (!box_exc);
+ res = mono_runtime_try_invoke (box_method, NULL, box_args, &box_exc, &error);
+ g_assert (box_exc == NULL);
+ mono_error_assert_ok (&error);
}
if (has_byref_nullables) {
if (!mono_error_ok (error))
return NULL;
- o = mono_runtime_invoke (im, NULL, pa, NULL);
- if (o != NULL) return o;
+ o = mono_runtime_invoke_checked (im, NULL, pa, error);
+ if (!mono_error_ok (error))
+ return NULL;
+
+ if (o != NULL)
+ return o;
}
return mono_object_new_alloc_specific_checked (vtable, error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
pa [1] = obj;
- res = mono_runtime_invoke (im, rp, pa, NULL);
-
+ res = mono_runtime_invoke_checked (im, rp, pa, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
if (*(MonoBoolean *) mono_object_unbox(res)) {
/* Update the vtable of the remote type, so it can safely cast to this new type */
mono_upgrade_remote_class (domain, obj, klass);
handle_set = mono_class_get_property_from_name (mono_defaults.manualresetevent_class, "Handle")->set;
params [0] = &handle;
- mono_runtime_invoke (handle_set, res, params, NULL);
+
+ mono_runtime_invoke_checked (handle_set, res, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return res;
}
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoAsyncCall *ac;
MonoObject *res;
if (ac->cb_method) {
/* we swallow the excepton as it is the behavior on .NET */
MonoObject *exc = NULL;
- mono_runtime_invoke (ac->cb_method, ac->cb_target, (gpointer*) &ares, &exc);
+ mono_runtime_try_invoke (ac->cb_method, ac->cb_target, (gpointer*) &ares, &exc, &error);
+ if (exc == NULL && !mono_error_ok (&error))
+ exc = (MonoObject*) mono_error_convert_to_exception (&error);
+
if (exc)
mono_unhandled_exception (exc);
}
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
+ MonoObject *o;
MonoMethod *im = real_proxy->vtable->domain->private_invoke_method;
gpointer pa [4];
pa [2] = exc;
pa [3] = out_args;
- return mono_runtime_invoke (im, NULL, pa, exc);
+ if (exc) {
+ o = mono_runtime_try_invoke (im, NULL, pa, exc, &error);
+ } else {
+ o = mono_runtime_invoke_checked (im, NULL, pa, &error);
+ }
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ return o;
}
#endif
MONO_REQ_GC_UNSAFE_MODE;
static MonoMethod *to_string = NULL;
+ MonoError error;
MonoMethod *method;
+ MonoString *s;
void *target = obj;
g_assert (obj);
target = mono_object_unbox (obj);
}
- return (MonoString *) mono_runtime_invoke (method, target, NULL, exc);
+ if (exc) {
+ s = (MonoString *) mono_runtime_try_invoke (method, target, NULL, exc, &error);
+ if (*exc == NULL && !mono_error_ok (&error))
+ *exc = (MonoObject*) mono_error_convert_to_exception (&error);
+ } else {
+ s = (MonoString *) mono_runtime_invoke_checked (method, target, NULL, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
+
+ return s;
}
/**
MONO_API MonoMethod*
mono_object_get_virtual_method (MonoObject *obj, MonoMethod *method);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoObject*
mono_runtime_invoke (MonoMethod *method, void *obj, void **params,
MonoObject **exc);
retval = mono_object_new_checked (mono_domain_get (), klass, &error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
unboxed = mono_object_unbox (retval);
- mono_runtime_invoke (ctor, unboxed, params, NULL);
+
+ mono_runtime_invoke_checked (ctor, unboxed, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return retval;
}
retval = mono_object_new_checked (mono_domain_get (), klass, &error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
unboxed = mono_object_unbox (retval);
- mono_runtime_invoke (ctor, unboxed, params, NULL);
+
+ mono_runtime_invoke_checked (ctor, unboxed, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return retval;
}
if (len == 0) {
attr = mono_object_new_checked (mono_domain_get (), method->klass, error);
if (!mono_error_ok (error)) return NULL;
- mono_runtime_invoke (method, attr, NULL, NULL);
+
+ mono_runtime_invoke_checked (method, attr, NULL, error);
+ if (!mono_error_ok (error))
+ return NULL;
+
return attr;
}
attr = mono_object_new_checked (mono_domain_get (), method->klass, error);
if (!mono_error_ok (error)) goto fail;
- mono_runtime_invoke (method, attr, params, &exc);
+ mono_runtime_try_invoke (method, attr, params, &exc, error);
+ if (!mono_error_ok (error))
+ goto fail;
if (exc)
goto fail;
+
num_named = read16 (named);
named += 2;
for (j = 0; j < num_named; j++) {
mono_error_raise_exception (&error); /* FIXME don't raise here */
params [2] = (gpointer)&cattr->data;
params [3] = &cattr->data_size;
- mono_runtime_invoke (ctor, attr, params, NULL);
+
+ mono_runtime_invoke_checked (ctor, attr, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
return attr;
}
mono_reflection_type_get_underlying_system_type (MonoReflectionType* t)
{
static MonoMethod *method_get_underlying_system_type = NULL;
+ MonoError error;
+ MonoReflectionType *rt;
MonoMethod *usertype_method;
if (!method_get_underlying_system_type)
method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
+
usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
- return (MonoReflectionType *) mono_runtime_invoke (usertype_method, t, NULL, NULL);
+
+ rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ return rt;
}
params [0] = mono_type_get_object_checked (mono_domain_get (), &oklass->byval_arg, &error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
- res = mono_runtime_invoke (method, (MonoObject*)(mono_class_get_ref_info (klass)), params, &exc);
- if (exc)
+ res = mono_runtime_try_invoke (method, (MonoObject*)(mono_class_get_ref_info (klass)), params, &exc, &error);
+
+ if (exc || !mono_error_ok (&error)) {
+ mono_error_cleanup (&error);
return FALSE;
- else
+ } else
return *(MonoBoolean*)mono_object_unbox (res);
}
static MonoObject *
mono_remoting_wrapper (MonoMethod *method, gpointer *params)
{
+ MonoError error;
MonoMethodMessage *msg;
MonoTransparentProxy *this_obj;
MonoObject *res, *exc;
}
}
- return mono_runtime_invoke (method, method->klass->valuetype? mono_object_unbox ((MonoObject*)this_obj): this_obj, mparams, NULL);
+ res = mono_runtime_invoke_checked (method, method->klass->valuetype? mono_object_unbox ((MonoObject*)this_obj): this_obj, mparams, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ return res;
}
msg = mono_method_call_message_new (method, params, NULL, NULL, NULL);
{
static MonoClass *threadpool_class = NULL;
static MonoMethod *unsafe_queue_custom_work_item_method = NULL;
+ MonoError error;
MonoDomain *current_domain;
MonoBoolean f;
gpointer args [2];
current_domain = mono_domain_get ();
if (current_domain == domain) {
- mono_runtime_invoke (unsafe_queue_custom_work_item_method, NULL, args, NULL);
+ mono_runtime_invoke_checked (unsafe_queue_custom_work_item_method, NULL, args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
} else {
mono_thread_push_appdomain_ref (domain);
if (mono_domain_set (domain, FALSE)) {
- mono_runtime_invoke (unsafe_queue_custom_work_item_method, NULL, args, NULL);
+ mono_runtime_invoke_checked (unsafe_queue_custom_work_item_method, NULL, args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
mono_domain_set (current_domain, TRUE);
}
mono_thread_pop_appdomain_ref ();
static void
worker_thread (gpointer data)
{
+ MonoError error;
MonoInternalThread *thread;
ThreadPoolDomain *tpdomain, *previous_tpdomain;
ThreadPoolCounter counter;
mono_thread_push_appdomain_ref (tpdomain->domain);
if (mono_domain_set (tpdomain->domain, FALSE)) {
- MonoObject *exc = NULL;
- MonoObject *res = mono_runtime_invoke (mono_defaults.threadpool_perform_wait_callback_method, NULL, NULL, &exc);
- if (exc)
+ MonoObject *exc = NULL, *res;
+
+ res = mono_runtime_try_invoke (mono_defaults.threadpool_perform_wait_callback_method, NULL, NULL, &exc, &error);
+ if (exc || !mono_error_ok(&error)) {
+ if (exc == NULL)
+ exc = (MonoObject *) mono_error_convert_to_exception (&error);
+ else
+ mono_error_cleanup (&error);
mono_thread_internal_unhandled_exception (exc);
- else if (res && *(MonoBoolean*) mono_object_unbox (res) == FALSE)
+ } else if (res && *(MonoBoolean*) mono_object_unbox (res) == FALSE)
retire = TRUE;
mono_thread_clr_state (thread, (MonoThreadState)~ThreadState_Background);
gboolean abort_requested;
/*
- * The current mono_runtime_invoke invocation.
+ * The current mono_runtime_invoke_checked invocation.
*/
InvokeData *invoke;
static ErrorCode
do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 *p, guint8 **endp)
{
+ MonoError error;
guint8 *end = invoke->endp;
MonoMethod *m;
int i, nargs;
*/
this_arg = NULL;
DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer) (gsize) mono_native_thread_id_get (), mono_method_full_name (invoke->method, TRUE), this_arg ? this_arg->vtable->klass->name : "<null>");
- mono_runtime_invoke (invoke->method, NULL, invoke->args, &exc);
+
+ mono_runtime_try_invoke (invoke->method, NULL, invoke->args, &exc, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
g_assert_not_reached ();
}
#endif
mono_stopwatch_start (&watch);
- if (m->klass->valuetype)
- res = mono_runtime_invoke (m, this_buf, args, &exc);
- else
- res = mono_runtime_invoke (m, this_arg, args, &exc);
+ res = mono_runtime_try_invoke (m, m->klass->valuetype ? (gpointer) this_buf : (gpointer) this_arg, args, &exc, &error);
+ if (exc == NULL && !mono_error_ok (&error)) {
+ exc = (MonoObject*) mono_error_convert_to_exception (&error);
+ } else {
+ mono_error_cleanup (&error); /* FIXME report error */
+ }
mono_stopwatch_stop (&watch);
DEBUG_PRINTF (1, "[%p] Invoke result: %p, exc: %s, time: %ld ms.\n", (gpointer) (gsize) mono_native_thread_id_get (), res, exc ? exc->vtable->klass->name : NULL, (long)mono_stopwatch_elapsed_ms (&watch));
if (exc) {
* Take the loader lock to avoid race conditions with CMD_VM_ABORT_INVOKE:
*
* It is possible that ves_icall_System_Threading_Thread_Abort () was called
- * after the mono_runtime_invoke() already returned, but it doesn't matter
+ * after the mono_runtime_invoke_checked() already returned, but it doesn't matter
* because we reset the abort here.
*/
}
/*
- * Check whether we're still inside the mono_runtime_invoke() and that it's
+ * Check whether we're still inside the mono_runtime_invoke_checked() and that it's
* actually the correct invocation.
*
* Careful, we do not stop the thread that's doing the invocation, so we can't
pa [0] = main_args;
/* Pass NULL as 'exc' so unhandled exceptions abort the runtime */
- mono_runtime_invoke (method, NULL, pa, NULL);
+ mono_runtime_invoke_checked (method, NULL, pa, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return 0;
}
* mono_gsharedvt_constrained_call:
*
* Make a call to CMETHOD using the receiver MP, which is assumed to be of type KLASS. ARGS contains
- * the arguments to the method in the format used by mono_runtime_invoke ().
+ * the arguments to the method in the format used by mono_runtime_invoke_checked ().
*/
MonoObject*
mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gboolean deref_arg, gpointer *args)
{
MonoError error;
+ MonoObject *o;
MonoMethod *m;
gpointer this_arg;
gpointer new_args [16];
args [0] = this_arg;
this_arg = NULL;
}
- return mono_runtime_invoke (m, this_arg, args, NULL);
+
+ o = mono_runtime_invoke_checked (m, this_arg, args, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+
+ return o;
}
void
#include <mono/metadata/mono-mlist.h>
#include <mono/utils/mono-mmap.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/mono-error.h>
+#include <mono/utils/mono-error-internals.h>
#include "mini.h"
#include "trace.h"
static gboolean
mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resume, MonoJitInfo **out_ji)
{
+ MonoError error;
MonoDomain *domain = mono_domain_get ();
MonoJitInfo *ji, *prev_ji;
static int (*call_filter) (MonoContext *, gpointer) = NULL;
MonoObject *message;
const char *type_name = mono_class_get_name (mono_object_class (mono_ex));
char *msg = NULL;
- MonoObject *exc = NULL;
if (get_message == NULL) {
message = NULL;
} else if (!strcmp (type_name, "OutOfMemoryException") || !strcmp (type_name, "StackOverflowException")) {
message = NULL;
msg = g_strdup_printf ("(No exception message for: %s)\n", type_name);
} else {
- message = mono_runtime_invoke (get_message, obj, NULL, &exc);
-
+ MonoObject *exc = NULL;
+ message = mono_runtime_try_invoke (get_message, obj, NULL, &exc, &error);
+ g_assert (exc == NULL);
+ mono_error_assert_ok (&error);
}
if (msg == NULL) {
msg = message ? mono_string_to_utf8 ((MonoString *) message) : g_strdup ("(System.Exception.Message property not available)");
gboolean unhandled = FALSE;
/*
- * The exceptions caught by the mono_runtime_invoke () calls
+ * The exceptions caught by the mono_runtime_invoke_checked () calls
* in the threadpool needs to be treated as unhandled (#669836).
*
* FIXME: The check below is hackish, but its hard to distinguish
runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke;
runtime_invoke (NULL, args, exc, info->compiled_method);
+ if (exc && *exc)
+ mono_error_set_exception_instance (error, (MonoException*) *exc);
if (sig->ret->type != MONO_TYPE_VOID && info->ret_box_class)
return mono_value_box (domain, info->ret_box_class, retval);
* @method: the method to invoke
* @obj: this pointer
* @params: array of parameter values.
- * @error: error
- * @exc: used to catch exceptions objects
+ * @exc: Set to the exception raised in the managed method. If NULL, error is thrown instead.
+ * If coop is enabled, this argument is ignored - all exceptoins are caught and propagated
+ * through @error
+ * @error: error or caught exception object
*/
static MonoObject*
mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError *error)
*/
mono_class_setup_vtable (method->klass);
if (method->klass->exception_type != MONO_EXCEPTION_NONE) {
+ MonoException *fail_exc = mono_class_get_exception_for_failure (method->klass);
if (exc)
- *exc = (MonoObject*)mono_class_get_exception_for_failure (method->klass);
- else
- mono_raise_exception (mono_class_get_exception_for_failure (method->klass));
+ *exc = (MonoObject*)fail_exc;
+ mono_error_set_exception_instance (error, fail_exc);
return NULL;
}
}
* We need this here because mono_marshal_get_runtime_invoke can place
* the helper method in System.Object and not the target class.
*/
- if (exc) {
+ if (exc)
+ {
*exc = (MonoObject*)mono_runtime_class_init_full (info->vtable, FALSE);
- if (*exc)
+ if (*exc) {
+ mono_error_set_exception_instance (error, (MonoException*) *exc);
return NULL;
+ }
} else {
mono_runtime_class_init (info->vtable);
}
+ /* If coop is enabled, and the caller didn't ask for the exception to be caught separately,
+ we always catch the exception and propagate it through the MonoError */
+ gboolean catchExcInMonoError =
+ (exc == NULL) && mono_threads_is_coop_enabled ();
+ MonoObject *invoke_exc = NULL;
+ if (catchExcInMonoError)
+ exc = &invoke_exc;
+
/* The wrappers expect this to be initialized to NULL */
if (exc)
*exc = NULL;
mono_arch_start_dyn_call (info->dyn_call_info, (gpointer**)args, retval, buf, sizeof (buf));
dyn_runtime_invoke (buf, exc, info->compiled_method);
+ if (exc && *exc)
+ mono_error_set_exception_instance (error, (MonoException*) *exc);
mono_arch_finish_dyn_call (info->dyn_call_info, buf);
runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke;
- return runtime_invoke ((MonoObject *)obj, params, exc, info->compiled_method);
+ MonoObject *result = runtime_invoke ((MonoObject *)obj, params, exc, info->compiled_method);
+ if (catchExcInMonoError && *exc != NULL)
+ mono_error_set_exception_instance (error, (MonoException*) *exc);
+ return result;
}
typedef struct {