Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZoltan Varga <vargaz@gmail.com>2016-01-28 21:16:24 +0300
committerZoltan Varga <vargaz@gmail.com>2016-01-28 21:16:24 +0300
commit5c3d125e79d725335cfbedb685342edf629e418b (patch)
treeb1ee2e9b6581b0e02522a845ea2d0099ab17e0df
parent2002994d0c06860d22253edbb7bae0ddcda7df44 (diff)
parent2af945bb5d93a064ee88e17f5b22fcdc1a7bd406 (diff)
Merge pull request #2528 from vargaz/jit-errors2
Jit errors2
-rw-r--r--mono/metadata/object-internals.h4
-rw-r--r--mono/metadata/object.c40
-rw-r--r--mono/mini/aot-runtime.c5
-rw-r--r--mono/mini/method-to-ir.c26
-rw-r--r--mono/mini/mini-runtime.c88
-rw-r--r--mono/mini/mini-trampolines.c91
-rw-r--r--mono/mini/mini.c94
-rw-r--r--mono/mini/mini.h4
-rw-r--r--mono/utils/mono-error.c1
9 files changed, 214 insertions, 139 deletions
diff --git a/mono/metadata/object-internals.h b/mono/metadata/object-internals.h
index 3700043213c..fdcd8f4ae57 100644
--- a/mono/metadata/object-internals.h
+++ b/mono/metadata/object-internals.h
@@ -618,6 +618,7 @@ typedef struct {
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);
} MonoRuntimeCallbacks;
typedef gboolean (*MonoInternalStackWalk) (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data);
@@ -684,9 +685,6 @@ void
mono_runtime_free_method (MonoDomain *domain, MonoMethod *method);
void
-mono_install_runtime_invoke (MonoInvokeFunc func);
-
-void
mono_install_compile_method (MonoCompileFunc func);
void
diff --git a/mono/metadata/object.c b/mono/metadata/object.c
index bd31aaa2a8b..5d6fbd89bb8 100644
--- a/mono/metadata/object.c
+++ b/mono/metadata/object.c
@@ -2846,13 +2846,24 @@ mono_object_get_virtual_method (MonoObject *obj, MonoMethod *method)
}
static MonoObject*
-dummy_mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
+do_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
{
- g_error ("runtime invoke called on uninitialized runtime");
- return NULL;
-}
+ 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 = mono_error_convert_to_exception (&error);
+ return NULL;
+ } else {
+ mono_error_raise_exception (&error);
+ }
+ }
-static MonoInvokeFunc default_mono_runtime_invoke = dummy_mono_runtime_invoke;
+ return result;
+}
/**
* mono_runtime_invoke:
@@ -2901,7 +2912,7 @@ mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_start_invoke (method);
- result = default_mono_runtime_invoke (method, obj, params, exc);
+ result = do_runtime_invoke (method, obj, params, exc);
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_end_invoke (method);
@@ -3473,7 +3484,7 @@ mono_property_set_value (MonoProperty *prop, void *obj, void **params, MonoObjec
{
MONO_REQ_GC_UNSAFE_MODE;
- default_mono_runtime_invoke (prop->set, obj, params, exc);
+ do_runtime_invoke (prop->set, obj, params, exc);
}
/**
@@ -3498,7 +3509,7 @@ mono_property_get_value (MonoProperty *prop, void *obj, void **params, MonoObjec
{
MONO_REQ_GC_UNSAFE_MODE;
- return default_mono_runtime_invoke (prop->get, obj, params, exc);
+ return do_runtime_invoke (prop->get, obj, params, exc);
}
/*
@@ -4254,19 +4265,6 @@ mono_runtime_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
}
/**
- * mono_install_runtime_invoke:
- * @func: Function to install
- *
- * This is a VM internal routine
- */
-void
-mono_install_runtime_invoke (MonoInvokeFunc func)
-{
- default_mono_runtime_invoke = func ? func: dummy_mono_runtime_invoke;
-}
-
-
-/**
* mono_runtime_invoke_array:
* @method: method to invoke
* @obJ: object instance
diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c
index 437d82f05f8..98c346de4cd 100644
--- a/mono/mini/aot-runtime.c
+++ b/mono/mini/aot-runtime.c
@@ -4607,6 +4607,7 @@ mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code
MonoAotModule *module = (MonoAotModule*)aot_module;
gboolean res, no_ftnptr = FALSE;
MonoMemPool *mp;
+ MonoError error;
gboolean using_gsharedvt = FALSE;
//printf ("DYN: %p %d\n", aot_module, plt_info_offset);
@@ -4635,7 +4636,9 @@ mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code
*/
if (mono_aot_only && ji.type == MONO_PATCH_INFO_METHOD && !ji.data.method->is_generic && !mono_method_check_context_used (ji.data.method) && !(ji.data.method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) &&
!mono_method_needs_static_rgctx_invoke (ji.data.method, FALSE) && !using_gsharedvt) {
- target = (guint8 *)mono_jit_compile_method (ji.data.method);
+ target = (guint8 *)mono_jit_compile_method (ji.data.method, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
no_ftnptr = TRUE;
} else {
target = (guint8 *)mono_resolve_patch_target (NULL, mono_domain_get (), NULL, &ji, TRUE);
diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c
index 2ff04067b88..130c62165ba 100644
--- a/mono/mini/method-to-ir.c
+++ b/mono/mini/method-to-ir.c
@@ -7084,12 +7084,12 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
cheader = mono_method_get_header (cmethod);
if (cheader == NULL || mono_loader_get_last_error ()) {
- MonoLoaderError *error = mono_loader_get_last_error ();
-
if (cheader)
mono_metadata_free_mh (cheader);
- if (inline_always && error)
- mono_cfg_set_exception (cfg, error->exception_type);
+ if (inline_always && mono_loader_get_last_error ()) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ mono_error_set_from_loader_error (&cfg->error);
+ }
mono_loader_clear_error ();
return 0;
@@ -8152,10 +8152,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
image = method->klass->image;
header = mono_method_get_header (method);
if (!header) {
- MonoLoaderError *error;
-
- if ((error = mono_loader_get_last_error ())) {
- mono_cfg_set_exception (cfg, error->exception_type);
+ if (mono_loader_get_last_error ()) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ mono_error_set_from_loader_error (&cfg->error);
} else {
mono_cfg_set_exception_invalid_program (cfg, g_strdup_printf ("Missing or incorrect header for method %s", cfg->method->name));
}
@@ -9220,8 +9219,15 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
}
}
- if (!cmethod || mono_loader_get_last_error ())
- LOAD_ERROR;
+ if (!cmethod || mono_loader_get_last_error ()) {
+ if (mono_loader_get_last_error ()) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ mono_error_set_from_loader_error (&cfg->error);
+ CHECK_CFG_ERROR;
+ } else {
+ LOAD_ERROR;
+ }
+ }
if (!dont_verify && !cfg->skip_visibility) {
MonoMethod *target_method = cil_method;
if (method->is_inflated) {
diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c
index 159e3e4affb..44d3fb6c848 100644
--- a/mono/mini/mini-runtime.c
+++ b/mono/mini/mini-runtime.c
@@ -1846,7 +1846,7 @@ no_gsharedvt_in_wrapper (void)
}
static gpointer
-mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException **ex)
+mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *error)
{
MonoDomain *target_domain, *domain = mono_domain_get ();
MonoJitInfo *info;
@@ -1855,6 +1855,8 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
MonoJitICallInfo *callinfo = NULL;
WrapperInfo *winfo = NULL;
+ mono_error_init (error);
+
/*
* ICALL wrappers are handled specially, since there is only one copy of them
* shared by all appdomains.
@@ -1887,9 +1889,8 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
ctx = mono_method_get_context (method);
method = info->d.synchronized_inner.method;
if (ctx) {
- MonoError error;
- method = mono_class_inflate_generic_method_checked (method, ctx, &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ method = mono_class_inflate_generic_method_checked (method, ctx, error);
+ g_assert (mono_error_ok (error)); /* FIXME don't swallow the error */
}
}
}
@@ -1904,9 +1905,9 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
mono_jit_stats.methods_lookups++;
vtable = mono_class_vtable (domain, method->klass);
g_assert (vtable);
- tmpEx = mono_runtime_class_init_full (vtable, ex == NULL);
+ tmpEx = mono_runtime_class_init_full (vtable, FALSE);
if (tmpEx) {
- *ex = tmpEx;
+ mono_error_set_exception_instance (error, tmpEx);
return NULL;
}
return mono_create_ftnptr (target_domain, info->code_start);
@@ -1937,7 +1938,9 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
#endif
if (!code)
- code = mono_jit_compile_method_inner (method, target_domain, opt, ex);
+ code = mono_jit_compile_method_inner (method, target_domain, opt, error);
+ if (!mono_error_ok (error))
+ return NULL;
if (!code && mono_llvm_only) {
if (method->wrapper_type == MONO_WRAPPER_UNKNOWN) {
@@ -1988,15 +1991,25 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
}
gpointer
-mono_jit_compile_method (MonoMethod *method)
+mono_jit_compile_method (MonoMethod *method, MonoError *error)
+{
+ gpointer code;
+
+ code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), error);
+ return code;
+}
+
+static gpointer
+mono_jit_compile_method_raise (MonoMethod *method)
{
- MonoException *ex = NULL;
+ MonoError error;
gpointer code;
- code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), &ex);
+ mono_error_init (&error);
+ code = mono_jit_compile_method (method, &error);
if (!code) {
- g_assert (ex);
- mono_raise_exception (ex);
+ g_assert (!mono_error_ok (&error));
+ mono_error_raise_exception (&error);
}
return code;
@@ -2199,7 +2212,7 @@ typedef struct {
} RuntimeInvokeInfo;
static RuntimeInvokeInfo*
-create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer compiled_method, gboolean callee_gsharedvt)
+create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer compiled_method, gboolean callee_gsharedvt, MonoError *error)
{
MonoMethod *invoke;
RuntimeInvokeInfo *info;
@@ -2302,7 +2315,11 @@ create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer com
invoke = mono_marshal_get_runtime_invoke_for_sig (wrapper_sig);
g_free (wrapper_sig);
- info->compiled_method = mono_jit_compile_method (wrapper);
+ info->compiled_method = mono_jit_compile_method (wrapper, error);
+ if (!mono_error_ok (error)) {
+ g_free (info);
+ return NULL;
+ }
} else {
/* Gsharedvt methods can be invoked the same way */
/* The out wrapper has the same signature as the compiled gsharedvt method */
@@ -2314,7 +2331,11 @@ create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer com
g_free (wrapper_sig);
}
}
- info->runtime_invoke = mono_jit_compile_method (invoke);
+ info->runtime_invoke = mono_jit_compile_method (invoke, error);
+ if (!mono_error_ok (error)) {
+ g_free (info);
+ return NULL;
+ }
}
return info;
@@ -2396,10 +2417,11 @@ mono_llvmonly_runtime_invoke (MonoMethod *method, RuntimeInvokeInfo *info, void
* @method: the method to invoke
* @obj: this pointer
* @params: array of parameter values.
+ * @error: error
* @exc: used to catch exceptions objects
*/
static MonoObject*
-mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
+mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoError *error, MonoObject **exc)
{
MonoMethod *invoke, *callee;
MonoObject *(*runtime_invoke) (MonoObject *this_obj, void **params, MonoObject **exc, void* compiled_method);
@@ -2409,6 +2431,8 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
MonoJitInfo *ji = NULL;
gboolean callee_gsharedvt = FALSE;
+ mono_error_init (error);
+
if (obj == NULL && !(method->flags & METHOD_ATTRIBUTE_STATIC) && !method->string_ctor && (method->wrapper_type == 0)) {
g_warning ("Ignoring invocation of an instance method on a NULL instance.\n");
return NULL;
@@ -2458,18 +2482,10 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
}
if (callee) {
- MonoException *jit_ex = NULL;
-
- compiled_method = mono_jit_compile_method_with_opt (callee, mono_get_optimizations_for_method (callee, default_opt), &jit_ex);
+ compiled_method = mono_jit_compile_method_with_opt (callee, mono_get_optimizations_for_method (callee, default_opt), error);
if (!compiled_method) {
- g_assert (jit_ex);
- if (exc) {
- *exc = (MonoObject*)jit_ex;
- return NULL;
- } else {
- mono_raise_exception (jit_ex);
- /* coverity[unreachable] */
- }
+ g_assert (!mono_error_ok (error));
+ return NULL;
}
if (mono_llvm_only) {
@@ -2485,7 +2501,9 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
compiled_method = NULL;
}
- info = create_runtime_invoke_info (domain, method, compiled_method, callee_gsharedvt);
+ info = create_runtime_invoke_info (domain, method, compiled_method, callee_gsharedvt, error);
+ if (!mono_error_ok (error))
+ return NULL;
mono_domain_lock (domain);
info2 = (RuntimeInvokeInfo *)mono_conc_hashtable_insert (domain_info->runtime_invoke_hash, method, info);
@@ -2523,7 +2541,9 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
if (!dyn_runtime_invoke) {
invoke = mono_marshal_get_runtime_invoke_dynamic ();
- dyn_runtime_invoke = (RuntimeInvokeDynamicFunction)mono_jit_compile_method (invoke);
+ dyn_runtime_invoke = (RuntimeInvokeDynamicFunction)mono_jit_compile_method (invoke, error);
+ if (!mono_error_ok (error))
+ return NULL;
}
/* Convert the arguments to the format expected by start_dyn_call () */
@@ -3491,6 +3511,10 @@ mini_init (const char *filename, const char *runtime_version)
callbacks.get_imt_trampoline = mini_get_imt_trampoline;
callbacks.imt_entry_inited = mini_imt_entry_inited;
callbacks.init_delegate = mini_init_delegate;
+#define JIT_INVOKE_WORKS
+#ifdef JIT_INVOKE_WORKS
+ callbacks.runtime_invoke = mono_jit_runtime_invoke;
+#endif
mono_install_callbacks (&callbacks);
@@ -3562,7 +3586,7 @@ mini_init (const char *filename, const char *runtime_version)
#define JIT_TRAMPOLINES_WORK
#ifdef JIT_TRAMPOLINES_WORK
- mono_install_compile_method (mono_jit_compile_method);
+ mono_install_compile_method (mono_jit_compile_method_raise);
mono_install_free_method (mono_jit_free_method);
mono_install_trampoline (mono_create_jit_trampoline);
mono_install_jump_trampoline (mono_create_jump_trampoline);
@@ -3573,10 +3597,6 @@ mini_init (const char *filename, const char *runtime_version)
mono_install_create_domain_hook (mini_create_jit_domain_info);
mono_install_free_domain_hook (mini_free_jit_domain_info);
#endif
-#define JIT_INVOKE_WORKS
-#ifdef JIT_INVOKE_WORKS
- mono_install_runtime_invoke (mono_jit_runtime_invoke);
-#endif
mono_install_get_cached_class_info (mono_aot_get_cached_class_info);
mono_install_get_class_from_name (mono_aot_get_class_from_name);
mono_install_jit_info_find_in_aot (mono_aot_find_jit_info);
diff --git a/mono/mini/mini-trampolines.c b/mono/mini/mini-trampolines.c
index f1fe616b969..e9d2a645e14 100644
--- a/mono/mini/mini-trampolines.c
+++ b/mono/mini/mini-trampolines.c
@@ -501,13 +501,13 @@ mini_add_method_wrappers_llvmonly (MonoMethod *m, gpointer compiled_method, gboo
}
/**
- * 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;
@@ -520,6 +520,8 @@ common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVT
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;
@@ -691,8 +693,9 @@ common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVT
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?*/
@@ -801,11 +804,11 @@ common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVT
}
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;
}
@@ -818,9 +821,17 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *
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;
}
/**
@@ -835,7 +846,8 @@ mono_vcall_trampoline (mgreg_t *regs, guint8 *code, int slot, guint8 *tramp)
MonoVTable *vt;
gpointer *vtable_slot;
MonoMethod *m;
- gpointer addr;
+ MonoError error;
+ gpointer addr, res;
trampoline_calls ++;
@@ -889,7 +901,12 @@ mono_vcall_trampoline (mgreg_t *regs, guint8 *code, int slot, guint8 *tramp)
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
@@ -922,7 +939,11 @@ mono_generic_virtual_remoting_trampoline (mgreg_t *regs, guint8 *code, MonoMetho
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;
@@ -990,8 +1011,14 @@ mono_aot_plt_trampoline (mgreg_t *regs, guint8 *code, guint8 *aot_module,
res = mono_aot_plt_resolve (aot_module, plt_info_offset, code);
if (!res) {
- if (mono_loader_get_last_error ())
- mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+ 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);
}
@@ -1070,6 +1097,7 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
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;
@@ -1114,8 +1142,10 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
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) {
@@ -1146,8 +1176,10 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
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;
@@ -1196,7 +1228,11 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
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)
@@ -1222,7 +1258,11 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
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);
}
@@ -1407,6 +1447,7 @@ mono_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, M
gpointer
mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper)
{
+ MonoError error;
MonoJitInfo *ji;
gpointer code;
guint32 code_size = 0;
@@ -1421,8 +1462,12 @@ mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean ad
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))
+ mono_error_raise_exception (&error);
+ return code;
+ }
mono_domain_lock (domain);
code = g_hash_table_lookup (domain_jit_info (domain)->jump_trampoline_hash, method);
@@ -1461,6 +1506,7 @@ method_not_found (void)
gpointer
mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method)
{
+ MonoError error;
gpointer tramp;
if (mono_aot_only) {
@@ -1475,7 +1521,10 @@ mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *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))
+ mono_error_raise_exception (&error);
+ return code;
}
}
diff --git a/mono/mini/mini.c b/mono/mini/mini.c
index ba5577ef60a..c7306b08998 100644
--- a/mono/mini/mini.c
+++ b/mono/mini/mini.c
@@ -1208,7 +1208,7 @@ mini_assembly_can_skip_verification (MonoDomain *domain, MonoMethod *method)
/*
* mini_method_verify:
*
- * Verify the method using the new verfier.
+ * Verify the method using the verfier.
*
* Returns true if the method is invalid.
*/
@@ -1217,7 +1217,6 @@ mini_method_verify (MonoCompile *cfg, MonoMethod *method, gboolean fail_compile)
{
GSList *tmp, *res;
gboolean is_fulltrust;
- MonoLoaderError *error;
if (method->verification_success)
return FALSE;
@@ -1230,11 +1229,13 @@ mini_method_verify (MonoCompile *cfg, MonoMethod *method, gboolean fail_compile)
res = mono_method_verify_with_current_settings (method, cfg->skip_visibility, is_fulltrust);
- if ((error = mono_loader_get_last_error ())) {
- if (fail_compile)
- cfg->exception_type = error->exception_type;
- else
+ if (mono_loader_get_last_error ()) {
+ if (fail_compile) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ mono_error_set_from_loader_error (&cfg->error);
+ } else {
mono_loader_clear_error ();
+ }
if (res)
mono_free_verify_list (res);
return TRUE;
@@ -1256,16 +1257,20 @@ mini_method_verify (MonoCompile *cfg, MonoMethod *method, gboolean fail_compile)
if (info->info.status == MONO_VERIFY_NOT_VERIFIABLE && (!is_fulltrust || info->exception_type == MONO_EXCEPTION_METHOD_ACCESS || info->exception_type == MONO_EXCEPTION_FIELD_ACCESS)) {
if (fail_compile) {
char *method_name = mono_method_full_name (method, TRUE);
-
- if (info->exception_type == MONO_EXCEPTION_METHOD_ACCESS || info->exception_type == MONO_EXCEPTION_FIELD_ACCESS) {
- if (info->exception_type == MONO_EXCEPTION_METHOD_ACCESS)
- mono_error_set_generic_error (&cfg->error, "System", "MethodAccessException", "Error verifying %s: %s", method_name, info->info.message);
- else
- mono_error_set_generic_error (&cfg->error, "System", "FieldAccessException", "Error verifying %s: %s", method_name, info->info.message);
- cfg->exception_type = MONO_EXCEPTION_MONO_ERROR;
+ char *msg = g_strdup_printf ("Error verifying %s: %s", method_name, info->info.message);
+
+ if (info->exception_type == MONO_EXCEPTION_METHOD_ACCESS)
+ mono_error_set_generic_error (&cfg->error, "System", "MethodAccessException", "%s", msg);
+ else if (info->exception_type == info->exception_type == MONO_EXCEPTION_FIELD_ACCESS)
+ mono_error_set_generic_error (&cfg->error, "System", "FieldAccessException", "%s", msg);
+ else if (info->exception_type == MONO_EXCEPTION_UNVERIFIABLE_IL)
+ mono_error_set_generic_error (&cfg->error, "System.Security", "VerificationException", msg);
+ if (!mono_error_ok (&cfg->error)) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ g_free (msg);
} else {
cfg->exception_type = info->exception_type;
- cfg->exception_message = g_strdup_printf ("Error verifying %s: %s", method_name, info->info.message);
+ cfg->exception_message = msg;
}
g_free (method_name);
}
@@ -3481,10 +3486,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
header = cfg->header;
if (!header) {
- MonoLoaderError *error;
-
- if ((error = mono_loader_get_last_error ())) {
- cfg->exception_type = error->exception_type;
+ if (mono_loader_get_last_error ()) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ mono_error_set_from_loader_error (&cfg->error);
} else {
mono_cfg_set_exception_invalid_program (cfg, g_strdup_printf ("Missing or incorrect header for method %s", cfg->method->name));
}
@@ -4186,7 +4190,7 @@ create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info)
* Main entry point for the JIT.
*/
gpointer
-mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoException **jit_ex)
+mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoError *error)
{
MonoCompile *cfg;
gpointer code = NULL;
@@ -4197,6 +4201,8 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
GTimer *jit_timer;
MonoMethod *prof_method, *shared;
+ mono_error_init (error);
+
if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
MonoMethod *nm;
@@ -4259,7 +4265,8 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
full_name = mono_method_full_name (method, TRUE);
msg = g_strdup_printf ("Unrecognizable runtime implemented method '%s'", full_name);
- *jit_ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", msg);
+ ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", msg);
+ mono_error_set_exception_instance (error, ex);
g_free (full_name);
g_free (msg);
return NULL;
@@ -4302,7 +4309,8 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
char *fullname = mono_method_full_name (method, TRUE);
char *msg = g_strdup_printf ("Attempting to JIT compile method '%s' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.\n", fullname);
- *jit_ex = mono_get_exception_execution_engine (msg);
+ ex = mono_get_exception_execution_engine (msg);
+ mono_error_set_exception_instance (error, ex);
g_free (fullname);
g_free (msg);
@@ -4327,34 +4335,26 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
case MONO_EXCEPTION_FILE_NOT_FOUND:
case MONO_EXCEPTION_BAD_IMAGE: {
/* Throw a type load exception if needed */
- MonoLoaderError *error = mono_loader_get_last_error ();
-
- if (error) {
- ex = mono_loader_error_prepare_exception (error);
+ if (cfg->exception_ptr) {
+ ex = mono_class_get_exception_for_failure ((MonoClass *)cfg->exception_ptr);
} else {
- if (cfg->exception_ptr) {
- ex = mono_class_get_exception_for_failure ((MonoClass *)cfg->exception_ptr);
- } else {
- if (cfg->exception_type == MONO_EXCEPTION_MISSING_FIELD)
- ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MissingFieldException", cfg->exception_message);
- else if (cfg->exception_type == MONO_EXCEPTION_MISSING_METHOD)
- ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MissingMethodException", cfg->exception_message);
- else if (cfg->exception_type == MONO_EXCEPTION_TYPE_LOAD)
- ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "TypeLoadException", cfg->exception_message);
- else if (cfg->exception_type == MONO_EXCEPTION_FILE_NOT_FOUND)
- ex = mono_exception_from_name_msg (mono_defaults.corlib, "System.IO", "FileNotFoundException", cfg->exception_message);
- else if (cfg->exception_type == MONO_EXCEPTION_BAD_IMAGE)
- ex = mono_get_exception_bad_image_format (cfg->exception_message);
- else
- g_assert_not_reached ();
- }
+ if (cfg->exception_type == MONO_EXCEPTION_MISSING_FIELD)
+ ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MissingFieldException", cfg->exception_message);
+ else if (cfg->exception_type == MONO_EXCEPTION_MISSING_METHOD)
+ ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MissingMethodException", cfg->exception_message);
+ else if (cfg->exception_type == MONO_EXCEPTION_TYPE_LOAD)
+ ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "TypeLoadException", cfg->exception_message);
+ else if (cfg->exception_type == MONO_EXCEPTION_FILE_NOT_FOUND)
+ ex = mono_exception_from_name_msg (mono_defaults.corlib, "System.IO", "FileNotFoundException", cfg->exception_message);
+ else if (cfg->exception_type == MONO_EXCEPTION_BAD_IMAGE)
+ ex = mono_get_exception_bad_image_format (cfg->exception_message);
+ else
+ g_assert_not_reached ();
}
break;
}
- case MONO_EXCEPTION_UNVERIFIABLE_IL:
- ex = mono_exception_from_name_msg (mono_defaults.corlib, "System.Security", "VerificationException", cfg->exception_message);
- break;
case MONO_EXCEPTION_MONO_ERROR:
+ // FIXME: MonoError has no copy ctor
g_assert (!mono_error_ok (&cfg->error));
ex = mono_error_convert_to_exception (&cfg->error);
break;
@@ -4367,7 +4367,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
mono_profiler_method_end_jit (method, NULL, MONO_PROFILE_FAILED);
mono_destroy_compile (cfg);
- *jit_ex = ex;
+ mono_error_set_exception_instance (error, ex);
return NULL;
}
@@ -4464,7 +4464,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
if (!vtable) {
ex = mono_class_get_exception_for_failure (method->klass);
g_assert (ex);
- *jit_ex = ex;
+ mono_error_set_exception_instance (error, ex);
return NULL;
}
@@ -4484,7 +4484,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
ex = mono_runtime_class_init_full (vtable, FALSE);
if (ex) {
- *jit_ex = ex;
+ mono_error_set_exception_instance (error, ex);
return NULL;
}
return code;
diff --git a/mono/mini/mini.h b/mono/mini/mini.h
index 592d2945d2f..277a3906f85 100644
--- a/mono/mini/mini.h
+++ b/mono/mini/mini.h
@@ -2325,8 +2325,8 @@ MonoJumpInfo *mono_patch_info_list_prepend (MonoJumpInfo *list, int ip, MonoJum
gpointer mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors) MONO_LLVM_INTERNAL;
gpointer mono_jit_find_compiled_method_with_jit_info (MonoDomain *domain, MonoMethod *method, MonoJitInfo **ji);
gpointer mono_jit_find_compiled_method (MonoDomain *domain, MonoMethod *method);
-gpointer mono_jit_compile_method (MonoMethod *method);
-gpointer mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoException **jit_ex);
+gpointer mono_jit_compile_method (MonoMethod *method, MonoError *error);
+gpointer mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoError *error);
MonoLMF * mono_get_lmf (void);
MonoLMF** mono_get_lmf_addr (void);
void mono_set_lmf (MonoLMF *lmf);
diff --git a/mono/utils/mono-error.c b/mono/utils/mono-error.c
index ca3350c5fd4..4ab45ba9e2c 100644
--- a/mono/utils/mono-error.c
+++ b/mono/utils/mono-error.c
@@ -347,6 +347,7 @@ mono_error_set_exception_instance (MonoError *oerror, MonoException *exc)
{
MonoErrorInternal *error = (MonoErrorInternal*)oerror;
+ mono_error_prepare (error);
error->error_code = MONO_ERROR_EXCEPTION_INSTANCE;
error->exn.instance_handle = mono_gchandle_new (exc ? &exc->object : NULL, FALSE);
}