-/*
- * sre.c: Routines for creating an image at runtime
- * and related System.Reflection.Emit icalls
+/**
+ * \file
+ * Routines for creating an image at runtime
+ * and related System.Reflection.Emit icalls
*
*
* Author:
#include "mono/metadata/tokentype.h"
#include "mono/utils/checked-build.h"
#include "mono/utils/mono-digest.h"
+#include "mono/utils/w32api.h"
+
+static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, "System.Runtime.InteropServices", "MarshalAsAttribute");
+static GENERATE_GET_CLASS_WITH_CACHE (module_builder, "System.Reflection.Emit", "ModuleBuilder");
-static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
-static GENERATE_GET_CLASS_WITH_CACHE (module_builder, System.Reflection.Emit, ModuleBuilder);
+static char* string_to_utf8_image_raw (MonoImage *image, MonoString *s, MonoError *error);
#ifndef DISABLE_REFLECTION_EMIT
-static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
-static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
+static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error);
static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error);
static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
-static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error);
+static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
+static gboolean reflection_init_generic_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
+static gboolean reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error);
+
static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
#endif
static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass);
-static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error);
+static MonoReflectionTypeHandle mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error);
static gboolean is_sre_array (MonoClass *klass);
static gboolean is_sre_byref (MonoClass *klass);
static gboolean is_sre_pointer (MonoClass *klass);
static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
+static guint32 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error);
+
-#define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
+#ifndef DISABLE_REFLECTION_EMIT
+static MonoType* mono_type_array_get_and_resolve_raw (MonoArray* array, int idx, MonoError* error);
+#endif
-static void mono_image_module_basic_init (MonoReflectionModuleBuilder *module);
+static gboolean mono_image_module_basic_init (MonoReflectionModuleBuilderHandle module, MonoError *error);
void
mono_reflection_emit_init (void)
mono_dynamic_images_init ();
}
+char*
+string_to_utf8_image_raw (MonoImage *image, MonoString *s_raw, MonoError *error)
+{
+ /* FIXME all callers to string_to_utf8_image_raw should use handles */
+ HANDLE_FUNCTION_ENTER ();
+ char* result = NULL;
+ error_init (error);
+ MONO_HANDLE_DCL (MonoString, s);
+ result = mono_string_to_utf8_image (image, s, error);
+ HANDLE_FUNCTION_RETURN_VAL (result);
+}
+
static char*
type_get_fully_qualified_name (MonoType *type)
{
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoExceptionClause *clauses;
MonoExceptionClause *clause;
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
memset (rmb, 0, sizeof (ReflectionMethodBuilder));
rmb->ilgen = mb->ilgen;
const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
- mono_error_init (error);
+ error_init (error);
memset (rmb, 0, sizeof (ReflectionMethodBuilder));
rmb->call_conv = mb->call_conv;
rmb->code = NULL;
rmb->type = mb->type;
- rmb->name = mono_string_new (mono_domain_get (), name);
+ rmb->name = mono_string_new_checked (mono_domain_get (), name, error);
+ return_val_if_nok (error, FALSE);
rmb->table_idx = &mb->table_idx;
rmb->init_locals = mb->init_locals;
rmb->skip_visibility = FALSE;
}
-static guint32
+guint32
mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
{
MONO_REQ_GC_NEUTRAL_MODE;
return token;
}
+#else /* DISABLE_REFLECTION_EMIT */
+
+guint32
+mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
+{
+ g_assert_not_reached ();
+ return -1;
+}
#endif
static gboolean
#ifndef DISABLE_REFLECTION_EMIT
static guint32
-mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
+mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObjectHandle f, MonoClassField *field)
{
MonoType *type;
guint32 token;
g_assert (field);
g_assert (field->parent);
- token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, MONO_HANDLE_RAW (f)));
if (token)
return token;
token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
mono_field_get_name (field),
mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
- mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
+ mono_g_hash_table_insert (assembly->handleref_managed, MONO_HANDLE_RAW (f), GUINT_TO_POINTER(token));
return token;
}
}
static guint32
-mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
+mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
{
guint32 idx;
MonoDynamicTable *table;
guint32 *values;
- mono_error_init (error);
+ error_init (error);
table = &assembly->tables [MONO_TABLE_STANDALONESIG];
idx = table->next_idx ++;
#ifndef DISABLE_REFLECTION_EMIT
static guint32
-mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
+mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethodHandle m, MonoError *error)
{
- guint32 nparams, i;
- GList *tmp;
+ MonoMethodSignature *sig = NULL;
char *name = NULL;
- MonoMethodSignature *sig;
- ArrayMethod *am = NULL;
- MonoType *mtype;
- mono_error_init (error);
+ error_init (error);
- nparams = mono_array_length (m->parameters);
+ MonoArrayHandle parameters = MONO_HANDLE_NEW_GET (MonoArray, m, parameters);
+ guint32 nparams = mono_array_handle_length (parameters);
sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
sig->hasthis = 1;
sig->sentinelpos = -1;
- sig->call_convention = reflection_cc_to_file (m->call_conv);
+ sig->call_convention = reflection_cc_to_file (MONO_HANDLE_GETVAL (m, call_conv));
sig->param_count = nparams;
- if (m->ret) {
- sig->ret = mono_reflection_type_get_handle (m->ret, error);
+ MonoReflectionTypeHandle ret = MONO_HANDLE_NEW_GET (MonoReflectionType, m, ret);
+ if (!MONO_HANDLE_IS_NULL (ret)) {
+ sig->ret = mono_reflection_type_handle_mono_type (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);
+ MonoReflectionTypeHandle parent = MONO_HANDLE_NEW_GET (MonoReflectionType, m, parent);
+ MonoType *mtype = mono_reflection_type_handle_mono_type (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);
+ for (int i = 0; i < nparams; ++i) {
+ sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
if (!is_ok (error))
goto fail;
}
- name = mono_string_to_utf8_checked (m->name, error);
+ MonoStringHandle mname = MONO_HANDLE_NEW_GET (MonoString, m, name);
+ name = mono_string_handle_to_utf8 (mname, error);
if (!is_ok (error))
goto fail;
- for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
+
+ ArrayMethod *am = NULL;
+ for (GList *tmp = assembly->array_methods; tmp; tmp = tmp->next) {
am = (ArrayMethod *)tmp->data;
if (strcmp (name, am->name) == 0 &&
mono_metadata_type_equal (am->parent, mtype) &&
mono_metadata_signature_equal (am->sig, sig)) {
g_free (name);
g_free (sig);
- m->table_idx = am->token & 0xffffff;
+ MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
return am->token;
}
}
am->token = mono_image_get_memberref_token (assembly, am->parent, name,
mono_dynimage_encode_method_signature (assembly, sig));
assembly->array_methods = g_list_prepend (assembly->array_methods, am);
- m->table_idx = am->token & 0xffffff;
+ MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
return am->token;
fail:
- g_free (am);
g_free (name);
g_free (sig);
return 0;
* Insert @str into the user string stream of @module.
*/
guint32
-mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
+mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module, MonoStringHandle str, MonoError *error)
{
- MonoDynamicImage *assembly;
+ HANDLE_FUNCTION_ENTER ();
guint32 idx;
char buf [16];
char *b = buf;
-
- if (!module->dynamic_image)
- mono_image_module_basic_init (module);
+ guint32 token = 0;
+
+ MonoDynamicImage *assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
+ if (!assembly) {
+ if (!mono_image_module_basic_init (ref_module, error))
+ goto leave;
+
+ assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
+ }
+ g_assert (assembly != NULL);
- assembly = module->dynamic_image;
-
if (assembly->save) {
- mono_metadata_encode_value (1 | (str->length * 2), b, &b);
+ int32_t length = mono_string_length (MONO_HANDLE_RAW (str));
+ mono_metadata_encode_value (1 | (length * 2), b, &b);
idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
+ /* pinned */
+ uint32_t gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, str), TRUE);
+ const char *p = (const char*)mono_string_chars (MONO_HANDLE_RAW (str));
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
{
- char *swapped = g_malloc (2 * mono_string_length (str));
- const char *p = (const char*)mono_string_chars (str);
+ char *swapped = g_malloc (2 * length);
- swap_with_size (swapped, p, 2, mono_string_length (str));
- mono_image_add_stream_data (&assembly->us, swapped, str->length * 2);
+ swap_with_size (swapped, p, 2, length);
+ mono_image_add_stream_data (&assembly->us, swapped, length * 2);
g_free (swapped);
}
#else
- mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
+ mono_image_add_stream_data (&assembly->us, p, length * 2);
#endif
+ mono_gchandle_free (gchandle);
mono_image_add_stream_data (&assembly->us, "", 1);
} else {
idx = assembly->us.index ++;
}
- mono_dynamic_image_register_token (assembly, MONO_TOKEN_STRING | idx, (MonoObject*)str);
+ token = MONO_TOKEN_STRING | idx;
+ mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str), MONO_DYN_IMAGE_TOK_NEW);
- return MONO_TOKEN_STRING | idx;
+leave:
+ HANDLE_FUNCTION_RETURN_VAL (token);
}
-guint32
-mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
+static guint32
+create_method_token (MonoDynamicImage *assembly, MonoMethod *method, MonoArrayHandle opt_param_types, MonoError *error)
{
- MonoClass *klass;
- guint32 token = 0;
- MonoMethodSignature *sig;
+ guint32 sig_token, parent;
- mono_error_init (error);
- klass = obj->vtable->klass;
- if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
- MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
- MonoMethodSignature *old;
- guint32 sig_token, parent;
- int nargs, i;
+ int nargs = mono_array_handle_length (opt_param_types);
+ MonoMethodSignature *old = mono_method_signature (method);
+ MonoMethodSignature *sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
- g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));
-
- nargs = mono_array_length (opt_param_types);
- old = mono_method_signature (method);
- sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
-
- sig->hasthis = old->hasthis;
- sig->explicit_this = old->explicit_this;
- sig->call_convention = old->call_convention;
- sig->generic_param_count = old->generic_param_count;
- sig->param_count = old->param_count + nargs;
- sig->sentinelpos = old->param_count;
- sig->ret = old->ret;
-
- for (i = 0; i < old->param_count; i++)
- sig->params [i] = old->params [i];
-
- for (i = 0; i < nargs; i++) {
- MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
- sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt, error);
- if (!is_ok (error)) goto fail;
- }
+ sig->hasthis = old->hasthis;
+ sig->explicit_this = old->explicit_this;
+ sig->call_convention = old->call_convention;
+ sig->generic_param_count = old->generic_param_count;
+ sig->param_count = old->param_count + nargs;
+ sig->sentinelpos = old->param_count;
+ sig->ret = old->ret;
- parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
- g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
- parent >>= MONO_TYPEDEFORREF_BITS;
+ for (int i = 0; i < old->param_count; i++)
+ sig->params [i] = old->params [i];
- parent <<= MONO_MEMBERREF_PARENT_BITS;
- parent |= MONO_MEMBERREF_PARENT_TYPEREF;
+ MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
+ for (int i = 0; i < nargs; i++) {
+ MONO_HANDLE_ARRAY_GETREF (rt, opt_param_types, i);
+ sig->params [old->param_count + i] = mono_reflection_type_handle_mono_type (rt, error);
+ if (!is_ok (error)) goto fail;
+ }
- sig_token = mono_dynimage_encode_method_signature (assembly, sig);
- token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
- } else if (strcmp (klass->name, "MethodBuilder") == 0) {
- MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
- ReflectionMethodBuilder rmb;
- guint32 parent, sig_token;
- int nopt_args, nparams, ngparams, i;
+ parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
+ g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
+ parent >>= MONO_TYPEDEFORREF_BITS;
- if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
- goto fail;
-
- rmb.opt_types = opt_param_types;
- nopt_args = mono_array_length (opt_param_types);
-
- nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
- ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
- sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
-
- sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
- sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
- sig->call_convention = rmb.call_conv;
- sig->generic_param_count = ngparams;
- sig->param_count = nparams + nopt_args;
- sig->sentinelpos = nparams;
- sig->ret = mono_reflection_type_get_handle (rmb.rtype, error);
- if (!is_ok (error)) goto fail;
+ parent <<= MONO_MEMBERREF_PARENT_BITS;
+ parent |= MONO_MEMBERREF_PARENT_TYPEREF;
- for (i = 0; i < nparams; i++) {
- MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
- sig->params [i] = mono_reflection_type_get_handle (rt, error);
- if (!is_ok (error)) goto fail;
- }
+ sig_token = mono_dynimage_encode_method_signature (assembly, sig);
+ guint32 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
+ g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
+ return token;
+fail:
+ return 0;
+}
- for (i = 0; i < nopt_args; i++) {
- MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
- sig->params [nparams + i] = mono_reflection_type_get_handle (rt, error);
- if (!is_ok (error)) goto fail;
- }
+guint32
+mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
+{
+ guint32 token = 0;
- // FIXME: This doesn't work, we don't use 'sig' for anything
- // The token fixup doesn't work either
- g_assert_not_reached ();
+ error_init (error);
- sig_token = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
+ MonoClass *klass = mono_handle_class (obj);
+ if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
+ MonoReflectionMethodHandle ref_method = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
+ MonoMethod *method = MONO_HANDLE_GETVAL (ref_method, method);
+ g_assert (!MONO_HANDLE_IS_NULL (opt_param_types) && (mono_method_signature (method)->sentinelpos >= 0));
+ token = create_method_token (assembly, method, opt_param_types, error);
if (!is_ok (error))
goto fail;
-
- parent = mono_image_create_token (assembly, obj, TRUE, TRUE, error);
- if (!mono_error_ok (error))
- goto fail;
- g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
-
- parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
- parent |= MONO_MEMBERREF_PARENT_METHODDEF;
-
- char *name = mono_string_to_utf8_checked (rmb.name, error);
- if (!is_ok (error)) goto fail;
- token = mono_image_get_varargs_method_token (
- assembly, parent, name, sig_token);
- g_free (name);
+ } else if (strcmp (klass->name, "MethodBuilder") == 0) {
+ g_assert_not_reached ();
} else {
g_error ("requested method token for %s\n", klass->name);
}
- g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
- mono_dynamic_image_register_token (assembly, token, obj);
+ mono_dynamic_image_register_token (assembly, token, obj, MONO_DYN_IMAGE_TOK_NEW);
return token;
fail:
g_assert (!mono_error_ok (error));
* entry.
*/
guint32
-mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
+mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
gboolean create_open_instance, gboolean register_token,
MonoError *error)
{
- MonoClass *klass;
guint32 token = 0;
- mono_error_init (error);
+ error_init (error);
- klass = obj->vtable->klass;
+ MonoClass *klass = mono_handle_class (obj);
/* Check for user defined reflection objects */
/* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
return 0;
}
+ /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
+ int how_collide = MONO_DYN_IMAGE_TOK_SAME_OK;
+
if (strcmp (klass->name, "RuntimeType") == 0) {
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
+ MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
return_val_if_nok (error, 0);
MonoClass *mc = mono_class_from_mono_type (type);
token = mono_metadata_token_from_dor (
mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
+ /* If it's a RuntimeType now, we could have registered a
+ * TypeBuilder for it before, so replacing is okay. */
+ how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
} else if (strcmp (klass->name, "MonoCMethod") == 0 ||
strcmp (klass->name, "MonoMethod") == 0) {
- MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
- if (m->method->is_inflated) {
+ MonoReflectionMethodHandle m = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
+ MonoMethod *method = MONO_HANDLE_GETVAL (m, method);
+ if (method->is_inflated) {
if (create_open_instance)
- token = mono_image_get_methodspec_token (assembly, m->method);
+ token = mono_image_get_methodspec_token (assembly, method);
else
- token = mono_image_get_inflated_method_token (assembly, m->method);
- } else if ((m->method->klass->image == &assembly->image) &&
- !mono_class_is_ginst (m->method->klass)) {
+ token = mono_image_get_inflated_method_token (assembly, method);
+ } else if ((method->klass->image == &assembly->image) &&
+ !mono_class_is_ginst (method->klass)) {
static guint32 method_table_idx = 0xffffff;
- if (m->method->klass->wastypebuilder) {
+ if (method->klass->wastypebuilder) {
/* we use the same token as the one that was assigned
* to the Methodbuilder.
* FIXME: do the equivalent for Fields.
*/
- token = m->method->token;
+ token = method->token;
+ how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
} else {
/*
* Each token should have a unique index, but the indexes are
*/
method_table_idx --;
token = MONO_TOKEN_METHOD_DEF | method_table_idx;
+ how_collide = MONO_DYN_IMAGE_TOK_NEW;
}
} else {
- token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
+ token = mono_image_get_methodref_token (assembly, method, create_open_instance);
}
/*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
} else if (strcmp (klass->name, "MonoField") == 0) {
- MonoReflectionField *f = (MonoReflectionField *)obj;
- if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
+ MonoReflectionFieldHandle f = MONO_HANDLE_CAST (MonoReflectionField, obj);
+ MonoClassField *field = MONO_HANDLE_GETVAL (f, field);
+ if ((field->parent->image == &assembly->image) && !is_field_on_inst (field)) {
static guint32 field_table_idx = 0xffffff;
field_table_idx --;
token = MONO_TOKEN_FIELD_DEF | field_table_idx;
+ how_collide = MONO_DYN_IMAGE_TOK_NEW;
} else {
- token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
+ token = mono_image_get_fieldref_token (assembly, obj, field);
}
/*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
} else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
- MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
+ MonoReflectionArrayMethodHandle m = MONO_HANDLE_CAST (MonoReflectionArrayMethod, obj);
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;
+ MonoReflectionSigHelperHandle s = MONO_HANDLE_CAST (MonoReflectionSigHelper, obj);
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);
+ MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
return_val_if_nok (error, 0);
token = mono_metadata_token_from_dor (
mono_image_typedef_or_ref (assembly, type));
}
if (register_token)
- mono_image_register_token (assembly, token, obj);
+ mono_dynamic_image_register_token (assembly, token, obj, how_collide);
return token;
}
#ifndef DISABLE_REFLECTION_EMIT
+static gboolean
+assemblybuilderaccess_can_refonlyload (guint32 access)
+{
+ return (access & 0x4) != 0;
+}
+
+static gboolean
+assemblybuilderaccess_can_run (guint32 access)
+{
+ return (access & MonoAssemblyBuilderAccess_Run) != 0;
+}
+
+static gboolean
+assemblybuilderaccess_can_save (guint32 access)
+{
+ return (access & MonoAssemblyBuilderAccess_Save) != 0;
+}
+
+
/*
* mono_reflection_dynimage_basic_init:
* @assembly: an assembly builder object
if (assemblyb->dynamic_assembly)
return;
-#if HAVE_BOEHM_GC
- /* assembly->assembly.image might be GC allocated */
- assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
-#else
assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
-#endif
- mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
+ MONO_PROFILER_RAISE (assembly_loading, (&assembly->assembly));
assembly->assembly.ref_count = 1;
assembly->assembly.dynamic = TRUE;
assembly->assembly.aname.revision = 0;
}
- assembly->run = assemblyb->access != 2;
- assembly->save = assemblyb->access != 1;
+ assembly->assembly.ref_only = assemblybuilderaccess_can_refonlyload (assemblyb->access);
+ assembly->run = assemblybuilderaccess_can_run (assemblyb->access);
+ assembly->save = assemblybuilderaccess_can_save (assemblyb->access);
assembly->domain = domain;
char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
- mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
+ MONO_PROFILER_RAISE (assembly_loaded, (&assembly->assembly));
mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
}
static gpointer
register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
{
- CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
+ return CACHE_OBJECT (MonoReflectionAssembly *, assembly, &res->object, NULL);
}
-static gpointer
-register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
+static MonoReflectionModuleBuilderHandle
+register_module (MonoDomain *domain, MonoReflectionModuleBuilderHandle res, MonoDynamicImage *module)
{
- CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
+ return CACHE_OBJECT_HANDLE (MonoReflectionModuleBuilderHandle, module, MONO_HANDLE_CAST (MonoObject, res), NULL);
}
static gboolean
-image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
+image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
{
- MonoDynamicImage *image = moduleb->dynamic_image;
- MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
- mono_error_init (error);
+ error_init (error);
+ MonoDomain *domain = MONO_HANDLE_DOMAIN (moduleb);
+ MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
+ MonoReflectionAssemblyBuilderHandle ab = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
+ MONO_HANDLE_GET (ab, moduleb, assemblyb);
if (!image) {
- int module_count;
- MonoImage **new_modules;
- MonoImage *ass;
- char *name, *fqname;
/*
* FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
* we don't know which module it belongs to, since that is only
* determined at assembly save time.
*/
/*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
- name = mono_string_to_utf8_checked (ab->name, error);
+ MonoStringHandle abname = MONO_HANDLE_NEW_GET (MonoString, ab, name);
+ char *name = mono_string_handle_to_utf8 (abname, error);
return_val_if_nok (error, FALSE);
- fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
+ MonoStringHandle modfqname = MONO_HANDLE_NEW_GET (MonoString, MONO_HANDLE_CAST (MonoReflectionModule, moduleb), fqname);
+ char *fqname = mono_string_handle_to_utf8 (modfqname, error);
if (!is_ok (error)) {
g_free (name);
return FALSE;
}
- image = mono_dynamic_image_create (ab->dynamic_assembly, name, fqname);
+ MonoDynamicAssembly *dynamic_assembly = MONO_HANDLE_GETVAL (ab, dynamic_assembly);
+ image = mono_dynamic_image_create (dynamic_assembly, name, fqname);
- moduleb->module.image = &image->image;
- moduleb->dynamic_image = image;
- register_module (mono_object_domain (moduleb), moduleb, image);
+ MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule, moduleb), image, MonoImage*, &image->image);
+ MONO_HANDLE_SETVAL (moduleb, dynamic_image, MonoDynamicImage*, image);
+ register_module (domain, moduleb, image);
/* register the module with the assembly */
- ass = ab->dynamic_assembly->assembly.image;
- module_count = ass->module_count;
- new_modules = g_new0 (MonoImage *, module_count + 1);
+ MonoImage *ass = dynamic_assembly->assembly.image;
+ int module_count = ass->module_count;
+ MonoImage **new_modules = g_new0 (MonoImage *, module_count + 1);
if (ass->modules)
memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
return TRUE;
}
-static void
-mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
+static gboolean
+mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
{
- MonoError error;
- (void) image_module_basic_init (moduleb, &error);
- mono_error_set_pending_exception (&error);
+ error_init (error);
+ return image_module_basic_init (moduleb, error);
}
#endif
} while (0) \
+MonoType*
+mono_type_array_get_and_resolve (MonoArrayHandle array, int idx, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER();
+ error_init (error);
+ MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
+ MONO_HANDLE_ARRAY_GETREF (t, array, idx);
+ MonoType *result = mono_reflection_type_handle_mono_type (t, error);
+ HANDLE_FUNCTION_RETURN_VAL (result);
+}
+
#ifndef DISABLE_REFLECTION_EMIT
static gboolean
check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
}
-static MonoReflectionType*
-mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
+static MonoReflectionTypeHandle
+mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error)
{
static MonoMethod *method_get_underlying_system_type = NULL;
- MonoReflectionType *rt;
- MonoMethod *usertype_method;
+ HANDLE_FUNCTION_ENTER ();
- mono_error_init (error);
+ error_init (error);
if (!method_get_underlying_system_type)
method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
- usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
+ MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
- rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
+ MonoMethod *usertype_method = mono_object_handle_get_virtual_method (MONO_HANDLE_CAST (MonoObject, t), method_get_underlying_system_type, error);
+ if (!is_ok (error))
+ goto leave;
- return rt;
+ MONO_HANDLE_ASSIGN (rt, MONO_HANDLE_NEW (MonoReflectionType, mono_runtime_invoke_checked (usertype_method, MONO_HANDLE_RAW (t), NULL, error)));
+
+leave:
+ HANDLE_FUNCTION_RETURN_REF (MonoReflectionType, rt);
}
MonoType*
-mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
+mono_reflection_type_get_handle (MonoReflectionType* ref_raw, MonoError *error)
{
- MonoClass *klass;
- mono_error_init (error);
-
- if (!ref)
- return NULL;
- if (ref->type)
- return ref->type;
+ HANDLE_FUNCTION_ENTER ();
+ error_init (error);
+ MONO_HANDLE_DCL (MonoReflectionType, ref);
+ MonoType *result = mono_reflection_type_handle_mono_type (ref, error);
+ HANDLE_FUNCTION_RETURN_VAL (result);
+}
- if (mono_reflection_is_usertype (ref)) {
- ref = mono_reflection_type_get_underlying_system_type (ref, error);
- if (ref == NULL || mono_reflection_is_usertype (ref) || !is_ok (error))
- return NULL;
- if (ref->type)
- return ref->type;
+static MonoType*
+reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclass, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER ();
+ MonoType *result = NULL;
+ MonoType **types = NULL;
+
+ MonoArrayHandle typeargs = MONO_HANDLE_NEW_GET (MonoArray, ref_gclass, type_arguments);
+ int count = mono_array_handle_length (typeargs);
+ types = g_new0 (MonoType*, count);
+ MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
+ for (int i = 0; i < count; ++i) {
+ MONO_HANDLE_ARRAY_GETREF (t, typeargs, i);
+ types [i] = mono_reflection_type_handle_mono_type (t, error);
+ if (!types[i] || !is_ok (error)) {
+ goto leave;
+ }
+ }
+ /* Need to resolve the generic_type in order for it to create its generic context. */
+ MonoReflectionTypeHandle ref_gtd = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_gclass, generic_type);
+ MonoType *gtd = mono_reflection_type_handle_mono_type (ref_gtd, error);
+ if (!is_ok (error)) {
+ goto leave;
+ }
+ MonoClass *gtd_klass = mono_class_from_mono_type (gtd);
+ if (is_sre_type_builder (mono_handle_class (ref_gtd))) {
+ reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_gtd), error);
+ if (!is_ok (error)) {
+ goto leave;
+ }
}
+ g_assert (count == 0 || mono_class_is_gtd (gtd_klass));
+ result = mono_reflection_bind_generic_parameters (ref_gtd, count, types, error);
+ if (!is_ok (error))
+ goto leave;
+ g_assert (result);
+ MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gclass), type, MonoType*, result);
+leave:
+ g_free (types);
+ HANDLE_FUNCTION_RETURN_VAL (result);
+}
- klass = mono_object_class (ref);
+static MonoType*
+reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER ();
+ error_init (error);
+ MonoType *result = NULL;
- if (is_sre_array (klass)) {
- MonoType *res;
- MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
- MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
- return_val_if_nok (error, NULL);
- g_assert (base);
- if (sre_array->rank == 0) //single dimentional array
- res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
- else
- res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
- sre_array->type.type = res;
- return res;
- } else if (is_sre_byref (klass)) {
- MonoType *res;
- MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
- MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
- return_val_if_nok (error, NULL);
- g_assert (base);
- res = &mono_class_from_mono_type (base)->this_arg;
- sre_byref->type.type = res;
- return res;
- } else if (is_sre_pointer (klass)) {
- MonoType *res;
- MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
- MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
- return_val_if_nok (error, NULL);
- g_assert (base);
- res = &mono_ptr_class_get (base)->byval_arg;
- sre_pointer->type.type = res;
- return res;
- } else if (is_sre_generic_instance (klass)) {
- MonoType *res, **types;
- MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
- int i, count;
-
- count = mono_array_length (gclass->type_arguments);
- types = g_new0 (MonoType*, count);
- for (i = 0; i < count; ++i) {
- MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
- types [i] = mono_reflection_type_get_handle (t, error);
- if (!types[i] || !is_ok (error)) {
- g_free (types);
- return NULL;
- }
+
+ MonoReflectionTypeBuilderHandle ref_tbuilder = MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder, ref_gparam, tbuilder);
+ MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tbuilder, module);
+ MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
+ MonoImage *image = &dynamic_image->image;
+
+ MonoGenericParamFull *param = mono_image_new0 (image, MonoGenericParamFull, 1);
+
+ MonoStringHandle ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_gparam, name);
+ param->info.name = mono_string_to_utf8_image (image, ref_name, error);
+ mono_error_assert_ok (error);
+ param->param.num = MONO_HANDLE_GETVAL (ref_gparam, index);
+
+ MonoReflectionMethodBuilderHandle ref_mbuilder = MONO_HANDLE_NEW_GET (MonoReflectionMethodBuilder, ref_gparam, mbuilder);
+ if (!MONO_HANDLE_IS_NULL (ref_mbuilder)) {
+ MonoGenericContainer *generic_container = MONO_HANDLE_GETVAL (ref_mbuilder, generic_container);
+ if (!generic_container) {
+ generic_container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer));
+ generic_container->is_method = TRUE;
+ /*
+ * Cannot set owner.method, since the MonoMethod is not created yet.
+ * Set the image field instead, so type_in_image () works.
+ */
+ generic_container->is_anonymous = TRUE;
+ generic_container->owner.image = image;
+ MONO_HANDLE_SETVAL (ref_mbuilder, generic_container, MonoGenericContainer*, generic_container);
}
+ param->param.owner = generic_container;
+ } else {
+ MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_tbuilder), error);
+ if (!is_ok (error))
+ goto leave;
+ MonoClass *owner = mono_class_from_mono_type (type);
+ g_assert (mono_class_is_gtd (owner));
+ param->param.owner = mono_class_get_generic_container (owner);
+ }
- res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
- g_free (types);
- g_assert (res);
- gclass->type.type = res;
- return res;
- } else if (is_sre_gparam_builder (klass)) {
- MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)ref;
- MonoGenericParamFull *param;
- MonoImage *image;
- MonoClass *pklass;
+ MonoClass *pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
- image = &gparam->tbuilder->module->dynamic_image->image;
+ result = &pklass->byval_arg;
- param = mono_image_new0 (image, MonoGenericParamFull, 1);
+ mono_class_set_ref_info (pklass, MONO_HANDLE_CAST (MonoObject, ref_gparam));
+ mono_image_append_class_to_reflection_info_set (pklass);
- param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
- mono_error_assert_ok (error);
- param->param.num = gparam->index;
+ MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), type, MonoType*, result);
- if (gparam->mbuilder) {
- if (!gparam->mbuilder->generic_container) {
- gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer));
- gparam->mbuilder->generic_container->is_method = TRUE;
- /*
- * Cannot set owner.method, since the MonoMethod is not created yet.
- * Set the image field instead, so type_in_image () works.
- */
- gparam->mbuilder->generic_container->is_anonymous = TRUE;
- gparam->mbuilder->generic_container->owner.image = image;
- }
- param->param.owner = gparam->mbuilder->generic_container;
- } else if (gparam->tbuilder) {
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)(gparam->tbuilder), error);
- mono_error_assert_ok (error);
- MonoClass *owner = mono_class_from_mono_type (type);
- g_assert (mono_class_is_gtd (owner));
- param->param.owner = mono_class_get_generic_container (owner);
- }
+leave:
+ HANDLE_FUNCTION_RETURN_VAL (result);
+}
- pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
+static MonoType*
+mono_type_array_get_and_resolve_raw (MonoArray* array_raw, int idx, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
+ error_init (error);
+ MONO_HANDLE_DCL (MonoArray, array);
+ MonoType *result = mono_type_array_get_and_resolve (array, idx, error);
+ HANDLE_FUNCTION_RETURN_VAL (result);
+}
- gparam->type.type = &pklass->byval_arg;
+MonoType*
+mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER ();
+ error_init (error);
+
+ MonoType* result = NULL;
- mono_class_set_ref_info (pklass, gparam);
- mono_image_append_class_to_reflection_info_set (pklass);
+ g_assert (ref);
+ if (MONO_HANDLE_IS_NULL (ref))
+ goto leave;
+ MonoType *t = MONO_HANDLE_GETVAL (ref, type);
+ if (t) {
+ result = t;
+ goto leave;
+ }
- return &pklass->byval_arg;
+ if (mono_reflection_is_usertype (ref)) {
+ MONO_HANDLE_ASSIGN (ref, mono_reflection_type_get_underlying_system_type (ref, error));
+ if (!is_ok (error) || MONO_HANDLE_IS_NULL (ref) || mono_reflection_is_usertype (ref))
+ goto leave;
+ t = MONO_HANDLE_GETVAL (ref, type);
+ if (t) {
+ result = t;
+ goto leave;
+ }
+ }
+
+ MonoClass *klass = mono_handle_class (ref);
+
+ if (is_sre_array (klass)) {
+ MonoReflectionArrayTypeHandle sre_array = MONO_HANDLE_CAST (MonoReflectionArrayType, ref);
+ MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_array, element_type);
+ MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
+ if (!is_ok (error))
+ goto leave;
+ g_assert (base);
+ gint32 rank = MONO_HANDLE_GETVAL (sre_array, rank);
+ MonoClass *eclass = mono_class_from_mono_type (base);
+ result = mono_image_new0 (eclass->image, MonoType, 1);
+ if (rank == 0) {
+ result->type = MONO_TYPE_SZARRAY;
+ result->data.klass = eclass;
+ } else {
+ MonoArrayType *at = (MonoArrayType *)mono_image_alloc0 (eclass->image, sizeof (MonoArrayType));
+ result->type = MONO_TYPE_ARRAY;
+ result->data.array = at;
+ at->eklass = eclass;
+ at->rank = rank;
+ }
+ MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
+ } else if (is_sre_byref (klass)) {
+ MonoReflectionDerivedTypeHandle sre_byref = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
+ MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_byref, element_type);
+ MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
+ if (!is_ok (error))
+ goto leave;
+ g_assert (base);
+ result = &mono_class_from_mono_type (base)->this_arg;
+ MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
+ } else if (is_sre_pointer (klass)) {
+ MonoReflectionDerivedTypeHandle sre_pointer = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
+ MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_pointer, element_type);
+ MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
+ if (!is_ok (error))
+ goto leave;
+ g_assert (base);
+ result = &mono_ptr_class_get (base)->byval_arg;
+ MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
+ } else if (is_sre_generic_instance (klass)) {
+ result = reflection_instance_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericClass, ref), error);
+ } else if (is_sre_gparam_builder (klass)) {
+ result = reflection_param_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericParam, ref), error);
} else if (is_sre_enum_builder (klass)) {
- MonoReflectionEnumBuilder *ebuilder = (MonoReflectionEnumBuilder *)ref;
+ MonoReflectionEnumBuilderHandle ref_ebuilder = MONO_HANDLE_CAST (MonoReflectionEnumBuilder, ref);
- return mono_reflection_type_get_handle ((MonoReflectionType*)ebuilder->tb, error);
+ MonoReflectionTypeHandle ref_tb = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_ebuilder, tb);
+ result = mono_reflection_type_handle_mono_type (ref_tb, error);
} else if (is_sre_type_builder (klass)) {
- MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)ref;
+ MonoReflectionTypeBuilderHandle ref_tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref);
/* This happens when a finished type references an unfinished one. Have to create the minimal type */
- reflection_setup_internal_class (tb, error);
+ reflection_setup_internal_class (ref_tb, error);
mono_error_assert_ok (error);
- g_assert (ref->type);
- return ref->type;
+ result = MONO_HANDLE_GETVAL (ref, type);
+ } else {
+ g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
}
-
- g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
- return NULL;
+leave:
+ HANDLE_FUNCTION_RETURN_VAL (result);
}
/**
* LOCKING: Assumes the loader lock is held.
*/
static MonoMethodSignature*
-parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
+parameters_to_signature (MonoImage *image, MonoArrayHandle parameters, MonoError *error) {
MonoMethodSignature *sig;
int count, i;
- mono_error_init (error);
+ error_init (error);
- count = parameters? mono_array_length (parameters): 0;
+ count = MONO_HANDLE_IS_NULL (parameters) ? 0 : mono_array_handle_length (parameters);
sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
sig->param_count = count;
* LOCKING: Assumes the loader lock is held.
*/
static MonoMethodSignature*
-ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
+ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilderHandle ctor, MonoError *error) {
MonoMethodSignature *sig;
- mono_error_init (error);
+ error_init (error);
- sig = parameters_to_signature (image, ctor->parameters, error);
+ sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET (MonoArray, ctor, parameters), error);
return_val_if_nok (error, NULL);
- sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
+ sig->hasthis = MONO_HANDLE_GETVAL (ctor, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
sig->ret = &mono_defaults.void_class->byval_arg;
return sig;
}
+static MonoMethodSignature*
+ctor_builder_to_signature_raw (MonoImage *image, MonoReflectionCtorBuilder* ctor_raw, MonoError *error) {
+ HANDLE_FUNCTION_ENTER();
+ MONO_HANDLE_DCL (MonoReflectionCtorBuilder, ctor);
+ MonoMethodSignature *sig = ctor_builder_to_signature (image, ctor, error);
+ HANDLE_FUNCTION_RETURN_VAL (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, MonoReflectionMethodBuilderHandle method, MonoError *error) {
MonoMethodSignature *sig;
- mono_error_init (error);
+ error_init (error);
- sig = parameters_to_signature (image, method->parameters, error);
+ sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET(MonoArray, 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);
+ sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
+ MonoReflectionTypeHandle rtype = MONO_HANDLE_NEW_GET (MonoReflectionType, method, rtype);
+ if (!MONO_HANDLE_IS_NULL (rtype)) {
+ sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
if (!is_ok (error)) {
image_g_free (image, sig);
return NULL;
} else {
sig->ret = &mono_defaults.void_class->byval_arg;
}
- sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
+ MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, method, generic_params);
+ sig->generic_param_count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
return sig;
}
static MonoMethodSignature*
-dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
- MonoMethodSignature *sig;
+dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method, MonoError *error) {
+ HANDLE_FUNCTION_ENTER ();
+ MonoMethodSignature *sig = NULL;
- mono_error_init (error);
+ 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);
+ sig = parameters_to_signature (NULL, MONO_HANDLE_NEW_GET (MonoArray, method, parameters), error);
+ if (!is_ok (error))
+ goto leave;
+ sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
+ MonoReflectionTypeHandle rtype = MONO_HANDLE_NEW_GET (MonoReflectionType, method, rtype);
+ if (!MONO_HANDLE_IS_NULL (rtype)) {
+ sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
if (!is_ok (error)) {
g_free (sig);
- return NULL;
+ sig = NULL;
+ goto leave;
}
} else {
sig->ret = &mono_defaults.void_class->byval_arg;
}
sig->generic_param_count = 0;
- return sig;
+leave:
+ HANDLE_FUNCTION_RETURN_VAL (sig);
}
static void
get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
MonoClass *klass = mono_object_class (prop);
if (strcmp (klass->name, "PropertyBuilder") == 0) {
MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
static void
get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
MonoClass *klass = mono_object_class (field);
if (strcmp (klass->name, "FieldBuilder") == 0) {
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
{
MonoTypeEnum simple_type;
- mono_error_init (error);
+ error_init (error);
if ((p-buffer) + 10 >= *buflen) {
char *newbuf;
*buflen *= 2;
{
int len;
- mono_error_init (error);
+ error_init (error);
/* Preallocate a large enough buffer */
if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
/**
* mono_reflection_get_custom_attrs_blob:
- * @ctor: custom attribute constructor
- * @ctorArgs: arguments o the constructor
- * @properties:
- * @propValues:
- * @fields:
- * @fieldValues:
- *
+ * \param ctor custom attribute constructor
+ * \param ctorArgs arguments o the constructor
+ * \param properties
+ * \param propValues
+ * \param fields
+ * \param fieldValues
* 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.
+ * the custom attributed described by \p ctor, \p ctorArgs etc.
+ * \returns a \c Byte array representing the blob of data.
*/
MonoArray*
mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
/**
* mono_reflection_get_custom_attrs_blob_checked:
- * @ctor: custom attribute constructor
- * @ctorArgs: arguments o the constructor
- * @properties:
- * @propValues:
- * @fields:
- * @fieldValues:
- * @error: set on error
- *
+ * \param ctor custom attribute constructor
+ * \param ctorArgs arguments o the constructor
+ * \param properties
+ * \param propValues
+ * \param fields
+ * \param fieldValues
+ * \param 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.
+ * the custom attributed described by \p ctor, \p ctorArgs etc.
+ * \returns a \c Byte array representing the blob of data. On failure returns NULL and sets \p 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)
char *buffer, *p;
guint32 buflen, i;
- mono_error_init (error);
+ 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, error);
+ sig = ctor_builder_to_signature_raw (NULL, (MonoReflectionCtorBuilder*)ctor, error); /* FIXME use handles */
if (!is_ok (error)) {
g_free (sig);
return NULL;
return result;
}
-/**
- * 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.
- */
static gboolean
-reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
+reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error)
{
- MonoClass *klass, *parent;
-
- mono_error_init (error);
+ error_init (error);
mono_loader_lock ();
- if (tb->parent) {
- MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
- if (!is_ok (error)) {
- mono_loader_unlock ();
- return FALSE;
+ MonoType *parent_type;
+ MonoType *child_type;
+ GHashTableIter iter;
+
+ g_hash_table_iter_init (&iter, unparented);
+
+ while (g_hash_table_iter_next (&iter, (gpointer *) &child_type, (gpointer *) &parent_type)) {
+ MonoClass *child_class = mono_class_from_mono_type (child_type);
+ if (parent_type != NULL) {
+ MonoClass *parent_class = mono_class_from_mono_type (parent_type);
+ child_class->parent = NULL;
+ /* fool mono_class_setup_parent */
+ child_class->supertypes = NULL;
+ mono_class_setup_parent (child_class, parent_class);
+ } else if (strcmp (child_class->name, "Object") == 0 && strcmp (child_class->name_space, "System") == 0) {
+ const char *old_n = child_class->name;
+ /* trick to get relative numbering right when compiling corlib */
+ child_class->name = "BuildingObject";
+ mono_class_setup_parent (child_class, mono_defaults.object_class);
+ child_class->name = old_n;
}
- /* check so we can compile corlib correctly */
- if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
- /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
- parent = parent_type->data.klass;
- } else {
- parent = mono_class_from_mono_type (parent_type);
- }
- } else {
- parent = NULL;
+ mono_class_setup_mono_type (child_class);
+ mono_class_setup_supertypes (child_class);
}
-
- /* the type has already being created: it means we just have to change the parent */
- if (tb->type.type) {
- klass = mono_class_from_mono_type (tb->type.type);
- klass->parent = NULL;
- /* fool mono_class_setup_parent */
- klass->supertypes = NULL;
- mono_class_setup_parent (klass, parent);
- mono_class_setup_mono_type (klass);
- mono_loader_unlock ();
- return TRUE;
+
+ mono_loader_unlock ();
+ return is_ok (error);
+}
+
+static gboolean
+reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER ();
+ error_init (error);
+
+ mono_loader_lock ();
+
+ gint32 entering_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_tb), state);
+ if (entering_state != MonoTypeBuilderNew) {
+ g_assert (MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type));
+ goto leave;
}
+ MONO_HANDLE_SETVAL (ref_tb, state, MonoTypeBuilderState, MonoTypeBuilderEntered);
+ MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
+ GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
+
+ // If this type is already setup, exit. We'll fix the parenting later
+ MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
+ if (type)
+ goto leave;
+
+ MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
+ MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
+
+ MonoStringHandle ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_tb, name);
+ MonoStringHandle ref_nspace = MONO_HANDLE_NEW_GET (MonoString, ref_tb, nspace);
+
+ guint32 table_idx = MONO_HANDLE_GETVAL (ref_tb, table_idx);
/*
* The size calculation here warrants some explaining.
* reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
* meaning we need to alloc enough space to morth a def into a gtd.
*/
- klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
+ MonoClass *klass = (MonoClass *)mono_image_alloc0 (&dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
klass->class_kind = MONO_CLASS_DEF;
- klass->image = &tb->module->dynamic_image->image;
+ klass->image = &dynamic_image->image;
klass->inited = 1; /* we lie to the runtime */
- klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
+ klass->name = mono_string_to_utf8_image (klass->image, ref_name, error);
if (!is_ok (error))
- goto failure;
- klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
+ goto leave;
+ klass->name_space = mono_string_to_utf8_image (klass->image, ref_nspace, error);
if (!is_ok (error))
- goto failure;
- klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
- mono_class_set_flags (klass, tb->attrs);
+ goto leave;
+ klass->type_token = MONO_TOKEN_TYPE_DEF | table_idx;
+ mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
- mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
+ MONO_PROFILER_RAISE (class_loading, (klass));
klass->element_class = klass;
- if (mono_class_get_ref_info (klass) == NULL) {
- mono_class_set_ref_info (klass, tb);
+ g_assert (!mono_class_has_ref_info (klass));
+ mono_class_set_ref_info (klass, MONO_HANDLE_CAST (MonoObject, ref_tb));
- /* Put into cache so mono_class_get_checked () will find it.
- Skip nested types as those should not be available on the global scope. */
- if (!tb->nesting_type)
- mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
+ MonoReflectionTypeHandle ref_nesting_type = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, nesting_type);
+ /* Put into cache so mono_class_get_checked () will find it.
+ Skip nested types as those should not be available on the global scope. */
+ if (MONO_HANDLE_IS_NULL (ref_nesting_type))
+ mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, table_idx);
- /*
- We must register all types as we cannot rely on the name_cache hashtable since we find the class
- by performing a mono_class_get which does the full resolution.
-
- Working around this semantics would require us to write a lot of code for no clear advantage.
- */
- mono_image_append_class_to_reflection_info_set (klass);
- } else {
- g_assert (mono_class_get_ref_info (klass) == tb);
- }
+ /*
+ We must register all types as we cannot rely on the name_cache hashtable since we find the class
+ by performing a mono_class_get which does the full resolution.
- mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
+ Working around this semantics would require us to write a lot of code for no clear advantage.
+ */
+ mono_image_append_class_to_reflection_info_set (klass);
- if (parent != NULL) {
- mono_class_setup_parent (klass, parent);
- } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
- const char *old_n = klass->name;
- /* trick to get relative numbering right when compiling corlib */
- klass->name = "BuildingObject";
- mono_class_setup_parent (klass, mono_defaults.object_class);
- klass->name = old_n;
- }
+ mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb), MONO_DYN_IMAGE_TOK_NEW);
if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
(!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
mono_class_setup_mono_type (klass);
- mono_class_setup_supertypes (klass);
-
/*
* FIXME: handle interfaces.
*/
+ MonoReflectionTypeHandle ref_tb_type = MONO_HANDLE_CAST (MonoReflectionType, ref_tb);
+ MONO_HANDLE_SETVAL (ref_tb_type, type, MonoType*, &klass->byval_arg);
+ MONO_HANDLE_SETVAL (ref_tb, state, gint32, MonoTypeBuilderFinished);
+
+ reflection_init_generic_class (ref_tb, error);
+ if (!is_ok (error))
+ goto leave;
- tb->type.type = &klass->byval_arg;
+ // Do here so that the search inside of the parent can see the above type that's been set.
+ MonoReflectionTypeHandle ref_parent = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, parent);
+ MonoType *parent_type = NULL;
+ if (!MONO_HANDLE_IS_NULL (ref_parent)) {
+ MonoClass *parent_klass = mono_handle_class (ref_parent);
+ gboolean recursive_init = TRUE;
- if (tb->nesting_type) {
- reflection_setup_internal_class ((MonoReflectionTypeBuilder*)tb->nesting_type, error);
- g_assert (tb->nesting_type->type);
- MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
- if (!is_ok (error)) goto failure;
+ if (is_sre_type_builder (parent_klass)) {
+ MonoTypeBuilderState parent_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_parent), state);
+
+ if (parent_state != MonoTypeBuilderNew) {
+ // Initialize types reachable from parent recursively
+ // We'll fix the type hierarchy later
+ recursive_init = FALSE;
+ }
+ }
+
+ if (recursive_init) {
+ // If we haven't encountered a cycle, force the creation of ref_parent's type
+ mono_reflection_type_handle_mono_type (ref_parent, error);
+ if (!is_ok (error))
+ goto leave;
+ }
+
+ parent_type = MONO_HANDLE_GETVAL (ref_parent, type);
+
+ // If we failed to create the parent, fail the child
+ if (!parent_type)
+ goto leave;
+ }
+
+ // Push the child type and parent type to process later
+ // Note: parent_type may be null.
+ g_assert (!g_hash_table_lookup (unparented_classes, &klass->byval_arg));
+ g_hash_table_insert (unparented_classes, &klass->byval_arg, parent_type);
+
+ if (!MONO_HANDLE_IS_NULL (ref_nesting_type)) {
+ if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_nesting_type), error))
+ goto leave;
+
+ MonoType *nesting_type = mono_reflection_type_handle_mono_type (ref_nesting_type, error);
+ if (!is_ok (error))
+ goto leave;
klass->nested_in = mono_class_from_mono_type (nesting_type);
}
/*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
- mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
+ MONO_PROFILER_RAISE (class_loaded, (klass));
+leave:
mono_loader_unlock ();
- return TRUE;
-
-failure:
- mono_loader_unlock ();
- return FALSE;
+ HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
}
/**
- * reflection_create_generic_class:
+ * reflection_init_generic_class:
* @tb: a TypeBuilder object
* @error: set on error
*
* Creates the generic class after all generic parameters have been added.
* On success returns TRUE, on failure returns FALSE and sets @error.
+ *
+ * This assumes that reflection_setup_internal_class has already set up
+ * ref_tb
*/
static gboolean
-reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
+reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
{
- MonoClass *klass;
- int count, i;
+ HANDLE_FUNCTION_ENTER ();
- mono_error_init (error);
+ error_init (error);
- reflection_setup_internal_class (tb, error);
+ MonoTypeBuilderState ref_state = MONO_HANDLE_GETVAL (ref_tb, state);
+ g_assert (ref_state == MonoTypeBuilderFinished);
- klass = mono_class_from_mono_type (tb->type.type);
+ MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
+ MonoClass *klass = mono_class_from_mono_type (type);
- count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
+ MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
+ int count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
if (count == 0)
- return TRUE;
+ goto leave;
+
+ if (mono_class_try_get_generic_container (klass) != NULL)
+ goto leave; /* already setup */
MonoGenericContainer *generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
mono_class_set_generic_container (klass, generic_container);
- for (i = 0; i < count; i++) {
- MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
- MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
- return_val_if_nok (error, FALSE);
+ MonoReflectionGenericParamHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionGenericParam, NULL);
+ for (int i = 0; i < count; i++) {
+ MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
+ MonoType *param_type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), error);
+ if (!is_ok (error))
+ goto leave;
MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
generic_container->type_params [i] = *param;
/*Make sure we are a diferent type instance */
generic_container->type_params [i].param.owner = generic_container;
generic_container->type_params [i].info.pklass = NULL;
- generic_container->type_params [i].info.flags = gparam->attrs;
+ generic_container->type_params [i].info.flags = MONO_HANDLE_GETVAL (ref_gparam, attrs);
g_assert (generic_container->type_params [i].param.owner);
}
generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
- return TRUE;
+ MonoGenericContext* context = &generic_container->context;
+ MonoType *canonical_inst = &((MonoClassGtd*)klass)->canonical_inst;
+ canonical_inst->type = MONO_TYPE_GENERICINST;
+ canonical_inst->data.generic_class = mono_metadata_lookup_generic_class (klass, context->class_inst, FALSE);
+
+leave:
+ HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
}
static MonoMarshalSpec*
{
MonoMarshalSpec *res;
- mono_error_init (error);
+ error_init (error);
res = image_g_new0 (image, MonoMarshalSpec, 1);
res->native = (MonoMarshalNative)minfo->type;
}
#endif /* !DISABLE_REFLECTION_EMIT */
-MonoReflectionMarshalAsAttribute*
+MonoReflectionMarshalAsAttributeHandle
mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
MonoMarshalSpec *spec, MonoError *error)
{
- MonoReflectionType *rt;
- MonoReflectionMarshalAsAttribute *minfo;
- MonoType *mtype;
-
- mono_error_init (error);
+ error_init (error);
- minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
- if (!minfo)
- return NULL;
- minfo->utype = spec->native;
+ MonoReflectionMarshalAsAttributeHandle minfo = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error));
+ if (!is_ok (error))
+ goto fail;
+ guint32 utype = spec->native;
+ MONO_HANDLE_SETVAL (minfo, utype, guint32, utype);
- switch (minfo->utype) {
+ switch (utype) {
case MONO_NATIVE_LPARRAY:
- minfo->array_subtype = spec->data.array_data.elem_type;
- minfo->size_const = spec->data.array_data.num_elem;
+ MONO_HANDLE_SETVAL (minfo, array_subtype, guint32, spec->data.array_data.elem_type);
+ MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
if (spec->data.array_data.param_num != -1)
- minfo->size_param_index = spec->data.array_data.param_num;
+ MONO_HANDLE_SETVAL (minfo, size_param_index, gint16, spec->data.array_data.param_num);
break;
case MONO_NATIVE_BYVALTSTR:
case MONO_NATIVE_BYVALARRAY:
- minfo->size_const = spec->data.array_data.num_elem;
+ MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
break;
case MONO_NATIVE_CUSTOM:
if (spec->data.custom_data.custom_name) {
- mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
- return_val_if_nok (error, NULL);
+ MonoType *mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
+ if (!is_ok (error))
+ goto fail;
if (mtype) {
- rt = mono_type_get_object_checked (domain, mtype, error);
- if (!rt)
- return NULL;
+ MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, mtype, error);
+ if (!is_ok (error))
+ goto fail;
- MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
+ MONO_HANDLE_SET (minfo, marshal_type_ref, rt);
}
- MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
+ MonoStringHandle custom_name = mono_string_new_handle (domain, spec->data.custom_data.custom_name, error);
+ if (!is_ok (error))
+ goto fail;
+ MONO_HANDLE_SET (minfo, marshal_type, custom_name);
+ }
+ if (spec->data.custom_data.cookie) {
+ MonoStringHandle cookie = mono_string_new_handle (domain, spec->data.custom_data.cookie, error);
+ if (!is_ok (error))
+ goto fail;
+ MONO_HANDLE_SET (minfo, marshal_cookie, cookie);
}
- if (spec->data.custom_data.cookie)
- MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
break;
default:
}
return minfo;
+fail:
+ return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
}
#ifndef DISABLE_REFLECTION_EMIT
gboolean dynamic;
int i;
- mono_error_init (error);
+ error_init (error);
/*
* Methods created using a MethodBuilder should have their memory allocated
* inside the image mempool, while dynamic methods should have their memory
method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
- method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
+ method_aux->dllentry = rmb->dllentry ? string_to_utf8_image_raw (image, rmb->dllentry, error) : image_strdup (image, m->name);
mono_error_assert_ok (error);
- method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
+ method_aux->dll = string_to_utf8_image_raw (image, rmb->dll, error);
mono_error_assert_ok (error);
((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
}
if (pb->name) {
- method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
+ method_aux->param_names [i] = string_to_utf8_image_raw (image, pb->name, error);
mono_error_assert_ok (error);
}
if (pb->cattrs) {
return NULL;
g_assert (klass->image != NULL);
- sig = ctor_builder_to_signature (klass->image, mb, error);
+ sig = ctor_builder_to_signature_raw (klass->image, mb, error); /* FIXME use handles */
mono_loader_unlock ();
return_val_if_nok (error, NULL);
}
static MonoMethod*
-methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
+methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilderHandle ref_mb, MonoError *error)
{
ReflectionMethodBuilder rmb;
MonoMethodSignature *sig;
- mono_error_init (error);
+ error_init (error);
mono_loader_lock ();
+ MonoReflectionMethodBuilder *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME use handles */
if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
return NULL;
g_assert (klass->image != NULL);
- sig = method_builder_to_signature (klass->image, mb, error);
+ sig = method_builder_to_signature (klass->image, ref_mb, error);
mono_loader_unlock ();
return_val_if_nok (error, NULL);
- mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
+ MonoMethod *method = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
return_val_if_nok (error, NULL);
- mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
+ MONO_HANDLE_SETVAL (ref_mb, mhandle, MonoMethod*, method);
+ mono_save_custom_attrs (klass->image, method, mb->cattrs);
if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save)
/* ilgen is no longer needed */
mb->ilgen = NULL;
- return mb->mhandle;
+ return method;
}
+
+static MonoMethod*
+methodbuilder_to_mono_method_raw (MonoClass *klass, MonoReflectionMethodBuilder* mb_raw, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
+ error_init (error);
+ MONO_HANDLE_DCL (MonoReflectionMethodBuilder, mb);
+ MonoMethod *result = methodbuilder_to_mono_method (klass, mb, error);
+ HANDLE_FUNCTION_RETURN_VAL (result);
+}
+
#endif
#ifndef DISABLE_REFLECTION_EMIT
MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
int i;
- mono_error_init (error);
+ error_init (error);
if (klass->wastypebuilder)
return TRUE;
{
MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
- mono_error_init (error);
+ error_init (error);
if (!ensure_runtime_vtable (gklass, error))
return FALSE;
static gboolean
ensure_runtime_vtable (MonoClass *klass, MonoError *error)
{
- MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
int i, num, j;
- mono_error_init (error);
+ error_init (error);
if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
return TRUE;
num = tb->num_methods;
j = i;
for (i = 0; i < num; ++i) {
- MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
+ MonoMethod *meth = methodbuilder_to_mono_method_raw (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error); /* FIXME use handles */
if (!meth)
return FALSE;
klass->methods [j++] = meth;
klass->interface_count = mono_array_length (tb->interfaces);
klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
for (i = 0; i < klass->interface_count; ++i) {
- MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
+ MonoType *iface = mono_type_array_get_and_resolve_raw (tb->interfaces, i, error); /* FIXME use handles */
return_val_if_nok (error, FALSE);
klass->interfaces [i] = mono_class_from_mono_type (iface);
if (!ensure_runtime_vtable (klass->interfaces [i], error))
static MonoMethod*
mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
MonoClass *klass = mono_object_class (method);
if (is_sr_mono_method (klass)) {
MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
int i, j, onum;
MonoReflectionMethod *m;
- mono_error_init (error);
+ error_init (error);
*overrides = NULL;
*num_overrides = 0;
g_assert (image_is_dynamic (klass->image));
- if (!mono_class_get_ref_info (klass))
+ if (!mono_class_has_ref_info (klass))
return;
- g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
-
- tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
+ tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
+ g_assert (strcmp (mono_object_class (tb)->name, "TypeBuilder") == 0);
onum = 0;
if (tb->methods) {
static void
typebuilder_setup_fields (MonoClass *klass, MonoError *error)
{
- MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
MonoReflectionFieldBuilder *fb;
MonoClassField *field;
MonoFieldDefaultValue *def_values;
int fcount = tb->num_fields;
mono_class_set_field_count (klass, fcount);
- mono_error_init (error);
+ error_init (error);
if (tb->class_size) {
packing_size = tb->packing_size;
fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
field = &klass->fields [i];
field->parent = klass;
- field->name = mono_string_to_utf8_image (image, fb->name, error);
+ field->name = string_to_utf8_image_raw (image, fb->name, error); /* FIXME use handles */
if (!mono_error_ok (error))
return;
if (fb->attrs) {
return_if_nok (error);
}
+ if (!klass->enumtype && !mono_type_get_underlying_type (field->type)) {
+ mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name);
+ continue;
+ }
+
if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
char *base = mono_array_addr (rva_data, char, 0);
size_t size = mono_array_length (rva_data);
}
}
- mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
+ if (!mono_class_has_failure (klass)) {
+ mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
+ }
}
static void
typebuilder_setup_properties (MonoClass *klass, MonoError *error)
{
- MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
MonoReflectionPropertyBuilder *pb;
MonoImage *image = klass->image;
MonoProperty *properties;
MonoClassPropertyInfo *info;
int i;
- mono_error_init (error);
+ error_init (error);
info = mono_class_get_property_info (klass);
if (!info) {
pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
properties [i].parent = klass;
properties [i].attrs = pb->attrs;
- properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
+ properties [i].name = string_to_utf8_image_raw (image, pb->name, error); /* FIXME use handles */
if (!mono_error_ok (error))
return;
if (pb->get_method)
static void
typebuilder_setup_events (MonoClass *klass, MonoError *error)
{
- MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
MonoReflectionEventBuilder *eb;
MonoImage *image = klass->image;
MonoEvent *events;
MonoClassEventInfo *info;
int i;
- mono_error_init (error);
+ error_init (error);
info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo));
mono_class_set_event_info (klass, info);
eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
events [i].parent = klass;
events [i].attrs = eb->attrs;
- events [i].name = mono_string_to_utf8_image (image, eb->name, error);
+ events [i].name = string_to_utf8_image_raw (image, eb->name, error); /* FIXME use handles */
if (!mono_error_ok (error))
return;
if (eb->add_method)
return FALSE;
}
-MonoReflectionType*
-ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
+/**
+ * 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.
+ */
+static gboolean
+reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
{
- MonoError error;
- MonoClass *klass;
- MonoDomain* domain;
- MonoReflectionType* res;
- int i;
+ MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
+ GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
+
+ if (unparented_classes) {
+ return reflection_setup_internal_class_internal (ref_tb, error);
+ } else {
+ // If we're not being called recursively
+ unparented_classes = g_hash_table_new (NULL, NULL);
+ MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, unparented_classes);
+
+ gboolean ret_val = reflection_setup_internal_class_internal (ref_tb, error);
+ mono_error_assert_ok (error);
+
+ // Fix the relationship between the created classes and their parents
+ reflection_setup_class_hierarchy (unparented_classes, error);
+ mono_error_assert_ok (error);
+
+ g_hash_table_destroy (unparented_classes);
+ MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, NULL);
+
+ return ret_val;
+ }
+}
+
- mono_error_init (&error);
+MonoReflectionTypeHandle
+ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
+{
+ error_init (error);
- reflection_create_generic_class (tb, &error);
- mono_error_assert_ok (&error);
+ reflection_setup_internal_class (ref_tb, error);
+ mono_error_assert_ok (error);
- domain = mono_object_domain (tb);
- klass = mono_class_from_mono_type (tb->type.type);
+ MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_tb);
+ MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
+ MonoClass *klass = mono_class_from_mono_type (type);
- mono_save_custom_attrs (klass->image, klass, tb->cattrs);
+ MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, cattrs);
+ mono_save_custom_attrs (klass->image, klass, MONO_HANDLE_RAW (cattrs)); /* FIXME use handles */
/*
* we need to lock the domain because the lock will be taken inside
mono_domain_unlock (domain);
mono_loader_unlock ();
- res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
- mono_error_set_pending_exception (&error);
-
- return res;
+ return mono_type_get_object_handle (domain, &klass->byval_arg, error);
}
/*
* Fields to set in klass:
* the various flags: delegate/unicode/contextbound etc.
*/
- mono_class_set_flags (klass, tb->attrs);
+ mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
klass->has_cctor = 1;
mono_class_setup_parent (klass, klass->parent);
/* enums are done right away */
if (!klass->enumtype)
- if (!ensure_runtime_vtable (klass, &error))
+ if (!ensure_runtime_vtable (klass, error))
goto failure;
- if (tb->subtypes) {
+ MonoArrayHandle nested_types = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, subtypes);
+ if (!MONO_HANDLE_IS_NULL (nested_types)) {
GList *nested = NULL;
- for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
- MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
-
- if (!subtb->type.type) {
- reflection_setup_internal_class (subtb, &error);
- mono_error_assert_ok (&error);
+ int num_nested = mono_array_handle_length (nested_types);
+ MonoReflectionTypeHandle nested_tb = MONO_HANDLE_NEW (MonoReflectionType, NULL);
+ for (int i = 0; i < num_nested; ++i) {
+ MONO_HANDLE_ARRAY_GETREF (nested_tb, nested_types, i);
+
+ if (MONO_HANDLE_GETVAL (nested_tb, type) == NULL) {
+ reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, nested_tb), error);
+ mono_error_assert_ok (error);
}
- MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
- if (!is_ok (&error)) goto failure;
+ MonoType *subtype = mono_reflection_type_handle_mono_type (nested_tb, error);
+ if (!is_ok (error)) goto failure;
nested = g_list_prepend_image (klass->image, nested, mono_class_from_mono_type (subtype));
}
mono_class_set_nested_classes_property (klass, nested);
klass->nested_classes_inited = TRUE;
- typebuilder_setup_fields (klass, &error);
- if (!mono_error_ok (&error))
+ typebuilder_setup_fields (klass, error);
+ if (!is_ok (error))
goto failure;
- typebuilder_setup_properties (klass, &error);
- if (!mono_error_ok (&error))
+ typebuilder_setup_properties (klass, error);
+ if (!is_ok (error))
goto failure;
- typebuilder_setup_events (klass, &error);
- if (!mono_error_ok (&error))
+ typebuilder_setup_events (klass, error);
+ if (!is_ok (error))
goto failure;
klass->wastypebuilder = TRUE;
- if (tb->generic_params) {
- for (i = 0; i < mono_array_length (tb->generic_params); i++) {
- MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
- MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, &error);
+ MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
+ if (!MONO_HANDLE_IS_NULL (generic_params)) {
+ int num_params = mono_array_handle_length (generic_params);
+ MonoReflectionTypeHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionType, NULL);
+ for (int i = 0; i < num_params; i++) {
+ MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
+ MonoType *param_type = mono_reflection_type_handle_mono_type (ref_gparam, error);
+ if (!is_ok (error))
+ goto failure;
MonoClass *gklass = mono_class_from_mono_type (param_type);
gklass->wastypebuilder = TRUE;
if (domain->type_hash && mono_class_is_gtd (klass)) {
struct remove_instantiations_user_data data;
data.klass = klass;
- data.error = &error;
- mono_error_assert_ok (&error);
+ 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))
+ if (!is_ok (error))
goto failure;
}
if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
mono_class_set_type_load_failure (klass, "Not a valid enumeration");
- mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
+ 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);
- if (!is_ok (&error))
+ MonoReflectionTypeHandle res = mono_type_get_object_handle (domain, &klass->byval_arg, error);
+ if (!is_ok (error))
goto failure_unlocked;
- g_assert (res != (MonoReflectionType*)tb);
-
return res;
failure:
- mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (&error));
+ mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error));
klass->wastypebuilder = TRUE;
mono_domain_unlock (domain);
mono_loader_unlock ();
failure_unlocked:
- mono_error_set_pending_exception (&error);
return NULL;
}
}
static gboolean
-reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
+reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, MonoError *error)
{
MonoReferenceQueue *queue;
MonoMethod *handle;
GSList *l;
int i;
- mono_error_init (error);
+ error_init (error);
if (mono_runtime_is_shutting_down ()) {
mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
mono_loader_unlock ();
}
- sig = dynamic_method_to_signature (mb, error);
+ sig = dynamic_method_to_signature (ref_mb, error);
return_val_if_nok (error, FALSE);
+ MonoReflectionDynamicMethod *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME convert reflection_create_dynamic_method to use handles */
reflection_methodbuilder_from_dynamic_method (&rmb, mb);
/*
}
void
-ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
+ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
{
- MonoError error;
- (void) reflection_create_dynamic_method (mb, &error);
- mono_error_set_pending_exception (&error);
+ (void) reflection_create_dynamic_method (mb, error);
}
#endif /* DISABLE_REFLECTION_EMIT */
MonoMethodSignature *sig;
g_assert (image_is_dynamic (image));
- mono_error_init (error);
+ error_init (error);
sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
if (sig)
static void
ensure_complete_type (MonoClass *klass, MonoError *error)
{
- mono_error_init (error);
+ 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);
+ if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_has_ref_info (klass)) {
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
return_if_nok (error);
MonoClass *oklass = obj->vtable->klass;
gpointer result = NULL;
- mono_error_init (error);
+ error_init (error);
if (strcmp (oklass->name, "String") == 0) {
result = mono_string_intern_checked ((MonoString*)obj, error);
/* 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);
+ sig->params [i] = mono_type_array_get_and_resolve_raw (helper->arguments, i, error); /* FIXME use handles */
if (!is_ok (error)) {
image_g_free (image, sig);
return NULL;
g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
}
-static void
-mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
+static gboolean
+mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
{
g_assert_not_reached ();
+ return FALSE;
}
guint32
-mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
+mono_image_insert_string (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
{
g_assert_not_reached ();
return 0;
}
guint32
-mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
+mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
{
g_assert_not_reached ();
return 0;
}
guint32
-mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
+mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
gboolean create_open_instance, gboolean register_token, MonoError *error)
{
g_assert_not_reached ();
void
mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
*overrides = NULL;
*num_overrides = 0;
}
-MonoReflectionType*
-ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
+MonoReflectionTypeHandle
+ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb, MonoError *error)
{
g_assert_not_reached ();
return NULL;
}
void
-ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
+ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
{
+ error_init (error);
}
MonoType*
mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
if (!ref)
return NULL;
return ref->type;
}
+MonoType*
+mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
+{
+ error_init (error);
+ if (MONO_HANDLE_IS_NULL (ref))
+ return NULL;
+ return MONO_HANDLE_GETVAL (ref, type);
+}
+
+
#endif /* DISABLE_REFLECTION_EMIT */
void
mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
{
- mono_gc_deregister_root ((char*) &entry->gparam);
+ MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry->gparam);
g_free (entry);
}
gint32
-ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
+ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, gboolean create_open_instance, MonoError *error)
{
- MONO_CHECK_ARG_NULL (obj, 0);
-
- MonoError error;
- gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
- mono_error_set_pending_exception (&error);
- return result;
+ error_init (error);
+ if (MONO_HANDLE_IS_NULL (obj)) {
+ mono_error_set_argument_null (error, "obj", "");
+ return 0;
+ }
+ return mono_image_create_token (MONO_HANDLE_GETVAL (mb, dynamic_image), obj, create_open_instance, TRUE, error);
}
gint32
-ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
- MonoReflectionMethod *method,
- MonoArray *opt_param_types)
+ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb,
+ MonoReflectionMethodHandle method,
+ MonoArrayHandle opt_param_types,
+ MonoError *error)
{
- MONO_CHECK_ARG_NULL (method, 0);
+ error_init (error);
+ if (MONO_HANDLE_IS_NULL (method)) {
+ mono_error_set_argument_null (error, "method", "");
+ return 0;
+ }
- MonoError error;
- gint32 result = mono_image_create_method_token (
- mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
- mono_error_set_pending_exception (&error);
- return result;
+ return mono_image_create_method_token (MONO_HANDLE_GETVAL (mb, dynamic_image), MONO_HANDLE_CAST (MonoObject, method), opt_param_types, error);
}
void
}
void
-ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
+ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, guint32 token, MonoError *error)
{
- mono_image_register_token (mb->dynamic_image, token, obj);
+ error_init (error);
+ /* This function may be called by ModuleBuilder.FixupTokens to update
+ * an existing token, so replace is okay here. */
+ mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj, MONO_DYN_IMAGE_TOK_REPLACE);
}
-MonoObject*
-ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
+MonoObjectHandle
+ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb, guint32 token, MonoError *error)
{
- MonoObject *obj;
-
- mono_loader_lock ();
- obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
- mono_loader_unlock ();
-
- return obj;
+ error_init (error);
+ MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
+ return mono_dynamic_image_get_registered_token (dynamic_image, token, error);
}
#ifndef DISABLE_REFLECTION_EMIT
}
void
-ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
- MonoReflectionType *t)
+ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype,
+ MonoReflectionTypeHandle t,
+ MonoError *error)
{
- enumtype->type = t->type;
+ error_init (error);
+ MONO_HANDLE_SETVAL (enumtype, type, MonoType*, MONO_HANDLE_GETVAL (t, type));
}
void
-ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
+ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
{
- mono_image_module_basic_init (moduleb);
+ error_init (error);
+ mono_image_module_basic_init (moduleb, error);
}
guint32
-ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
+ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
{
- return mono_image_insert_string (module, str);
+ return mono_image_insert_string (module, str, error);
}
void
-ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
+ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb, MonoReflectionTypeHandle ref_type, MonoError *error)
{
- MonoDynamicImage *image = moduleb->dynamic_image;
+ error_init (error);
+ MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
+ MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
- g_assert (type->type);
- image->wrappers_type = mono_class_from_mono_type (type->type);
+ g_assert (type);
+ image->wrappers_type = mono_class_from_mono_type (type);
}