compute_llvm_code_range (MonoAotModule *amodule, guint8 **code_start, guint8 **code_end);
static gboolean
-init_llvm_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass *init_class, MonoGenericContext *context, MonoError *error);
+init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass *init_class, MonoGenericContext *context, MonoError *error);
static MonoJumpInfo*
decode_patches (MonoAotModule *amodule, MonoMemPool *mp, int n_patches, gboolean llvm, guint32 *got_offsets);
* load_image:
*
* Load one of the images referenced by AMODULE. Returns NULL if the image is not
- * found, and sets the loader error if SET_ERROR is TRUE.
+ * found, and sets @error for what happened
*/
static MonoImage *
-load_image (MonoAotModule *amodule, int index, gboolean set_error)
+load_image (MonoAotModule *amodule, int index, MonoError *error)
{
MonoAssembly *assembly;
MonoImageOpenStatus status;
g_assert (index < amodule->image_table_len);
+ mono_error_init (error);
+
if (amodule->image_table [index])
return amodule->image_table [index];
- if (amodule->out_of_date)
+ if (amodule->out_of_date) {
+ mono_error_set_bad_image_name (error, amodule->aot_name, "Image out of date");
return NULL;
+ }
assembly = mono_assembly_load (&amodule->image_names [index], amodule->assembly->basedir, &status);
if (!assembly) {
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: module %s is unusable because dependency %s is not found.\n", amodule->aot_name, amodule->image_names [index].name);
+ mono_error_set_bad_image_name (error, amodule->aot_name, "module is unusable because dependency %s is not found (error %d).\n", amodule->image_names [index].name, status);
amodule->out_of_date = TRUE;
-
- if (set_error) {
- char *full_name = mono_stringify_assembly_name (&amodule->image_names [index]);
- mono_loader_set_error_assembly_load (full_name, FALSE);
- g_free (full_name);
- }
return NULL;
}
if (strcmp (assembly->image->guid, amodule->image_guids [index])) {
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: module %s is unusable (GUID of dependent assembly %s doesn't match (expected '%s', got '%s').\n", amodule->aot_name, amodule->image_names [index].name, amodule->image_guids [index], assembly->image->guid);
+ mono_error_set_bad_image_name (error, amodule->aot_name, "module is unusable (GUID of dependent assembly %s doesn't match (expected '%s', got '%s').\n", amodule->image_names [index].name, amodule->image_guids [index], assembly->image->guid);
amodule->out_of_date = TRUE;
return NULL;
}
}
static MonoMethod*
-decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf);
+decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error);
static MonoClass*
-decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf);
+decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error);
static MonoType*
-decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf);
+decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error);
static MonoGenericInst*
-decode_generic_inst (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
+decode_generic_inst (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error)
{
int type_argc, i;
MonoType **type_argv;
MonoGenericInst *inst;
guint8 *p = buf;
+ mono_error_init (error);
type_argc = decode_value (p, &p);
type_argv = g_new0 (MonoType*, type_argc);
for (i = 0; i < type_argc; ++i) {
- MonoClass *pclass = decode_klass_ref (module, p, &p);
+ MonoClass *pclass = decode_klass_ref (module, p, &p, error);
if (!pclass) {
g_free (type_argv);
return NULL;
}
static gboolean
-decode_generic_context (MonoAotModule *module, MonoGenericContext *ctx, guint8 *buf, guint8 **endbuf)
+decode_generic_context (MonoAotModule *module, MonoGenericContext *ctx, guint8 *buf, guint8 **endbuf, MonoError *error)
{
guint8 *p = buf;
guint8 *p2;
int argc;
+ mono_error_init (error);
p2 = p;
argc = decode_value (p, &p);
if (argc) {
p = p2;
- ctx->class_inst = decode_generic_inst (module, p, &p);
+ ctx->class_inst = decode_generic_inst (module, p, &p, error);
if (!ctx->class_inst)
return FALSE;
}
argc = decode_value (p, &p);
if (argc) {
p = p2;
- ctx->method_inst = decode_generic_inst (module, p, &p);
+ ctx->method_inst = decode_generic_inst (module, p, &p, error);
if (!ctx->method_inst)
return FALSE;
}
}
static MonoClass*
-decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
+decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error)
{
- MonoError error;
MonoImage *image;
MonoClass *klass = NULL, *eklass;
guint32 token, rank, idx;
guint8 *p = buf;
int reftype;
+ mono_error_init (error);
reftype = decode_value (p, &p);
if (reftype == 0) {
*endbuf = p;
+ mono_error_set_bad_image_name (error, module->aot_name, "Decoding a null class ref");
return NULL;
}
switch (reftype) {
case MONO_AOT_TYPEREF_TYPEDEF_INDEX:
idx = decode_value (p, &p);
- image = load_image (module, 0, TRUE);
+ image = load_image (module, 0, error);
if (!image)
return NULL;
- klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, &error);
- g_assert (mono_error_ok (&error));
+ klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, error);
break;
case MONO_AOT_TYPEREF_TYPEDEF_INDEX_IMAGE:
idx = decode_value (p, &p);
- image = load_image (module, decode_value (p, &p), TRUE);
+ image = load_image (module, decode_value (p, &p), error);
if (!image)
return NULL;
- klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, &error);
- g_assert (mono_error_ok (&error));
+ klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, error);
break;
case MONO_AOT_TYPEREF_TYPESPEC_TOKEN:
token = decode_value (p, &p);
image = module->assembly->image;
- if (!image)
+ if (!image) {
+ mono_error_set_bad_image_name (error, module->aot_name, "No image associated with the aot module");
return NULL;
- klass = mono_class_get_checked (image, token, &error);
- g_assert (mono_error_ok (&error));
+ }
+ klass = mono_class_get_checked (image, token, error);
break;
case MONO_AOT_TYPEREF_GINST: {
- MonoError error;
MonoClass *gclass;
MonoGenericContext ctx;
MonoType *type;
- gclass = decode_klass_ref (module, p, &p);
+ gclass = decode_klass_ref (module, p, &p, error);
if (!gclass)
return NULL;
g_assert (gclass->generic_container);
memset (&ctx, 0, sizeof (ctx));
- ctx.class_inst = decode_generic_inst (module, p, &p);
+ ctx.class_inst = decode_generic_inst (module, p, &p, error);
if (!ctx.class_inst)
return NULL;
- type = mono_class_inflate_generic_type_checked (&gclass->byval_arg, &ctx, &error);
- mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ type = mono_class_inflate_generic_type_checked (&gclass->byval_arg, &ctx, error);
+ if (!type)
+ return NULL;
klass = mono_class_from_mono_type (type);
mono_metadata_free_type (type);
break;
MonoClass *par_klass;
MonoType *gshared_constraint;
- gshared_constraint = decode_type (module, p, &p);
+ gshared_constraint = decode_type (module, p, &p, error);
if (!gshared_constraint)
return NULL;
- par_klass = decode_klass_ref (module, p, &p);
+ par_klass = decode_klass_ref (module, p, &p, error);
if (!par_klass)
return NULL;
if (is_method) {
MonoMethod *method_def;
g_assert (type == MONO_TYPE_MVAR);
- method_def = decode_resolve_method_ref (module, p, &p);
+ method_def = decode_resolve_method_ref (module, p, &p, error);
if (!method_def)
return NULL;
} else {
MonoClass *class_def;
g_assert (type == MONO_TYPE_VAR);
- class_def = decode_klass_ref (module, p, &p);
+ class_def = decode_klass_ref (module, p, &p, error);
if (!class_def)
return NULL;
case MONO_AOT_TYPEREF_ARRAY:
/* Array */
rank = decode_value (p, &p);
- eklass = decode_klass_ref (module, p, &p);
+ eklass = decode_klass_ref (module, p, &p, error);
+ if (!eklass)
+ return NULL;
klass = mono_array_class_get (eklass, rank);
break;
case MONO_AOT_TYPEREF_PTR: {
MonoType *t;
- t = decode_type (module, p, &p);
+ t = decode_type (module, p, &p, error);
if (!t)
return NULL;
klass = mono_class_from_mono_type (t);
guint8 *p2;
p2 = module->blob + offset;
- klass = decode_klass_ref (module, p2, &p2);
+ klass = decode_klass_ref (module, p2, &p2, error);
break;
}
default:
- g_assert_not_reached ();
+ mono_error_set_bad_image_name (error, module->aot_name, "Invalid klass reftype %d", reftype);
}
- g_assert (klass);
+ //g_assert (klass);
//printf ("BLA: %s\n", mono_type_full_name (&klass->byval_arg));
*endbuf = p;
return klass;
static MonoClassField*
decode_field_info (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
{
- MonoClass *klass = decode_klass_ref (module, buf, &buf);
+ MonoError error;
+ MonoClass *klass = decode_klass_ref (module, buf, &buf, &error);
guint32 token;
guint8 *p = buf;
- if (!klass)
+ if (!klass) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
return NULL;
+ }
token = MONO_TOKEN_FIELD_DEF + decode_value (p, &p);
* memory.
*/
static MonoType*
-decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
+decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error)
{
guint8 *p = buf;
MonoType *t;
t = (MonoType *)g_malloc0 (sizeof (MonoType));
+ mono_error_init (error);
while (TRUE) {
if (*p == MONO_TYPE_PINNED) {
break;
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_CLASS:
- t->data.klass = decode_klass_ref (module, p, &p);
+ t->data.klass = decode_klass_ref (module, p, &p, error);
+ if (!t->data.klass)
+ goto fail;
break;
case MONO_TYPE_SZARRAY:
- t->data.klass = decode_klass_ref (module, p, &p);
+ t->data.klass = decode_klass_ref (module, p, &p, error);
if (!t->data.klass)
- return NULL;
+ goto fail;
break;
case MONO_TYPE_PTR:
- t->data.type = decode_type (module, p, &p);
+ t->data.type = decode_type (module, p, &p, error);
+ if (!t->data.type)
+ goto fail;
break;
case MONO_TYPE_GENERICINST: {
- MonoError error;
MonoClass *gclass;
MonoGenericContext ctx;
MonoType *type;
MonoClass *klass;
- gclass = decode_klass_ref (module, p, &p);
+ gclass = decode_klass_ref (module, p, &p, error);
if (!gclass)
- return NULL;
+ goto fail;
g_assert (gclass->generic_container);
memset (&ctx, 0, sizeof (ctx));
- ctx.class_inst = decode_generic_inst (module, p, &p);
+ ctx.class_inst = decode_generic_inst (module, p, &p, error);
if (!ctx.class_inst)
- return NULL;
- type = mono_class_inflate_generic_type_checked (&gclass->byval_arg, &ctx, &error);
- mono_error_assert_ok (&error); /* FIXME don't swallow the error */
-
+ goto fail;
+ type = mono_class_inflate_generic_type_checked (&gclass->byval_arg, &ctx, error);
+ if (!type)
+ goto fail;
klass = mono_class_from_mono_type (type);
t->data.generic_class = klass->generic_class;
break;
// FIXME: memory management
array = g_new0 (MonoArrayType, 1);
- array->eklass = decode_klass_ref (module, p, &p);
+ array->eklass = decode_klass_ref (module, p, &p, error);
if (!array->eklass)
- return NULL;
+ goto fail;
array->rank = decode_value (p, &p);
array->numsizes = decode_value (p, &p);
}
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR: {
- MonoClass *klass = decode_klass_ref (module, p, &p);
+ MonoClass *klass = decode_klass_ref (module, p, &p, error);
if (!klass)
- return NULL;
+ goto fail;
t->data.generic_param = klass->byval_arg.data.generic_param;
break;
}
default:
- g_assert_not_reached ();
+ mono_error_set_bad_image_name (error, module->aot_name, "Invalid encoded type %d", t->type);
+ goto fail;
}
*endbuf = p;
return t;
+fail:
+ g_free (t);
+ return NULL;
}
// FIXME: Error handling, memory management
static MonoMethodSignature*
decode_signature_with_target (MonoAotModule *module, MonoMethodSignature *target, guint8 *buf, guint8 **endbuf)
{
+ MonoError error;
MonoMethodSignature *sig;
guint32 flags;
int i, gen_param_count = 0, param_count, call_conv;
sig->explicit_this = explicit_this;
sig->call_convention = call_conv;
sig->generic_param_count = gen_param_count;
- sig->ret = decode_type (module, p, &p);
+ sig->ret = decode_type (module, p, &p, &error);
+ if (!sig->ret)
+ goto fail;
for (i = 0; i < param_count; ++i) {
if (*p == MONO_TYPE_SENTINEL) {
g_assert (sig->call_convention == MONO_CALL_VARARG);
sig->sentinelpos = i;
p ++;
}
- sig->params [i] = decode_type (module, p, &p);
+ sig->params [i] = decode_type (module, p, &p, &error);
+ if (!sig->params [i])
+ goto fail;
}
if (sig->call_convention == MONO_CALL_VARARG && sig->sentinelpos == -1)
*endbuf = p;
return sig;
+fail:
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ g_free (sig);
+ return NULL;
}
static MonoMethodSignature*
* that the method reference matches a given method. This is normally not a problem
* as these wrappers only occur in the extra_methods table, where we already have
* a method we want to lookup.
+ *
+ * If there was a decoding error, we return FALSE and set @error
*/
static gboolean
-decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod *target, guint8 *buf, guint8 **endbuf)
+decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod *target, guint8 *buf, guint8 **endbuf, MonoError *error)
{
guint32 image_index, value;
MonoImage *image = NULL;
guint8 *p = buf;
memset (ref, 0, sizeof (MethodRef));
+ mono_error_init (error);
value = decode_value (p, &p);
image_index = value >> 24;
}
if (image_index < MONO_AOT_METHODREF_MIN || image_index == MONO_AOT_METHODREF_METHODSPEC || image_index == MONO_AOT_METHODREF_GINST) {
- if (target && target->wrapper_type)
+ if (target && target->wrapper_type) {
return FALSE;
+ }
}
if (image_index == MONO_AOT_METHODREF_WRAPPER) {
switch (wrapper_type) {
#ifndef DISABLE_REMOTING
case MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK: {
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
mono_class_init (m->klass);
break;
}
case MONO_WRAPPER_PROXY_ISINST: {
- MonoClass *klass = decode_klass_ref (module, p, &p);
+ MonoClass *klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
ref->method = mono_marshal_get_proxy_cancast (klass);
case MONO_WRAPPER_LDFLDA:
case MONO_WRAPPER_STFLD:
case MONO_WRAPPER_ISINST: {
- MonoClass *klass = decode_klass_ref (module, p, &p);
+ MonoClass *klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
if (wrapper_type == MONO_WRAPPER_LDFLD)
ref->method = mono_marshal_get_stfld_wrapper (&klass->byval_arg);
else if (wrapper_type == MONO_WRAPPER_ISINST)
ref->method = mono_marshal_get_isinst (klass);
- else
- g_assert_not_reached ();
+ else {
+ mono_error_set_bad_image_name (error, module->aot_name, "Unknown AOT wrapper type %d", wrapper_type);
+ return FALSE;
+ }
break;
}
case MONO_WRAPPER_LDFLD_REMOTE:
int atype = decode_value (p, &p);
ref->method = mono_gc_get_managed_allocator_by_type (atype, !!(mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS));
- if (!ref->method)
- g_error ("Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
+ if (!ref->method) {
+ mono_error_set_bad_image_name (error, module->aot_name, "Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
+ return FALSE;
+ }
break;
}
case MONO_WRAPPER_WRITE_BARRIER: {
return FALSE;
}
} else {
- g_assert_not_reached ();
+ mono_error_set_bad_image_name (error, module->aot_name, "Invalid STELEMREF subtype %d", subtype);
+ return FALSE;
}
break;
}
case MONO_WRAPPER_SYNCHRONIZED: {
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_synchronized_wrapper (m);
int subtype = decode_value (p, &p);
if (subtype == WRAPPER_SUBTYPE_PTR_TO_STRUCTURE || subtype == WRAPPER_SUBTYPE_STRUCTURE_TO_PTR) {
- MonoClass *klass = decode_klass_ref (module, p, &p);
-
+ MonoClass *klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
ref->method = mono_marshal_get_struct_to_ptr (klass);
}
} else if (subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER) {
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_synchronized_inner_wrapper (m);
} else if (subtype == WRAPPER_SUBTYPE_ARRAY_ACCESSOR) {
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_array_accessor_wrapper (m);
return FALSE;
ref->method = mini_get_gsharedvt_out_sig_wrapper (sig);
} else {
- g_assert_not_reached ();
+ mono_error_set_bad_image_name (error, module->aot_name, "Invalid UNKNOWN wrapper subtype %d", subtype);
+ return FALSE;
}
break;
}
} else if (subtype == WRAPPER_SUBTYPE_STRING_CTOR) {
MonoMethod *m;
- m = decode_resolve_method_ref (module, p, &p);
+ m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
return FALSE;
ref->method = target;
} else {
- m = decode_resolve_method_ref (module, p, &p);
-
+ m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_castclass_with_cache ();
else if (subtype == WRAPPER_SUBTYPE_ISINST_WITH_CACHE)
ref->method = mono_marshal_get_isinst_with_cache ();
- else
- g_assert_not_reached ();
+ else {
+ mono_error_set_bad_image_name (error, module->aot_name, "Invalid CASTCLASS wrapper subtype %d", subtype);
+ return FALSE;
+ }
break;
}
case MONO_WRAPPER_RUNTIME_INVOKE: {
ref->method = target;
} else if (subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_DIRECT) {
/* Direct wrapper */
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_runtime_invoke (m, FALSE);
} else if (subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_VIRTUAL) {
/* Virtual direct wrapper */
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_runtime_invoke (m, TRUE);
MonoClass *klass;
MonoMethod *invoke, *wrapper;
- klass = decode_klass_ref (module, p, &p);
+ klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
MonoMethod *m;
MonoClass *klass;
- m = decode_resolve_method_ref (module, p, &p);
+ m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
- klass = decode_klass_ref (module, p, &p);
+ klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
ref->method = mono_marshal_get_managed_wrapper (m, klass, 0);
image_index = decode_value (p, &p);
ref->token = decode_value (p, &p);
- image = load_image (module, image_index, TRUE);
+ image = load_image (module, image_index, error);
if (!image)
return FALSE;
} else if (image_index == MONO_AOT_METHODREF_GINST) {
- MonoError error;
MonoClass *klass;
MonoGenericContext ctx;
* These methods do not have a token which resolves them, so we
* resolve them immediately.
*/
- klass = decode_klass_ref (module, p, &p);
+ klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
image_index = decode_value (p, &p);
ref->token = decode_value (p, &p);
- image = load_image (module, image_index, TRUE);
+ image = load_image (module, image_index, error);
if (!image)
return FALSE;
- ref->method = mono_get_method_checked (image, ref->token, NULL, NULL, &error);
- if (!ref->method) {
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ ref->method = mono_get_method_checked (image, ref->token, NULL, NULL, error);
+ if (!ref->method)
return FALSE;
- }
+
memset (&ctx, 0, sizeof (ctx));
ctx.class_inst = klass->generic_class->context.class_inst;
ctx.method_inst = NULL;
- ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, &error);
+ ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, error);
if (!ref->method)
- g_error ("AOT runtime could not load method due to %s", mono_error_get_message (&error)); /* FIXME don't swallow the error */
+ return FALSE;
}
memset (&ctx, 0, sizeof (ctx));
- if (!decode_generic_context (module, &ctx, p, &p))
+ if (!decode_generic_context (module, &ctx, p, &p, error))
return FALSE;
- ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, &error);
+ ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, error);
if (!ref->method)
- g_error ("AOT runtime could not load method due to %s", mono_error_get_message (&error)); /* FIXME don't swallow the error */
+ return FALSE;
} else if (image_index == MONO_AOT_METHODREF_ARRAY) {
MonoClass *klass;
int method_type;
- klass = decode_klass_ref (module, p, &p);
+ klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
method_type = decode_value (p, &p);
ref->method = mono_class_get_method_from_name (klass, "Set", -1);
break;
default:
- g_assert_not_reached ();
+ mono_error_set_bad_image_name (error, module->aot_name, "Invalid METHODREF_ARRAY method type %d", method_type);
+ return FALSE;
}
} else {
if (image_index == MONO_AOT_METHODREF_LARGE_IMAGE_INDEX) {
ref->token = MONO_TOKEN_METHOD_DEF | (value & 0xffffff);
- image = load_image (module, image_index, TRUE);
+ image = load_image (module, image_index, error);
if (!image)
return FALSE;
}
}
static gboolean
-decode_method_ref (MonoAotModule *module, MethodRef *ref, guint8 *buf, guint8 **endbuf)
+decode_method_ref (MonoAotModule *module, MethodRef *ref, guint8 *buf, guint8 **endbuf, MonoError *error)
{
- return decode_method_ref_with_target (module, ref, NULL, buf, endbuf);
+ return decode_method_ref_with_target (module, ref, NULL, buf, endbuf, error);
}
/*
* Similar to decode_method_ref, but resolve and return the method itself.
*/
static MonoMethod*
-decode_resolve_method_ref_with_target (MonoAotModule *module, MonoMethod *target, guint8 *buf, guint8 **endbuf)
+decode_resolve_method_ref_with_target (MonoAotModule *module, MonoMethod *target, guint8 *buf, guint8 **endbuf, MonoError *error)
{
- MonoError error;
MethodRef ref;
- gboolean res;
- MonoMethod *result;
- res = decode_method_ref_with_target (module, &ref, target, buf, endbuf);
- if (!res)
+ mono_error_init (error);
+
+ if (!decode_method_ref_with_target (module, &ref, target, buf, endbuf, error))
return NULL;
if (ref.method)
return ref.method;
- if (!ref.image)
+ if (!ref.image) {
+ mono_error_set_bad_image_name (error, module->aot_name, "No image found for methodref with target");
return NULL;
- result = mono_get_method_checked (ref.image, ref.token, NULL, NULL, &error);
- if (!result)
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
- return result;
+ }
+ return mono_get_method_checked (ref.image, ref.token, NULL, NULL, error);
}
static MonoMethod*
-decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
+decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error)
{
- return decode_resolve_method_ref_with_target (module, NULL, buf, endbuf);
+ return decode_resolve_method_ref_with_target (module, NULL, buf, endbuf, error);
}
#ifdef ENABLE_AOT_CACHE
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module '%s' not found: %s\n", aot_name, err);
g_free (err);
- aot_name = g_strdup_printf ("%s/mono/aot-cache/%s/%s%s", mono_assembly_getrootdir(), MONO_ARCHITECTURE, g_path_get_basename (assembly->image->name), MONO_SOLIB_EXT);
+ g_free (aot_name);
+ char *basename = g_path_get_basename (assembly->image->name);
+ aot_name = g_strdup_printf ("%s/mono/aot-cache/%s/%s%s", mono_assembly_getrootdir(), MONO_ARCHITECTURE, basename, MONO_SOLIB_EXT);
+ g_free (basename);
sofile = mono_dl_open (aot_name, MONO_DL_LAZY, &err);
if (!sofile) {
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module '%s' not found: %s\n", aot_name, err);
}
#endif
if (do_load_image) {
- for (i = 0; i < amodule->image_table_len; ++i)
- load_image (amodule, i, FALSE);
+ for (i = 0; i < amodule->image_table_len; ++i) {
+ MonoError error;
+ load_image (amodule, i, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ }
}
if (amodule->out_of_date) {
static gboolean
decode_cached_class_info (MonoAotModule *module, MonoCachedClassInfo *info, guint8 *buf, guint8 **endbuf)
{
+ MonoError error;
guint32 flags;
MethodRef ref;
gboolean res;
info->is_generic_container = (flags >> 8) & 0x1;
if (info->has_cctor) {
- res = decode_method_ref (module, &ref, buf, &buf);
+ res = decode_method_ref (module, &ref, buf, &buf, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
if (!res)
return FALSE;
info->cctor_token = ref.token;
}
if (info->has_finalize) {
- res = decode_method_ref (module, &ref, buf, &buf);
+ res = decode_method_ref (module, &ref, buf, &buf, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
if (!res)
return FALSE;
info->finalize_image = ref.image;
gpointer
mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot)
{
+ MonoError error;
int i;
MonoClass *klass = vtable->klass;
MonoAotModule *amodule = (MonoAotModule *)klass->image->aot_module;
if (!err)
return NULL;
- for (i = 0; i < slot; ++i)
- decode_method_ref (amodule, &ref, p, &p);
+ for (i = 0; i < slot; ++i) {
+ 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);
+ 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)
MonoMethod *method, guint8* ex_info,
guint8 *code, guint32 code_len)
{
+ MonoError error;
int i, buf_len, num_clauses, len;
MonoJitInfo *jinfo;
MonoJitInfoFlags flags = JIT_INFO_NONE;
ei->flags = decode_value (p, &p);
- if (decode_value (p, &p))
- ei->data.catch_class = decode_klass_ref (amodule, p, &p);
+ if (decode_value (p, &p)) {
+ ei->data.catch_class = decode_klass_ref (amodule, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ }
ei->clause_index = i;
int len = decode_value (p, &p);
if (len > 0) {
- if (async)
+ if (async) {
p += len;
- else
- ei->data.catch_class = decode_klass_ref (amodule, p, &p);
+ } else {
+ ei->data.catch_class = decode_klass_ref (amodule, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ }
}
}
}
len = decode_value (p, &p);
- if (async)
+ if (async) {
p += len;
- else
- jinfo->d.method = decode_resolve_method_ref (amodule, p, &p);
+ } else {
+ jinfo->d.method = decode_resolve_method_ref (amodule, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ }
gi->generic_sharing_context = g_new0 (MonoGenericSharingContext, 1);
if (decode_value (p, &p)) {
MonoJitInfo *
mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
{
+ MonoError error;
int pos, left, right, code_len;
int method_index, table_len;
guint32 token;
}
p = amodule->blob + table [(pos * 2) + 1];
- method = decode_resolve_method_ref (amodule, p, &p);
+ method = decode_resolve_method_ref (amodule, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!method)
/* Happens when a random address is passed in which matches a not-yey called wrapper encoded using its name */
return NULL;
static gboolean
decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guint8 *buf, guint8 **endbuf)
{
+ MonoError error;
guint8 *p = buf;
gpointer *table;
MonoImage *image;
case MONO_PATCH_INFO_METHOD:
case MONO_PATCH_INFO_METHOD_JUMP:
case MONO_PATCH_INFO_ICALL_ADDR:
+ case MONO_PATCH_INFO_ICALL_ADDR_CALL:
case MONO_PATCH_INFO_METHOD_RGCTX:
case MONO_PATCH_INFO_METHOD_CODE_SLOT: {
MethodRef ref;
gboolean res;
- res = decode_method_ref (aot_module, &ref, p, &p);
+ res = decode_method_ref (aot_module, &ref, p, &p, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
if (!res)
goto cleanup;
}
case MONO_PATCH_INFO_METHODCONST:
/* Shared */
- ji->data.method = decode_resolve_method_ref (aot_module, p, &p);
+ ji->data.method = decode_resolve_method_ref (aot_module, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!ji->data.method)
goto cleanup;
break;
case MONO_PATCH_INFO_IID:
case MONO_PATCH_INFO_ADJUSTED_IID:
/* Shared */
- ji->data.klass = decode_klass_ref (aot_module, p, &p);
+ ji->data.klass = decode_klass_ref (aot_module, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!ji->data.klass)
goto cleanup;
break;
case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
ji->data.del_tramp = (MonoDelegateClassMethodPair *)mono_mempool_alloc0 (mp, sizeof (MonoDelegateClassMethodPair));
- ji->data.del_tramp->klass = decode_klass_ref (aot_module, p, &p);
+ ji->data.del_tramp->klass = decode_klass_ref (aot_module, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!ji->data.del_tramp->klass)
goto cleanup;
if (decode_value (p, &p)) {
- ji->data.del_tramp->method = decode_resolve_method_ref (aot_module, p, &p);
+ ji->data.del_tramp->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!ji->data.del_tramp->method)
goto cleanup;
}
ji->data.del_tramp->is_virtual = decode_value (p, &p) ? TRUE : FALSE;
break;
case MONO_PATCH_INFO_IMAGE:
- ji->data.image = load_image (aot_module, decode_value (p, &p), TRUE);
+ ji->data.image = load_image (aot_module, decode_value (p, &p), &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!ji->data.image)
goto cleanup;
break;
break;
}
case MONO_PATCH_INFO_LDSTR:
- image = load_image (aot_module, decode_value (p, &p), TRUE);
+ image = load_image (aot_module, decode_value (p, &p), &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!image)
goto cleanup;
ji->data.token = mono_jump_info_token_new (mp, image, MONO_TOKEN_STRING + decode_value (p, &p));
case MONO_PATCH_INFO_LDTOKEN:
case MONO_PATCH_INFO_TYPE_FROM_HANDLE:
/* Shared */
- image = load_image (aot_module, decode_value (p, &p), TRUE);
+ image = load_image (aot_module, decode_value (p, &p), &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!image)
goto cleanup;
ji->data.token = mono_jump_info_token_new (mp, image, decode_value (p, &p));
ji->data.token->has_context = decode_value (p, &p);
if (ji->data.token->has_context) {
- gboolean res = decode_generic_context (aot_module, &ji->data.token->context, p, &p);
+ gboolean res = decode_generic_context (aot_module, &ji->data.token->context, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!res)
goto cleanup;
}
break;
case MONO_PATCH_INFO_EXC_NAME:
- ji->data.klass = decode_klass_ref (aot_module, p, &p);
+ ji->data.klass = decode_klass_ref (aot_module, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!ji->data.klass)
goto cleanup;
ji->data.name = ji->data.klass->name;
entry = (MonoJumpInfoRgctxEntry *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfoRgctxEntry));
p2 = aot_module->blob + offset;
- entry->method = decode_resolve_method_ref (aot_module, p2, &p2);
+ entry->method = decode_resolve_method_ref (aot_module, p2, &p2, &error);
entry->in_mrgctx = ((val & 1) > 0) ? TRUE : FALSE;
entry->info_type = (MonoRgctxInfoType)((val >> 1) & 0xff);
entry->data = (MonoJumpInfo *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfo));
entry->data->type = (MonoJumpInfoType)((val >> 9) & 0xff);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
res = decode_patch (aot_module, mp, entry->data, p, &p);
if (!res)
MonoJumpInfoGSharedVtCall *info = (MonoJumpInfoGSharedVtCall *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfoGSharedVtCall));
info->sig = decode_signature (aot_module, p, &p);
g_assert (info->sig);
- info->method = decode_resolve_method_ref (aot_module, p, &p);
- g_assert (info->method);
+ info->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
ji->data.target = info;
break;
MonoGSharedVtMethodInfo *info = (MonoGSharedVtMethodInfo *)mono_mempool_alloc0 (mp, sizeof (MonoGSharedVtMethodInfo));
int i;
- info->method = decode_resolve_method_ref (aot_module, p, &p);
- g_assert (info->method);
+ info->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
info->num_entries = decode_value (p, &p);
info->count_entries = info->num_entries;
info->entries = (MonoRuntimeGenericContextInfoTemplate *)mono_mempool_alloc0 (mp, sizeof (MonoRuntimeGenericContextInfoTemplate) * info->num_entries);
template_->info_type = (MonoRgctxInfoType)decode_value (p, &p);
switch (mini_rgctx_info_type_to_patch_info_type (template_->info_type)) {
case MONO_PATCH_INFO_CLASS: {
- MonoClass *klass = decode_klass_ref (aot_module, p, &p);
+ MonoClass *klass = decode_klass_ref (aot_module, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!klass)
goto cleanup;
template_->data = &klass->byval_arg;
case MONO_PATCH_INFO_VIRT_METHOD: {
MonoJumpInfoVirtMethod *info = (MonoJumpInfoVirtMethod *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfoVirtMethod));
- info->klass = decode_klass_ref (aot_module, p, &p);
- g_assert (info->klass);
- info->method = decode_resolve_method_ref (aot_module, p, &p);
- g_assert (info->method);
+ info->klass = decode_klass_ref (aot_module, p, &p, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
+ info->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
ji->data.target = info;
break;
if (!(is_llvm_code (amodule, code) && (amodule->info.flags & MONO_AOT_FILE_FLAG_LLVM_ONLY))) {
MonoError error;
- res = init_llvm_method (amodule, method_index, method, NULL, NULL, &error);
+ res = init_method (amodule, method_index, method, NULL, NULL, &error);
if (!mono_error_ok (&error))
mono_error_raise_exception (&error); /* FIXME: Don't raise here */
if (!res)
static guint32
find_aot_method_in_amodule (MonoAotModule *amodule, MonoMethod *method, guint32 hash_full)
{
+ MonoError error;
guint32 table_size, entry_size, hash;
guint32 *table, *entry;
guint32 index;
m = (MonoMethod *)g_hash_table_lookup (amodule->method_ref_to_method, p);
amodule_unlock (amodule);
if (!m) {
- m = decode_resolve_method_ref_with_target (amodule, method, p, &p);
+ m = decode_resolve_method_ref_with_target (amodule, method, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
/*
* Can't catche runtime invoke wrappers since it would break
* the check in decode_method_ref_with_target ().
}
static gboolean
-init_llvm_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass *init_class, MonoGenericContext *context, MonoError *error)
+init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass *init_class, MonoGenericContext *context, MonoError *error)
{
MonoDomain *domain = mono_domain_get ();
MonoMemPool *mp;
- MonoClass *klass;
+ MonoClass *klass_to_run_ctor = NULL;
gboolean from_plt = method == NULL;
int pindex, n_patches;
guint8 *p;
p = info;
- if (method) {
- klass = method->klass;
- decode_klass_ref (amodule, p, &p);
- } else {
- klass = decode_klass_ref (amodule, p, &p);
- }
+ //does the method's class has a cctor?
+ if (decode_value (p, &p) == 1)
+ klass_to_run_ctor = decode_klass_ref (amodule, p, &p, error);
+ if (!is_ok (error))
+ return FALSE;
+
+ //FIXME old code would use the class from @method if not null and ignore the one encoded. I don't know if we need to honor that -- @kumpera
+ if (method)
+ klass_to_run_ctor = method->klass;
n_patches = decode_value (p, &p);
gboolean inited_ok = TRUE;
if (init_class)
inited_ok = mono_runtime_class_init_full (mono_class_vtable (domain, init_class), error);
- else if (from_plt && klass && !klass->generic_container)
- inited_ok = mono_runtime_class_init_full (mono_class_vtable (domain, klass), error);
+ else if (from_plt && klass_to_run_ctor && !klass_to_run_ctor->generic_container)
+ inited_ok = mono_runtime_class_init_full (mono_class_vtable (domain, klass_to_run_ctor), error);
if (!inited_ok)
return FALSE;
MonoError error;
// FIXME: Handle errors
- res = init_llvm_method (amodule, method_index, NULL, NULL, NULL, &error);
+ res = init_method (amodule, method_index, NULL, NULL, NULL, &error);
g_assert (res);
}
context = mono_method_get_context (method);
g_assert (context);
- res = init_llvm_method (amodule, method_index, NULL, klass, context, &error);
+ res = init_method (amodule, method_index, NULL, klass, context, &error);
g_assert (res);
}
context.class_inst = klass->generic_container->context.class_inst;
context.method_inst = rgctx->method_inst;
- res = init_llvm_method (amodule, method_index, NULL, rgctx->class_vtable->klass, &context, &error);
+ res = init_method (amodule, method_index, NULL, rgctx->class_vtable->klass, &context, &error);
g_assert (res);
}
context = mono_method_get_context (method);
g_assert (context);
- res = init_llvm_method (amodule, method_index, NULL, klass, context, &error);
+ res = init_method (amodule, method_index, NULL, klass, context, &error);
g_assert (res);
}
if (mono_llvm_only) {
/* Needed by mono_aot_init_gshared_method_this () */
- /* orig_method is a random instance but it is enough to make init_llvm_method () work */
+ /* orig_method is a random instance but it is enough to make init_method () work */
amodule_lock (amodule);
g_hash_table_insert (amodule->extra_methods, GUINT_TO_POINTER (method_index), orig_method);
amodule_unlock (amodule);