}
gpointer
-mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot)
+mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot, MonoError *error)
{
- MonoError error;
int i;
MonoClass *klass = vtable->klass;
MonoAotModule *amodule = (MonoAotModule *)klass->image->aot_module;
MethodRef ref;
gboolean res;
+ mono_error_init (error);
+
if (MONO_CLASS_IS_INTERFACE (klass) || klass->rank || !amodule)
return NULL;
return NULL;
for (i = 0; i < slot; ++i) {
- decode_method_ref (amodule, &ref, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ decode_method_ref (amodule, &ref, p, &p, error);
+ mono_error_cleanup (error); /* FIXME don't swallow the error */
}
- res = decode_method_ref (amodule, &ref, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ res = decode_method_ref (amodule, &ref, p, &p, error);
+ mono_error_cleanup (error); /* FIXME don't swallow the error */
if (!res)
return NULL;
if (ref.no_aot_trampoline)
if (mono_metadata_token_index (ref.token) == 0 || mono_metadata_token_table (ref.token) != MONO_TABLE_METHOD)
return NULL;
- return mono_aot_get_method_from_token (domain, ref.image, ref.token);
+ return mono_aot_get_method_from_token (domain, ref.image, ref.token, error);
}
gboolean
return FALSE;
}
-void
-mono_aot_init_llvm_method (gpointer aot_module, guint32 method_index)
+static void
+init_llvmonly_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass *init_class, MonoGenericContext *context)
{
- MonoAotModule *amodule = (MonoAotModule *)aot_module;
gboolean res;
MonoError error;
- res = init_method (amodule, method_index, NULL, NULL, NULL, &error);
- // FIXME: Pass the exception up to the caller ?
+ res = init_method (amodule, method_index, method, init_class, context, &error);
/* Its okay to raise in llvmonly mode */
- mono_error_raise_exception (&error);
+ if (!is_ok (&error)) {
+ MonoException *ex = mono_error_convert_to_exception (&error);
+ if (ex)
+ mono_llvm_throw_exception ((MonoObject*)ex);
+ }
+}
+
+void
+mono_aot_init_llvm_method (gpointer aot_module, guint32 method_index)
+{
+ MonoAotModule *amodule = (MonoAotModule *)aot_module;
+
+ init_llvmonly_method (amodule, method_index, NULL, NULL, NULL);
}
void
mono_aot_init_gshared_method_this (gpointer aot_module, guint32 method_index, MonoObject *this_obj)
{
MonoAotModule *amodule = (MonoAotModule *)aot_module;
- gboolean res;
MonoClass *klass;
MonoGenericContext *context;
MonoMethod *method;
- MonoError error;
// FIXME:
g_assert (this_obj);
context = mono_method_get_context (method);
g_assert (context);
- res = init_method (amodule, method_index, NULL, klass, context, &error);
- /* Its okay to raise in llvmonly mode */
- mono_error_raise_exception (&error);
+ init_llvmonly_method (amodule, method_index, NULL, klass, context);
}
void
mono_aot_init_gshared_method_mrgctx (gpointer aot_module, guint32 method_index, MonoMethodRuntimeGenericContext *rgctx)
{
MonoAotModule *amodule = (MonoAotModule *)aot_module;
- gboolean res;
MonoGenericContext context = { NULL, NULL };
MonoClass *klass = rgctx->class_vtable->klass;
- MonoError error;
if (klass->generic_class)
context.class_inst = klass->generic_class->context.class_inst;
context.class_inst = klass->generic_container->context.class_inst;
context.method_inst = rgctx->method_inst;
- res = init_method (amodule, method_index, NULL, rgctx->class_vtable->klass, &context, &error);
- /* Its okay to raise in llvmonly mode */
- mono_error_raise_exception (&error);
+ init_llvmonly_method (amodule, method_index, NULL, rgctx->class_vtable->klass, &context);
}
void
mono_aot_init_gshared_method_vtable (gpointer aot_module, guint32 method_index, MonoVTable *vtable)
{
MonoAotModule *amodule = (MonoAotModule *)aot_module;
- gboolean res;
MonoClass *klass;
MonoGenericContext *context;
MonoMethod *method;
- MonoError error;
klass = vtable->klass;
context = mono_method_get_context (method);
g_assert (context);
- res = init_method (amodule, method_index, NULL, klass, context, &error);
- /* Its okay to raise in llvmonly mode */
- mono_error_raise_exception (&error);
+ init_llvmonly_method (amodule, method_index, NULL, klass, context);
}
/*
* remoting.
*/
if (mono_aot_only && method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK)
- return mono_aot_get_method (domain, mono_marshal_method_from_wrapper (method));
+ return mono_aot_get_method_checked (domain, mono_marshal_method_from_wrapper (method), error);
g_assert (klass->inited);
if (method_index == 0xffffff && method->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED && method->klass->rank && strstr (method->name, "System.Collections.Generic")) {
MonoMethod *m = mono_aot_get_array_helper_from_wrapper (method);
- code = (guint8 *)mono_aot_get_method (domain, m);
+ code = (guint8 *)mono_aot_get_method_checked (domain, m, error);
if (code)
return code;
+ if (!is_ok (error))
+ return NULL;
}
/*
* an out parameter, so the managed-to-native wrappers can share the same code.
*/
if (method_index == 0xffffff && method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE && method->klass == mono_defaults.array_class && !strcmp (method->name, "GetGenericValueImpl")) {
- MonoError error;
MonoMethod *m;
MonoGenericContext ctx;
MonoType *args [16];
args [0] = &mono_defaults.object_class->byval_arg;
ctx.method_inst = mono_metadata_get_generic_inst (1, args);
- m = mono_marshal_get_native_wrapper (mono_class_inflate_generic_method_checked (m, &ctx, &error), TRUE, TRUE);
+ m = mono_marshal_get_native_wrapper (mono_class_inflate_generic_method_checked (m, &ctx, error), TRUE, TRUE);
if (!m)
- g_error ("AOT runtime could not load method due to %s", mono_error_get_message (&error)); /* FIXME don't swallow the error */
+ g_error ("AOT runtime could not load method due to %s", mono_error_get_message (error)); /* FIXME don't swallow the error */
/*
* Get the code for the <object> instantiation which should be emitted into
* the mscorlib aot image by the AOT compiler.
*/
- code = (guint8 *)mono_aot_get_method (domain, m);
+ code = (guint8 *)mono_aot_get_method_checked (domain, m, error);
if (code)
return code;
+ if (!is_ok (error))
+ return NULL;
}
/* Same for CompareExchange<T> and Exchange<T> */
((!strcmp (method->klass->name_space, "System.Threading") && !strcmp (method->klass->name, "Interlocked") && (!strcmp (method->name, "CompareExchange") || !strcmp (method->name, "Exchange")) && MONO_TYPE_IS_REFERENCE (mini_type_get_underlying_type (mono_method_signature (method)->params [1]))) ||
(!strcmp (method->klass->name_space, "System.Threading") && !strcmp (method->klass->name, "Volatile") && (!strcmp (method->name, "Read") && MONO_TYPE_IS_REFERENCE (mini_type_get_underlying_type (mono_method_signature (method)->ret)))) ||
(!strcmp (method->klass->name_space, "System.Threading") && !strcmp (method->klass->name, "Volatile") && (!strcmp (method->name, "Write") && MONO_TYPE_IS_REFERENCE (mini_type_get_underlying_type (mono_method_signature (method)->params [1])))))) {
- MonoError error;
MonoMethod *m;
MonoGenericContext ctx;
MonoType *args [16];
args [0] = &mono_defaults.object_class->byval_arg;
ctx.method_inst = mono_metadata_get_generic_inst (1, args);
- m = mono_marshal_get_native_wrapper (mono_class_inflate_generic_method_checked (m, &ctx, &error), TRUE, TRUE);
+ m = mono_marshal_get_native_wrapper (mono_class_inflate_generic_method_checked (m, &ctx, error), TRUE, TRUE);
if (!m)
- g_error ("AOT runtime could not load method due to %s", mono_error_get_message (&error)); /* FIXME don't swallow the error */
+ g_error ("AOT runtime could not load method due to %s", mono_error_get_message (error)); /* FIXME don't swallow the error */
/* Avoid recursion */
if (method == m)
* Get the code for the <object> instantiation which should be emitted into
* the mscorlib aot image by the AOT compiler.
*/
- code = (guint8 *)mono_aot_get_method (domain, m);
+ code = (guint8 *)mono_aot_get_method_checked (domain, m, error);
if (code)
return code;
+ if (!is_ok (error))
+ return NULL;
}
/* For ARRAY_ACCESSOR wrappers with reference types, use the <object> instantiation saved in corlib */
m = mono_marshal_get_array_accessor_wrapper (m);
if (m != method) {
- code = (guint8 *)mono_aot_get_method (domain, m);
+ code = (guint8 *)mono_aot_get_method_checked (domain, m, error);
if (code)
return code;
+ if (!is_ok (error))
+ return NULL;
}
}
}
MonoError error;
gpointer res = mono_aot_get_method_checked (domain, method, &error);
+ /* This is a public api function so it can raise exceptions */
mono_error_raise_exception (&error);
return res;
}
* method.
*/
gpointer
-mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 token)
+mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 token, MonoError *error)
{
MonoAotModule *aot_module = (MonoAotModule *)image->aot_module;
int method_index;
- MonoError error;
gpointer res;
+ mono_error_init (error);
+
if (!aot_module)
return NULL;
method_index = mono_metadata_token_index (token) - 1;
- res = load_method (domain, aot_module, image, NULL, token, method_index, &error);
- mono_error_raise_exception (&error); /* FIXME: Don't raise here */
+ res = load_method (domain, aot_module, image, NULL, token, method_index, error);
return res;
}
return NULL;
}
+gpointer
+mono_aot_get_method_checked (MonoDomain *domain, MonoMethod *method, MonoError *error)
+{
+ return NULL;
+}
+
gboolean
mono_aot_is_got_entry (guint8 *code, guint8 *addr)
{
}
gpointer
-mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 token)
+mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 token, MonoError *error)
{
return NULL;
}
}
gpointer
-mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot)
+mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot, MonoError *error)
{
return NULL;
}
impl = mono_class_inflate_generic_method_checked (impl, &context, &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the 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));
- else
+ 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);
+ g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ } else {
aot_addr = NULL;
+ }
if (aot_addr)
impl = NULL;
else
vtable_slot = &(vt->vtable [slot]);
/* 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);
+ if (!is_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
if (addr && !vt->klass->valuetype) {
if (mono_domain_owns_vtable_slot (mono_domain_get (), vtable_slot))
*vtable_slot = addr;
MonoMethod *method = NULL;
gpointer addr;
guint8 *plt_entry;
+ MonoError error;
trampoline_calls ++;
token_info += sizeof (gpointer);
token = *(guint32*)(gpointer)token_info;
- addr = mono_aot_get_method_from_token (mono_domain_get (), image, token);
+ addr = mono_aot_get_method_from_token (mono_domain_get (), image, token, &error);
if (!addr) {
- MonoError error;
+ if (!is_ok (&error))
+ g_error ("Could not load AOT method due to %s", mono_error_get_message (&error));
method = mono_get_method_checked (image, token, NULL, NULL, &error);
if (!method)
- g_error ("Could not load AOT trampoline due to %s", mono_error_get_message (&error));
+ g_error ("Could not load AOT method due to %s", mono_error_get_message (&error));
/* Use the generic code */
return mono_magic_trampoline (regs, code, method, tramp);