* Copyright 2004-2009 Novell, Inc (http://www.novell.com)
* Copyright 2011 Rodrigo Kumpera
*
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include <config.h>
#include "mono/utils/mono-digest.h"
static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_open_instance, MonoError *error);
static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb, MonoError *error);
-static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper);
+static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error);
-static gpointer resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context);
+static gpointer resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error);
static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error);
static guint32 encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context);
static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
static void encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
static void get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types);
static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error);
-static MonoType* mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve);
+static MonoType* mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve, MonoError *error);
static MonoReflectionType* mono_reflection_type_resolve_user_types (MonoReflectionType *type, MonoError *error);
static gboolean is_sre_array (MonoClass *klass);
static gboolean is_sre_byref (MonoClass *klass);
static gboolean is_sre_method_on_tb_inst (MonoClass *klass);
static gboolean is_sre_ctor_on_tb_inst (MonoClass *klass);
+static gboolean type_is_reference (MonoType *type);
+
static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error);
* Return a copy of TYPE, adding the custom modifiers in MODREQ and MODOPT.
*/
static MonoType*
-add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt)
+add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt, MonoError *error)
{
- MonoError error;
int i, count, len, pos;
MonoType *t;
+ mono_error_init (error);
+
count = 0;
if (modreq)
count += mono_array_length (modreq);
pos = 0;
if (modreq) {
for (i = 0; i < mono_array_length (modreq); ++i) {
- MonoType *mod = mono_type_array_get_and_resolve (modreq, i, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
+ if (!is_ok (error))
+ goto fail;
t->modifiers [pos].required = 1;
t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
pos ++;
}
if (modopt) {
for (i = 0; i < mono_array_length (modopt); ++i) {
- MonoType *mod = mono_type_array_get_and_resolve (modopt, i, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
+ if (!is_ok (error))
+ goto fail;
t->modifiers [pos].required = 0;
t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
pos ++;
}
return t;
+fail:
+ g_free (t);
+ return NULL;
}
static void
}
static guint32
-mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb)
+mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
{
- MonoError error;
MonoDynamicTable *table;
MonoType *custom = NULL, *type;
guint32 *values;
guint32 token, pclass, parent, sig;
gchar *name;
+ mono_error_init (error);
+
token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, fb));
if (token)
return token;
- MonoType *typeb = mono_reflection_type_get_handle (fb->typeb, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *typeb = mono_reflection_type_get_handle (fb->typeb, error);
+ return_val_if_nok (error, 0);
/* FIXME: is this call necessary? */
mono_class_from_mono_type (typeb);
- name = mono_string_to_utf8 (fb->name);
/*FIXME this is one more layer of ugliness due how types are created.*/
init_type_builder_generics (fb->type);
/* fb->type does not include the custom modifiers */
/* FIXME: We should do this in one place when a fieldbuilder is created */
- type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+ return_val_if_nok (error, 0);
- if (fb->modreq || fb->modopt)
- type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt);
+ if (fb->modreq || fb->modopt) {
+ type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt, error);
+ return_val_if_nok (error, 0);
+ }
sig = fieldref_encode_signature (assembly, NULL, type);
g_free (custom);
- parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb, error);
+ return_val_if_nok (error, 0);
g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
table = &assembly->tables [MONO_TABLE_MEMBERREF];
+ name = mono_string_to_utf8 (fb->name);
+
if (assembly->save) {
alloc_table (table, table->rows + 1);
values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
}
static guint32
-mono_reflection_encode_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper)
+mono_reflection_encode_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
{
- MonoError error;
SigBuffer buf;
guint32 nargs;
guint32 i, idx;
+ mono_error_init (error);
+
if (!assembly->save)
return 0;
sigbuffer_add_byte (&buf, idx);
sigbuffer_add_value (&buf, nargs);
- encode_reflection_type (assembly, helper->return_type, &buf, &error);
- if (!is_ok (&error))
+ encode_reflection_type (assembly, helper->return_type, &buf, error);
+ if (!is_ok (error))
goto fail;
for (i = 0; i < nargs; ++i) {
MonoArray *modreqs = NULL;
if (helper->modopts && (i < mono_array_length (helper->modopts)))
modopts = mono_array_get (helper->modopts, MonoArray*, i);
- encode_custom_modifiers (assembly, modreqs, modopts, &buf, &error);
- if (!is_ok (&error))
+ encode_custom_modifiers (assembly, modreqs, modopts, &buf, error);
+ if (!is_ok (error))
goto fail;
pt = mono_array_get (helper->arguments, MonoReflectionType*, i);
- encode_reflection_type (assembly, pt, &buf, &error);
- if (!is_ok (&error))
+ encode_reflection_type (assembly, pt, &buf, error);
+ if (!is_ok (error))
goto fail;
}
idx = sigbuffer_add_to_blob_cached (assembly, &buf);
return idx;
fail:
sigbuffer_free (&buf);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
- g_assert_not_reached ();
+ return 0;
}
static guint32
-mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper)
+mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
{
guint32 idx;
MonoDynamicTable *table;
guint32 *values;
+ mono_error_init (error);
+
table = &assembly->tables [MONO_TABLE_STANDALONESIG];
idx = table->next_idx ++;
table->rows ++;
values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
values [MONO_STAND_ALONE_SIGNATURE] =
- mono_reflection_encode_sighelper (assembly, helper);
-
+ mono_reflection_encode_sighelper (assembly, helper, error);
+ return_val_if_nok (error, 0);
+
return idx;
}
#ifndef DISABLE_REFLECTION_EMIT
static guint32
-mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m)
+mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
{
- MonoError error;
guint32 nparams, i;
GList *tmp;
- char *name;
+ char *name = NULL;
MonoMethodSignature *sig;
- ArrayMethod *am;
+ ArrayMethod *am = NULL;
MonoType *mtype;
- name = mono_string_to_utf8 (m->name);
+ mono_error_init (error);
+
nparams = mono_array_length (m->parameters);
sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
sig->hasthis = 1;
sig->call_convention = reflection_cc_to_file (m->call_conv);
sig->param_count = nparams;
if (m->ret) {
- sig->ret = mono_reflection_type_get_handle (m->ret, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ sig->ret = mono_reflection_type_get_handle (m->ret, error);
+ if (!is_ok (error))
+ goto fail;
} else
sig->ret = &mono_defaults.void_class->byval_arg;
- mtype = mono_reflection_type_get_handle (m->parent, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mtype = mono_reflection_type_get_handle (m->parent, error);
+ if (!is_ok (error))
+ goto fail;
for (i = 0; i < nparams; ++i) {
- sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, error);
+ if (!is_ok (error))
+ goto fail;
}
+ name = mono_string_to_utf8 (m->name);
for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
am = (ArrayMethod *)tmp->data;
if (strcmp (name, am->name) == 0 &&
assembly->array_methods = g_list_prepend (assembly->array_methods, am);
m->table_idx = am->token & 0xffffff;
return am->token;
+fail:
+ g_free (am);
+ g_free (name);
+ g_free (sig);
+ return 0;
+
}
/*
static void
mono_image_fill_export_table (MonoDomain *domain, MonoReflectionTypeBuilder *tb,
- guint32 module_index, guint32 parent_index, MonoDynamicImage *assembly)
+ guint32 module_index, guint32 parent_index, MonoDynamicImage *assembly,
+ MonoError *error)
{
- MonoError error;
MonoClass *klass;
guint32 idx, i;
- MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)tb, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_init (error);
+
+ MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
+ return_if_nok (error);
klass = mono_class_from_mono_type (t);
* We need to do this ourselves since klass->nested_classes is not set up.
*/
if (tb->subtypes) {
- for (i = 0; i < mono_array_length (tb->subtypes); ++i)
- mono_image_fill_export_table (domain, mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i), module_index, idx, assembly);
+ for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
+ mono_image_fill_export_table (domain, mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i), module_index, idx, assembly, error);
+ return_if_nok (error);
+ }
}
}
}
static void
-mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb)
+mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb, MonoError *error)
{
MonoDynamicTable *table;
MonoDynamicImage *assembly;
int i;
guint32 module_index;
+ mono_error_init (error);
+
assemblyb = moduleb->assemblyb;
assembly = moduleb->dynamic_image;
domain = mono_object_domain (assemblyb);
if (file_module->types) {
for (j = 0; j < file_module->num_types; ++j) {
MonoReflectionTypeBuilder *tb = mono_array_get (file_module->types, MonoReflectionTypeBuilder*, j);
- mono_image_fill_export_table (domain, tb, module_index, 0, assembly);
+ mono_image_fill_export_table (domain, tb, module_index, 0, assembly, error);
+ return_if_nok (error);
}
}
}
assembly->text_rva = START_TEXT_RVA;
if (moduleb->is_main) {
- mono_image_emit_manifest (moduleb);
+ mono_image_emit_manifest (moduleb, error);
+ return_val_if_nok (error, FALSE);
}
table = &assembly->tables [MONO_TABLE_TYPEDEF];
/* Check for user defined reflection objects */
/* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
- mono_error_set_generic_error (error, "System", "NotSupportedException", "User defined subclasses of System.Type are not yet supported");
+ mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
return 0;
}
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
if (tb->generic_params) {
- token = mono_image_get_generic_field_token (assembly, fb);
+ token = mono_image_get_generic_field_token (assembly, fb, error);
+ return_val_if_nok (error, 0);
} else {
if (tb->module->dynamic_image == assembly) {
token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
/*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
} else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
- token = mono_image_get_array_token (assembly, m);
+ token = mono_image_get_array_token (assembly, m, error);
+ return_val_if_nok (error, 0);
} else if (strcmp (klass->name, "SignatureHelper") == 0) {
MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
- token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s);
+ token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
+ return_val_if_nok (error, 0);
} else if (strcmp (klass->name, "EnumBuilder") == 0) {
MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
return_val_if_nok (error, 0);
#ifndef DISABLE_REFLECTION_EMIT
MonoReflectionModule *
-mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
+mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName, MonoError *error)
{
- MonoError error;
- MonoReflectionModule *result = NULL;
char *name;
MonoImage *image;
MonoImageOpenStatus status;
MonoImage **new_modules;
gboolean *new_modules_loaded;
+ mono_error_init (error);
+
name = mono_string_to_utf8 (fileName);
image = mono_image_open (name, &status);
if (!image) {
- MonoException *exc;
if (status == MONO_IMAGE_ERROR_ERRNO)
- exc = mono_get_exception_file_not_found (fileName);
+ mono_error_set_exception_instance (error, mono_get_exception_file_not_found (fileName));
else
- exc = mono_get_exception_bad_image_format (name);
+ mono_error_set_bad_image_name (error, name, NULL);
g_free (name);
- mono_raise_exception (exc);
+ return NULL;
}
g_free (name);
mono_assembly_load_references (image, &status);
if (status) {
mono_image_close (image);
- mono_raise_exception (mono_get_exception_file_not_found (fileName));
+ mono_error_set_exception_instance (error, mono_get_exception_file_not_found (fileName));
+ return NULL;
}
- result = mono_module_get_object_checked (mono_domain_get (), image, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
- return result;
+ return mono_module_get_object_checked (mono_domain_get (), image, error);
}
#endif /* DISABLE_REFLECTION_EMIT */
static MonoObject *
mono_get_reflection_missing_object (MonoDomain *domain)
{
+ MonoError error;
MonoObject *obj;
static MonoClassField *missing_value_field = NULL;
missing_value_field = mono_class_get_field_from_name (missing_klass, "Value");
g_assert (missing_value_field);
}
- obj = mono_field_get_value_object (domain, missing_value_field, NULL);
- g_assert (obj);
+ obj = mono_field_get_value_object_checked (domain, missing_value_field, NULL, &error);
+ mono_error_assert_ok (&error);
return obj;
}
* in the method @method.
*/
MonoArray*
-mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoClass *refclass)
+mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoClass *refclass, MonoError *error)
{
static MonoClass *System_Reflection_ParameterInfo;
static MonoClass *System_Reflection_ParameterInfo_array;
- MonoError error;
MonoArray *res = NULL;
MonoReflectionMethod *member = NULL;
MonoReflectionParameter *param = NULL;
MonoReflectionType *rt;
int i;
- mono_error_init (&error);
+ mono_error_init (error);
if (!System_Reflection_ParameterInfo_array) {
MonoClass *klass;
System_Reflection_ParameterInfo_array = klass;
}
- sig = mono_method_signature_checked (method, &error);
- if (!mono_error_ok (&error))
+ sig = mono_method_signature_checked (method, error);
+ if (!mono_error_ok (error))
goto leave;
if (!sig->param_count) {
- res = mono_array_new_specific_checked (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), 0, &error);
+ res = mono_array_new_specific_checked (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), 0, error);
if (!res)
goto leave;
*/
CHECK_OBJECT (MonoArray*, &(method->signature), refclass);
- member = mono_method_get_object_checked (domain, method, refclass, &error);
+ member = mono_method_get_object_checked (domain, method, refclass, error);
if (!member)
goto leave;
names = g_new (char *, sig->param_count);
mspecs = g_new (MonoMarshalSpec*, sig->param_count + 1);
mono_method_get_marshal_info (method, mspecs);
- res = mono_array_new_specific_checked (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), sig->param_count, &error);
+ res = mono_array_new_specific_checked (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), sig->param_count, error);
if (!res)
goto leave;
pinfo_vtable = mono_class_vtable (domain, System_Reflection_ParameterInfo);
for (i = 0; i < sig->param_count; ++i) {
- param = (MonoReflectionParameter *) mono_object_new_specific_checked (pinfo_vtable, &error);
+ param = (MonoReflectionParameter *) mono_object_new_specific_checked (pinfo_vtable, error);
if (!param)
goto leave;
- rt = mono_type_get_object_checked (domain, sig->params [i], &error);
+ rt = mono_type_get_object_checked (domain, sig->params [i], error);
if (!rt)
goto leave;
} else
type->data.klass = mono_class_from_mono_type (type);
- MONO_OBJECT_SETREF (param, DefaultValueImpl, mono_get_object_from_blob (domain, type, blobs [i]));
+ MonoObject *default_val_obj = mono_get_object_from_blob (domain, type, blobs [i], error);
+ if (!is_ok (error))
+ goto leave;
+ MONO_OBJECT_SETREF (param, DefaultValueImpl, default_val_obj);
/* Type in the Constant table is MONO_TYPE_CLASS for nulls */
if (types [i] != MONO_TYPE_CLASS && !param->DefaultValueImpl) {
if (mspecs [i + 1]) {
MonoReflectionMarshalAsAttribute* mobj;
- mobj = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [i + 1], &error);
+ mobj = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [i + 1], error);
if (!mobj)
goto leave;
MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mobj);
}
g_free (mspecs);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!is_ok (error))
+ return NULL;
CACHE_OBJECT (MonoArray *, &(method->signature), res, refclass);
}
MonoArray*
mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
{
- return mono_param_get_objects_internal (domain, method, NULL);
+ MonoError error;
+ MonoArray *result = mono_param_get_objects_internal (domain, method, NULL, &error);
+ mono_error_assert_ok (&error);
+ return result;
}
/*
mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
{
MonoError error;
+ MonoReflectionMethodBody *result = mono_method_body_get_object_checked (domain, method, &error);
+ mono_error_cleanup (&error); /* FIXME better API that doesn't swallow the error */
+ return result;
+}
+
+/**
+ * mono_method_body_get_object_checked:
+ * @domain: an app domain
+ * @method: a method
+ * @error: set on error
+ *
+ * Return an System.Reflection.MethodBody object representing the
+ * method @method. On failure, returns NULL and sets @error.
+ */
+MonoReflectionMethodBody*
+mono_method_body_get_object_checked (MonoDomain *domain, MonoMethod *method, MonoError *error)
+{
MonoReflectionMethodBody *ret;
MonoMethodHeader *header;
MonoImage *image;
MonoReflectionType *rt;
guint32 method_rva, local_var_sig_token;
- char *ptr;
+ char *ptr;
unsigned char format, flags;
int i;
+ mono_error_init (error);
+
/* for compatibility with .net */
- if (method_is_dynamic (method))
- mono_raise_exception (mono_get_exception_invalid_operation (NULL));
+ if (method_is_dynamic (method)) {
+ mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
+ return NULL;
+ }
CHECK_OBJECT (MonoReflectionMethodBody *, method, NULL);
return NULL;
image = method->klass->image;
- header = mono_method_get_header_checked (method, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ header = mono_method_get_header_checked (method, error);
+ return_val_if_nok (error, NULL);
if (!image_is_dynamic (image)) {
/* Obtain local vars signature token */
} else
local_var_sig_token = 0; //FIXME
- ret = (MonoReflectionMethodBody*)mono_object_new_checked (domain, mono_class_get_method_body_class (), &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ ret = (MonoReflectionMethodBody*)mono_object_new_checked (domain, mono_class_get_method_body_class (), error);
+ if (!is_ok (error))
+ goto fail;
ret->init_locals = header->init_locals;
ret->max_stack = header->max_stack;
/* Locals */
MONO_OBJECT_SETREF (ret, locals, mono_array_new_cached (domain, mono_class_get_local_variable_info_class (), header->num_locals));
for (i = 0; i < header->num_locals; ++i) {
- MonoReflectionLocalVariableInfo *info = (MonoReflectionLocalVariableInfo*)mono_object_new_checked (domain, mono_class_get_local_variable_info_class (), &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoReflectionLocalVariableInfo *info = (MonoReflectionLocalVariableInfo*)mono_object_new_checked (domain, mono_class_get_local_variable_info_class (), error);
+ if (!is_ok (error))
+ goto fail;
- rt = mono_type_get_object_checked (domain, header->locals [i], &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ rt = mono_type_get_object_checked (domain, header->locals [i], error);
+ if (!is_ok (error))
+ goto fail;
MONO_OBJECT_SETREF (info, local_type, rt);
/* Exceptions */
MONO_OBJECT_SETREF (ret, clauses, mono_array_new_cached (domain, mono_class_get_exception_handling_clause_class (), header->num_clauses));
for (i = 0; i < header->num_clauses; ++i) {
- MonoReflectionExceptionHandlingClause *info = (MonoReflectionExceptionHandlingClause*)mono_object_new_checked (domain, mono_class_get_exception_handling_clause_class (), &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoReflectionExceptionHandlingClause *info = (MonoReflectionExceptionHandlingClause*)mono_object_new_checked (domain, mono_class_get_exception_handling_clause_class (), error);
+ if (!is_ok (error))
+ goto fail;
MonoExceptionClause *clause = &header->clauses [i];
info->flags = clause->flags;
if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER)
info->filter_offset = clause->data.filter_offset;
else if (clause->data.catch_class) {
- rt = mono_type_get_object_checked (mono_domain_get (), &clause->data.catch_class->byval_arg, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ rt = mono_type_get_object_checked (mono_domain_get (), &clause->data.catch_class->byval_arg, error);
+ if (!is_ok (error))
+ goto fail;
MONO_OBJECT_SETREF (info, catch_type, rt);
}
mono_metadata_free_mh (header);
CACHE_OBJECT (MonoReflectionMethodBody *, method, ret, NULL);
return ret;
+
+fail:
+ mono_metadata_free_mh (header);
+ return NULL;
}
/**
MonoObject *
mono_get_dbnull_object (MonoDomain *domain)
{
+ MonoError error;
MonoObject *obj;
static MonoClassField *dbnull_value_field = NULL;
dbnull_value_field = mono_class_get_field_from_name (dbnull_klass, "Value");
g_assert (dbnull_value_field);
}
- obj = mono_field_get_value_object (domain, dbnull_value_field, NULL);
- g_assert (obj);
+ obj = mono_field_get_value_object_checked (domain, dbnull_value_field, NULL, &error);
+ mono_error_assert_ok (&error);
return obj;
}
}
MonoObject *
-mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob)
+mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob, MonoError *error)
{
- MonoError error;
void *retval;
MonoClass *klass;
MonoObject *object;
MonoType *basetype = type;
+ mono_error_init (error);
+
if (!blob)
return NULL;
klass = mono_class_from_mono_type (type);
if (klass->valuetype) {
- object = mono_object_new_checked (domain, klass, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ object = mono_object_new_checked (domain, klass, error);
+ return_val_if_nok (error, NULL);
retval = ((gchar *) object + sizeof (MonoObject));
if (klass->enumtype)
basetype = mono_class_enum_basetype (klass);
}
static MonoType*
-_mono_reflection_get_type_from_info (MonoTypeNameParse *info, MonoImage *image, gboolean ignorecase)
+_mono_reflection_get_type_from_info (MonoTypeNameParse *info, MonoImage *image, gboolean ignorecase, MonoError *error)
{
gboolean type_resolve = FALSE;
MonoType *type;
MonoImage *rootimage = image;
+ mono_error_init (error);
+
if (info->assembly.name) {
MonoAssembly *assembly = mono_assembly_loaded (&info->assembly);
if (!assembly && image && image->assembly && mono_assembly_names_equal (&info->assembly, &image->assembly->aname))
image = mono_defaults.corlib;
}
- type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve);
+ type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve, error);
if (type == NULL && !info->assembly.name && image != mono_defaults.corlib) {
+ mono_error_cleanup (error);
image = mono_defaults.corlib;
- type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve);
+ type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve, error);
}
return type;
for (i = 0; i < info->type_arguments->len; i++) {
MonoTypeNameParse *subinfo = (MonoTypeNameParse *)g_ptr_array_index (info->type_arguments, i);
- type_args [i] = _mono_reflection_get_type_from_info (subinfo, rootimage, ignorecase);
+ type_args [i] = _mono_reflection_get_type_from_info (subinfo, rootimage, ignorecase, error);
if (!type_args [i]) {
g_free (type_args);
return NULL;
return NULL;
instance = mono_reflection_bind_generic_parameters (
- the_type, info->type_arguments->len, type_args);
+ the_type, info->type_arguments->len, type_args, error);
g_free (type_args);
if (!instance)
MonoType*
mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve) {
- return mono_reflection_get_type_with_rootimage(image, image, info, ignorecase, type_resolve);
+ MonoError error;
+ MonoType *result = mono_reflection_get_type_with_rootimage (image, image, info, ignorecase, type_resolve, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+/**
+ * mono_reflection_get_type_checked:
+ * @image: a metadata context
+ * @info: type description structure
+ * @ignorecase: flag for case-insensitive string compares
+ * @type_resolve: whenever type resolve was already tried
+ * @error: set on error.
+ *
+ * Build a MonoType from the type description in @info. On failure returns NULL and sets @error.
+ *
+ */
+MonoType*
+mono_reflection_get_type_checked (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve, MonoError *error) {
+ mono_error_init (error);
+ return mono_reflection_get_type_with_rootimage (image, image, info, ignorecase, type_resolve, error);
}
+
static MonoType*
mono_reflection_get_type_internal_dynamic (MonoImage *rootimage, MonoAssembly *assembly, MonoTypeNameParse *info, gboolean ignorecase, MonoError *error)
{
}
MonoType*
-mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve)
+mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve, MonoError *error)
{
- MonoError error;
MonoType *type;
MonoReflectionAssembly *assembly;
GString *fullName;
GList *mod;
+ mono_error_init (error);
+
if (image && image_is_dynamic (image))
- type = mono_reflection_get_type_internal_dynamic (rootimage, image->assembly, info, ignorecase, &error);
+ type = mono_reflection_get_type_internal_dynamic (rootimage, image->assembly, info, ignorecase, error);
else {
- type = mono_reflection_get_type_internal (rootimage, image, info, ignorecase, &error);
+ type = mono_reflection_get_type_internal (rootimage, image, info, ignorecase, error);
}
- if (!mono_error_ok (&error))
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return_val_if_nok (error, NULL);
if (type)
return type;
for (mod = info->nested; mod; mod = mod->next)
g_string_append_printf (fullName, "+%s", (char*)mod->data);
- assembly = mono_domain_try_type_resolve_checked ( mono_domain_get (), fullName->str, NULL, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ assembly = mono_domain_try_type_resolve_checked ( mono_domain_get (), fullName->str, NULL, error);
+ if (!is_ok (error)) {
+ g_string_free (fullName, TRUE);
+ return NULL;
+ }
if (assembly) {
if (assembly_is_dynamic (assembly->assembly))
type = mono_reflection_get_type_internal_dynamic (rootimage, assembly->assembly,
- info, ignorecase, &error);
+ info, ignorecase, error);
else
type = mono_reflection_get_type_internal (rootimage, assembly->assembly->image,
- info, ignorecase, &error);
+ info, ignorecase, error);
}
g_string_free (fullName, TRUE);
- if (!mono_error_ok (&error))
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return_val_if_nok (error, NULL);
return type;
}
*/
MonoType*
mono_reflection_type_from_name (char *name, MonoImage *image)
+{
+ MonoError error;
+ MonoType *result = mono_reflection_type_from_name_checked (name, image, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+/**
+ * mono_reflection_type_from_name_checked:
+ * @name: type name.
+ * @image: a metadata context (can be NULL).
+ * @error: set on errror.
+ *
+ * Retrieves a MonoType from its @name. If the name is not fully qualified,
+ * it defaults to get the type from @image or, if @image is NULL or loading
+ * from it fails, uses corlib. On failure returns NULL and sets @error.
+ *
+ */
+MonoType*
+mono_reflection_type_from_name_checked (char *name, MonoImage *image, MonoError *error)
{
MonoType *type = NULL;
MonoTypeNameParse info;
char *tmp;
+ mono_error_init (error);
/* Make a copy since parse_type modifies its argument */
tmp = g_strdup (name);
/*g_print ("requested type %s\n", str);*/
if (mono_reflection_parse_type (tmp, &info)) {
- type = _mono_reflection_get_type_from_info (&info, image, FALSE);
+ type = _mono_reflection_get_type_from_info (&info, image, FALSE, error);
+ if (!is_ok (error)) {
+ g_free (tmp);
+ mono_reflection_free_type_info (&info);
+ return NULL;
+ }
}
g_free (tmp);
mono_reflection_get_token (MonoObject *obj)
{
MonoError error;
+ guint32 result = mono_reflection_get_token_checked (obj, &error);
+ mono_error_assert_ok (&error);
+ return result;
+}
+
+/**
+ * mono_reflection_get_token_checked:
+ * @obj: the object
+ * @error: set on error
+ *
+ * Return the metadata token of @obj which should be an object
+ * representing a metadata element. On failure sets @error.
+ */
+guint32
+mono_reflection_get_token_checked (MonoObject *obj, MonoError *error)
+{
MonoClass *klass;
guint32 token = 0;
+ mono_error_init (error);
+
klass = obj->vtable->klass;
if (strcmp (klass->name, "MethodBuilder") == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
} else if (strcmp (klass->name, "MonoType") == 0) {
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
+ return_val_if_nok (error, 0);
MonoClass *mc = mono_class_from_mono_type (type);
- if (!mono_class_init (mc))
- mono_raise_exception (mono_class_get_exception_for_failure (mc));
+ if (!mono_class_init (mc)) {
+ mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (mc));
+ return 0;
+ }
token = mc->type_token;
} else if (strcmp (klass->name, "MonoCMethod") == 0 ||
g_assert (field_index >= 0 && field_index < dgclass->count_fields);
obj = dgclass->field_objects [field_index];
- return mono_reflection_get_token (obj);
+ return mono_reflection_get_token_checked (obj, error);
}
}
token = mono_class_get_field_token (f->field);
} else if (strcmp (klass->name, "Assembly") == 0 || strcmp (klass->name, "MonoAssembly") == 0) {
token = mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1);
} else {
- gchar *msg = g_strdup_printf ("MetadataToken is not supported for type '%s.%s'", klass->name_space, klass->name);
- MonoException *ex = mono_get_exception_not_implemented (msg);
- g_free (msg);
- mono_raise_exception (ex);
+ mono_error_set_not_implemented (error, "MetadataToken is not supported for type '%s.%s'",
+ klass->name_space, klass->name);
+ return 0;
}
return token;
n = (char *)g_memdup (p, slen + 1);
n [slen] = 0;
- t = mono_reflection_type_from_name (n, image);
+ t = mono_reflection_type_from_name_checked (n, image, error);
if (!t) {
- /* FIXME the error should come from mono_reflection_type_from_name as it will have type/assembly names split */
+ char *msg = g_strdup (mono_error_get_message (error));
+ mono_error_cleanup (error);
/* We don't free n, it's consumed by mono_error */
- mono_error_set_type_load_name (error, n, NULL, "Could not load enum type %s while decoding custom attribute", n);
+ mono_error_set_type_load_name (error, n, NULL, "Could not load enum type %s while decoding custom attribute: %s", n, msg);
+ g_free (msg);
return NULL;
}
g_free (n);
slen = mono_metadata_decode_value (p, &p);
n = (char *)g_memdup (p, slen + 1);
n [slen] = 0;
- t = mono_reflection_type_from_name (n, image);
+ t = mono_reflection_type_from_name_checked (n, image, error);
if (!t) {
- /* FIXME the error should come from mono_reflection_type_from_name as it will have type/assembly names split */
+ char *msg = g_strdup (mono_error_get_message (error));
+ mono_error_cleanup (error);
/* We don't free n, it's consumed by mono_error */
- mono_error_set_type_load_name (error, n, NULL, "Could not load type %s while decoding custom attribute", n);
+ mono_error_set_type_load_name (error, n, NULL, "Could not load type %s while decoding custom attribute: %msg", n, msg);
+ g_free (msg);
return NULL;
}
g_free (n);
slen = mono_metadata_decode_value (p, &p);
n = (char *)g_memdup (p, slen + 1);
n [slen] = 0;
- t = mono_reflection_type_from_name (n, image);
+ t = mono_reflection_type_from_name_checked (n, image, error);
if (!t) {
- /* FIXME the error should come from mono_reflection_type_from_name as it will have type/assembly names split */
+ char *msg = g_strdup (mono_error_get_message (error));
+ mono_error_cleanup (error);
/* We don't free n, it's consumed by mono_error */
- mono_error_set_type_load_name (error, n, NULL, "Could not load type %s while decoding custom attribute", n);
+ mono_error_set_type_load_name (error, n, NULL, "Could not load type %s while decoding custom attribute: %s", n, msg);
+ g_free (msg);
return NULL;
}
g_free (n);
return NULL;
}
+static MonoObject*
+load_cattr_value_boxed (MonoDomain *domain, MonoImage *image, MonoType *t, const char* p, const char** end, MonoError *error)
+{
+ mono_error_init (error);
+
+ gboolean is_ref = type_is_reference (t);
+
+ void *val = load_cattr_value (image, t, p, end, error);
+ if (!is_ok (error)) {
+ if (is_ref)
+ g_free (val);
+ return NULL;
+ }
+
+ if (is_ref)
+ return (MonoObject*)val;
+
+ MonoObject *boxed = mono_value_box_checked (domain, mono_class_from_mono_type (t), val, error);
+ g_free (val);
+ return boxed;
+}
+
static MonoObject*
create_cattr_typed_arg (MonoType *t, MonoObject *val, MonoError *error)
{
p += 2;
for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
MonoObject *obj;
- void *val;
-
- val = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p, error);
- if (!mono_error_ok (error)) {
- if (!type_is_reference (mono_method_signature (method)->params [i]))
- g_free (val);
- return;
- }
- obj = (MonoObject *)(type_is_reference (mono_method_signature (method)->params [i]) ?
- val : mono_value_box (domain, mono_class_from_mono_type (mono_method_signature (method)->params [i]), val));
+ obj = load_cattr_value_boxed (domain, image, mono_method_signature (method)->params [i], p, &p, error);
+ return_if_nok (error);
mono_array_setref (typedargs, i, obj);
-
- if (!type_is_reference (mono_method_signature (method)->params [i]))
- g_free (val);
}
named = p;
if (named_type == 0x53) {
MonoObject *obj;
MonoClassField *field = mono_class_get_field_from_name (attrklass, name);
- void *val;
if (!field) {
g_free (name);
arginfo [j].type = field->type;
arginfo [j].field = field;
- val = load_cattr_value (image, field->type, named, &named, error);
- if (!mono_error_ok (error)) {
- if (!type_is_reference (field->type))
- g_free (val);
+ obj = load_cattr_value_boxed (domain, image, field->type, named, &named, error);
+ if (!is_ok (error)) {
g_free (name);
return;
}
-
- obj = (MonoObject *)(type_is_reference (field->type) ? val : mono_value_box (domain, mono_class_from_mono_type (field->type), val));
mono_array_setref (namedargs, j, obj);
- if (!type_is_reference (field->type))
- g_free (val);
+
} else if (named_type == 0x54) {
MonoObject *obj;
MonoType *prop_type;
MonoProperty *prop = mono_class_get_property_from_name (attrklass, name);
- void *val;
if (!prop || !prop->set) {
g_free (name);
arginfo [j].type = prop_type;
arginfo [j].prop = prop;
- val = load_cattr_value (image, prop_type, named, &named, error);
- if (!mono_error_ok (error)) {
- if (!type_is_reference (prop_type))
- g_free (val);
+ obj = load_cattr_value_boxed (domain, image, prop_type, named, &named, error);
+ if (!is_ok (error)) {
g_free (name);
return;
}
-
- obj = (MonoObject *)(type_is_reference (prop_type) ? val : mono_value_box (domain, mono_class_from_mono_type (prop_type), val));
mono_array_setref (namedargs, j, obj);
- if (!type_is_reference (prop_type))
- g_free (val);
}
g_free (name);
}
#endif
else {
char *type_name = mono_type_get_full_name (member_class);
- mono_error_set_generic_error (error, "System", "NotSupportedException",
+ mono_error_set_not_supported (error,
"Custom attributes on a ParamInfo with member %s are not supported",
type_name);
g_free (type_name);
}
}
- res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types);
+ res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
g_free (types);
g_assert (res);
gclass->type.type = res;
mono_error_set_pending_exception (&error);
}
-void
-mono_reflection_register_with_runtime (MonoReflectionType *type)
+static gboolean
+reflection_register_with_runtime (MonoReflectionType *type, MonoError *error)
{
- MonoError error;
- MonoType *res = mono_reflection_type_get_handle (type, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
MonoDomain *domain = mono_object_domain ((MonoObject*)type);
MonoClass *klass;
- if (!res)
- mono_raise_exception (mono_get_exception_argument (NULL, "Invalid generic instantiation, one or more arguments are not proper user types"));
+ mono_error_init (error);
+
+ MonoType *res = mono_reflection_type_get_handle (type, error);
+
+ if (!res && is_ok (error)) {
+ mono_error_set_argument (error, NULL, "Invalid generic instantiation, one or more arguments are not proper user types");
+ }
+ return_val_if_nok (error, FALSE);
klass = mono_class_from_mono_type (res);
}
mono_domain_unlock (domain);
mono_loader_unlock ();
+
+ return TRUE;
+}
+
+void
+mono_reflection_register_with_runtime (MonoReflectionType *type)
+{
+ MonoError error;
+ (void) reflection_register_with_runtime (type, &error);
+ mono_error_set_pending_exception (&error);
}
/**
* LOCKING: Assumes the loader lock is held.
*/
static MonoMethodSignature*
-parameters_to_signature (MonoImage *image, MonoArray *parameters) {
- MonoError error;
+parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
MonoMethodSignature *sig;
int count, i;
+ mono_error_init (error);
+
count = parameters? mono_array_length (parameters): 0;
sig = (MonoMethodSignature *)image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
sig->param_count = count;
sig->sentinelpos = -1; /* FIXME */
for (i = 0; i < count; ++i) {
- sig->params [i] = mono_type_array_get_and_resolve (parameters, i, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
+ if (!is_ok (error)) {
+ image_g_free (image, sig);
+ return NULL;
+ }
}
return sig;
}
* LOCKING: Assumes the loader lock is held.
*/
static MonoMethodSignature*
-ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor) {
+ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
MonoMethodSignature *sig;
- sig = parameters_to_signature (image, ctor->parameters);
+ mono_error_init (error);
+
+ sig = parameters_to_signature (image, ctor->parameters, error);
+ return_val_if_nok (error, NULL);
sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
sig->ret = &mono_defaults.void_class->byval_arg;
return sig;
* LOCKING: Assumes the loader lock is held.
*/
static MonoMethodSignature*
-method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method) {
- MonoError error;
+method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
MonoMethodSignature *sig;
- sig = parameters_to_signature (image, method->parameters);
+ mono_error_init (error);
+
+ sig = parameters_to_signature (image, method->parameters, error);
+ return_val_if_nok (error, NULL);
sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
if (method->rtype) {
- sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
+ if (!is_ok (error)) {
+ image_g_free (image, sig);
+ return NULL;
+ }
} else {
sig->ret = &mono_defaults.void_class->byval_arg;
}
}
static MonoMethodSignature*
-dynamic_method_to_signature (MonoReflectionDynamicMethod *method) {
- MonoError error;
+dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
MonoMethodSignature *sig;
- sig = parameters_to_signature (NULL, method->parameters);
+ mono_error_init (error);
+
+ sig = parameters_to_signature (NULL, method->parameters, error);
+ return_val_if_nok (error, NULL);
sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
if (method->rtype) {
- sig->ret = mono_reflection_type_get_handle (method->rtype, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ sig->ret = mono_reflection_type_get_handle (method->rtype, error);
+ if (!is_ok (error)) {
+ g_free (sig);
+ return NULL;
+ }
} else {
sig->ret = &mono_defaults.void_class->byval_arg;
}
}
static void
-get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type)
+get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
{
- MonoError error;
+ mono_error_init (error);
MonoClass *klass = mono_object_class (prop);
if (strcmp (klass->name, "PropertyBuilder") == 0) {
MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
*name = mono_string_to_utf8 (pb->name);
- *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
} else {
MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
*name = g_strdup (p->property->name);
}
static void
-get_field_name_and_type (MonoObject *field, char **name, MonoType **type)
+get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
{
- MonoError error;
+ mono_error_init (error);
MonoClass *klass = mono_object_class (field);
if (strcmp (klass->name, "FieldBuilder") == 0) {
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
*name = mono_string_to_utf8 (fb->name);
- *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
} else {
MonoReflectionField *f = (MonoReflectionField *)field;
*name = g_strdup (mono_field_get_name (f->field));
type = mono_reflection_type_get_underlying_system_type (type, error);
return_val_if_nok (error, NULL);
if (is_usertype (type)) {
- mono_error_set_generic_error (error, "System", "NotSupportedException", "User defined subclasses of System.Type are not yet supported22");
+ mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported22");
return NULL;
}
}
return type;
}
-/*
+/**
+ * encode_cattr_value:
* Encode a value in a custom attribute stream of bytes.
* The value to encode is either supplied as an object in argument val
* (valuetypes are boxed), or as a pointer to the data in the
* @buflen contains the size of the buffer and is used to return the new buffer size
* if this needs to be realloced.
* @retbuffer and @retp return the start and the position of the buffer
+ * @error set on error.
*/
static void
-encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval)
+encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
{
- MonoError error;
MonoTypeEnum simple_type;
+ mono_error_init (error);
if ((p-buffer) + 10 >= *buflen) {
char *newbuf;
*buflen *= 2;
break;
}
handle_type:
- arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
+ return_if_nok (error);
+
str = type_get_qualified_name (arg_type, NULL);
slen = strlen (str);
if ((p-buffer) + 10 + slen >= *buflen) {
char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
int elsize = mono_class_array_element_size (arg_eclass);
for (i = 0; i < len; ++i) {
- encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr);
+ encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
+ return_if_nok (error);
elptr += elsize;
}
} else if (eclass->valuetype && arg_eclass->valuetype) {
char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
int elsize = mono_class_array_element_size (eclass);
for (i = 0; i < len; ++i) {
- encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr);
+ encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
+ return_if_nok (error);
elptr += elsize;
}
} else {
for (i = 0; i < len; ++i) {
- encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL);
+ encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
+ return_if_nok (error);
}
}
break;
klass = mono_object_class (arg);
- if (mono_object_isinst (arg, mono_defaults.systemtype_class)) {
+ if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
*p++ = 0x50;
goto handle_type;
- } else if (klass->enumtype) {
+ } else {
+ return_if_nok (error);
+ }
+
+ if (klass->enumtype) {
*p++ = 0x55;
} else if (klass == mono_defaults.string_class) {
simple_type = MONO_TYPE_STRING;
*p++ = 0x51;
else
*p++ = klass->element_class->byval_arg.type;
- encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL);
+ encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
+ return_if_nok (error);
break;
} else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
*p++ = simple_type = klass->byval_arg.type;
#ifndef DISABLE_REFLECTION_EMIT
static void
-encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value)
+encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
{
int len;
+
+ mono_error_init (error);
+
/* Preallocate a large enough buffer */
if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
char *str = type_get_qualified_name (type, NULL);
mono_metadata_encode_value (len, p, &p);
memcpy (p, name, len);
p += len;
- encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL);
+ encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
+ return_if_nok (error);
*retp = p;
*retbuffer = buffer;
}
-/*
+/**
* mono_reflection_get_custom_attrs_blob:
* @ctor: custom attribute constructor
* @ctorArgs: arguments o the constructor
MonoArray*
mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
{
- MonoArray *result;
+ MonoError error;
+ MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
+ mono_error_cleanup (&error); /* FIXME better API that doesn't swallow the error */
+ return result;
+}
+
+/**
+ * mono_reflection_get_custom_attrs_blob_checked:
+ * @ctor: custom attribute constructor
+ * @ctorArgs: arguments o the constructor
+ * @properties:
+ * @propValues:
+ * @fields:
+ * @fieldValues:
+ * @error: set on error
+ *
+ * Creates the blob of data that needs to be saved in the metadata and that represents
+ * the custom attributed described by @ctor, @ctorArgs etc.
+ * Returns: a Byte array representing the blob of data. On failure returns NULL and sets @error.
+ */
+MonoArray*
+mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error)
+{
+ MonoArray *result = NULL;
MonoMethodSignature *sig;
MonoObject *arg;
char *buffer, *p;
guint32 buflen, i;
+ mono_error_init (error);
+
if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
/* sig is freed later so allocate it in the heap */
- sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor);
+ sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
+ if (!is_ok (error)) {
+ g_free (sig);
+ return NULL;
+ }
} else {
sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
}
*p++ = 0;
for (i = 0; i < sig->param_count; ++i) {
arg = mono_array_get (ctorArgs, MonoObject*, i);
- encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL);
+ encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
+ if (!is_ok (error)) goto leave;
}
i = 0;
if (properties)
char *pname;
prop = (MonoObject *)mono_array_get (properties, gpointer, i);
- get_prop_name_and_type (prop, &pname, &ptype);
+ get_prop_name_and_type (prop, &pname, &ptype, error);
+ if (!is_ok (error)) goto leave;
*p++ = 0x54; /* PROPERTY signature */
- encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i));
+ encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
g_free (pname);
+ if (!is_ok (error)) goto leave;
}
}
char *fname;
field = (MonoObject *)mono_array_get (fields, gpointer, i);
- get_field_name_and_type (field, &fname, &ftype);
+ get_field_name_and_type (field, &fname, &ftype, error);
+ if (!is_ok (error)) goto leave;
*p++ = 0x53; /* FIELD signature */
- encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i));
+ encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
g_free (fname);
+ if (!is_ok (error)) goto leave;
}
}
result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, buflen);
p = mono_array_addr (result, char, 0);
memcpy (p, buffer, buflen);
+leave:
g_free (buffer);
if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
g_free (sig);
return result;
}
-/*
- * mono_reflection_setup_internal_class:
+/**
+ * reflection_setup_internal_class:
* @tb: a TypeBuilder object
+ * @error: set on error
*
* Creates a MonoClass that represents the TypeBuilder.
* This is a trick that lets us simplify a lot of reflection code
* (and will allow us to support Build and Run assemblies easier).
+ *
+ * Returns TRUE on success. On failure, returns FALSE and sets @error.
*/
-void
-mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
+static gboolean
+reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
{
- MonoError error;
MonoClass *klass, *parent;
- RESOLVE_TYPE (tb->parent, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_init (error);
+ RESOLVE_TYPE (tb->parent, error);
+ return_val_if_nok (error, FALSE);
mono_loader_lock ();
if (tb->parent) {
- MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, &error);
- if (!is_ok (&error)) {
+ MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
+ if (!is_ok (error)) {
mono_loader_unlock ();
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return FALSE;
}
/* check so we can compile corlib correctly */
if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
mono_class_setup_parent (klass, parent);
mono_class_setup_mono_type (klass);
mono_loader_unlock ();
- return;
+ return TRUE;
}
klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
klass->image = &tb->module->dynamic_image->image;
klass->inited = 1; /* we lie to the runtime */
- klass->name = mono_string_to_utf8_image (klass->image, tb->name, &error);
- if (!mono_error_ok (&error))
+ klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
+ if (!is_ok (error))
goto failure;
- klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, &error);
- if (!mono_error_ok (&error))
+ klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
+ if (!is_ok (error))
goto failure;
klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
klass->flags = tb->attrs;
if (tb->nesting_type) {
g_assert (tb->nesting_type->type);
- MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, &error);
- if (!is_ok (&error)) goto failure;
+ MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
+ if (!is_ok (error)) goto failure;
klass->nested_in = mono_class_from_mono_type (nesting_type);
}
mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
mono_loader_unlock ();
- return;
+ return TRUE;
failure:
mono_loader_unlock ();
- mono_error_raise_exception (&error);
+ return FALSE;
+}
+
+/**
+ * mono_reflection_setup_internal_class:
+ * @tb: a TypeBuilder object
+ *
+ * (icall)
+ * Creates a MonoClass that represents the TypeBuilder.
+ * This is a trick that lets us simplify a lot of reflection code
+ * (and will allow us to support Build and Run assemblies easier).
+ *
+ */
+void
+mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
+{
+ MonoError error;
+ (void) reflection_setup_internal_class (tb, &error);
+ mono_error_set_pending_exception (&error);
}
/*
klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
}
-/*
- * mono_reflection_create_internal_class:
+/**
+ * reflection_create_internal_class:
* @tb: a TypeBuilder object
+ * @error: set on error
*
* Actually create the MonoClass that is associated with the TypeBuilder.
+ * On success returns TRUE, on failure returns FALSE and sets @error.
+ *
*/
-void
-mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
+static gboolean
+reflection_create_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
{
- MonoError error;
+
MonoClass *klass;
+ mono_error_init (error);
klass = mono_class_from_mono_type (tb->type.type);
mono_loader_lock ();
fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, 0);
- MonoType *field_type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, &error);
- if (!is_ok (&error)) {
+ MonoType *field_type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+ if (!is_ok (error)) {
mono_loader_unlock ();
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return FALSE;
}
if (!mono_type_is_valid_enum_basetype (field_type)) {
mono_loader_unlock ();
- return;
+ return TRUE;
}
- enum_basetype = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, &error);
- if (!is_ok (&error)) {
+ enum_basetype = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+ if (!is_ok (error)) {
mono_loader_unlock ();
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return FALSE;
}
klass->element_class = mono_class_from_mono_type (enum_basetype);
if (!klass->element_class)
mono_class_setup_vtable_general (klass, NULL, 0, NULL);
}
mono_loader_unlock ();
+ return TRUE;
+}
+
+/**
+ * mono_reflection_create_internal_class:
+ * @tb: a TypeBuilder object
+ *
+ * (icall)
+ * Actually create the MonoClass that is associated with the TypeBuilder.
+ */
+void
+mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
+{
+ MonoError error;
+ (void) reflection_create_internal_class (tb, &error);
+ mono_error_set_pending_exception (&error);
}
static MonoMarshalSpec*
mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
- MonoReflectionMarshal *minfo)
+ MonoReflectionMarshal *minfo, MonoError *error)
{
- MonoError error;
MonoMarshalSpec *res;
+ mono_error_init (error);
+
res = image_g_new0 (image, MonoMarshalSpec, 1);
res->native = (MonoMarshalNative)minfo->type;
case MONO_NATIVE_CUSTOM:
if (minfo->marshaltyperef) {
- MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
+ if (!is_ok (error)) {
+ image_g_free (image, res);
+ return NULL;
+ }
res->data.custom_data.custom_name =
type_get_fully_qualified_name (marshaltyperef);
}
case MONO_NATIVE_CUSTOM:
if (spec->data.custom_data.custom_name) {
- mtype = mono_reflection_type_from_name (spec->data.custom_data.custom_name, klass->image);
+ mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
+ return_val_if_nok (error, NULL);
+
if (mtype) {
rt = mono_type_get_object_checked (domain, mtype, error);
if (!rt)
if (specs == NULL)
specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
specs [pb->position] =
- mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info);
+ mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, &error);
+ if (!is_ok (&error)) {
+ mono_loader_unlock ();
+ image_g_free (image, specs);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
}
}
}
MonoMethodSignature *sig;
mono_loader_lock ();
- sig = ctor_builder_to_signature (klass->image, mb);
+ g_assert (klass->image != NULL);
+ sig = ctor_builder_to_signature (klass->image, mb, error);
mono_loader_unlock ();
+ return_val_if_nok (error, NULL);
if (!reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
return NULL;
mono_error_init (error);
mono_loader_lock ();
- sig = method_builder_to_signature (klass->image, mb);
+ g_assert (klass->image != NULL);
+ sig = method_builder_to_signature (klass->image, mb, error);
mono_loader_unlock ();
+ return_val_if_nok (error, NULL);
if (!reflection_methodbuilder_from_method_builder (&rmb, mb, error))
return NULL;
}
static MonoClassField*
-fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* fb)
+fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* fb, MonoError *error)
{
MonoClassField *field;
MonoType *custom;
- MonoError error;
+
+ mono_error_init (error);
field = g_new0 (MonoClassField, 1);
- field->name = mono_string_to_utf8_image (klass->image, fb->name, &error);
- g_assert (mono_error_ok (&error));
+ field->name = mono_string_to_utf8_image (klass->image, fb->name, error);
+ mono_error_assert_ok (error);
if (fb->attrs || fb->modreq || fb->modopt) {
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, &error);
- if (!is_ok (&error)) {
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+ if (!is_ok (error)) {
g_free (field);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return NULL;
}
field->type = mono_metadata_type_dup (NULL, type);
field->type->attrs = fb->attrs;
g_assert (image_is_dynamic (klass->image));
- custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt);
+ custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt, error);
g_free (field->type);
+ if (!is_ok (error)) {
+ g_free (field);
+ return NULL;
+ }
field->type = mono_metadata_type_dup (klass->image, custom);
g_free (custom);
} else {
- field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, &error);
- if (!is_ok (&error)) {
+ field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+ if (!is_ok (error)) {
g_free (field);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return NULL;
}
}
if (fb->offset != -1)
}
#endif
+/**
+ * mono_reflection_bind_generic_parameters:
+ * @type: a managed type object (which should be some kind of generic (instance? definition?))
+ * @type_args: the number of type arguments to bind
+ * @types: array of type arguments
+ * @error: set on error
+ *
+ * Given a managed type object for a generic type instance, binds each of its arguments to the specified types.
+ * Returns the MonoType* for the resulting type instantiation. On failure returns NULL and sets @error.
+ */
MonoType*
-mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
+mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types, MonoError *error)
{
- MonoError error;
MonoClass *klass;
MonoReflectionTypeBuilder *tb = NULL;
gboolean is_dynamic = FALSE;
MonoClass *geninst;
+ mono_error_init (error);
+
mono_loader_lock ();
if (is_sre_type_builder (mono_object_class (type))) {
if (tb && tb->generic_container)
mono_reflection_create_generic_class (tb);
- MonoType *t = mono_reflection_type_get_handle (type, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *t = mono_reflection_type_get_handle (type, error);
+ if (!is_ok (error)) {
+ mono_loader_unlock ();
+ return NULL;
+ }
klass = mono_class_from_mono_type (t);
if (!klass->generic_container) {
mono_loader_unlock ();
+ mono_error_set_type_load_class (error, klass, "Cannot bind generic parameters of a non-generic type");
return NULL;
}
}
/*TODO avoid saving custom attrs for generic classes as it's enough to have them on the generic type definition.*/
-void
-mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
+static gboolean
+reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields, MonoError *error)
{
- MonoError error;
MonoGenericClass *gclass;
MonoDynamicGenericClass *dgclass;
MonoClass *klass, *gklass;
MonoType *gtype;
int i;
- gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_init (error);
+
+ gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type, error);
+ return_val_if_nok (error, FALSE);
klass = mono_class_from_mono_type (gtype);
g_assert (gtype->type == MONO_TYPE_GENERICINST);
gclass = gtype->data.generic_class;
if (!gclass->is_dynamic)
- return;
+ return TRUE;
dgclass = (MonoDynamicGenericClass *) gclass;
if (dgclass->initialized)
- return;
+ return TRUE;
gklass = gclass->container_class;
mono_class_init (gklass);
dgclass->field_generic_types = mono_image_set_new0 (gclass->owner, MonoType*, dgclass->count_fields);
for (i = 0; i < dgclass->count_fields; i++) {
- MonoError error;
MonoObject *obj = (MonoObject *)mono_array_get (fields, gpointer, i);
MonoClassField *field, *inflated_field = NULL;
- if (!strcmp (obj->vtable->klass->name, "FieldBuilder"))
- inflated_field = field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj);
- else if (!strcmp (obj->vtable->klass->name, "MonoField"))
+ if (!strcmp (obj->vtable->klass->name, "FieldBuilder")) {
+ inflated_field = field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj, error);
+ return_val_if_nok (error, FALSE);
+ } else if (!strcmp (obj->vtable->klass->name, "MonoField"))
field = ((MonoReflectionField *) obj)->field;
else {
field = NULL; /* prevent compiler warning */
dgclass->fields [i] = *field;
dgclass->fields [i].parent = klass;
dgclass->fields [i].type = mono_class_inflate_generic_type_checked (
- field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass), &error);
- mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass), error);
+ mono_error_assert_ok (error); /* FIXME don't swallow the error */
dgclass->field_generic_types [i] = field->type;
MONO_GC_REGISTER_ROOT_IF_MOVING (dgclass->field_objects [i], MONO_ROOT_SOURCE_REFLECTION, "dynamic generic class field object");
dgclass->field_objects [i] = obj;
}
dgclass->initialized = TRUE;
+ return TRUE;
+}
+
+void
+mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
+{
+ MonoError error;
+ (void) reflection_generic_class_initialize (type, fields, &error);
+ mono_error_set_pending_exception (&error);
}
void
}
}
-static void
-fix_partial_generic_class (MonoClass *klass)
+/**
+ * fix_partial_generic_class:
+ * @klass: a generic instantiation MonoClass
+ * @error: set on error
+ *
+ * Assumes that the generic container of @klass has its vtable
+ * initialized, and updates the parent class, insterfaces, methods and
+ * fields of @klass by inflating the types using the generic context.
+ *
+ * On success returns TRUE, on failure returns FALSE and sets @error.
+ *
+ */
+static gboolean
+fix_partial_generic_class (MonoClass *klass, MonoError *error)
{
MonoClass *gklass = klass->generic_class->container_class;
MonoDynamicGenericClass *dgclass;
int i;
+ mono_error_init (error);
+
if (klass->wastypebuilder)
- return;
+ return TRUE;
dgclass = (MonoDynamicGenericClass *) klass->generic_class;
if (klass->parent != gklass->parent) {
- MonoError error;
- MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, &error);
- if (mono_error_ok (&error)) {
+ MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
+ if (mono_error_ok (error)) {
MonoClass *parent = mono_class_from_mono_type (parent_type);
mono_metadata_free_type (parent_type);
if (parent != klass->parent) {
mono_class_setup_parent (klass, parent);
}
} else {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
- mono_error_cleanup (&error);
if (gklass->wastypebuilder)
klass->wastypebuilder = TRUE;
- return;
+ return FALSE;
}
}
if (!dgclass->initialized)
- return;
+ return TRUE;
if (klass->method.count != gklass->method.count) {
klass->method.count = gklass->method.count;
klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
for (i = 0; i < klass->method.count; i++) {
- MonoError error;
klass->methods [i] = mono_class_inflate_generic_method_full_checked (
- gklass->methods [i], klass, mono_class_get_context (klass), &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ gklass->methods [i], klass, mono_class_get_context (klass), error);
+ mono_error_assert_ok (error);
}
}
klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
for (i = 0; i < gklass->interface_count; ++i) {
- MonoError error;
- MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
+ return_val_if_nok (error, FALSE);
klass->interfaces [i] = mono_class_from_mono_type (iface_type);
mono_metadata_free_type (iface_type);
- ensure_runtime_vtable (klass->interfaces [i], &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!ensure_runtime_vtable (klass->interfaces [i], error))
+ return FALSE;
}
klass->interfaces_inited = 1;
}
klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
for (i = 0; i < klass->field.count; i++) {
- MonoError error;
klass->fields [i] = gklass->fields [i];
klass->fields [i].parent = klass;
- klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
+ return_val_if_nok (error, FALSE);
}
}
/*We can only finish with this klass once it's parent has as well*/
if (gklass->wastypebuilder)
klass->wastypebuilder = TRUE;
- return;
+ return TRUE;
}
/**
if (!ensure_runtime_vtable (gklass, error))
return FALSE;
- fix_partial_generic_class (klass);
-
- return TRUE;
+ return fix_partial_generic_class (klass, error);
}
/**
klass->interfaces_inited = 1;
}
} else if (klass->generic_class){
- if (!ensure_generic_class_runtime_vtable (klass, error))
+ if (!ensure_generic_class_runtime_vtable (klass, error)) {
+ mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
return FALSE;
+ }
}
if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
}
static MonoMethod*
-mono_reflection_method_get_handle (MonoObject *method)
+mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
{
- MonoError error;
+ mono_error_init (error);
MonoClass *klass = mono_object_class (method);
if (is_sr_mono_method (klass) || is_sr_mono_generic_method (klass)) {
MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
MonoMethod *result;
/*FIXME move this to a proper method and unify with resolve_object*/
if (m->method_args) {
- result = mono_reflection_method_on_tb_inst_get_handle (m, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ result = mono_reflection_method_on_tb_inst_get_handle (m, error);
} else {
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
+ return_val_if_nok (error, NULL);
MonoClass *inflated_klass = mono_class_from_mono_type (type);
MonoMethod *mono_method;
}
void
-mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
+mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
{
MonoReflectionTypeBuilder *tb;
int i, j, onum;
MonoReflectionMethod *m;
+ mono_error_init (error);
*overrides = NULL;
*num_overrides = 0;
for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
- (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m);
+ (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
+ return_if_nok (error);
(*overrides) [onum * 2 + 1] = mb->mhandle;
g_assert (mb->mhandle);
}
klass->instance_size = MAX (klass->instance_size, real_size);
- mono_class_layout_fields (klass);
+ mono_class_layout_fields (klass, klass->instance_size);
}
static void
}
}
-MonoReflectionEvent *
-mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
+static MonoReflectionEvent *
+reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb, MonoError *error)
{
- MonoError error;
+ mono_error_init (error);
+
MonoEvent *event = g_new0 (MonoEvent, 1);
MonoClass *klass;
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
+ if (!is_ok (error)) {
+ g_free (event);
+ return NULL;
+ }
klass = mono_class_from_mono_type (type);
event->parent = klass;
}
#endif
- MonoReflectionEvent *ev_obj = mono_event_get_object_checked (mono_object_domain (tb), klass, event, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoReflectionEvent *ev_obj = mono_event_get_object_checked (mono_object_domain (tb), klass, event, error);
+ if (!is_ok (error)) {
+#ifndef MONO_SMALL_CONFIG
+ g_free (event->other);
+#endif
+ g_free (event);
+ return NULL;
+ }
return ev_obj;
}
+MonoReflectionEvent *
+mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
+{
+ MonoError error;
+ MonoReflectionEvent *result = reflection_event_builder_get_event_info (tb, eb, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
+}
+
static void
typebuilder_setup_events (MonoClass *klass, MonoError *error)
{
}
}
+struct remove_instantiations_user_data
+{
+ MonoClass *klass;
+ MonoError *error;
+};
+
static gboolean
remove_instantiations_of_and_ensure_contents (gpointer key,
gpointer value,
gpointer user_data)
{
+ struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
MonoType *type = (MonoType*)key;
- MonoClass *klass = (MonoClass*)user_data;
+ MonoClass *klass = data->klass;
+ gboolean already_failed = !is_ok (data->error);
+ MonoError lerror;
+ MonoError *error = already_failed ? &lerror : data->error;
if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
- fix_partial_generic_class (mono_class_from_mono_type (type)); //Ensure it's safe to use it.
+ MonoClass *inst_klass = mono_class_from_mono_type (type);
+ //Ensure it's safe to use it.
+ if (!fix_partial_generic_class (inst_klass, error)) {
+ mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ // Marked the class with failure, but since some other instantiation already failed,
+ // just report that one, and swallow the error from this one.
+ if (already_failed)
+ mono_error_cleanup (error);
+ }
return TRUE;
} else
return FALSE;
MonoReflectionType* res;
int i, j;
+ mono_error_init (&error);
+
domain = mono_object_domain (tb);
klass = mono_class_from_mono_type (tb->type.type);
* Check for user defined Type subclasses.
*/
RESOLVE_TYPE (tb->parent, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
check_array_for_usertypes (tb->interfaces, &error);
- mono_error_raise_exception (&error); /*FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
if (tb->fields) {
for (i = 0; i < mono_array_length (tb->fields); ++i) {
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
if (fb) {
RESOLVE_TYPE (fb->type, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
check_array_for_usertypes (fb->modreq, &error);
- mono_error_raise_exception (&error); /*FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
check_array_for_usertypes (fb->modopt, &error);
- mono_error_raise_exception (&error); /*FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
if (fb->marshal_info && fb->marshal_info->marshaltyperef) {
RESOLVE_TYPE (fb->marshal_info->marshaltyperef, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
}
}
}
MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)mono_array_get (tb->methods, gpointer, i);
if (mb) {
RESOLVE_TYPE (mb->rtype, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
check_array_for_usertypes (mb->return_modreq, &error);
- mono_error_raise_exception (&error); /*FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
check_array_for_usertypes (mb->return_modopt, &error);
- mono_error_raise_exception (&error); /*FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
check_array_for_usertypes (mb->parameters, &error);
- mono_error_raise_exception (&error); /*FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
if (mb->param_modreq)
for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
- mono_error_raise_exception (&error); /*FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
}
if (mb->param_modopt)
for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
- mono_error_raise_exception (&error); /*FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
}
}
}
MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)mono_array_get (tb->ctors, gpointer, i);
if (mb) {
check_array_for_usertypes (mb->parameters, &error);
- mono_error_raise_exception (&error); /*FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
if (mb->param_modreq)
for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
- mono_error_raise_exception (&error); /*FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
}
if (mb->param_modopt)
for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
- mono_error_raise_exception (&error); /*FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
}
}
}
mono_loader_unlock ();
res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_set_pending_exception (&error);
return res;
}
mono_domain_unlock (domain);
res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_set_pending_exception (&error);
return res;
}
*
* Together with this we must ensure the contents of all instances to match the created type.
*/
- if (domain->type_hash && klass->generic_container)
- mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, klass);
+ if (domain->type_hash && klass->generic_container) {
+ struct remove_instantiations_user_data data;
+ data.klass = klass;
+ data.error = &error;
+ mono_error_assert_ok (&error);
+ mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
+ if (!is_ok (&error))
+ goto failure;
+ }
mono_domain_unlock (domain);
mono_loader_unlock ();
if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
- mono_raise_exception (mono_get_exception_type_load (tb->name, NULL));
+ mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
+ goto failure_unlocked;
}
res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!is_ok (&error))
+ goto failure_unlocked;
g_assert (res != (MonoReflectionType*)tb);
klass->wastypebuilder = TRUE;
mono_domain_unlock (domain);
mono_loader_unlock ();
- mono_error_raise_exception (&error);
+failure_unlocked:
+ mono_error_set_pending_exception (&error);
return NULL;
}
-void
-mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
+static gboolean
+reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error)
{
MonoGenericParamFull *param;
MonoImage *image;
MonoClass *pklass;
- MonoError error;
+
+ mono_error_init (error);
image = &gparam->tbuilder->module->dynamic_image->image;
param = mono_image_new0 (image, MonoGenericParamFull, 1);
- param->info.name = mono_string_to_utf8_image (image, gparam->name, &error);
- g_assert (mono_error_ok (&error));
+ param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
+ mono_error_assert_ok (error);
param->param.num = gparam->index;
if (gparam->mbuilder) {
if (!gparam->mbuilder->generic_container) {
- MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error);
+ return_val_if_nok (error, FALSE);
MonoClass *klass = mono_class_from_mono_type (tb);
gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
param->param.owner = gparam->mbuilder->generic_container;
} else if (gparam->tbuilder) {
if (!gparam->tbuilder->generic_container) {
- MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error);
+ return_val_if_nok (error, FALSE);
MonoClass *klass = mono_class_from_mono_type (tb);
gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
gparam->tbuilder->generic_container->owner.klass = klass;
mono_class_set_ref_info (pklass, gparam);
mono_image_append_class_to_reflection_info_set (pklass);
+
+ return TRUE;
}
+void
+mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
+{
+ MonoError error;
+ (void) reflection_initialize_generic_parameter (gparam, &error);
+ mono_error_set_pending_exception (&error);
+}
+
+
MonoArray *
mono_reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig)
{
g_free (data);
}
-void
-mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
+static gboolean
+reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
{
- MonoError error;
MonoReferenceQueue *queue;
MonoMethod *handle;
DynamicMethodReleaseData *release_data;
GSList *l;
int i;
- if (mono_runtime_is_shutting_down ())
- mono_raise_exception (mono_get_exception_invalid_operation (""));
+ mono_error_init (error);
+
+ if (mono_runtime_is_shutting_down ()) {
+ mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
+ return FALSE;
+ }
if (!(queue = dynamic_method_queue)) {
mono_loader_lock ();
mono_loader_unlock ();
}
- sig = dynamic_method_to_signature (mb);
+ sig = dynamic_method_to_signature (mb, error);
+ return_val_if_nok (error, FALSE);
reflection_methodbuilder_from_dynamic_method (&rmb, mb);
handle_class = mono_defaults.methodhandle_class;
} else {
MonoException *ex = NULL;
- ref = resolve_object (mb->module->image, obj, &handle_class, NULL);
+ ref = resolve_object (mb->module->image, obj, &handle_class, NULL, error);
+ if (!is_ok (error)) {
+ g_free (rmb.refs);
+ return FALSE;
+ }
if (!ref)
ex = mono_get_exception_type_load (NULL, NULL);
else if (mono_security_core_clr_enabled ())
if (ex) {
g_free (rmb.refs);
- mono_raise_exception (ex);
- return;
+ mono_error_set_exception_instance (error, ex);
+ return FALSE;
}
}
}
if (mb->owner) {
- MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, &error);
- if (!is_ok (&error)) {
+ MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
+ if (!is_ok (error)) {
g_free (rmb.refs);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return FALSE;
}
klass = mono_class_from_mono_type (owner_type);
} else {
domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
mono_domain_unlock (domain);
+
+ return TRUE;
+}
+
+void
+mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
+{
+ MonoError error;
+ (void) reflection_create_dynamic_method (mb, &error);
+ mono_error_set_pending_exception (&error);
}
#endif /* DISABLE_REFLECTION_EMIT */
* LOCKING: Take the loader lock
*/
gpointer
-mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context)
+mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
{
MonoDynamicImage *assembly = (MonoDynamicImage*)image;
MonoObject *obj;
MonoClass *klass;
+ mono_error_init (error);
+
obj = lookup_dyn_token (assembly, token);
if (!obj) {
if (valid_token)
g_error ("Could not find required dynamic token 0x%08x", token);
- else
+ else {
+ mono_error_set_execution_engine (error, "Could not find dynamic token 0x%08x", token);
return NULL;
+ }
}
if (!handle_class)
handle_class = &klass;
- return resolve_object (image, obj, handle_class, context);
+ gpointer result = resolve_object (image, obj, handle_class, context, error);
+ return result;
}
/*
* dynamic types.
*/
static void
-ensure_complete_type (MonoClass *klass)
+ensure_complete_type (MonoClass *klass, MonoError *error)
{
- MonoError error;
+ mono_error_init (error);
if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
- mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
+ return_if_nok (error);
// Asserting here could break a lot of code
//g_assert (klass->wastypebuilder);
int i;
for (i = 0; i < inst->type_argc; ++i) {
- ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]));
+ ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
+ return_if_nok (error);
}
}
}
static gpointer
-resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context)
+resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
{
- MonoError error;
gpointer result = NULL;
+ mono_error_init (error);
+
if (strcmp (obj->vtable->klass->name, "String") == 0) {
- result = mono_string_intern_checked ((MonoString*)obj, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ result = mono_string_intern_checked ((MonoString*)obj, error);
+ return_val_if_nok (error, NULL);
*handle_class = mono_defaults.string_class;
g_assert (result);
} else if (strcmp (obj->vtable->klass->name, "MonoType") == 0) {
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
+ return_val_if_nok (error, NULL);
MonoClass *mc = mono_class_from_mono_type (type);
- if (!mono_class_init (mc))
- mono_raise_exception (mono_class_get_exception_for_failure (mc));
+ if (!mono_class_init (mc)) {
+ mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (mc));
+ return NULL;
+ }
if (context) {
- MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
+ return_val_if_nok (error, NULL);
result = mono_class_from_mono_type (inflated);
mono_metadata_free_type (inflated);
strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
result = ((MonoReflectionMethod*)obj)->method;
if (context) {
- MonoError error;
- result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
+ mono_error_assert_ok (error);
}
*handle_class = mono_defaults.methodhandle_class;
g_assert (result);
/* Type is not yet created */
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
- mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
+ return_val_if_nok (error, NULL);
/*
* Hopefully this has been filled in by calling CreateType() on the
result = mb->mhandle;
}
if (context) {
- MonoError error;
- result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
+ mono_error_assert_ok (error);
}
*handle_class = mono_defaults.methodhandle_class;
} else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
if (!result) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)cb->type;
- mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
+ return_val_if_nok (error, NULL);
result = cb->mhandle;
}
if (context) {
- MonoError error;
- result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
+ mono_error_assert_ok (error);
}
*handle_class = mono_defaults.methodhandle_class;
} else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
MonoClassField *field = ((MonoReflectionField*)obj)->field;
- ensure_complete_type (field->parent);
+ ensure_complete_type (field->parent, error);
+ return_val_if_nok (error, NULL);
+
if (context) {
- MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
+ return_val_if_nok (error, NULL);
MonoClass *klass = mono_class_from_mono_type (inflated);
MonoClassField *inflated_field;
if (!result) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)fb->typeb;
- mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
+ return_val_if_nok (error, NULL);
result = fb->handle;
}
if (fb->handle && fb->handle->parent->generic_container) {
MonoClass *klass = fb->handle->parent;
- MonoType *type = mono_class_inflate_generic_type_checked (&klass->byval_arg, context, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *type = mono_class_inflate_generic_type_checked (&klass->byval_arg, context, error);
+ return_val_if_nok (error, NULL);
MonoClass *inflated = mono_class_from_mono_type (type);
*handle_class = mono_defaults.fieldhandle_class;
} else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
+ return_val_if_nok (error, NULL);
MonoClass *klass;
klass = type->data.klass;
result = klass;
}
else {
- mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
+ return_val_if_nok (error, NULL);
result = type->data.klass;
g_assert (result);
}
/* TODO: Copy type ? */
sig->ret = helper->return_type->type;
for (i = 0; i < nargs; ++i) {
- sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
+ if (!is_ok (error)) {
+ image_g_free (image, sig);
+ return NULL;
+ }
}
result = sig;
result = method->mhandle;
*handle_class = mono_defaults.methodhandle_class;
} else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
- type = mono_class_inflate_generic_type_checked (type, context, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
+ return_val_if_nok (error, NULL);
+ type = mono_class_inflate_generic_type_checked (type, context, error);
+ return_val_if_nok (error, NULL);
result = mono_class_from_mono_type (type);
*handle_class = mono_defaults.typehandle_class;
g_assert (result);
mono_metadata_free_type (type);
} else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
- type = mono_class_inflate_generic_type_checked (type, context, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
+ return_val_if_nok (error, NULL);
+ type = mono_class_inflate_generic_type_checked (type, context, error);
+ return_val_if_nok (error, NULL);
result = mono_class_from_mono_type (type);
*handle_class = mono_defaults.typehandle_class;
else
g_error ("resolve_object:: can't handle a FTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (f->fb)));
- MonoType *finst = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
- type = mono_class_inflate_generic_type_checked (finst, context, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *finst = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
+ return_val_if_nok (error, NULL);
+ type = mono_class_inflate_generic_type_checked (finst, context, error);
+ return_val_if_nok (error, NULL);
inflated = mono_class_from_mono_type (type);
result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
- ensure_complete_type (field->parent);
+ ensure_complete_type (field->parent, error);
+ if (!is_ok (error)) {
+ mono_metadata_free_type (type);
+ return NULL;
+ }
+
g_assert (result);
mono_metadata_free_type (type);
*handle_class = mono_defaults.fieldhandle_class;
} else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
- MonoType *cinst = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
- MonoType *type = mono_class_inflate_generic_type_checked (cinst, context, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *cinst = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
+ return_val_if_nok (error, NULL);
+ MonoType *type = mono_class_inflate_generic_type_checked (cinst, context, error);
+ return_val_if_nok (error, NULL);
MonoClass *inflated_klass = mono_class_from_mono_type (type);
MonoMethod *method;
} else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
if (m->method_args) {
- result = mono_reflection_method_on_tb_inst_get_handle (m, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ result = mono_reflection_method_on_tb_inst_get_handle (m, error);
+ return_val_if_nok (error, NULL);
if (context) {
- result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, &error);
- mono_error_assert_ok (&error);
+ result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
+ mono_error_assert_ok (error);
}
} else {
- MonoType *minst = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
- MonoType *type = mono_class_inflate_generic_type_checked (minst, context, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *minst = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
+ return_val_if_nok (error, NULL);
+ MonoType *type = mono_class_inflate_generic_type_checked (minst, context, error);
+ return_val_if_nok (error, NULL);
MonoClass *inflated_klass = mono_class_from_mono_type (type);
MonoMethod *method;
gpointer iter;
char *name;
- mtype = mono_reflection_type_get_handle (m->parent, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mtype = mono_reflection_type_get_handle (m->parent, error);
+ return_val_if_nok (error, NULL);
klass = mono_class_from_mono_type (mtype);
/* Find the method */
is_sre_byref (mono_object_get_class(obj)) ||
is_sre_pointer (mono_object_get_class(obj))) {
MonoReflectionType *ref_type = (MonoReflectionType *)obj;
- MonoType *type = mono_reflection_type_get_handle (ref_type, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *type = mono_reflection_type_get_handle (ref_type, error);
+ return_val_if_nok (error, NULL);
if (context) {
- MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
+ return_val_if_nok (error, NULL);
result = mono_class_from_mono_type (inflated);
mono_metadata_free_type (inflated);
}
MonoReflectionModule *
-mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
+mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName, MonoError *error)
{
g_assert_not_reached ();
return NULL;
}
void
-mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
+mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
{
+ mono_error_init (error);
*overrides = NULL;
*num_overrides = 0;
}
}
MonoType*
-mono_reflection_type_get_handle (MonoReflectionType* ref)
+mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
{
+ mono_error_init (error);
if (!ref)
return NULL;
return ref->type;
}
gboolean
-mono_reflection_call_is_assignable_to (MonoClass *klass, MonoClass *oklass)
+mono_reflection_call_is_assignable_to (MonoClass *klass, MonoClass *oklass, MonoError *error)
{
- MonoError error;
MonoObject *res, *exc;
void *params [1];
static MonoMethod *method = NULL;
+ mono_error_init (error);
+
if (method == NULL) {
method = mono_class_get_method_from_name (mono_class_get_type_builder_class (), "IsAssignableTo", 1);
g_assert (method);
g_assert (mono_class_get_ref_info (klass));
g_assert (!strcmp (((MonoObject*)(mono_class_get_ref_info (klass)))->vtable->klass->name, "TypeBuilder"));
- params [0] = mono_type_get_object_checked (mono_domain_get (), &oklass->byval_arg, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ params [0] = mono_type_get_object_checked (mono_domain_get (), &oklass->byval_arg, error);
+ return_val_if_nok (error, FALSE);
- res = mono_runtime_try_invoke (method, (MonoObject*)(mono_class_get_ref_info (klass)), params, &exc, &error);
+ res = mono_runtime_try_invoke (method, (MonoObject*)(mono_class_get_ref_info (klass)), params, &exc, error);
- if (exc || !mono_error_ok (&error)) {
- mono_error_cleanup (&error);
+ if (exc || !mono_error_ok (error)) {
+ mono_error_cleanup (error);
return FALSE;
} else
return *(MonoBoolean*)mono_object_unbox (res);