* 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;
+ mono_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;
+ 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, &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);
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) {
}
// 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;
}
/*
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;
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;
* Either IMPL_METHOD or OUT_AOT_ADDR will be set on return.
*/
gpointer*
-mini_resolve_imt_method (MonoVTable *vt, gpointer *vtable_slot, MonoMethod *imt_method, MonoMethod **impl_method, gpointer *out_aot_addr, gboolean *out_need_rgctx_tramp, MonoMethod **variant_iface)
+mini_resolve_imt_method (MonoVTable *vt, gpointer *vtable_slot, MonoMethod *imt_method, MonoMethod **impl_method, gpointer *out_aot_addr, gboolean *out_need_rgctx_tramp, MonoMethod **variant_iface, MonoError *error)
{
MonoMethod *impl = NULL, *generic_virtual = NULL;
gboolean lookup_aot, variance_used = FALSE, need_rgctx_tramp = FALSE;
g_assert (imt_slot < MONO_IMT_SIZE);
+ mono_error_init (error);
/* This has to be variance aware since imt_method can be from an interface that vt->klass doesn't directly implement */
interface_offset = mono_class_interface_offset_with_variance (vt->klass, imt_method->klass, &variance_used);
if (interface_offset < 0)
mono_vtable_build_imt_slot (vt, mono_method_get_imt_slot (imt_method));
if (imt_method->is_inflated && ((MonoMethodInflated*)imt_method)->context.method_inst) {
- MonoError error;
MonoGenericContext context = { NULL, NULL };
/*
if (impl->klass->generic_class)
context.class_inst = impl->klass->generic_class->context.class_inst;
context.method_inst = ((MonoMethodInflated*)imt_method)->context.method_inst;
- impl = mono_class_inflate_generic_method_checked (impl, &context, &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ impl = mono_class_inflate_generic_method_checked (impl, &context, error);
+ mono_error_assert_ok (error);
} else {
- MonoError error;
/* Avoid loading metadata or creating a generic vtable if possible */
if (lookup_aot && !vt->klass->valuetype) {
- aot_addr = (guint8 *)mono_aot_get_method_from_vt_slot (mono_domain_get (), vt, interface_offset + mono_method_get_vtable_slot (imt_method), &error);
- mono_error_raise_exception (&error); // FIXME: Don't raise here
+ aot_addr = (guint8 *)mono_aot_get_method_from_vt_slot (mono_domain_get (), vt, interface_offset + mono_method_get_vtable_slot (imt_method), error);
+ return_val_if_nok (error, NULL);
} else {
aot_addr = NULL;
}
need_rgctx_tramp = TRUE;
}
- vtable_slot = mini_resolve_imt_method (vt, vtable_slot, imt_method, &impl_method, &addr, &need_rgctx_tramp, &variant_iface);
+ vtable_slot = mini_resolve_imt_method (vt, vtable_slot, imt_method, &impl_method, &addr, &need_rgctx_tramp, &variant_iface, error);
+ return_val_if_nok (error, NULL);
+
/* This is the vcall slot which gets called through the IMT thunk */
vtable_slot_to_patch = vtable_slot;
* return TRUE for methods used in IMT calls too.
*/
if (virtual_ && is_generic_method_definition (m)) {
- MonoError error;
MonoGenericContext context = { NULL, NULL };
MonoMethod *declaring;
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: only do this if the method is sharable */
need_rgctx_tramp = TRUE;
} else if ((context_used = mono_method_check_context_used (m))) {
}
if (method_inst || m->wrapper_type) {
- MonoError error;
MonoGenericContext context = { NULL, NULL };
if (m->is_inflated)
context.class_inst = klass->generic_container->context.class_inst;
context.method_inst = method_inst;
- actual_method = mono_class_inflate_generic_method_checked (declaring, &context, &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ actual_method = mono_class_inflate_generic_method_checked (declaring, &context, error);
+ mono_error_assert_ok (error);
} else {
actual_method = mono_class_get_method_generic (klass, m);
}