}
/**
- * common_call_trampoline:
+ * common_call_trampoline_inner:
*
* The code to handle normal, virtual, and interface method calls and jumps, both
* from JITted and LLVM compiled code.
*/
static gpointer
-common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot)
+common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot, MonoError *error)
{
gpointer addr, compiled_method;
gboolean generic_shared = FALSE;
gpointer *orig_vtable_slot, *vtable_slot_to_patch = NULL;
MonoJitInfo *ji = NULL;
+ mono_error_init (error);
+
virtual_ = vt && (gpointer)vtable_slot > (gpointer)vt;
imt_call = vt && (gpointer)vtable_slot < (gpointer)vt;
if (!code && mono_method_needs_static_rgctx_invoke (m, FALSE))
need_rgctx_tramp = TRUE;
- addr = compiled_method = mono_compile_method (m);
- g_assert (addr);
+ addr = compiled_method = mono_jit_compile_method (m, error);
+ if (!addr)
+ return NULL;
if (generic_virtual || variant_iface) {
if (vt->klass->valuetype) /*FIXME is this required variant iface?*/
}
static gpointer
-common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot)
+common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot, MonoError *error)
{
gpointer res;
MONO_PREPARE_RESET_BLOCKING;
- res = common_call_trampoline_inner (regs, code, m, vt, vtable_slot);
+ res = common_call_trampoline_inner (regs, code, m, vt, vtable_slot, error);
MONO_FINISH_RESET_BLOCKING;
return res;
}
gpointer
mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
{
+ MonoError error;
+ gpointer res;
+
trampoline_calls ++;
- return common_call_trampoline (regs, code, (MonoMethod *)arg, NULL, NULL);
+ res = common_call_trampoline (regs, code, (MonoMethod *)arg, NULL, NULL, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
/**
MonoVTable *vt;
gpointer *vtable_slot;
MonoMethod *m;
- gpointer addr;
+ MonoError error;
+ gpointer addr, res;
trampoline_calls ++;
m = NULL;
}
- return common_call_trampoline (regs, code, m, vt, vtable_slot);
+ res = common_call_trampoline (regs, code, m, vt, vtable_slot, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
#ifndef DISABLE_REMOTING
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */;
m = mono_marshal_get_remoting_invoke_with_check (m);
- addr = mono_compile_method (m);
+ addr = mono_jit_compile_method (m, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
g_assert (addr);
return addr;
{
guint32 plt_info_offset = mono_aot_get_plt_info_offset (regs, code);
gpointer res;
+ MonoError error;
trampoline_calls ++;
- res = mono_aot_plt_resolve (aot_module, plt_info_offset, code);
+ res = mono_aot_plt_resolve (aot_module, plt_info_offset, code, &error);
if (!res) {
- if (mono_loader_get_last_error ())
- mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ if (mono_loader_get_last_error ()) {
+ MonoError error;
+
+ mono_error_init (&error);
+ mono_error_set_from_loader_error (&error);
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
// FIXME: Error handling (how ?)
g_assert (res);
}
gpointer arg = (gpointer)(gssize)r [MONO_ARCH_VTABLE_REG];
guint32 index = MONO_RGCTX_SLOT_INDEX (slot);
gboolean mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
+ MonoError error;
+ gpointer res;
trampoline_calls ++;
num_lookups++;
if (mrgctx)
- return mono_method_fill_runtime_generic_context ((MonoMethodRuntimeGenericContext *)arg, index);
+ res = mono_method_fill_runtime_generic_context ((MonoMethodRuntimeGenericContext *)arg, index, &error);
else
- return mono_class_fill_runtime_generic_context ((MonoVTable *)arg, index);
+ res = mono_class_fill_runtime_generic_context ((MonoVTable *)arg, index, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
/*
MonoJitInfo *ji;
MonoMethod *m;
MonoMethod *method = NULL;
+ MonoError error;
gboolean multicast, callvirt = FALSE, closed_over_null = FALSE;
gboolean need_rgctx_tramp = FALSE;
gboolean need_unbox_tramp = FALSE;
if (!(sig && method == tramp_info->method)) {
mono_error_init (&err);
sig = mono_method_signature_checked (method, &err);
- if (!sig)
- mono_error_raise_exception (&err);
+ if (!sig) {
+ mono_error_set_pending_exception (&err);
+ return NULL;
+ }
}
if (sig->hasthis && method->klass->valuetype) {
if (!(sig && method == tramp_info->method)) {
mono_error_init (&err);
sig = mono_method_signature_checked (method, &err);
- if (!sig)
- mono_error_raise_exception (&err);
+ if (!sig) {
+ mono_error_set_pending_exception (&err);
+ return NULL;
+ }
}
callvirt = !delegate->target && sig->hasthis;
if (enable_caching && delegate->method_code && *delegate->method_code) {
delegate->method_ptr = *delegate->method_code;
} else {
- compiled_method = addr = mono_compile_method (method);
+ compiled_method = addr = mono_jit_compile_method (method, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
addr = mini_add_method_trampoline (method, compiled_method, need_rgctx_tramp, need_unbox_tramp);
delegate->method_ptr = addr;
if (enable_caching && delegate->method_code)
if (!code) {
/* The general, unoptimized case */
m = mono_marshal_get_delegate_invoke (invoke, delegate);
- code = (guint8 *)mono_compile_method (m);
+ code = (guint8 *)mono_jit_compile_method (m, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
code = (guint8 *)mini_add_method_trampoline (m, code, mono_method_needs_static_rgctx_invoke (m, FALSE), FALSE);
}
}
gpointer
-mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper)
+mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper, MonoError *error)
{
MonoJitInfo *ji;
gpointer code;
guint32 code_size = 0;
+ mono_error_init (error);
+
code = mono_jit_find_compiled_method_with_jit_info (domain, method, &ji);
/*
* We cannot recover the correct type of a shared generic
if (code && !ji->has_generic_jit_info && !(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED))
return code;
- if (mono_llvm_only)
- return mono_jit_compile_method (method);
+ if (mono_llvm_only) {
+ code = mono_jit_compile_method (method, error);
+ if (!mono_error_ok (error))
+ return NULL;
+ return code;
+ }
mono_domain_lock (domain);
code = g_hash_table_lookup (domain_jit_info (domain)->jump_trampoline_hash, method);
}
gpointer
-mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method)
+mono_create_jit_trampoline (MonoDomain *domain, MonoMethod *method, MonoError *error)
{
gpointer tramp;
+ mono_error_init (error);
+
if (mono_aot_only) {
/* Avoid creating trampolines if possible */
gpointer code = mono_jit_find_compiled_method (domain, method);
/* These wrappers are not generated */
return method_not_found;
/* Methods are lazily initialized on first call, so this can't lead recursion */
- return mono_compile_method (method);
+ code = mono_jit_compile_method (method, error);
+ if (!mono_error_ok (error))
+ return NULL;
+ return code;
}
}
return tramp;
}
-gpointer
-mono_create_jit_trampoline (MonoMethod *method)
-{
- return mono_create_jit_trampoline_in_domain (mono_domain_get (), method);
-}
-
gpointer
mono_create_jit_trampoline_from_token (MonoImage *image, guint32 token)
{