diff options
-rw-r--r-- | mono/metadata/object-internals.h | 4 | ||||
-rw-r--r-- | mono/metadata/object.c | 40 | ||||
-rw-r--r-- | mono/mini/aot-runtime.c | 5 | ||||
-rw-r--r-- | mono/mini/method-to-ir.c | 26 | ||||
-rw-r--r-- | mono/mini/mini-runtime.c | 88 | ||||
-rw-r--r-- | mono/mini/mini-trampolines.c | 91 | ||||
-rw-r--r-- | mono/mini/mini.c | 94 | ||||
-rw-r--r-- | mono/mini/mini.h | 4 | ||||
-rw-r--r-- | mono/utils/mono-error.c | 1 |
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); } |