#include "jit-icalls.h"
#include <mono/utils/mono-error-internals.h>
+#include <mono/metadata/exception-internals.h>
#include <mono/metadata/threads-types.h>
#include <mono/metadata/reflection-internals.h>
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);
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);
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*
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;
}
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;
}
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 */
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;
* 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;
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)
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
* 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);
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) {
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);
{
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;
}
/*
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;
/*
* 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);
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);
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;
* 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);
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))
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*
if (ex)
mono_raise_exception (ex);
}
+
+void
+mono_throw_method_access (MonoMethod *callee, MonoMethod *caller)
+{
+ char *callee_name = mono_method_full_name (callee, 1);
+ char *caller_name = mono_method_full_name (caller, 1);
+ MonoError 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)
+{
+}