X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fjit-icalls.c;h=dbf89a8d517e0ea20d793f181a7c8f65487aeffb;hb=3fd54893bc792eee42164bfb605b418105a92f92;hp=83603d75367601a16901b5f5b46e19451d7c6488;hpb=02d129eecc9997966db53ad539dd4ae266446c45;p=mono.git diff --git a/mono/mini/jit-icalls.c b/mono/mini/jit-icalls.c index 83603d75367..f8a328375b9 100644 --- a/mono/mini/jit-icalls.c +++ b/mono/mini/jit-icalls.c @@ -8,6 +8,7 @@ * (C) 2002 Ximian, Inc. * Copyright 2003-2011 Novell Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include @@ -18,6 +19,9 @@ #include "jit-icalls.h" #include +#include +#include +#include #ifdef ENABLE_LLVM #include "mini-llvm-cpp.h" @@ -27,11 +31,13 @@ void* mono_ldftn (MonoMethod *method) { gpointer addr; + MonoError error; if (mono_llvm_only) { // FIXME: No error handling - addr = mono_compile_method (method); + addr = mono_compile_method_checked (method, &error); + mono_error_assert_ok (&error); g_assert (addr); if (mono_method_needs_static_rgctx_invoke (method, FALSE)) @@ -42,8 +48,11 @@ mono_ldftn (MonoMethod *method) return addr; } - addr = mono_create_jump_trampoline (mono_domain_get (), method, FALSE); - + addr = mono_create_jump_trampoline (mono_domain_get (), method, FALSE, &error); + if (!mono_error_ok (&error)) { + mono_error_set_pending_exception (&error); + return NULL; + } return mono_create_ftnptr (mono_domain_get (), addr); } @@ -96,11 +105,14 @@ mono_ldvirtfn_gshared (MonoObject *obj, MonoMethod *method) void mono_helper_stelem_ref_check (MonoArray *array, MonoObject *val) { + MonoError error; if (!array) { mono_set_pending_exception (mono_get_exception_null_reference ()); return; } - if (val && !mono_object_isinst (val, array->obj.vtable->klass->element_class)) { + if (val && !mono_object_isinst_checked (val, array->obj.vtable->klass->element_class, &error)) { + if (mono_error_set_pending_exception (&error)) + return; mono_set_pending_exception (mono_get_exception_array_type_mismatch ()); return; } @@ -694,7 +706,11 @@ mono_array_new_va (MonoMethod *cm, ...) va_end(ap); arr = mono_array_new_full_checked (domain, cm->klass, lengths, lower_bounds, &error); - mono_error_raise_exception (&error); /* FIXME don't raise here */ + + if (!mono_error_ok (&error)) { + mono_error_set_pending_exception (&error); + return NULL; + } return arr; } @@ -726,7 +742,11 @@ mono_array_new_1 (MonoMethod *cm, guint32 length) } arr = mono_array_new_full_checked (domain, cm->klass, lengths, lower_bounds, &error); - mono_error_raise_exception (&error); /* FIXME don't raise here */ + + if (!mono_error_ok (&error)) { + mono_error_set_pending_exception (&error); + return NULL; + } return arr; } @@ -758,7 +778,11 @@ mono_array_new_2 (MonoMethod *cm, guint32 length1, guint32 length2) } arr = mono_array_new_full_checked (domain, cm->klass, lengths, lower_bounds, &error); - mono_error_raise_exception (&error); /* FIXME don't raise here */ + + if (!mono_error_ok (&error)) { + mono_error_set_pending_exception (&error); + return NULL; + } return arr; } @@ -791,7 +815,11 @@ mono_array_new_3 (MonoMethod *cm, guint32 length1, guint32 length2, guint32 leng } arr = mono_array_new_full_checked (domain, cm->klass, lengths, lower_bounds, &error); - mono_error_raise_exception (&error); /* FIXME don't raise here */ + + if (!mono_error_ok (&error)) { + mono_error_set_pending_exception (&error); + return NULL; + } return arr; } @@ -825,7 +853,11 @@ mono_array_new_4 (MonoMethod *cm, guint32 length1, guint32 length2, guint32 leng } arr = mono_array_new_full_checked (domain, cm->klass, lengths, lower_bounds, &error); - mono_error_raise_exception (&error); /* FIXME don't raise here */ + + if (!mono_error_ok (&error)) { + mono_error_set_pending_exception (&error); + return NULL; + } return arr; } @@ -833,6 +865,7 @@ mono_array_new_4 (MonoMethod *cm, guint32 length1, guint32 length2, guint32 leng gpointer mono_class_static_field_address (MonoDomain *domain, MonoClassField *field) { + MonoError error; MonoVTable *vtable; gpointer addr; @@ -840,9 +873,17 @@ mono_class_static_field_address (MonoDomain *domain, MonoClassField *field) mono_class_init (field->parent); - vtable = mono_class_vtable_full (domain, field->parent, TRUE); - if (!vtable->initialized) - mono_runtime_class_init (vtable); + vtable = mono_class_vtable_full (domain, field->parent, &error); + if (!is_ok (&error)) { + mono_error_set_pending_exception (&error); + return NULL; + } + if (!vtable->initialized) { + if (!mono_runtime_class_init_full (vtable, &error)) { + mono_error_set_pending_exception (&error); + return NULL; + } + } //printf ("SFLDA1 %p\n", (char*)vtable->data + field->offset); @@ -1055,6 +1096,7 @@ mono_fmod(double a, double b) gpointer mono_helper_compile_generic_method (MonoObject *obj, MonoMethod *method, gpointer *this_arg) { + MonoError error; MonoMethod *vmethod; gpointer addr; MonoGenericContext *context = mono_method_get_context (method); @@ -1070,7 +1112,9 @@ mono_helper_compile_generic_method (MonoObject *obj, MonoMethod *method, gpointe g_assert (!vmethod->klass->generic_class || !vmethod->klass->generic_class->context.class_inst->is_open); g_assert (!context->method_inst || !context->method_inst->is_open); - addr = mono_compile_method (vmethod); + addr = mono_compile_method_checked (vmethod, &error); + if (mono_error_set_pending_exception (&error)) + return NULL; addr = mini_add_method_trampoline (vmethod, addr, mono_method_needs_static_rgctx_invoke (vmethod, FALSE), FALSE); @@ -1083,16 +1127,31 @@ mono_helper_compile_generic_method (MonoObject *obj, MonoMethod *method, gpointe return addr; } +MonoString* +ves_icall_mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 idx) +{ + MonoError error; + MonoString *result = mono_ldstr_checked (domain, image, idx, &error); + mono_error_set_pending_exception (&error); + return result; +} + MonoString* mono_helper_ldstr (MonoImage *image, guint32 idx) { - return mono_ldstr (mono_domain_get (), image, idx); + MonoError error; + MonoString *result = mono_ldstr_checked (mono_domain_get (), image, idx, &error); + mono_error_set_pending_exception (&error); + return result; } MonoString* mono_helper_ldstr_mscorlib (guint32 idx) { - return mono_ldstr (mono_domain_get (), mono_defaults.corlib, idx); + MonoError error; + MonoString *result = mono_ldstr_checked (mono_domain_get (), mono_defaults.corlib, idx, &error); + mono_error_set_pending_exception (&error); + return result; } MonoObject* @@ -1106,7 +1165,10 @@ mono_helper_newobj_mscorlib (guint32 idx) return NULL; } - return mono_object_new (mono_domain_get (), klass); + MonoObject *obj = mono_object_new_checked (mono_domain_get (), klass, &error); + if (!mono_error_ok (&error)) + mono_error_set_pending_exception (&error); + return obj; } /* @@ -1128,18 +1190,27 @@ mono_create_corlib_exception_0 (guint32 token) MonoException * mono_create_corlib_exception_1 (guint32 token, MonoString *arg) { - return mono_exception_from_token_two_strings (mono_defaults.corlib, token, arg, NULL); + MonoError error; + MonoException *ret = mono_exception_from_token_two_strings_checked ( + mono_defaults.corlib, token, arg, NULL, &error); + mono_error_set_pending_exception (&error); + return ret; } MonoException * mono_create_corlib_exception_2 (guint32 token, MonoString *arg1, MonoString *arg2) { - return mono_exception_from_token_two_strings (mono_defaults.corlib, token, arg1, arg2); + MonoError error; + MonoException *ret = mono_exception_from_token_two_strings_checked ( + mono_defaults.corlib, token, arg1, arg2, &error); + mono_error_set_pending_exception (&error); + return ret; } MonoObject* mono_object_castclass_unbox (MonoObject *obj, MonoClass *klass) { + MonoError error; MonoJitTlsData *jit_tls = NULL; MonoClass *oklass; @@ -1154,8 +1225,10 @@ mono_object_castclass_unbox (MonoObject *obj, MonoClass *klass) oklass = obj->vtable->klass; if ((klass->enumtype && oklass == klass->element_class) || (oklass->enumtype && klass == oklass->element_class)) return obj; - if (mono_object_isinst (obj, klass)) + if (mono_object_isinst_checked (obj, klass, &error)) return obj; + if (mono_error_set_pending_exception (&error)) + return NULL; if (mini_get_debug_options ()->better_cast_details) { jit_tls->class_cast_from = oklass; @@ -1171,6 +1244,7 @@ mono_object_castclass_unbox (MonoObject *obj, MonoClass *klass) MonoObject* mono_object_castclass_with_cache (MonoObject *obj, MonoClass *klass, gpointer *cache) { + MonoError error; MonoJitTlsData *jit_tls = NULL; gpointer cached_vtable, obj_vtable; @@ -1188,10 +1262,12 @@ mono_object_castclass_with_cache (MonoObject *obj, MonoClass *klass, gpointer *c if (cached_vtable == obj_vtable) return obj; - if (mono_object_isinst (obj, klass)) { + if (mono_object_isinst_checked (obj, klass, &error)) { *cache = obj_vtable; return obj; } + if (mono_error_set_pending_exception (&error)) + return NULL; if (mini_get_debug_options ()->better_cast_details) { jit_tls->class_cast_from = obj->vtable->klass; @@ -1207,6 +1283,7 @@ mono_object_castclass_with_cache (MonoObject *obj, MonoClass *klass, gpointer *c MonoObject* mono_object_isinst_with_cache (MonoObject *obj, MonoClass *klass, gpointer *cache) { + MonoError error; size_t cached_vtable, obj_vtable; if (!obj) @@ -1219,10 +1296,12 @@ mono_object_isinst_with_cache (MonoObject *obj, MonoClass *klass, gpointer *cach return (cached_vtable & 0x1) ? NULL : obj; } - if (mono_object_isinst (obj, klass)) { + if (mono_object_isinst_checked (obj, klass, &error)) { *cache = (gpointer)obj_vtable; return obj; } else { + if (mono_error_set_pending_exception (&error)) + return NULL; /*negative cache*/ *cache = (gpointer)(obj_vtable | 0x1); return NULL; @@ -1232,6 +1311,7 @@ mono_object_isinst_with_cache (MonoObject *obj, MonoClass *klass, gpointer *cach gpointer mono_get_native_calli_wrapper (MonoImage *image, MonoMethodSignature *sig, gpointer func) { + MonoError error; MonoMarshalSpec **mspecs; MonoMethodPInvoke piinfo; MonoMethod *m; @@ -1241,15 +1321,19 @@ mono_get_native_calli_wrapper (MonoImage *image, MonoMethodSignature *sig, gpoin m = mono_marshal_get_native_func_wrapper (image, sig, &piinfo, mspecs, func); - return mono_compile_method (m); + gpointer compiled_ptr = mono_compile_method_checked (m, &error); + mono_error_set_pending_exception (&error); + return compiled_ptr; } static MonoMethod* -constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gpointer *this_arg) +constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gpointer *this_arg, MonoError *error) { MonoMethod *m; int vt_slot, iface_offset; + mono_error_init (error); + if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) { MonoObject *this_obj; @@ -1282,7 +1366,7 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k /* * Calling a non-vtype method with a vtype receiver, has to box. */ - *this_arg = mono_value_box (mono_domain_get (), klass, mp); + *this_arg = mono_value_box_checked (mono_domain_get (), klass, mp, error); else if (klass->valuetype) /* * Calling a vtype method with a vtype receiver @@ -1300,16 +1384,23 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k * 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]; - m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg); + m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg, &error); + if (!mono_error_ok (&error)) { + mono_error_set_pending_exception (&error); + return NULL; + } + if (!m) return NULL; if (args && deref_arg) { @@ -1322,7 +1413,14 @@ mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *kl 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 @@ -1334,22 +1432,59 @@ mono_gsharedvt_value_copy (gpointer dest, gpointer src, MonoClass *klass) mono_gc_wbarrier_generic_store (dest, *(MonoObject**)src); } +void +ves_icall_runtime_class_init (MonoVTable *vtable) +{ + MONO_REQ_GC_UNSAFE_MODE; + MonoError error; + + mono_runtime_class_init_full (vtable, &error); + mono_error_set_pending_exception (&error); +} + + void mono_generic_class_init (MonoVTable *vtable) { - mono_runtime_class_init (vtable); + MonoError error; + mono_runtime_class_init_full (vtable, &error); + mono_error_set_pending_exception (&error); +} + +void +ves_icall_mono_delegate_ctor (MonoObject *this_obj, MonoObject *target, gpointer addr) +{ + MonoError error; + mono_delegate_ctor (this_obj, target, addr, &error); + mono_error_set_pending_exception (&error); } gpointer mono_fill_class_rgctx (MonoVTable *vtable, int index) { - return mono_class_fill_runtime_generic_context (vtable, index); + MonoError error; + gpointer res; + + res = mono_class_fill_runtime_generic_context (vtable, index, &error); + if (!mono_error_ok (&error)) { + mono_error_set_pending_exception (&error); + return NULL; + } + return res; } gpointer mono_fill_method_rgctx (MonoMethodRuntimeGenericContext *mrgctx, int index) { - return mono_method_fill_runtime_generic_context (mrgctx, index); + MonoError error; + gpointer res; + + res = mono_method_fill_runtime_generic_context (mrgctx, index, &error); + if (!mono_error_ok (&error)) { + mono_error_set_pending_exception (&error); + return NULL; + } + return res; } /* @@ -1361,7 +1496,7 @@ mono_fill_method_rgctx (MonoMethodRuntimeGenericContext *mrgctx, int index) * out parameter. */ static gpointer -resolve_iface_call (MonoObject *this_obj, int imt_slot, MonoMethod *imt_method, gpointer *out_arg, gboolean caller_gsharedvt) +resolve_iface_call (MonoObject *this_obj, int imt_slot, MonoMethod *imt_method, gpointer *out_arg, gboolean caller_gsharedvt, MonoError *error) { MonoVTable *vt; gpointer *imt, *vtable_slot; @@ -1369,6 +1504,7 @@ resolve_iface_call (MonoObject *this_obj, int imt_slot, MonoMethod *imt_method, gpointer addr, compiled_method, aot_addr; gboolean need_rgctx_tramp = FALSE, need_unbox_tramp = FALSE; + mono_error_init (error); if (!this_obj) /* The caller will handle it */ return NULL; @@ -1376,10 +1512,12 @@ resolve_iface_call (MonoObject *this_obj, int imt_slot, MonoMethod *imt_method, vt = this_obj->vtable; imt = (gpointer*)vt - MONO_IMT_SIZE; - vtable_slot = mini_resolve_imt_method (vt, imt + imt_slot, imt_method, &impl_method, &aot_addr, &need_rgctx_tramp, &variant_iface); + vtable_slot = mini_resolve_imt_method (vt, imt + imt_slot, imt_method, &impl_method, &aot_addr, &need_rgctx_tramp, &variant_iface, error); + return_val_if_nok (error, NULL); // FIXME: This can throw exceptions - addr = compiled_method = mono_compile_method (impl_method); + addr = compiled_method = mono_compile_method_checked (impl_method, error); + mono_error_assert_ok (error); g_assert (addr); if (imt_method->is_inflated && ((MonoMethodInflated*)imt_method)->context.method_inst) @@ -1409,7 +1547,13 @@ resolve_iface_call (MonoObject *this_obj, int imt_slot, MonoMethod *imt_method, gpointer mono_resolve_iface_call_gsharedvt (MonoObject *this_obj, int imt_slot, MonoMethod *imt_method, gpointer *out_arg) { - return resolve_iface_call (this_obj, imt_slot, imt_method, out_arg, TRUE); + MonoError error; + gpointer res = resolve_iface_call (this_obj, imt_slot, imt_method, out_arg, TRUE, &error); + if (!is_ok (&error)) { + MonoException *ex = mono_error_convert_to_exception (&error); + mono_llvm_throw_exception ((MonoObject*)ex); + } + return res; } static gboolean @@ -1438,23 +1582,24 @@ is_generic_method_definition (MonoMethod *m) * out parameter. */ static gpointer -resolve_vcall (MonoVTable *vt, int slot, MonoMethod *imt_method, gpointer *out_arg, gboolean gsharedvt) +resolve_vcall (MonoVTable *vt, int slot, MonoMethod *imt_method, gpointer *out_arg, gboolean gsharedvt, MonoError *error) { MonoMethod *m, *generic_virtual = NULL; gpointer addr, compiled_method; gboolean need_unbox_tramp = FALSE; + mono_error_init (error); /* Same as in common_call_trampoline () */ /* Avoid loading metadata or creating a generic vtable if possible */ - addr = mono_aot_get_method_from_vt_slot (mono_domain_get (), vt, slot); + addr = mono_aot_get_method_from_vt_slot (mono_domain_get (), vt, slot, error); + return_val_if_nok (error, NULL); if (addr && !vt->klass->valuetype) return mono_create_ftnptr (mono_domain_get (), addr); m = mono_class_get_vtable_entry (vt->klass, slot); if (is_generic_method_definition (m)) { - MonoError error; MonoGenericContext context = { NULL, NULL }; MonoMethod *declaring; @@ -1473,8 +1618,8 @@ resolve_vcall (MonoVTable *vt, int slot, MonoMethod *imt_method, gpointer *out_a g_assert (generic_virtual->is_inflated); context.method_inst = ((MonoMethodInflated*)generic_virtual)->context.method_inst; - m = mono_class_inflate_generic_method_checked (declaring, &context, &error); - g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ + m = mono_class_inflate_generic_method_checked (declaring, &context, error); + mono_error_assert_ok (error); /* FIXME don't swallow the error */ } if (generic_virtual) { @@ -1485,8 +1630,12 @@ resolve_vcall (MonoVTable *vt, int slot, MonoMethod *imt_method, gpointer *out_a need_unbox_tramp = TRUE; } + if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) + m = mono_marshal_get_synchronized_wrapper (m); + // FIXME: This can throw exceptions - addr = compiled_method = mono_compile_method (m); + addr = compiled_method = mono_compile_method_checked (m, error); + mono_error_assert_ok (error); g_assert (addr); addr = mini_add_method_wrappers_llvmonly (m, addr, gsharedvt, need_unbox_tramp, out_arg); @@ -1508,7 +1657,13 @@ mono_resolve_vcall_gsharedvt (MonoObject *this_obj, int slot, MonoMethod *imt_me { g_assert (this_obj); - return resolve_vcall (this_obj->vtable, slot, imt_method, out_arg, TRUE); + MonoError error; + gpointer result = resolve_vcall (this_obj->vtable, slot, imt_method, out_arg, TRUE, &error); + if (!is_ok (&error)) { + MonoException *ex = mono_error_convert_to_exception (&error); + mono_llvm_throw_exception ((MonoObject*)ex); + } + return result; } /* @@ -1552,7 +1707,8 @@ mono_resolve_generic_virtual_call (MonoVTable *vt, int slot, MonoMethod *generic need_unbox_tramp = TRUE; // FIXME: This can throw exceptions - addr = compiled_method = mono_compile_method (m); + addr = compiled_method = mono_compile_method_checked (m, &error); + mono_error_assert_ok (&error); g_assert (addr); addr = mini_add_method_wrappers_llvmonly (m, addr, FALSE, need_unbox_tramp, &arg); @@ -1579,6 +1735,7 @@ mono_resolve_generic_virtual_call (MonoVTable *vt, int slot, MonoMethod *generic MonoFtnDesc* mono_resolve_generic_virtual_iface_call (MonoVTable *vt, int imt_slot, MonoMethod *generic_virtual) { + MonoError error; MonoMethod *m, *variant_iface; gpointer addr, aot_addr, compiled_method; gboolean need_unbox_tramp = FALSE; @@ -1588,13 +1745,20 @@ mono_resolve_generic_virtual_iface_call (MonoVTable *vt, int imt_slot, MonoMetho imt = (gpointer*)vt - MONO_IMT_SIZE; - mini_resolve_imt_method (vt, imt + imt_slot, generic_virtual, &m, &aot_addr, &need_rgctx_tramp, &variant_iface); + mini_resolve_imt_method (vt, imt + imt_slot, generic_virtual, &m, &aot_addr, &need_rgctx_tramp, &variant_iface, &error); + if (!is_ok (&error)) { + MonoException *ex = mono_error_convert_to_exception (&error); + mono_llvm_throw_exception ((MonoObject*)ex); + } if (vt->klass->valuetype) need_unbox_tramp = TRUE; - // FIXME: This can throw exceptions - addr = compiled_method = mono_compile_method (m); + if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) + m = mono_marshal_get_synchronized_wrapper (m); + + addr = compiled_method = mono_compile_method_checked (m, &error); + mono_error_raise_exception (&error); g_assert (addr); addr = mini_add_method_wrappers_llvmonly (m, addr, FALSE, need_unbox_tramp, &arg); @@ -1621,11 +1785,14 @@ mono_resolve_generic_virtual_iface_call (MonoVTable *vt, int imt_slot, MonoMetho gpointer mono_init_vtable_slot (MonoVTable *vtable, int slot) { + MonoError error; gpointer arg = NULL; gpointer addr; gpointer *ftnptr; - addr = resolve_vcall (vtable, slot, NULL, &arg, FALSE); + addr = resolve_vcall (vtable, slot, NULL, &arg, FALSE, &error); + if (mono_error_set_pending_exception (&error)) + return NULL; ftnptr = mono_domain_alloc0 (vtable->domain, 2 * sizeof (gpointer)); ftnptr [0] = addr; ftnptr [1] = arg; @@ -1645,6 +1812,7 @@ mono_init_vtable_slot (MonoVTable *vtable, int slot) void mono_llvmonly_init_delegate (MonoDelegate *del) { + MonoError error; MonoFtnDesc *ftndesc = *(MonoFtnDesc**)del->method_code; /* @@ -1653,7 +1821,17 @@ mono_llvmonly_init_delegate (MonoDelegate *del) * but we don't have a a structure which could own its memory. */ if (G_UNLIKELY (!ftndesc)) { - gpointer addr = mono_compile_method (del->method); + MonoMethod *m = del->method; + if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) + m = mono_marshal_get_synchronized_wrapper (m); + + gpointer addr = mono_compile_method_checked (m, &error); + if (mono_error_set_pending_exception (&error)) + return; + + if (m->klass->valuetype && mono_method_signature (m)->hasthis) + addr = mono_aot_get_unbox_trampoline (m); + gpointer arg = mini_get_delegate_arg (del->method, addr); ftndesc = mini_create_llvmonly_ftndesc (mono_domain_get (), addr, arg); @@ -1667,25 +1845,43 @@ mono_llvmonly_init_delegate (MonoDelegate *del) void mono_llvmonly_init_delegate_virtual (MonoDelegate *del, MonoObject *target, MonoMethod *method) { + MonoError error; + g_assert (target); method = mono_object_get_virtual_method (target, method); + if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) + method = mono_marshal_get_synchronized_wrapper (method); + del->method = method; - del->method_ptr = mono_compile_method (method); + del->method_ptr = mono_compile_method_checked (method, &error); + if (mono_error_set_pending_exception (&error)) + return; + if (method->klass->valuetype) + del->method_ptr = mono_aot_get_unbox_trampoline (method); del->extra_arg = mini_get_delegate_arg (del->method, del->method_ptr); } MonoObject* mono_get_assembly_object (MonoImage *image) { - return (MonoObject*)mono_assembly_get_object (mono_domain_get (), image->assembly); + MonoError error; + MonoObject *result; + result = (MonoObject*)mono_assembly_get_object_checked (mono_domain_get (), image->assembly, &error); + if (!result) + mono_error_set_pending_exception (&error); + return result; } MonoObject* mono_get_method_object (MonoMethod *method) { - return (MonoObject*)mono_method_get_object (mono_domain_get (), method, method->klass); + MonoError error; + MonoObject * result; + result = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), method, method->klass, &error); + mono_error_set_pending_exception (&error); + return result; } double @@ -1696,24 +1892,40 @@ mono_ckfinite (double d) return d; } +/* + * mono_interruption_checkpoint_from_trampoline: + * + * Check whenever the thread has a pending exception, and throw it + * if needed. + * Architectures should move away from calling this function and + * instead call mono_thread_force_interruption_checkpoint_noraise (), + * rewrind to the parent frame, and throw the exception normally. + */ void -mono_llvmonly_set_calling_assembly (MonoImage *image) +mono_interruption_checkpoint_from_trampoline (void) { - MonoJitTlsData *jit_tls = NULL; + MonoException *ex; - jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id); - g_assert (jit_tls); - jit_tls->calling_image = image; + ex = mono_thread_force_interruption_checkpoint_noraise (); + if (ex) + mono_raise_exception (ex); } -MonoObject* -mono_llvmonly_get_calling_assembly (void) +void +mono_throw_method_access (MonoMethod *callee, MonoMethod *caller) { - MonoJitTlsData *jit_tls = NULL; + char *callee_name = mono_method_full_name (callee, 1); + char *caller_name = mono_method_full_name (caller, 1); + MonoError error; - jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id); - g_assert (jit_tls); - if (!jit_tls->calling_image) - mono_raise_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform.")); - return (MonoObject*)mono_assembly_get_object (mono_domain_get (), jit_tls->calling_image->assembly); + mono_error_init (&error); + mono_error_set_generic_error (&error, "System", "MethodAccessException", "Method `%s' is inaccessible from method `%s'\n", callee_name, caller_name); + mono_error_set_pending_exception (&error); + g_free (callee_name); + g_free (caller_name); +} + +void +mono_dummy_jit_icall (void) +{ }