X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fjit-icalls.c;h=765d3096a1cd2707f02b2d45e89bb1b2a75f8943;hb=5c11fe647563fa051f73d3571da839dfccd26f8e;hp=39abeb285497461e407cb5f3f1bfb3dd0fa96d7b;hpb=4ae209510f6d1f6cd86ea936fae1c748ce83caf2;p=mono.git diff --git a/mono/mini/jit-icalls.c b/mono/mini/jit-icalls.c index 39abeb28549..765d3096a1c 100644 --- a/mono/mini/jit-icalls.c +++ b/mono/mini/jit-icalls.c @@ -19,6 +19,7 @@ #include "jit-icalls.h" #include +#include #include #include @@ -71,10 +72,10 @@ ldvirtfn_internal (MonoObject *obj, MonoMethod *method, gboolean gshared) if (gshared && method->is_inflated && mono_method_get_context (method)->method_inst) { MonoGenericContext context = { NULL, NULL }; - if (res->klass->generic_class) - context.class_inst = res->klass->generic_class->context.class_inst; - else if (res->klass->generic_container) - context.class_inst = res->klass->generic_container->context.class_inst; + if (mono_class_is_ginst (res->klass)) + context.class_inst = mono_class_get_generic_class (res->klass)->context.class_inst; + else if (mono_class_is_gtd (res->klass)) + context.class_inst = mono_class_get_generic_container (res->klass)->context.class_inst; context.method_inst = mono_method_get_context (method)->method_inst; res = mono_class_inflate_generic_method_checked (res, &context, &error); @@ -1107,8 +1108,8 @@ mono_helper_compile_generic_method (MonoObject *obj, MonoMethod *method, gpointe return NULL; } vmethod = mono_object_get_virtual_method (obj, method); - g_assert (!vmethod->klass->generic_container); - g_assert (!vmethod->klass->generic_class || !vmethod->klass->generic_class->context.class_inst->is_open); + g_assert (!mono_class_is_gtd (vmethod->klass)); + g_assert (!mono_class_is_ginst (vmethod->klass) || !mono_class_get_generic_class (vmethod->klass)->context.class_inst->is_open); g_assert (!context->method_inst || !context->method_inst->is_open); addr = mono_compile_method_checked (vmethod, &error); @@ -1189,13 +1190,21 @@ 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* @@ -1206,7 +1215,7 @@ mono_object_castclass_unbox (MonoObject *obj, MonoClass *klass) MonoClass *oklass; if (mini_get_debug_options ()->better_cast_details) { - jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id); + jit_tls = (MonoJitTlsData *)mono_tls_get_jit_tls (); jit_tls->class_cast_from = NULL; } @@ -1240,7 +1249,7 @@ mono_object_castclass_with_cache (MonoObject *obj, MonoClass *klass, gpointer *c gpointer cached_vtable, obj_vtable; if (mini_get_debug_options ()->better_cast_details) { - jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id); + jit_tls = (MonoJitTlsData *)mono_tls_get_jit_tls (); jit_tls->class_cast_from = NULL; } @@ -1323,9 +1332,9 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k MonoMethod *m; int vt_slot, iface_offset; - mono_error_init (error); + error_init (error); - if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) { + if (mono_class_is_interface (klass)) { MonoObject *this_obj; /* Have to use the receiver's type instead of klass, the receiver is a ref type */ @@ -1343,7 +1352,7 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k mono_class_setup_vtable (klass); g_assert (klass->vtable); vt_slot = mono_method_get_vtable_slot (cmethod); - if (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) { + if (mono_class_is_interface (cmethod->klass)) { iface_offset = mono_class_interface_offset (klass, cmethod->klass); g_assert (iface_offset != -1); vt_slot += iface_offset; @@ -1487,15 +1496,15 @@ 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) { - MonoError error; MonoVTable *vt; gpointer *imt, *vtable_slot; MonoMethod *impl_method, *generic_virtual = NULL, *variant_iface = NULL; gpointer addr, compiled_method, aot_addr; gboolean need_rgctx_tramp = FALSE, need_unbox_tramp = FALSE; + error_init (error); if (!this_obj) /* The caller will handle it */ return NULL; @@ -1503,11 +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_checked (impl_method, &error); - mono_error_assert_ok (&error); + 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) @@ -1537,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 @@ -1566,18 +1582,18 @@ 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) { - MonoError error; MonoMethod *m, *generic_virtual = NULL; gpointer addr, compiled_method; gboolean need_unbox_tramp = FALSE; + 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, &error); - mono_error_raise_exception (&error); // FIXME: Don't raise here + 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); @@ -1592,18 +1608,18 @@ resolve_vcall (MonoVTable *vt, int slot, MonoMethod *imt_method, gpointer *out_a else declaring = m; - if (m->klass->generic_class) - context.class_inst = m->klass->generic_class->context.class_inst; + if (mono_class_is_ginst (m->klass)) + context.class_inst = mono_class_get_generic_class (m->klass)->context.class_inst; else - g_assert (!m->klass->generic_container); + g_assert (!mono_class_is_gtd (m->klass)); generic_virtual = imt_method; g_assert (generic_virtual); 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); - mono_error_assert_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) { @@ -1614,9 +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_checked (m, &error); - mono_error_assert_ok (&error); + 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); @@ -1638,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; } /* @@ -1667,10 +1692,10 @@ mono_resolve_generic_virtual_call (MonoVTable *vt, int slot, MonoMethod *generic else declaring = m; - if (m->klass->generic_class) - context.class_inst = m->klass->generic_class->context.class_inst; + if (mono_class_is_ginst (m->klass)) + context.class_inst = mono_class_get_generic_class (m->klass)->context.class_inst; else - g_assert (!m->klass->generic_container); + g_assert (!mono_class_is_gtd (m->klass)); g_assert (generic_virtual->is_inflated); context.method_inst = ((MonoMethodInflated*)generic_virtual)->context.method_inst; @@ -1690,7 +1715,7 @@ mono_resolve_generic_virtual_call (MonoVTable *vt, int slot, MonoMethod *generic /* * This wastes memory but the memory usage is bounded since - * mono_method_add_generic_virtual_invocation () eventually builds an imt thunk for + * mono_method_add_generic_virtual_invocation () eventually builds an imt trampoline for * this vtable slot so we are not called any more for this instantiation. */ MonoFtnDesc *ftndesc = mini_create_llvmonly_ftndesc (mono_domain_get (), addr, arg); @@ -1720,21 +1745,27 @@ 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 + 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_assert_ok (&error); + mono_error_raise_exception (&error); g_assert (addr); addr = mini_add_method_wrappers_llvmonly (m, addr, FALSE, need_unbox_tramp, &arg); /* * This wastes memory but the memory usage is bounded since - * mono_method_add_generic_virtual_invocation () eventually builds an imt thunk for + * mono_method_add_generic_virtual_invocation () eventually builds an imt trampoline for * this vtable slot so we are not called any more for this instantiation. */ MonoFtnDesc *ftndesc = mini_create_llvmonly_ftndesc (mono_domain_get (), addr, arg); @@ -1754,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; @@ -1787,12 +1821,16 @@ 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_checked (del->method, &error); + 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 (del->method->klass->valuetype && mono_method_signature (del->method)->hasthis) - addr = mono_aot_get_unbox_trampoline (del->method); + 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); @@ -1813,6 +1851,9 @@ mono_llvmonly_init_delegate_virtual (MonoDelegate *del, MonoObject *target, Mono 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_checked (method, &error); if (mono_error_set_pending_exception (&error)) @@ -1825,12 +1866,9 @@ mono_llvmonly_init_delegate_virtual (MonoDelegate *del, MonoObject *target, Mono MonoObject* mono_get_assembly_object (MonoImage *image) { - 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; + ICALL_ENTRY(); + MonoObjectHandle result = MONO_HANDLE_CAST (MonoObject, mono_assembly_get_object_handle (mono_domain_get (), image->assembly, &error)); + ICALL_RETURN_OBJ (result); } MonoObject* @@ -1877,9 +1915,14 @@ mono_throw_method_access (MonoMethod *callee, MonoMethod *caller) char *caller_name = mono_method_full_name (caller, 1); MonoError error; - mono_error_init (&error); + 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) +{ +}