* 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;