gpointer
mono_compile_method (MonoMethod *method)
{
- gpointer res;
MonoError error;
+ gpointer result = mono_compile_method_checked (method, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+/**
+ * mono_compile_method:
+ * @method: The method to compile.
+ * @error: set on error.
+ *
+ * This JIT-compiles the method, and returns the pointer to the native code
+ * produced. On failure returns NULL and sets @error.
+ */
+gpointer
+mono_compile_method_checked (MonoMethod *method, MonoError *error)
+{
+ gpointer res;
MONO_REQ_GC_NEUTRAL_MODE
+ mono_error_init (error);
+
if (!callbacks.compile_method) {
g_error ("compile method called on uninitialized runtime");
return NULL;
}
- res = callbacks.compile_method (method, &error);
- if (!mono_error_ok (&error))
- mono_error_raise_exception (&error);
+ res = callbacks.compile_method (method, error);
return res;
}
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_start_invoke (method);
- MONO_PREPARE_RESET_BLOCKING;
+ MONO_ENTER_GC_UNSAFE;
result = callbacks.runtime_invoke (method, obj, params, exc, error);
- MONO_FINISH_RESET_BLOCKING;
+ MONO_EXIT_GC_UNSAFE;
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_end_invoke (method);
MONO_REQ_GC_NEUTRAL_MODE;
MONO_REQ_API_ENTRYPOINT;
+ MonoError error;
gpointer res;
- MONO_PREPARE_RESET_BLOCKING;
+ g_assert (!mono_threads_is_coop_enabled ());
+
+ MONO_ENTER_GC_UNSAFE;
method = mono_marshal_get_thunk_invoke_wrapper (method);
- res = mono_compile_method (method);
- MONO_FINISH_RESET_BLOCKING;
+ res = mono_compile_method_checked (method, &error);
+ mono_error_cleanup (&error);
+ MONO_EXIT_GC_UNSAFE;
return res;
}
MONO_REQ_GC_UNSAFE_MODE;
MonoError error;
+ if (exc) {
+ MonoObject *result = mono_runtime_delegate_try_invoke (delegate, params, exc, &error);
+ if (*exc) {
+ mono_error_cleanup (&error);
+ return NULL;
+ } else {
+ if (!is_ok (&error))
+ *exc = (MonoObject*)mono_error_convert_to_exception (&error);
+ return result;
+ }
+ } else {
+ MonoObject *result = mono_runtime_delegate_invoke_checked (delegate, params, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return result;
+ }
+}
+
+/**
+ * mono_runtime_delegate_try_invoke:
+ * @delegate: pointer to a delegate object.
+ * @params: parameters for the delegate.
+ * @exc: Pointer to the exception result.
+ * @error: set on error
+ *
+ * Invokes the delegate method @delegate with the parameters provided.
+ *
+ * You can pass NULL as the exc argument if you don't want to
+ * catch exceptions, otherwise, *exc will be set to the exception
+ * thrown, if any. On failure to execute, @error will be set.
+ * if an exception is thrown, you can't use the
+ * MonoObject* result from the function.
+ */
+MonoObject*
+mono_runtime_delegate_try_invoke (MonoObject *delegate, void **params, MonoObject **exc, MonoError *error)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
+ mono_error_init (error);
MonoMethod *im;
MonoClass *klass = delegate->vtable->klass;
MonoObject *o;
g_error ("Could not lookup delegate invoke method for delegate %s", mono_type_get_full_name (klass));
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
- mono_error_cleanup (&error);
+ o = mono_runtime_try_invoke (im, delegate, params, exc, error);
} else {
- o = mono_runtime_invoke_checked (im, delegate, params, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ o = mono_runtime_invoke_checked (im, delegate, params, error);
}
return o;
}
+/**
+ * mono_runtime_delegate_invoke_checked:
+ * @delegate: pointer to a delegate object.
+ * @params: parameters for the delegate.
+ * @error: set on error
+ *
+ * Invokes the delegate method @delegate with the parameters provided.
+ *
+ * On failure @error will be set and you can't use the MonoObject*
+ * result from the function.
+ */
+MonoObject*
+mono_runtime_delegate_invoke_checked (MonoObject *delegate, void **params, MonoError *error)
+{
+ mono_error_init (error);
+ return mono_runtime_delegate_try_invoke (delegate, params, NULL, error);
+}
+
static char **main_args = NULL;
static int num_main_args = 0;
/* Used in call_unhandled_exception_delegate */
static MonoObject *
-create_unhandled_exception_eventargs (MonoObject *exc)
+create_unhandled_exception_eventargs (MonoObject *exc, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoError error;
+ mono_error_init (error);
MonoClass *klass;
gpointer args [2];
MonoMethod *method = NULL;
args [0] = exc;
args [1] = &is_terminating;
- obj = mono_object_new_checked (mono_domain_get (), klass, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ obj = mono_object_new_checked (mono_domain_get (), klass, error);
+ return_val_if_nok (error, NULL);
- mono_runtime_invoke_checked (method, obj, args, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_runtime_invoke_checked (method, obj, args, error);
+ return_val_if_nok (error, NULL);
return obj;
}
call_unhandled_exception_delegate (MonoDomain *domain, MonoObject *delegate, MonoObject *exc) {
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoObject *e = NULL;
gpointer pa [2];
MonoDomain *current_domain = mono_domain_get ();
g_assert (domain == mono_object_domain (domain->domain));
if (mono_object_domain (exc) != domain) {
- MonoError error;
exc = mono_object_xdomain_representation (exc, domain, &error);
if (!exc) {
g_assert (mono_object_domain (exc) == domain);
pa [0] = domain->domain;
- pa [1] = create_unhandled_exception_eventargs (exc);
- mono_runtime_delegate_invoke (delegate, pa, &e);
+ pa [1] = create_unhandled_exception_eventargs (exc, &error);
+ mono_error_assert_ok (&error);
+ mono_runtime_delegate_try_invoke (delegate, pa, &e, &error);
+ if (!is_ok (&error)) {
+ if (e == NULL)
+ e = (MonoObject*)mono_error_convert_to_exception (&error);
+ else
+ mono_error_cleanup (&error);
+ }
if (domain != current_domain)
mono_domain_set_internal_with_options (current_domain, FALSE);
if (e) {
- MonoError error;
gchar *msg = mono_string_to_utf8_checked (((MonoException *) e)->message, &error);
if (!mono_error_ok (&error)) {
g_warning ("Exception inside UnhandledException handler with invalid message (Invalid characters)\n");
root_domain = mono_get_root_domain ();
root_appdomain_delegate = mono_field_get_value_object_checked (root_domain, field, (MonoObject*) root_domain->domain, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_assert_ok (&error);
if (current_domain != root_domain) {
current_appdomain_delegate = mono_field_get_value_object_checked (current_domain, field, (MonoObject*) current_domain->domain, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_assert_ok (&error);
}
if (!current_appdomain_delegate && !root_appdomain_delegate) {
static MonoObject*
-mono_runtime_capture_context (MonoDomain *domain)
+mono_runtime_capture_context (MonoDomain *domain, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
RuntimeInvokeFunction runtime_invoke;
+ mono_error_init (error);
+
if (!domain->capture_context_runtime_invoke || !domain->capture_context_method) {
MonoMethod *method = mono_get_context_capture_method ();
MonoMethod *wrapper;
if (!method)
return NULL;
wrapper = mono_marshal_get_runtime_invoke (method, FALSE);
- domain->capture_context_runtime_invoke = mono_compile_method (wrapper);
- domain->capture_context_method = mono_compile_method (method);
+ domain->capture_context_runtime_invoke = mono_compile_method_checked (wrapper, error);
+ return_val_if_nok (error, NULL);
+ domain->capture_context_method = mono_compile_method_checked (method, error);
+ return_val_if_nok (error, NULL);
}
runtime_invoke = (RuntimeInvokeFunction)domain->capture_context_runtime_invoke;
MonoError error;
MonoAsyncResult *res = (MonoAsyncResult *)mono_object_new_checked (domain, mono_defaults.asyncresult_class, &error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
- MonoObject *context = mono_runtime_capture_context (domain);
+ MonoObject *context = mono_runtime_capture_context (domain, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
/* we must capture the execution context from the original thread */
if (context) {
MONO_OBJECT_SETREF (res, execution_context, context);
ac = (MonoAsyncCall*) ares->object_data;
if (!ac) {
- res = mono_runtime_delegate_invoke (ares->async_delegate, (void**) &ares->async_state, NULL);
+ res = mono_runtime_delegate_invoke_checked (ares->async_delegate, (void**) &ares->async_state, &error);
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
} else {
gpointer wait_event = NULL;
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoDelegate *delegate = (MonoDelegate *)this_obj;
g_assert (this_obj);
if (target && target->vtable->klass == mono_defaults.transparent_proxy_class) {
g_assert (method);
method = mono_marshal_get_remoting_invoke (method);
- delegate->method_ptr = mono_compile_method (method);
+ delegate->method_ptr = mono_compile_method_checked (method, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
MONO_OBJECT_SETREF (delegate, target, target);
} else
#endif