#include <mono/metadata/gc-internal.h>
#include <mono/metadata/mempool-internals.h>
#include <mono/metadata/security-core-clr.h>
+#include <mono/metadata/debug-helpers.h>
+#include <mono/utils/mono-string.h>
+#include <mono/utils/mono-error-internals.h>
+
#if HAVE_SGEN_GC
static void* reflection_info_desc = NULL;
#define MOVING_GC_REGISTER(addr)
#endif
+static gboolean is_usertype (MonoReflectionType *ref);
+static MonoReflectionType *mono_reflection_type_resolve_user_types (MonoReflectionType *type);
+
typedef struct {
char *p;
char *buf;
static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method);
static guint32 encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context);
static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
-#endif
-
static void reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb);
static void reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb);
+static guint32 create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb);
+#endif
+
static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
static guint32 mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec);
static void mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly);
static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass);
static void encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
static void get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types);
-static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob);
static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t);
static MonoType* mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve);
+static MonoReflectionType* mono_reflection_type_resolve_user_types (MonoReflectionType *type);
+static gboolean is_sre_array (MonoClass *class);
+static gboolean is_sre_byref (MonoClass *class);
+static gboolean is_sre_pointer (MonoClass *class);
+static gboolean is_sre_type_builder (MonoClass *class);
+static gboolean is_sre_method_builder (MonoClass *class);
+static gboolean is_sre_ctor_builder (MonoClass *class);
+static gboolean is_sre_field_builder (MonoClass *class);
+static gboolean is_sr_mono_method (MonoClass *class);
+static gboolean is_sr_mono_cmethod (MonoClass *class);
+static gboolean is_sr_mono_generic_method (MonoClass *class);
+static gboolean is_sr_mono_generic_cmethod (MonoClass *class);
+static gboolean is_sr_mono_field (MonoClass *class);
+static gboolean is_sr_mono_property (MonoClass *class);
+static gboolean is_sre_method_on_tb_inst (MonoClass *class);
+static gboolean is_sre_ctor_on_tb_inst (MonoClass *class);
+
+static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
+static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
+static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj);
+
+#define RESOLVE_TYPE(type) do { type = (void*)mono_reflection_type_resolve_user_types ((MonoReflectionType*)type); } while (0)
+#define RESOLVE_ARRAY_TYPE_ELEMENT(array, index) do { \
+ MonoReflectionType *__type = mono_array_get (array, MonoReflectionType*, index); \
+ __type = mono_reflection_type_resolve_user_types (__type); \
+ mono_array_set (arr, MonoReflectionType*, index, __type); \
+} while (0)
+
+#define mono_type_array_get_and_resolve(array, index) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index))
void
mono_reflection_init (void)
}
#endif
+/*
+ * mono_class_get_ref_info:
+ *
+ * Return the type builder/generic param builder corresponding to KLASS, if it exists.
+ */
+gpointer
+mono_class_get_ref_info (MonoClass *klass)
+{
+ if (klass->ref_info_handle == 0)
+ return NULL;
+ else
+ return mono_gchandle_get_target (klass->ref_info_handle);
+}
+
+void
+mono_class_set_ref_info (MonoClass *klass, gpointer obj)
+{
+ klass->ref_info_handle = mono_gchandle_new ((MonoObject*)obj, FALSE);
+ g_assert (klass->ref_info_handle != 0);
+}
+
+void
+mono_class_free_ref_info (MonoClass *klass)
+{
+ if (klass->ref_info_handle) {
+ mono_gchandle_free (klass->ref_info_handle);
+ klass->ref_info_handle = 0;
+ }
+}
+
static void
encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
{
return;
}
- if (type->type ||
- ((type = mono_reflection_type_get_underlying_system_type (type)) && type->type)) {
- encode_type (assembly, type->type, buf);
- return;
- }
-
- g_assert_not_reached ();
-
+ encode_type (assembly, mono_reflection_type_get_handle (type), buf);
}
static void
if (modreq) {
for (i = 0; i < mono_array_length (modreq); ++i) {
- MonoReflectionType *mod = mono_type_array_get (modreq, i);
+ MonoType *mod = mono_type_array_get_and_resolve (modreq, i);
sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
- sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod->type));
+ sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
}
}
if (modopt) {
for (i = 0; i < mono_array_length (modopt); ++i) {
- MonoReflectionType *mod = mono_type_array_get (modopt, i);
+ MonoType *mod = mono_type_array_get_and_resolve (modopt, i);
sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
- sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod->type));
+ sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
}
}
}
if (mb->param_modopt && (i < mono_array_length (mb->param_modopt)))
modopt = mono_array_get (mb->param_modopt, MonoArray*, i);
encode_custom_modifiers (assembly, modreq, modopt, &buf);
- pt = mono_type_array_get (mb->parameters, i);
+ pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
encode_reflection_type (assembly, pt, &buf);
}
if (notypes)
for (i = 0; i < notypes; ++i) {
MonoReflectionType *pt;
- pt = mono_type_array_get (mb->opt_types, i);
+ pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
encode_reflection_type (assembly, pt, &buf);
}
if (lb->is_pinned)
sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
- encode_reflection_type (assembly, monotype_cast (lb->type), &buf);
+ encode_reflection_type (assembly, (MonoReflectionType*)lb->type, &buf);
}
sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
sigbuffer_free (&buf);
clause->handler_offset = ex_block->start;
clause->handler_len = ex_block->len;
if (ex_block->extype) {
- clause->data.catch_class = mono_class_from_mono_type (monotype_cast (ex_block->extype)->type);
+ clause->data.catch_class = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype));
} else {
if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
clause->data.filter_offset = ex_block->filter_offset;
mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
finally_start = ex_block->start + ex_block->len;
if (ex_block->extype) {
- val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, monotype_cast (ex_block->extype)->type));
+ val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype)));
} else {
if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
val = ex_block->filter_offset;
if (!res)
return NULL;
- return g_memdup (res, sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (res->num_attrs - MONO_ZERO_LEN_ARRAY));
+ return g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs);
}
static gboolean
}
count -= not_visible;
- ainfo = image_g_malloc0 (alloc_img, sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY));
+ ainfo = image_g_malloc0 (alloc_img, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * count);
ainfo->image = image;
ainfo->num_attrs = count;
}
}
+#ifndef DISABLE_REFLECTION_EMIT
static void
reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb)
{
memset (rmb, 0, sizeof (ReflectionMethodBuilder));
rmb->ilgen = mb->ilgen;
- rmb->rtype = monotype_cast (mb->rtype);
+ rmb->rtype = mono_reflection_type_resolve_user_types ((MonoReflectionType*)mb->rtype);
rmb->parameters = mb->parameters;
rmb->generic_params = mb->generic_params;
rmb->generic_container = mb->generic_container;
rmb->refs = NULL;
}
-#ifndef DISABLE_REFLECTION_EMIT
static void
reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
{
values [MONO_METHODIMPL_DECLARATION] = tok;
}
+#ifndef DISABLE_REFLECTION_EMIT
static void
mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *assembly)
{
mono_image_basic_method (&rmb, assembly);
mb->table_idx = *rmb.table_idx;
}
+#endif
static char*
type_get_fully_qualified_name (MonoType *type)
}
#ifndef DISABLE_REFLECTION_EMIT
+/*field_image is the image to which the eventual custom mods have been encoded against*/
static guint32
-fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
+fieldref_encode_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
{
SigBuffer buf;
- guint32 idx, i;
+ guint32 idx, i, token;
if (!assembly->save)
return 0;
sigbuffer_add_value (&buf, 0x06);
/* encode custom attributes before the type */
- /* FIXME: This should probably go in encode_type () */
if (type->num_mods) {
for (i = 0; i < type->num_mods; ++i) {
+ if (field_image) {
+ MonoClass *class = mono_class_get (field_image, type->modifiers [i].token);
+ g_assert (class);
+ token = mono_image_typedef_or_ref (assembly, &class->byval_arg);
+ } else {
+ token = type->modifiers [i].token;
+ }
+
if (type->modifiers [i].required)
sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD);
else
sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT);
- sigbuffer_add_value (&buf, type->modifiers [i].token);
+
+ sigbuffer_add_value (&buf, token);
}
}
encode_type (assembly, type, &buf);
sigbuffer_add_value (&buf, 0x06);
encode_custom_modifiers (assembly, fb->modreq, fb->modopt, &buf);
/* encode custom attributes before the type */
- encode_reflection_type (assembly, monotype_cast (fb->type), &buf);
+ encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf);
idx = sigbuffer_add_to_blob_cached (assembly, &buf);
sigbuffer_free (&buf);
return idx;
}
}
break;
+ case MONO_NATIVE_SAFEARRAY:
+ if (minfo->eltype)
+ sigbuffer_add_value (&buf, minfo->eltype);
+ break;
case MONO_NATIVE_CUSTOM:
if (minfo->guid) {
str = mono_string_to_utf8 (minfo->guid);
/* custom marshaler type name */
if (minfo->marshaltype || minfo->marshaltyperef) {
if (minfo->marshaltyperef)
- str = type_get_fully_qualified_name (monotype_cast (minfo->marshaltyperef)->type);
+ str = type_get_fully_qualified_name (mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef));
else
str = mono_string_to_utf8 (minfo->marshaltype);
len = strlen (str);
sigbuffer_add_byte (&buf, 0x08);
sigbuffer_add_value (&buf, nparams);
if (mb) {
- encode_reflection_type (assembly, monotype_cast (mb->rtype), &buf);
+ encode_reflection_type (assembly, (MonoReflectionType*)mb->rtype, &buf);
for (i = 0; i < nparams; ++i) {
- MonoReflectionType *pt = mono_type_array_get (mb->parameters, i);
+ MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
encode_reflection_type (assembly, pt, &buf);
}
} else if (smb && smb->parameters) {
/* the property type is the last param */
- encode_reflection_type (assembly, mono_type_array_get (smb->parameters, nparams), &buf);
+ encode_reflection_type (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf);
for (i = 0; i < nparams; ++i) {
- MonoReflectionType *pt = mono_type_array_get (smb->parameters, i);
+ MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
encode_reflection_type (assembly, pt, &buf);
}
} else {
- encode_reflection_type (assembly, monotype_cast (fb->type), &buf);
+ encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf);
}
idx = sigbuffer_add_to_blob_cached (assembly, &buf);
* PROPERTY (rows already preallocated in _get_type_info ())
* METHOD (method info already done with the generic method code)
* METHODSEMANTICS
+ * CONSTANT
*/
table = &assembly->tables [MONO_TABLE_PROPERTY];
pb->table_idx = table->next_idx ++;
values [MONO_METHOD_SEMA_METHOD] = pb->set_method->table_idx;
values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
}
+ if (pb->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT) {
+ guint32 field_type = 0;
+ table = &assembly->tables [MONO_TABLE_CONSTANT];
+ table->rows ++;
+ alloc_table (table, table->rows);
+ values = table->values + table->rows * MONO_CONSTANT_SIZE;
+ values [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_PROPERTY | (pb->table_idx << MONO_HASCONSTANT_BITS);
+ values [MONO_CONSTANT_VALUE] = encode_constant (assembly, pb->def_value, &field_type);
+ values [MONO_CONSTANT_TYPE] = field_type;
+ values [MONO_CONSTANT_PADDING] = 0;
+ }
}
static void
values = table->values + eb->table_idx * MONO_EVENT_SIZE;
values [MONO_EVENT_NAME] = string_heap_insert_mstring (&assembly->sheap, eb->name);
values [MONO_EVENT_FLAGS] = eb->attrs;
- values [MONO_EVENT_TYPE] = mono_image_typedef_or_ref (assembly, eb->type->type);
+ values [MONO_EVENT_TYPE] = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle (eb->type));
/*
* FIXME: we still don't handle 'other' methods
values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (
- assembly, gparam->base_type->type);
+ assembly, mono_reflection_type_get_handle (gparam->base_type));
}
for (i = 0; i < num_constraints; i++) {
values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (
- assembly, constraint->type);
+ assembly, mono_reflection_type_get_handle (constraint));
}
}
/* FIXME: track where gen_params should be freed and remove the GC root as well */
MOVING_GC_REGISTER (&entry->gparam);
entry->gparam = gparam;
-
+
g_ptr_array_add (assembly->gen_params, entry);
}
table_idx = table->next_idx ++;
values = table->values + table_idx * MONO_GENERICPARAM_SIZE;
- param = entry->gparam->type.type->data.generic_param;
+ param = mono_reflection_type_get_handle ((MonoReflectionType*)entry->gparam)->data.generic_param;
values [MONO_GENERICPARAM_OWNER] = entry->owner;
values [MONO_GENERICPARAM_FLAGS] = entry->gparam->attrs;
*/
if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) &&
(type->type != MONO_TYPE_MVAR)) {
- MonoReflectionTypeBuilder *tb = klass->reflection_info;
+ MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
token = MONO_TYPEDEFORREF_TYPEDEF | (tb->table_idx << MONO_TYPEDEFORREF_BITS);
- mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), klass->reflection_info);
+ mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), mono_class_get_ref_info (klass));
return token;
}
token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
table->next_idx ++;
- mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), klass->reflection_info);
+ mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), mono_class_get_ref_info (klass));
return token;
}
}
#ifndef DISABLE_REFLECTION_EMIT
-/*
- * Insert a memberef row into the metadata: the token that point to the memberref
- * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
- * mono_image_get_fieldref_token()).
- * The sig param is an index to an already built signature.
- */
static guint32
-mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
+mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
{
MonoDynamicTable *table;
guint32 *values;
guint32 token, pclass;
- guint32 parent;
- parent = mono_image_typedef_or_ref (assembly, type);
switch (parent & MONO_TYPEDEFORREF_MASK) {
case MONO_TYPEDEFORREF_TYPEREF:
pclass = MONO_MEMBERREF_PARENT_TYPEREF;
return token;
}
+/*
+ * Insert a memberef row into the metadata: the token that point to the memberref
+ * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
+ * mono_image_get_fieldref_token()).
+ * The sig param is an index to an already built signature.
+ */
+static guint32
+mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
+{
+ guint32 parent = mono_image_typedef_or_ref (assembly, type);
+ return mono_image_add_memberef_row (assembly, parent, name, sig);
+}
+
+
static guint32
mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
{
static guint32
mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method)
{
- guint32 token;
+ guint32 token, parent, sig;
ReflectionMethodBuilder rmb;
char *name;
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
if (token)
*/
if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG)
rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT;
- token = mono_image_get_memberref_token (assembly, ((MonoReflectionTypeBuilder*)rmb.type)->type.type,
- name, method_builder_encode_signature (assembly, &rmb));
+
+ sig = method_builder_encode_signature (assembly, &rmb);
+
+ if (tb->generic_params)
+ parent = create_generic_typespec (assembly, tb);
+ else
+ parent = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type));
+
+ token = mono_image_add_memberef_row (assembly, parent, name, sig);
g_free (name);
g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec)
{
guint32 token;
-
+
if (mb->generic_params && create_methodspec)
return mono_image_get_methodspec_token_for_generic_method_definition (assembly, mb);
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, mb));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
if (token)
return token;
token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb);
- g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
+ mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
return token;
}
static guint32
mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *mb)
{
- guint32 token;
+ guint32 token, parent, sig;
ReflectionMethodBuilder rmb;
char *name;
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, mb));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
if (token)
return token;
+ g_assert (tb->generic_params);
+
reflection_methodbuilder_from_ctor_builder (&rmb, mb);
+ parent = create_generic_typespec (assembly, tb);
name = mono_string_to_utf8 (rmb.name);
- token = mono_image_get_memberref_token (assembly, ((MonoReflectionTypeBuilder*)rmb.type)->type.type,
- name, method_builder_encode_signature (assembly, &rmb));
+ sig = method_builder_encode_signature (assembly, &rmb);
+
+ token = mono_image_add_memberef_row (assembly, parent, name, sig);
g_free (name);
- g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
+ mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
return token;
}
#endif
static MonoType*
get_field_on_inst_generic_type (MonoClassField *field)
{
+ MonoClass *class, *gtd;
MonoDynamicGenericClass *dgclass;
int field_index;
g_assert (is_field_on_inst (field));
dgclass = (MonoDynamicGenericClass*)field->parent->generic_class;
- field_index = field - dgclass->fields;
- g_assert (field_index >= 0 && field_index < dgclass->count_fields);
- return dgclass->field_generic_types [field_index];
+ if (field >= dgclass->fields && field - dgclass->fields < dgclass->count_fields) {
+ field_index = field - dgclass->fields;
+ return dgclass->field_generic_types [field_index];
+ }
+
+ class = field->parent;
+ gtd = class->generic_class->container_class;
+
+ if (field >= class->fields && field - class->fields < class->field.count) {
+ field_index = field - class->fields;
+ return gtd->fields [field_index].type;
+ }
+
+ g_assert_not_reached ();
+ return 0;
}
#ifndef DISABLE_REFLECTION_EMIT
guint32 token;
MonoClassField *field;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
if (token)
return token;
g_assert (f->field->parent);
}
token = mono_image_get_memberref_token (assembly, &f->field->parent->byval_arg,
mono_field_get_name (f->field),
- fieldref_encode_signature (assembly, type));
- g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token));
+ fieldref_encode_signature (assembly, field->parent->image, type));
+ mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
return token;
}
MonoClass *klass;
MonoGenericClass *gclass;
MonoDynamicGenericClass *dgclass;
- MonoReflectionFieldBuilder *fb = f->fb;
+ MonoType *type;
char *name;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
if (token)
return token;
- klass = mono_class_from_mono_type (f->inst->type.type);
- gclass = f->inst->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
- dgclass = (MonoDynamicGenericClass *) gclass;
+ if (is_sre_field_builder (mono_object_class (f->fb))) {
+ MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)f->fb;
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst);
+ klass = mono_class_from_mono_type (type);
+ gclass = type->data.generic_class;
+ g_assert (gclass->is_dynamic);
+ dgclass = (MonoDynamicGenericClass *) gclass;
+
+ name = mono_string_to_utf8 (fb->name);
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name,
+ field_encode_signature (assembly, fb));
+ g_free (name);
+ } else if (is_sr_mono_field (mono_object_class (f->fb))) {
+ guint32 sig;
+ MonoClassField *field = ((MonoReflectionField *)f->fb)->field;
+
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst);
+ klass = mono_class_from_mono_type (type);
- name = mono_string_to_utf8 (fb->name);
- token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name,
- field_encode_signature (assembly, fb));
- g_free (name);
- g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER (token));
+ sig = fieldref_encode_signature (assembly, field->parent->image, field->type);
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, field->name, sig);
+ } else {
+ char *name = mono_type_get_full_name (mono_object_class (f->fb));
+ g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+ }
+
+ mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
return token;
}
guint32 sig, token;
MonoClass *klass;
MonoGenericClass *gclass;
- MonoDynamicGenericClass *dgclass;
- MonoReflectionCtorBuilder *cb = c->cb;
- ReflectionMethodBuilder rmb;
- char *name;
+ MonoType *type;
/* A ctor cannot be a generic method, so we can ignore create_methodspec */
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, c));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, c));
if (token)
return token;
- klass = mono_class_from_mono_type (c->inst->type.type);
- gclass = c->inst->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
- dgclass = (MonoDynamicGenericClass *) gclass;
- reflection_methodbuilder_from_ctor_builder (&rmb, cb);
+ if (is_sre_ctor_builder (mono_object_class (c->cb))) {
+ MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder *)c->cb;
+ MonoDynamicGenericClass *dgclass;
+ ReflectionMethodBuilder rmb;
+ char *name;
- name = mono_string_to_utf8 (rmb.name);
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst);
+ klass = mono_class_from_mono_type (type);
- sig = method_builder_encode_signature (assembly, &rmb);
+ gclass = type->data.generic_class;
+ g_assert (gclass->is_dynamic);
+ dgclass = (MonoDynamicGenericClass *) gclass;
- token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
- g_free (name);
+ reflection_methodbuilder_from_ctor_builder (&rmb, cb);
+
+ name = mono_string_to_utf8 (rmb.name);
- g_hash_table_insert (assembly->handleref, c, GUINT_TO_POINTER (token));
+ sig = method_builder_encode_signature (assembly, &rmb);
+
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
+ g_free (name);
+ } else if (is_sr_mono_cmethod (mono_object_class (c->cb))) {
+ MonoMethod *mm = ((MonoReflectionMethod *)c->cb)->method;
+
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst);
+ klass = mono_class_from_mono_type (type);
+
+ sig = method_encode_signature (assembly, mono_method_signature (mm));
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
+ } else {
+ char *name = mono_type_get_full_name (mono_object_class (c->cb));
+ g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+ }
+
+
+ mono_g_hash_table_insert (assembly->handleref_managed, c, GUINT_TO_POINTER (token));
return token;
}
+static MonoMethod*
+mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderInst *m)
+{
+ MonoClass *klass;
+ MonoGenericContext tmp_context;
+ MonoType **type_argv;
+ MonoGenericInst *ginst;
+ MonoMethod *method, *inflated;
+ int count, i;
+
+ method = inflate_method (m->inst, (MonoObject*)m->mb);
+
+ klass = method->klass;
+
+ if (m->method_args == NULL)
+ return method;
+
+ if (method->is_inflated)
+ method = ((MonoMethodInflated *) method)->declaring;
+
+ count = mono_array_length (m->method_args);
+
+ type_argv = g_new0 (MonoType *, count);
+ for (i = 0; i < count; i++) {
+ MonoReflectionType *garg = mono_array_get (m->method_args, gpointer, i);
+ type_argv [i] = mono_reflection_type_get_handle (garg);
+ }
+ ginst = mono_metadata_get_generic_inst (count, type_argv);
+ g_free (type_argv);
+
+ tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
+ tmp_context.method_inst = ginst;
+
+ inflated = mono_class_inflate_generic_method (method, &tmp_context);
+ return inflated;
+}
+
static guint32
mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec)
{
- guint32 sig, token;
+ guint32 sig, token = 0;
+ MonoType *type;
MonoClass *klass;
- MonoGenericClass *gclass;
- MonoReflectionMethodBuilder *mb = m->mb;
- ReflectionMethodBuilder rmb;
- char *name;
- if (create_methodspec && mb->generic_params)
- // FIXME:
- g_assert_not_reached ();
+ if (m->method_args) {
+ MonoMethod *inflated;
+
+ inflated = mono_reflection_method_on_tb_inst_get_handle (m);
+ if (create_methodspec)
+ token = mono_image_get_methodspec_token (assembly, inflated);
+ else
+ token = mono_image_get_inflated_method_token (assembly, inflated);
+ return token;
+ }
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, m));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, m));
if (token)
return token;
- klass = mono_class_from_mono_type (m->inst->type.type);
- gclass = m->inst->type.type->data.generic_class;
- g_assert (gclass->is_dynamic);
- reflection_methodbuilder_from_method_builder (&rmb, mb);
+ if (is_sre_method_builder (mono_object_class (m->mb))) {
+ MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)m->mb;
+ MonoGenericClass *gclass;
+ ReflectionMethodBuilder rmb;
+ char *name;
- name = mono_string_to_utf8 (rmb.name);
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
+ klass = mono_class_from_mono_type (type);
+ gclass = type->data.generic_class;
+ g_assert (gclass->is_dynamic);
- sig = method_builder_encode_signature (assembly, &rmb);
+ reflection_methodbuilder_from_method_builder (&rmb, mb);
- token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
- g_free (name);
+ name = mono_string_to_utf8 (rmb.name);
+
+ sig = method_builder_encode_signature (assembly, &rmb);
+
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
+ g_free (name);
+ } else if (is_sr_mono_method (mono_object_class (m->mb))) {
+ MonoMethod *mm = ((MonoReflectionMethod *)m->mb)->method;
+
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
+ klass = mono_class_from_mono_type (type);
+
+ sig = method_encode_signature (assembly, mono_method_signature (mm));
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
+ } else {
+ char *name = mono_type_get_full_name (mono_object_class (m->mb));
+ g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+ }
- g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER (token));
+ mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
return token;
}
{
MonoDynamicTable *table;
MonoClass *klass;
+ MonoType *type;
guint32 *values;
guint32 token;
SigBuffer buf;
* ie. what we'd normally use as the generic type in a TypeSpec signature.
* Because of this, we must not insert it into the `typeref' hash table.
*/
-
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, tb->type.type));
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)tb);
+ token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type));
if (token)
return token;
sigbuffer_init (&buf, 32);
g_assert (tb->generic_params);
- klass = mono_class_from_mono_type (tb->type.type);
+ klass = mono_class_from_mono_type (type);
if (tb->generic_container)
mono_reflection_create_generic_class (tb);
gparam = mono_array_get (tb->generic_params, MonoReflectionGenericParam *, i);
- encode_type (assembly, gparam->type.type, &buf);
+ encode_type (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)gparam), &buf);
}
table = &assembly->tables [MONO_TABLE_TYPESPEC];
sigbuffer_free (&buf);
token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
- g_hash_table_insert (assembly->typespec, tb->type.type, GUINT_TO_POINTER(token));
+ g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
table->next_idx ++;
return token;
}
if (count == 0)
return mono_metadata_type_dup (NULL, type);
- len = sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod);
+ len = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod);
t = g_malloc (len);
- memcpy (t, type, len);
+ memcpy (t, type, MONO_SIZEOF_TYPE);
t->num_mods = count;
pos = 0;
if (modreq) {
for (i = 0; i < mono_array_length (modreq); ++i) {
- MonoReflectionType *mod = mono_type_array_get (modreq, i);
+ MonoType *mod = mono_type_array_get_and_resolve (modreq, i);
t->modifiers [pos].required = 1;
- t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod->type);
+ t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
pos ++;
}
}
if (modopt) {
for (i = 0; i < mono_array_length (modopt); ++i) {
- MonoReflectionType *mod = mono_type_array_get (modopt, i);
+ MonoType *mod = mono_type_array_get_and_resolve (modopt, i);
t->modifiers [pos].required = 0;
- t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod->type);
+ t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
pos ++;
}
}
guint32 token, pclass, parent, sig;
gchar *name;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, fb));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, fb));
if (token)
return token;
- klass = mono_class_from_mono_type (fb->typeb->type);
+ klass = mono_class_from_mono_type (mono_reflection_type_get_handle (fb->typeb));
name = mono_string_to_utf8 (fb->name);
/* fb->type does not include the custom modifiers */
/* FIXME: We should do this in one place when a fieldbuilder is created */
if (fb->modreq || fb->modopt) {
- custom = add_custom_modifiers (assembly, monotype_cast (fb->type)->type, fb->modreq, fb->modopt);
- sig = fieldref_encode_signature (assembly, custom);
+ custom = add_custom_modifiers (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type), fb->modreq, fb->modopt);
+ sig = fieldref_encode_signature (assembly, NULL, custom);
g_free (custom);
} else {
- sig = fieldref_encode_signature (assembly, monotype_cast (fb->type)->type);
+ sig = fieldref_encode_signature (assembly, NULL, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
}
parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb);
token = MONO_TOKEN_MEMBER_REF | table->next_idx;
table->next_idx ++;
- g_hash_table_insert (assembly->handleref, fb, GUINT_TO_POINTER(token));
+ mono_g_hash_table_insert (assembly->handleref_managed, fb, GUINT_TO_POINTER(token));
g_free (name);
return token;
}
modopts = mono_array_get (helper->modopts, MonoArray*, i);
encode_custom_modifiers (assembly, modreqs, modopts, &buf);
- pt = mono_type_array_get (helper->arguments, i);
+ pt = mono_array_get (helper->arguments, MonoReflectionType*, i);
encode_reflection_type (assembly, pt, &buf);
}
idx = sigbuffer_add_to_blob_cached (assembly, &buf);
char *name;
MonoMethodSignature *sig;
ArrayMethod *am;
-
+ MonoType *mtype;
+
name = mono_string_to_utf8 (m->name);
nparams = mono_array_length (m->parameters);
- sig = g_malloc0 (sizeof (MonoMethodSignature) + sizeof (MonoType*) * nparams);
+ sig = 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->param_count = nparams;
- sig->ret = m->ret? m->ret->type: &mono_defaults.void_class->byval_arg;
- for (i = 0; i < nparams; ++i) {
- MonoReflectionType *t = mono_type_array_get (m->parameters, i);
- sig->params [i] = t->type;
- }
+ sig->ret = m->ret ? mono_reflection_type_get_handle (m->ret): &mono_defaults.void_class->byval_arg;
+ mtype = mono_reflection_type_get_handle (m->parent);
+ for (i = 0; i < nparams; ++i)
+ sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i);
for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
am = tmp->data;
if (strcmp (name, am->name) == 0 &&
- mono_metadata_type_equal (am->parent, m->parent->type) &&
+ mono_metadata_type_equal (am->parent, mtype) &&
mono_metadata_signature_equal (am->sig, sig)) {
g_free (name);
g_free (sig);
am = g_new0 (ArrayMethod, 1);
am->name = name;
am->sig = sig;
- am->parent = m->parent->type;
+ am->parent = mtype;
am->token = mono_image_get_memberref_token (assembly, am->parent, name,
method_encode_signature (assembly, sig));
assembly->array_methods = g_list_prepend (assembly->array_methods, am);
m->table_idx = am->token & 0xffffff;
return am->token;
}
-#endif
/*
* Insert into the metadata tables all the info about the TypeBuilder tb.
g_free (n);
if (tb->parent && !(is_system && is_object) &&
!(tb->attrs & TYPE_ATTRIBUTE_INTERFACE)) { /* interfaces don't have a parent */
- values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, monotype_cast (tb->parent)->type);
+ values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent));
} else {
values [MONO_TYPEDEF_EXTENDS] = 0;
}
for (i = 0; i < mono_array_length (tb->interfaces); ++i) {
MonoReflectionType* iface = (MonoReflectionType*) mono_array_get (tb->interfaces, gpointer, i);
values [MONO_INTERFACEIMPL_CLASS] = tb->table_idx;
- values [MONO_INTERFACEIMPL_INTERFACE] = mono_image_typedef_or_ref (assembly, iface->type);
+ values [MONO_INTERFACEIMPL_INTERFACE] = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle (iface));
values += MONO_INTERFACEIMPL_SIZE;
}
}
}
}
}
+#endif
static void
collect_types (GPtrArray *types, MonoReflectionTypeBuilder *type)
MonoClass *klass;
guint32 idx, i;
- klass = mono_class_from_mono_type (tb->type.type);
+ klass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)tb));
klass->type_token = mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx);
}
}
-static void
-mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly)
+static guint32
+add_exported_type (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly, MonoClass *klass)
{
MonoDynamicTable *table;
- MonoClass *klass;
guint32 *values;
- guint32 scope, idx;
- int i;
+ guint32 scope, idx, res, impl;
+ gboolean forwarder = TRUE;
+
+ if (klass->nested_in) {
+ impl = add_exported_type (assemblyb, assembly, klass->nested_in);
+ forwarder = FALSE;
+ } else {
+ scope = resolution_scope_from_image (assembly, klass->image);
+ g_assert ((scope & MONO_RESOLTION_SCOPE_MASK) == MONO_RESOLTION_SCOPE_ASSEMBLYREF);
+ idx = scope >> MONO_RESOLTION_SCOPE_BITS;
+ impl = (idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
+ }
table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
- if (assemblyb->type_forwarders) {
- for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) {
- MonoReflectionType *t = mono_type_array_get (assemblyb->type_forwarders, i);
- if (!t)
- continue;
+ table->rows++;
+ alloc_table (table, table->rows);
+ values = table->values + table->next_idx * MONO_EXP_TYPE_SIZE;
- g_assert (t->type);
+ values [MONO_EXP_TYPE_FLAGS] = forwarder ? TYPE_ATTRIBUTE_FORWARDER : 0;
+ values [MONO_EXP_TYPE_TYPEDEF] = 0;
+ values [MONO_EXP_TYPE_IMPLEMENTATION] = impl;
+ values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
+ values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
- klass = mono_class_from_mono_type (t->type);
+ res = (table->next_idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
- scope = resolution_scope_from_image (assembly, klass->image);
- g_assert ((scope & MONO_RESOLTION_SCOPE_MASK) == MONO_RESOLTION_SCOPE_ASSEMBLYREF);
- idx = scope >> MONO_RESOLTION_SCOPE_BITS;
+ table->next_idx++;
- table->rows++;
- alloc_table (table, table->rows);
- values = table->values + table->next_idx * MONO_EXP_TYPE_SIZE;
+ return res;
+}
+
+static void
+mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly)
+{
+ MonoClass *klass;
+ int i;
- values [MONO_EXP_TYPE_FLAGS] = TYPE_ATTRIBUTE_FORWARDER;
- values [MONO_EXP_TYPE_TYPEDEF] = 0;
- values [MONO_EXP_TYPE_IMPLEMENTATION] = (idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
- values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
- values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
+ if (!assemblyb->type_forwarders)
+ return;
- table->next_idx++;
- }
+ for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) {
+ MonoReflectionType *t = mono_array_get (assemblyb->type_forwarders, MonoReflectionType *, i);
+ MonoType *type;
+ if (!t)
+ continue;
+
+ type = mono_reflection_type_get_handle (t);
+ g_assert (type);
+
+ klass = mono_class_from_mono_type (type);
+
+ add_exported_type (assemblyb, assembly, klass);
}
}
if ((*b_entry)->owner == (*a_entry)->owner)
return
- mono_type_get_generic_param_num ((*a_entry)->gparam->type.type) -
- mono_type_get_generic_param_num ((*b_entry)->gparam->type.type);
+ mono_type_get_generic_param_num (mono_reflection_type_get_handle ((MonoReflectionType*)(*a_entry)->gparam)) -
+ mono_type_get_generic_param_num (mono_reflection_type_get_handle ((MonoReflectionType*)(*b_entry)->gparam));
else
return (*a_entry)->owner - (*b_entry)->owner;
}
continue;
} else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
continue;
+ } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodOnTypeBuilderInst")) {
+ continue;
} else {
g_assert_not_reached ();
}
for (i = 0; i < nargs; i++) {
MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
- sig->params [old->param_count + i] = rt->type;
+ sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt);
}
parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
} else if (strcmp (klass->name, "MonoType") == 0) {
- MonoReflectionType *tb = (MonoReflectionType *)obj;
- MonoClass *mc = mono_class_from_mono_type (tb->type);
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
+ MonoClass *mc = mono_class_from_mono_type (type);
token = mono_metadata_token_from_dor (
- mono_image_typedef_or_ref_full (assembly, tb->type, mc->generic_container == NULL));
+ mono_image_typedef_or_ref_full (assembly, type, mc->generic_container == NULL));
} else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
- MonoReflectionType *tb = (MonoReflectionType *)obj;
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
token = mono_metadata_token_from_dor (
- mono_image_typedef_or_ref (assembly, tb->type));
+ mono_image_typedef_or_ref (assembly, type));
} else if (strcmp (klass->name, "MonoGenericClass") == 0) {
- MonoReflectionType *tb = (MonoReflectionType *)obj;
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
token = mono_metadata_token_from_dor (
- mono_image_typedef_or_ref (assembly, tb->type));
+ mono_image_typedef_or_ref (assembly, type));
} else if (strcmp (klass->name, "MonoCMethod") == 0 ||
strcmp (klass->name, "MonoMethod") == 0 ||
strcmp (klass->name, "MonoGenericMethod") == 0 ||
MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s);
} else if (strcmp (klass->name, "EnumBuilder") == 0) {
- MonoReflectionType *tb = (MonoReflectionType *)obj;
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
token = mono_metadata_token_from_dor (
- mono_image_typedef_or_ref (assembly, tb->type));
+ mono_image_typedef_or_ref (assembly, type));
} else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) {
MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
token = mono_image_get_field_on_inst_token (assembly, f);
} else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
token = mono_image_get_method_on_inst_token (assembly, m, create_methodspec);
+ } else if (is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
+ MonoReflectionType *type = (MonoReflectionType *)obj;
+ token = mono_metadata_token_from_dor (
+ mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle (type)));
} else {
g_error ("requested token for %s\n", klass->name);
}
mono_image_init (&image->image);
- image->token_fixups = mono_g_hash_table_new_type (mono_object_hash, NULL, MONO_HASH_KEY_GC);
+ image->token_fixups = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC);
image->method_to_table_idx = g_hash_table_new (NULL, NULL);
image->field_to_table_idx = g_hash_table_new (NULL, NULL);
image->method_aux_hash = g_hash_table_new (NULL, NULL);
image->handleref = g_hash_table_new (NULL, NULL);
+ image->handleref_managed = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC);
image->tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
image->generic_def_objects = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
- image->methodspec = mono_g_hash_table_new_type (mono_object_hash, NULL, MONO_HASH_KEY_GC);
+ image->methodspec = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC);
image->typespec = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
image->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
g_hash_table_destroy (di->typeref);
if (di->handleref)
g_hash_table_destroy (di->handleref);
+ if (di->handleref_managed)
+ mono_g_hash_table_destroy (di->handleref_managed);
if (di->tokens)
mono_g_hash_table_destroy (di->tokens);
if (di->generic_def_objects)
g_free ((char*)mono_generic_param_info (param)->name);
g_free (param);
}
+ mono_gc_deregister_root ((char*) &entry->gparam);
g_free (entry);
}
g_ptr_array_free (di->gen_params, TRUE);
assembly->run = assemblyb->access != 2;
assembly->save = assemblyb->access != 1;
+ assembly->domain = domain;
image = create_dynamic_mono_image (assembly, mono_string_to_utf8 (assemblyb->name), g_strdup ("RefEmit_YouForgotToDefineAModule"));
image->initial_image = TRUE;
assembly->assembly.aname.name = image->image.name;
assembly->assembly.image = &image->image;
+ if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
+ /* -1 to correct for the trailing NULL byte */
+ if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
+ g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
+ }
+ memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);
+ }
mono_domain_assemblies_lock (domain);
domain->domain_assemblies = g_slist_prepend (domain->domain_assemblies, assembly);
MonoDynamicImage *image = moduleb->dynamic_image;
MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
if (!image) {
+ MonoError error;
int module_count;
MonoImage **new_modules;
MonoImage *ass;
+ char *name, *fqname;
/*
* FIXME: we already created an image in mono_image_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; */
- image = create_dynamic_mono_image (ab->dynamic_assembly, mono_string_to_utf8 (ab->name), mono_string_to_utf8 (moduleb->module.fqname));
+ name = mono_string_to_utf8 (ab->name);
+ fqname = mono_string_to_utf8_checked (moduleb->module.fqname, &error);
+ if (!mono_error_ok (&error)) {
+ g_free (name);
+ mono_error_raise_exception (&error);
+ }
+ image = create_dynamic_mono_image (ab->dynamic_assembly, name, fqname);
moduleb->module.image = &image->image;
moduleb->dynamic_image = image;
}
}
+void
+mono_image_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
+{
+ MonoDynamicImage *image = moduleb->dynamic_image;
+
+ g_assert (type->type);
+ image->wrappers_type = mono_class_from_mono_type (type->type);
+}
+
#endif
/*
static MonoClass *System_Reflection_MonoGenericClass;
MonoReflectionGenericClass *res;
MonoClass *klass, *gklass;
+ MonoGenericInst *ginst;
+ MonoArray *type_args;
+ int i;
+ MonoObject *tb;
+
+ g_assert (0); /*This code path should not be taken anymore, all MGC instantiation must happen in managed code*/
if (!System_Reflection_MonoGenericClass) {
System_Reflection_MonoGenericClass = mono_class_from_name (
#endif
res->type.type = geninst;
- g_assert (gklass->reflection_info);
- g_assert (!strcmp (((MonoObject*)gklass->reflection_info)->vtable->klass->name, "TypeBuilder"));
- MONO_OBJECT_SETREF (res, generic_type, gklass->reflection_info);
+ tb = mono_class_get_ref_info (gklass);
+ g_assert (tb);
+ g_assert (!strcmp (tb->vtable->klass->name, "TypeBuilder"));
+ MONO_OBJECT_SETREF (res, generic_type, tb);
+
+ ginst = klass->generic_class->context.class_inst;
+ type_args = mono_array_new (domain, mono_defaults.systemtype_class, ginst->type_argc);
+ for (i = 0; i < ginst->type_argc; ++i)
+ mono_array_setref (type_args, i, mono_type_get_object (domain, ginst->type_argv [i]));
+ MONO_OBJECT_SETREF (res, type_arguments, type_args);
return res;
}
* the MonoType from there and avoid all locking and hash table lookups.
*
* We cannot do this for TypeBuilders as mono_reflection_create_runtime_class expects
- * that the resulting object is diferent.
+ * that the resulting object is different.
*/
if (type == &klass->byval_arg && !klass->image->dynamic) {
MonoVTable *vtable = mono_class_try_get_vtable (domain, klass);
mono_raise_exception (mono_get_exception_invalid_operation ("This type cannot be propagated to managed space"));
}
- if (klass->reflection_info && !klass->wastypebuilder) {
+ if (mono_class_get_ref_info (klass) && !klass->wastypebuilder) {
+ gboolean is_type_done = TRUE;
+ /* Generic parameters have reflection_info set but they are not finished together with their enclosing type.
+ * We must ensure that once a type is finished we don't return a GenericTypeParameterBuilder.
+ * We can't simply close the types as this will interfere with other parts of the generics machinery.
+ */
+ if (klass->byval_arg.type == MONO_TYPE_MVAR || klass->byval_arg.type == MONO_TYPE_VAR) {
+ MonoGenericParam *gparam = klass->byval_arg.data.generic_param;
+
+ if (gparam->owner && gparam->owner->is_method) {
+ MonoMethod *method = gparam->owner->owner.method;
+ if (method && mono_class_get_generic_type_definition (method->klass)->wastypebuilder)
+ is_type_done = FALSE;
+ } else if (gparam->owner && !gparam->owner->is_method) {
+ MonoClass *klass = gparam->owner->owner.klass;
+ if (klass && mono_class_get_generic_type_definition (klass)->wastypebuilder)
+ is_type_done = FALSE;
+ }
+ }
+
/* g_assert_not_reached (); */
/* should this be considered an error condition? */
- if (!type->byref) {
+ if (is_type_done && !type->byref) {
mono_domain_unlock (domain);
mono_loader_unlock ();
- return klass->reflection_info;
+ return mono_class_get_ref_info (klass);
}
}
// FIXME: Get rid of this, do it in the icalls for Type
mono_g_hash_table_insert (domain->type_hash, type, res);
if (type->type == MONO_TYPE_VOID)
- MONO_OBJECT_SETREF (domain, typeof_void, res);
+ domain->typeof_void = (MonoObject*)res;
mono_domain_unlock (domain);
mono_loader_unlock ();
MonoClass *klass;
MonoReflectionMethod *ret;
- /*
- * Don't let static RGCTX invoke wrappers get into
- * MonoReflectionMethods.
- */
- if (method->wrapper_type == MONO_WRAPPER_STATIC_RGCTX_INVOKE)
- method = mono_marshal_method_from_wrapper (method);
-
if (method->is_inflated) {
MonoReflectionGenericMethod *gret;
void
mono_method_clear_object (MonoDomain *domain, MonoMethod *method)
{
+ MonoClass *klass;
g_assert (method->dynamic);
- clear_cached_object (domain, method, method->klass);
+ klass = method->klass;
+ while (klass) {
+ clear_cached_object (domain, method, klass);
+ klass = klass->parent;
+ }
/* Added by mono_param_get_objects () */
clear_cached_object (domain, &(method->signature), NULL);
+ klass = method->klass;
+ while (klass) {
+ clear_cached_object (domain, &(method->signature), klass);
+ klass = klass->parent;
+ }
}
/*
format = flags & METHOD_HEADER_FORMAT_MASK;
switch (format){
case METHOD_HEADER_TINY_FORMAT:
- case METHOD_HEADER_TINY_FORMAT1:
local_var_sig_token = 0;
break;
case METHOD_HEADER_FAT_FORMAT:
mono_metadata_decode_row (paramt, i - 1, param_cols, MONO_PARAM_SIZE);
paramseq = param_cols [MONO_PARAM_SEQUENCE];
- if (!param_cols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_DEFAULT)
+ if (!(param_cols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_DEFAULT))
continue;
crow = mono_metadata_get_constant_index (image, MONO_TOKEN_PARAM_DEF | i, crow + 1);
return;
}
-static MonoObject *
+MonoObject *
mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob)
{
void *retval;
while ((klass = mono_class_get_nested_types (parent, &iter))) {
if (ignorecase) {
- if (g_strcasecmp (klass->name, mod->data) == 0)
+ if (mono_utf8_strcasecmp (klass->name, mod->data) == 0)
break;
} else {
if (strcmp (klass->name, mod->data) == 0)
static MonoType*
mono_reflection_get_type_internal_dynamic (MonoImage *rootimage, MonoAssembly *assembly, MonoTypeNameParse *info, gboolean ignorecase)
{
- MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)mono_assembly_get_object (mono_domain_get (), assembly);
+ MonoReflectionAssemblyBuilder *abuilder;
MonoType *type;
int i;
g_assert (assembly->dynamic);
+ abuilder = (MonoReflectionAssemblyBuilder*)mono_assembly_get_object (((MonoDynamicAssembly*)assembly)->domain, assembly);
/* Enumerate all modules */
if (info->name_space && (info->name_space [0] != '\0'))
g_string_printf (fullName, "%s.%s", info->name_space, info->name);
else
- g_string_printf (fullName, info->name);
+ g_string_printf (fullName, "%s", info->name);
for (mod = info->nested; mod; mod = mod->next)
g_string_append_printf (fullName, "+%s", (char*)mod->data);
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
} else if (strcmp (klass->name, "MonoType") == 0) {
- MonoReflectionType *tb = (MonoReflectionType *)obj;
- token = mono_class_from_mono_type (tb->type)->type_token;
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
+ token = mono_class_from_mono_type (type)->type_token;
} else if (strcmp (klass->name, "MonoCMethod") == 0 ||
strcmp (klass->name, "MonoMethod") == 0 ||
strcmp (klass->name, "MonoGenericMethod") == 0 ||
token = mono_class_get_event_token (p->event);
} else if (strcmp (klass->name, "ParameterInfo") == 0) {
MonoReflectionParameter *p = (MonoReflectionParameter*)obj;
+ MonoClass *member_class = mono_object_class (p->MemberImpl);
+ g_assert (mono_class_is_reflection_method_or_constructor (member_class));
token = mono_method_get_param_token (((MonoReflectionMethod*)p->MemberImpl)->method, p->PositionImpl);
} else if (strcmp (klass->name, "Module") == 0) {
}
val = load_cattr_value (image, &subc->byval_arg, p, end);
obj = mono_object_new (mono_domain_get (), subc);
+ g_assert (!subc->has_references);
memcpy ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL));
g_free (val);
return obj;
return attr;
}
-
-static MonoObject*
-create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
+
+/*
+ * mono_reflection_create_custom_attr_data_args:
+ *
+ * Create an array of typed and named arguments from the cattr blob given by DATA.
+ * TYPED_ARGS and NAMED_ARGS will contain the objects representing the arguments,
+ * NAMED_ARG_INFO will contain information about the named arguments.
+ */
+void
+mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoArray **typed_args, MonoArray **named_args, CattrNamedArg **named_arg_info)
{
MonoArray *typedargs, *namedargs;
MonoClass *attrklass;
- static MonoMethod *ctor;
MonoDomain *domain;
- MonoObject *attr;
const char *p = (const char*)data;
const char *named;
guint32 i, j, num_named;
- void *params [3];
+ CattrNamedArg *arginfo = NULL;
mono_class_init (method->klass);
- if (!ctor)
- ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 3);
-
+ *typed_args = NULL;
+ *named_args = NULL;
+ *named_arg_info = NULL;
+
domain = mono_domain_get ();
- if (len == 0) {
- /* This is for Attributes with no parameters */
- attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
- params [0] = mono_method_get_object (domain, method, NULL);
- params [1] = params [2] = NULL;
- mono_runtime_invoke (method, attr, params, NULL);
- return attr;
- }
if (len < 2 || read16 (p) != 0x0001) /* Prolog */
- return NULL;
+ return;
typedargs = mono_array_new (domain, mono_get_object_class (), mono_method_signature (method)->param_count);
/* skip prolog */
p += 2;
for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
- MonoObject *obj, *typedarg;
+ MonoObject *obj;
void *val;
val = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p);
obj = type_is_reference (mono_method_signature (method)->params [i]) ?
val : mono_value_box (domain, mono_class_from_mono_type (mono_method_signature (method)->params [i]), val);
- typedarg = create_cattr_typed_arg (mono_method_signature (method)->params [i], obj);
- mono_array_setref (typedargs, i, typedarg);
+ mono_array_setref (typedargs, i, obj);
if (!type_is_reference (mono_method_signature (method)->params [i]))
g_free (val);
namedargs = mono_array_new (domain, mono_get_object_class (), num_named);
named += 2;
attrklass = method->klass;
+
+ arginfo = g_new0 (CattrNamedArg, num_named);
+ *named_arg_info = arginfo;
+
for (j = 0; j < num_named; j++) {
gint name_len;
char *name, named_type, data_type;
name [name_len] = 0;
named += name_len;
if (named_type == 0x53) {
- MonoObject *obj, *typedarg, *namedarg;
+ MonoObject *obj;
MonoClassField *field = mono_class_get_field_from_name (attrklass, name);
- void *minfo, *val = load_cattr_value (image, field->type, named, &named);
-
- minfo = mono_field_get_object (domain, NULL, field);
+ void *val;
+
+ arginfo [j].type = field->type;
+ arginfo [j].field = field;
+
+ val = load_cattr_value (image, field->type, named, &named);
obj = type_is_reference (field->type) ? val : mono_value_box (domain, mono_class_from_mono_type (field->type), val);
- typedarg = create_cattr_typed_arg (field->type, obj);
- namedarg = create_cattr_named_arg (minfo, typedarg);
- mono_array_setref (namedargs, j, namedarg);
+ mono_array_setref (namedargs, j, obj);
if (!type_is_reference (field->type))
g_free (val);
} else if (named_type == 0x54) {
- MonoObject *obj, *typedarg, *namedarg;
+ MonoObject *obj;
MonoType *prop_type;
- void *val, *minfo;
MonoProperty *prop = mono_class_get_property_from_name (attrklass, name);
+ void *val;
prop_type = prop->get? mono_method_signature (prop->get)->ret :
mono_method_signature (prop->set)->params [mono_method_signature (prop->set)->param_count - 1];
- minfo = mono_property_get_object (domain, NULL, prop);
+
+ arginfo [j].type = prop_type;
+ arginfo [j].prop = prop;
+
val = load_cattr_value (image, prop_type, named, &named);
obj = type_is_reference (prop_type) ? val : mono_value_box (domain, mono_class_from_mono_type (prop_type), val);
- typedarg = create_cattr_typed_arg (prop_type, obj);
- namedarg = create_cattr_named_arg (minfo, typedarg);
- mono_array_setref (namedargs, j, namedarg);
+ mono_array_setref (namedargs, j, obj);
if (!type_is_reference (prop_type))
g_free (val);
}
g_free (name);
}
+
+ *typed_args = typedargs;
+ *named_args = namedargs;
+}
+
+static MonoObject*
+create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
+{
+ MonoArray *typedargs, *namedargs;
+ static MonoMethod *ctor;
+ MonoDomain *domain;
+ MonoObject *attr;
+ void *params [3];
+ CattrNamedArg *arginfo;
+ int i;
+
+ mono_class_init (method->klass);
+
+ if (!ctor)
+ ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 3);
+
+ domain = mono_domain_get ();
+ if (len == 0) {
+ /* This is for Attributes with no parameters */
+ attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
+ params [0] = mono_method_get_object (domain, method, NULL);
+ params [1] = params [2] = NULL;
+ mono_runtime_invoke (method, attr, params, NULL);
+ return attr;
+ }
+
+ mono_reflection_create_custom_attr_data_args (image, method, data, len, &typedargs, &namedargs, &arginfo);
+ if (!typedargs || !namedargs)
+ return NULL;
+
+ for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
+ MonoObject *obj = mono_array_get (typedargs, MonoObject*, i);
+ MonoObject *typedarg;
+
+ typedarg = create_cattr_typed_arg (mono_method_signature (method)->params [i], obj);
+ mono_array_setref (typedargs, i, typedarg);
+ }
+
+ for (i = 0; i < mono_array_length (namedargs); ++i) {
+ MonoObject *obj = mono_array_get (namedargs, MonoObject*, i);
+ MonoObject *typedarg, *namedarg, *minfo;
+
+ if (arginfo [i].prop)
+ minfo = (MonoObject*)mono_property_get_object (domain, NULL, arginfo [i].prop);
+ else
+ minfo = (MonoObject*)mono_field_get_object (domain, NULL, arginfo [i].field);
+
+ typedarg = create_cattr_typed_arg (arginfo [i].type, obj);
+ namedarg = create_cattr_named_arg (minfo, typedarg);
+
+ mono_array_setref (namedargs, i, namedarg);
+ }
+
attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
params [0] = mono_method_get_object (domain, method, NULL);
params [1] = typedargs;
len = g_list_length (list);
if (!len)
return NULL;
- ainfo = g_malloc0 (sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (len - MONO_ZERO_LEN_ARRAY));
+ ainfo = g_malloc0 (MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * len);
ainfo->num_attrs = len;
ainfo->image = image;
for (i = 0, tmp = list; i < len; ++i, tmp = tmp->next) {
/* Need to copy since it will be freed later */
ainfo = aux->param_cattr [param];
- size = sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (ainfo->num_attrs - MONO_ZERO_LEN_ARRAY);
+ if (!ainfo)
+ return NULL;
+ size = MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * ainfo->num_attrs;
res = g_malloc0 (size);
memcpy (res, ainfo, size);
return res;
klass = obj->vtable->klass;
if (klass == mono_defaults.monotype_class) {
- MonoReflectionType *rtype = (MonoReflectionType*)obj;
- klass = mono_class_from_mono_type (rtype->type);
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
+ klass = mono_class_from_mono_type (type);
cinfo = mono_custom_attrs_from_class (klass);
} else if (strcmp ("Assembly", klass->name) == 0) {
MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
cinfo = mono_custom_attrs_from_method (rmethod->method);
} else if (strcmp ("ParameterInfo", klass->name) == 0) {
MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
- MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
- cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl + 1);
+ MonoClass *member_class = mono_object_class (param->MemberImpl);
+ if (mono_class_is_reflection_method_or_constructor (member_class)) {
+ MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
+ cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl + 1);
+ } else if (is_sr_mono_property (member_class)) {
+ MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
+ MonoMethod *method;
+ if (!(method = prop->property->get))
+ method = prop->property->set;
+ g_assert (method);
+
+ cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+ } else if (is_sre_method_on_tb_inst (member_class)) {/*XXX This is a workaround for Compiler Context*/
+ MonoMethod *method = mono_reflection_method_on_tb_inst_get_handle ((MonoReflectionMethodOnTypeBuilderInst*)param->MemberImpl);
+ cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+ } else if (is_sre_ctor_on_tb_inst (member_class)) { /*XX This is a workaround for Compiler Context*/
+ MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)param->MemberImpl;
+ MonoMethod *method = NULL;
+ if (is_sre_ctor_builder (mono_object_class (c->cb)))
+ method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
+ else if (is_sr_mono_cmethod (mono_object_class (c->cb)))
+ method = ((MonoReflectionMethod *)c->cb)->method;
+ else
+ g_error ("mono_reflection_get_custom_attrs_info:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (member_class));
+
+ cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+ } else {
+ char *type_name = mono_type_get_full_name (member_class);
+ char *msg = g_strdup_printf ("Custom attributes on a ParamInfo with member %s are not supported", type_name);
+ MonoException *ex = mono_get_exception_not_supported (msg);
+ g_free (type_name);
+ g_free (msg);
+ mono_raise_exception (ex);
+ }
} else if (strcmp ("AssemblyBuilder", klass->name) == 0) {
MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)obj;
cinfo = mono_custom_attrs_from_builders (NULL, assemblyb->assembly.assembly->image, assemblyb->cattrs);
static MonoReflectionType*
mono_reflection_type_get_underlying_system_type (MonoReflectionType* t)
{
- MonoMethod *method_get_underlying_system_type;
+ static MonoMethod *method_get_underlying_system_type = NULL;
+ MonoMethod *usertype_method;
- method_get_underlying_system_type = mono_object_get_virtual_method ((MonoObject *) t,
- mono_class_get_method_from_name (mono_object_class (t),
- "get_UnderlyingSystemType",
- 0));
- return (MonoReflectionType *) mono_runtime_invoke (method_get_underlying_system_type, t, NULL, NULL);
+ 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);
+ return (MonoReflectionType *) mono_runtime_invoke (usertype_method, t, NULL, NULL);
}
#ifndef DISABLE_REFLECTION_EMIT
-static MonoType*
-mono_reflection_type_get_handle (MonoReflectionType* t)
+
+static gboolean
+is_corlib_type (MonoClass *class)
+{
+ return class->image == mono_defaults.corlib;
+}
+
+#define check_corlib_type_cached(_class, _namespace, _name) do { \
+ static MonoClass *cached_class; \
+ if (cached_class) \
+ return cached_class == _class; \
+ if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
+ cached_class = _class; \
+ return TRUE; \
+ } \
+ return FALSE; \
+} while (0) \
+
+static gboolean
+is_sre_array (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "ArrayType");
+}
+
+static gboolean
+is_sre_byref (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "ByRefType");
+}
+
+static gboolean
+is_sre_pointer (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "PointerType");
+}
+
+static gboolean
+is_sre_generic_instance (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection", "MonoGenericClass");
+}
+
+static gboolean
+is_sre_type_builder (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "TypeBuilder");
+}
+
+static gboolean
+is_sre_method_builder (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "MethodBuilder");
+}
+
+static gboolean
+is_sre_ctor_builder (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "ConstructorBuilder");
+}
+
+static gboolean
+is_sre_field_builder (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "FieldBuilder");
+}
+
+static gboolean
+is_sr_mono_method (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection", "MonoMethod");
+}
+
+static gboolean
+is_sr_mono_cmethod (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection", "MonoCMethod");
+}
+
+static gboolean
+is_sr_mono_generic_method (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection", "MonoGenericMethod");
+}
+
+static gboolean
+is_sr_mono_generic_cmethod (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection", "MonoGenericCMethod");
+}
+
+static gboolean
+is_sr_mono_field (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection", "MonoField");
+}
+
+static gboolean
+is_sr_mono_property (MonoClass *class)
{
- if (t->type)
- return t->type;
+ check_corlib_type_cached (class, "System.Reflection", "MonoProperty");
+}
+
+static gboolean
+is_sre_method_on_tb_inst (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
+}
- t = mono_reflection_type_get_underlying_system_type (t);
- if (t)
- return t->type;
+static gboolean
+is_sre_ctor_on_tb_inst (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
+}
- return NULL;
+gboolean
+mono_class_is_reflection_method_or_constructor (MonoClass *class)
+{
+ return is_sr_mono_method (class) || is_sr_mono_cmethod (class) || is_sr_mono_generic_method (class) || is_sr_mono_generic_cmethod (class);
+}
+
+MonoType*
+mono_reflection_type_get_handle (MonoReflectionType* ref)
+{
+ MonoClass *class;
+ if (!ref)
+ return NULL;
+ if (ref->type)
+ return ref->type;
+
+ if (is_usertype (ref)) {
+ ref = mono_reflection_type_get_underlying_system_type (ref);
+ if (ref == NULL || is_usertype (ref))
+ return NULL;
+ if (ref->type)
+ return ref->type;
+ }
+
+ class = mono_object_class (ref);
+
+ if (is_sre_array (class)) {
+ MonoType *res;
+ MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
+ MonoType *base = mono_reflection_type_get_handle (sre_array->element_type);
+ 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 (class)) {
+ MonoType *res;
+ MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
+ MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type);
+ g_assert (base);
+ res = &mono_class_from_mono_type (base)->this_arg;
+ sre_byref->type.type = res;
+ return res;
+ } else if (is_sre_pointer (class)) {
+ MonoType *res;
+ MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
+ MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type);
+ g_assert (base);
+ res = &mono_ptr_class_get (base)->byval_arg;
+ sre_pointer->type.type = res;
+ return res;
+ } else if (is_sre_generic_instance (class)) {
+ 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 = mono_array_get (gclass->type_arguments, gpointer, i);
+ types [i] = mono_reflection_type_get_handle (t);
+ if (!types[i]) {
+ g_free (types);
+ return NULL;
+ }
+ }
+
+ res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types);
+ g_free (types);
+ g_assert (res);
+ gclass->type.type = res;
+ return res;
+ }
+
+ g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
+ return NULL;
+}
+
+
+
+void
+mono_reflection_create_unmanaged_type (MonoReflectionType *type)
+{
+ mono_reflection_type_get_handle (type);
+}
+
+void
+mono_reflection_register_with_runtime (MonoReflectionType *type)
+{
+ MonoType *res = mono_reflection_type_get_handle (type);
+ MonoDomain *domain = mono_object_domain ((MonoObject*)type);
+ MonoClass *class;
+
+ if (!res)
+ mono_raise_exception (mono_get_exception_argument (NULL, "Invalid generic instantiation, one or more arguments are not proper user types"));
+
+ class = mono_class_from_mono_type (res);
+
+ mono_loader_lock (); /*same locking as mono_type_get_object*/
+ mono_domain_lock (domain);
+
+ if (!class->image->dynamic) {
+ mono_class_setup_supertypes (class);
+ } else {
+ if (!domain->type_hash)
+ domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash,
+ (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC);
+ mono_g_hash_table_insert (domain->type_hash, res, type);
+ }
+ mono_domain_unlock (domain);
+ mono_loader_unlock ();
}
/**
count = parameters? mono_array_length (parameters): 0;
- sig = image_g_malloc0 (image, sizeof (MonoMethodSignature) + sizeof (MonoType*) * count);
+ sig = image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
sig->param_count = count;
sig->sentinelpos = -1; /* FIXME */
- for (i = 0; i < count; ++i) {
- MonoReflectionType *pt = mono_type_array_get (parameters, i);
- sig->params [i] = mono_reflection_type_get_handle (pt);
- }
+ for (i = 0; i < count; ++i)
+ sig->params [i] = mono_type_array_get_and_resolve (parameters, i);
return sig;
}
sig = parameters_to_signature (image, method->parameters);
sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
- sig->ret = method->rtype? monotype_cast (method->rtype)->type: &mono_defaults.void_class->byval_arg;
+ sig->ret = method->rtype? mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype): &mono_defaults.void_class->byval_arg;
sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
return sig;
}
sig = parameters_to_signature (NULL, method->parameters);
sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
- sig->ret = method->rtype? method->rtype->type: &mono_defaults.void_class->byval_arg;
+ sig->ret = method->rtype? mono_reflection_type_get_handle (method->rtype): &mono_defaults.void_class->byval_arg;
sig->generic_param_count = 0;
return sig;
}
if (strcmp (klass->name, "PropertyBuilder") == 0) {
MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
*name = mono_string_to_utf8 (pb->name);
- *type = monotype_cast (pb->type)->type;
+ *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type);
} else {
MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
*name = g_strdup (p->property->name);
if (strcmp (klass->name, "FieldBuilder") == 0) {
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
*name = mono_string_to_utf8 (fb->name);
- *type = monotype_cast (fb->type)->type;
+ *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
} else {
MonoReflectionField *f = (MonoReflectionField *)field;
*name = g_strdup (mono_field_get_name (f->field));
*type = f->field->type;
}
}
+
+#else /* DISABLE_REFLECTION_EMIT */
+
+void
+mono_reflection_register_with_runtime (MonoReflectionType *type)
+{
+ /* This is empty */
+}
+
+static gboolean
+is_sre_type_builder (MonoClass *class)
+{
+ return FALSE;
+}
+
+static gboolean
+is_sre_generic_instance (MonoClass *class)
+{
+ return FALSE;
+}
+
#endif /* !DISABLE_REFLECTION_EMIT */
+static gboolean
+is_usertype (MonoReflectionType *ref)
+{
+ MonoClass *class = mono_object_class (ref);
+ return class->image != mono_defaults.corlib || strcmp ("TypeDelegator", class->name) == 0;
+}
+
+static MonoReflectionType*
+mono_reflection_type_resolve_user_types (MonoReflectionType *type)
+{
+ if (!type || type->type)
+ return type;
+
+ if (is_usertype (type)) {
+ type = mono_reflection_type_get_underlying_system_type (type);
+ if (is_usertype (type))
+ mono_raise_exception (mono_get_exception_not_supported ("User defined subclasses of System.Type are not yet supported22"));
+ }
+
+ return type;
+}
/*
* Encode a value in a custom attribute stream of bytes.
* The value to encode is either supplied as an object in argument val
case MONO_TYPE_CLASS: {
char *str;
guint32 slen;
- MonoClass *k;
if (!arg) {
*p++ = 0xFF;
break;
}
- k = mono_object_class (arg);
- if (!mono_object_isinst (arg, mono_defaults.monotype_class) &&
- (strcmp (k->name, "TypeBuilder") || strcmp (k->name_space, "System.Reflection.Emit"))) {
- MonoReflectionType* rt = mono_reflection_type_get_underlying_system_type ((MonoReflectionType*) arg);
- MonoClass *rtc;
-
- if (rt && (rtc = mono_object_class (rt)) &&
- (mono_object_isinst ((MonoObject *) rt, mono_defaults.monotype_class) ||
- !strcmp (rtc->name, "TypeBuilder") || !strcmp (rtc->name_space, "System.Reflection.Emit"))) {
- arg = (MonoObject *) rt;
- k = rtc;
- } else
- g_error ("Only System.Type allowed, not %s.%s", k->name_space, k->name);
- }
handle_type:
- str = type_get_qualified_name (((MonoReflectionType*)arg)->type, NULL);
+ str = type_get_qualified_name (mono_reflection_type_get_handle ((MonoReflectionType*)arg), NULL);
slen = strlen (str);
if ((p-buffer) + 10 + slen >= *buflen) {
char *newbuf;
void
mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
{
+ MonoError error;
MonoClass *klass, *parent;
MONO_ARCH_SAVE_REGS;
- CHECK_MONOTYPE (tb->parent);
+ RESOLVE_TYPE (tb->parent);
mono_loader_lock ();
/* 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 = monotype_cast (tb->parent)->type->data.klass;
+ parent = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent)->data.klass;
} else {
- parent = mono_class_from_mono_type (monotype_cast (tb->parent)->type);
+ parent = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent));
}
} else {
parent = NULL;
klass->image = &tb->module->dynamic_image->image;
klass->inited = 1; /* we lie to the runtime */
- klass->name = mono_string_to_utf8_image (klass->image, tb->name);
- klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace);
+ klass->name = mono_string_to_utf8_image (klass->image, tb->name, &error);
+ if (!mono_error_ok (&error))
+ goto failure;
+ klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, &error);
+ if (!mono_error_ok (&error))
+ goto failure;
klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
klass->flags = tb->attrs;
klass->element_class = klass;
- MOVING_GC_REGISTER (&klass->reflection_info);
- klass->reflection_info = tb;
+ if (mono_class_get_ref_info (klass) == NULL) {
+
+ mono_class_set_ref_info (klass, tb);
- /* Put into cache so mono_class_get () will find it */
- mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
+ /* Put into cache so mono_class_get () 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);
+ } else {
+ klass->image->reflection_info_unregister_classes =
+ g_slist_prepend (klass->image->reflection_info_unregister_classes, klass);
+ }
+ } else {
+ g_assert (mono_class_get_ref_info (klass) == tb);
+ }
mono_g_hash_table_insert (tb->module->dynamic_image->tokens,
GUINT_TO_POINTER (MONO_TOKEN_TYPE_DEF | tb->table_idx), tb);
if (tb->nesting_type) {
g_assert (tb->nesting_type->type);
- klass->nested_in = mono_class_from_mono_type (tb->nesting_type->type);
+ klass->nested_in = mono_class_from_mono_type (mono_reflection_type_get_handle (tb->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_loader_unlock ();
+ return;
+
+failure:
+ mono_loader_unlock ();
+ mono_error_raise_exception (&error);
}
/*
for (i = 0; i < count; i++) {
MonoReflectionGenericParam *gparam = mono_array_get (tb->generic_params, gpointer, i);
- MonoGenericParamFull *param = (MonoGenericParamFull *) gparam->type.type->data.generic_param;
+ MonoGenericParamFull *param = (MonoGenericParamFull *) mono_reflection_type_get_handle ((MonoReflectionType*)gparam)->data.generic_param;
klass->generic_container->type_params [i] = *param;
/*Make sure we are a diferent type instance */
klass->generic_container->type_params [i].param.owner = klass->generic_container;
fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, 0);
- if (!mono_type_is_valid_enum_basetype (monotype_cast (fb->type)->type)) {
+ if (!mono_type_is_valid_enum_basetype (mono_reflection_type_get_handle ((MonoReflectionType*)fb->type))) {
mono_loader_unlock ();
return;
}
- enum_basetype = monotype_cast (fb->type)->type;
+ enum_basetype = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
klass->element_class = mono_class_from_mono_type (enum_basetype);
if (!klass->element_class)
klass->element_class = mono_class_from_mono_type (enum_basetype);
case MONO_NATIVE_CUSTOM:
if (minfo->marshaltyperef)
res->data.custom_data.custom_name =
- type_get_fully_qualified_name (monotype_cast (minfo->marshaltyperef)->type);
+ type_get_fully_qualified_name (mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef));
if (minfo->mcookie)
res->data.custom_data.cookie = mono_string_to_utf8 (minfo->mcookie);
break;
ReflectionMethodBuilder *rmb,
MonoMethodSignature *sig)
{
+ MonoError error;
MonoMethod *m;
MonoMethodNormal *pm;
MonoMarshalSpec **specs;
gboolean dynamic;
int i;
+ mono_error_init (&error);
/*
* Methods created using a MethodBuilder should have their memory allocated
* inside the image mempool, while dynamic methods should have their memory
m->slot = -1;
m->flags = rmb->attrs;
m->iflags = rmb->iattrs;
- m->name = mono_string_to_utf8_image (image, rmb->name);
+ m->name = mono_string_to_utf8_image (image, rmb->name, &error);
+ g_assert (mono_error_ok (&error));
m->klass = klass;
m->signature = sig;
m->skip_visibility = rmb->skip_visibility;
method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
- method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry) : image_strdup (image, m->name);
- method_aux->dll = mono_string_to_utf8_image (image, rmb->dll);
+ method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, &error) : image_strdup (image, m->name);
+ g_assert (mono_error_ok (&error));
+ method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, &error);
+ g_assert (mono_error_ok (&error));
((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
}
}
- header = image_g_malloc0 (image, sizeof (MonoMethodHeader) +
- (num_locals - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
+ header = image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
header->code_size = code_size;
header->code = image_g_malloc (image, code_size);
memcpy ((char*)header->code, code, code_size);
mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
header->locals [i] = image_g_new0 (image, MonoType, 1);
- memcpy (header->locals [i], monotype_cast (lb->type)->type, sizeof (MonoType));
+ memcpy (header->locals [i], mono_reflection_type_get_handle ((MonoReflectionType*)lb->type), MONO_SIZEOF_TYPE);
}
header->num_clauses = num_clauses;
if (rmb->generic_params) {
int count = mono_array_length (rmb->generic_params);
- MonoGenericContainer *container;
+ MonoGenericContainer *container = rmb->generic_container;
+
+ g_assert (container);
- container = rmb->generic_container;
- if (container) {
- m->is_generic = TRUE;
- mono_method_set_generic_container (m, container);
- }
container->type_argc = count;
container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
container->owner.method = m;
+ m->is_generic = TRUE;
+ mono_method_set_generic_container (m, container);
+
for (i = 0; i < count; i++) {
MonoReflectionGenericParam *gp =
mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
- MonoGenericParamFull *param = (MonoGenericParamFull *) gp->type.type->data.generic_param;
+ MonoGenericParamFull *param = (MonoGenericParamFull *) mono_reflection_type_get_handle ((MonoReflectionType*)gp)->data.generic_param;
container->type_params [i] = *param;
}
memcpy ((gpointer)method_aux->param_defaults [i], p, len);
}
- if (pb->name)
- method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name);
+ if (pb->name) {
+ method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, &error);
+ g_assert (mono_error_ok (&error));
+ }
if (pb->cattrs) {
if (!method_aux->param_cattr)
method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
field->name = mono_string_to_utf8 (fb->name);
if (fb->attrs || fb->modreq || fb->modopt) {
- field->type = mono_metadata_type_dup (NULL, monotype_cast (fb->type)->type);
+ field->type = mono_metadata_type_dup (NULL, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
field->type->attrs = fb->attrs;
g_assert (klass->image->dynamic);
g_free (field->type);
field->type = custom;
} else {
- field->type = monotype_cast (fb->type)->type;
+ field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
}
if (fb->offset != -1)
field->offset = fb->offset;
domain = mono_object_domain (type);
- if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
+ if (is_sre_type_builder (mono_object_class (type))) {
tb = (MonoReflectionTypeBuilder *) type;
is_dynamic = TRUE;
- } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericClass")) {
+ } else if (is_sre_generic_instance (mono_object_class (type))) {
MonoReflectionGenericClass *rgi = (MonoReflectionGenericClass *) type;
+ MonoReflectionType *gtd = rgi->generic_type;
- tb = rgi->generic_type;
- is_dynamic = TRUE;
+ if (is_sre_type_builder (mono_object_class (gtd))) {
+ tb = (MonoReflectionTypeBuilder *)gtd;
+ is_dynamic = TRUE;
+ }
}
/* FIXME: fix the CreateGenericParameters protocol to avoid the two stage setup of TypeBuilders */
if (tb && tb->generic_container)
mono_reflection_create_generic_class (tb);
- klass = mono_class_from_mono_type (type->type);
+ klass = mono_class_from_mono_type (mono_reflection_type_get_handle (type));
if (!klass->generic_container) {
mono_loader_unlock ();
return NULL;
}
if (klass->wastypebuilder) {
- tb = (MonoReflectionTypeBuilder *) klass->reflection_info;
+ tb = (MonoReflectionTypeBuilder *) mono_class_get_ref_info (klass);
is_dynamic = TRUE;
}
MONO_ARCH_SAVE_REGS;
+ /*FIXME but this no longer should happen*/
if (!strcmp (rmethod->object.vtable->klass->name, "MethodBuilder")) {
#ifndef DISABLE_REFLECTION_EMIT
MonoReflectionMethodBuilder *mb = NULL;
mb = (MonoReflectionMethodBuilder *) rmethod;
tb = (MonoReflectionTypeBuilder *) mb->type;
- klass = mono_class_from_mono_type (tb->type.type);
+ klass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)tb));
method = methodbuilder_to_mono_method (klass, mb);
#else
type_argv = g_new0 (MonoType *, count);
for (i = 0; i < count; i++) {
MonoReflectionType *garg = mono_array_get (types, gpointer, i);
- type_argv [i] = garg->type;
+ type_argv [i] = mono_reflection_type_get_handle (garg);
}
ginst = mono_metadata_get_generic_inst (count, type_argv);
g_free (type_argv);
inflated = mono_class_inflate_generic_method (method, &tmp_context);
imethod = (MonoMethodInflated *) inflated;
+ /*FIXME but I think this is no longer necessary*/
if (method->klass->image->dynamic) {
MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
/*
}
static MonoMethod *
-inflate_method (MonoReflectionGenericClass *type, MonoObject *obj)
+inflate_method (MonoReflectionType *type, MonoObject *obj)
{
MonoMethod *method;
MonoClass *gklass;
- gklass = mono_class_from_mono_type (type->generic_type->type.type);
+ MonoClass *type_class = mono_object_class (type);
+
+ if (is_sre_generic_instance (type_class)) {
+ MonoReflectionGenericClass *mgc = (MonoReflectionGenericClass*)type;
+ gklass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)mgc->generic_type));
+ } else if (is_sre_type_builder (type_class)) {
+ gklass = mono_class_from_mono_type (mono_reflection_type_get_handle (type));
+ } else if (type->type) {
+ gklass = mono_class_from_mono_type (type->type);
+ gklass = mono_class_get_generic_type_definition (gklass);
+ } else {
+ g_error ("Can't handle type %s", mono_type_get_full_name (mono_object_class (type)));
+ }
if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
if (((MonoReflectionMethodBuilder*)obj)->mhandle)
method = ((MonoReflectionMethod *) obj)->method;
else {
method = NULL; /* prevent compiler warning */
- g_assert_not_reached ();
+ g_error ("can't handle type %s", obj->vtable->klass->name);
}
- return inflate_mono_method (mono_class_from_mono_type (type->type.type), method, obj);
+ return inflate_mono_method (mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)type)), method, obj);
}
/*TODO avoid saving custom attrs for generic classes as it's enough to have them on the generic type definition.*/
MonoGenericClass *gclass;
MonoDynamicGenericClass *dgclass;
MonoClass *klass, *gklass;
+ MonoType *gtype;
int i;
MONO_ARCH_SAVE_REGS;
- klass = mono_class_from_mono_type (type->type.type);
- g_assert (type->type.type->type == MONO_TYPE_GENERICINST);
- gclass = type->type.type->data.generic_class;
+ gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type);
+ klass = mono_class_from_mono_type (gtype);
+ g_assert (gtype->type == MONO_TYPE_GENERICINST);
+ gclass = gtype->data.generic_class;
+
+ if (!gclass->is_dynamic)
+ return;
- g_assert (gclass->is_dynamic);
dgclass = (MonoDynamicGenericClass *) gclass;
if (dgclass->initialized)
dgclass->count_methods = methods ? mono_array_length (methods) : 0;
dgclass->count_ctors = ctors ? mono_array_length (ctors) : 0;
dgclass->count_fields = fields ? mono_array_length (fields) : 0;
- dgclass->count_properties = properties ? mono_array_length (properties) : 0;
- dgclass->count_events = events ? mono_array_length (events) : 0;
dgclass->methods = g_new0 (MonoMethod *, dgclass->count_methods);
dgclass->ctors = g_new0 (MonoMethod *, dgclass->count_ctors);
dgclass->fields = g_new0 (MonoClassField, dgclass->count_fields);
- dgclass->properties = g_new0 (MonoProperty, dgclass->count_properties);
- dgclass->events = g_new0 (MonoEvent, dgclass->count_events);
dgclass->field_objects = g_new0 (MonoObject*, dgclass->count_fields);
dgclass->field_generic_types = g_new0 (MonoType*, dgclass->count_fields);
for (i = 0; i < dgclass->count_methods; i++) {
MonoObject *obj = mono_array_get (methods, gpointer, i);
- dgclass->methods [i] = inflate_method (type, obj);
+ dgclass->methods [i] = inflate_method ((MonoReflectionType*)type, obj);
}
for (i = 0; i < dgclass->count_ctors; i++) {
MonoObject *obj = mono_array_get (ctors, gpointer, i);
- dgclass->ctors [i] = inflate_method (type, obj);
+ dgclass->ctors [i] = inflate_method ((MonoReflectionType*)type, obj);
}
for (i = 0; i < dgclass->count_fields; i++) {
}
}
- for (i = 0; i < dgclass->count_properties; i++) {
- MonoObject *obj = mono_array_get (properties, gpointer, i);
- MonoProperty *property = &dgclass->properties [i];
-
- if (!strcmp (obj->vtable->klass->name, "PropertyBuilder")) {
- MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *) obj;
-
- property->parent = klass;
- property->attrs = pb->attrs;
- property->name = mono_string_to_utf8 (pb->name);
- if (pb->get_method)
- property->get = inflate_method (type, (MonoObject *) pb->get_method);
- if (pb->set_method)
- property->set = inflate_method (type, (MonoObject *) pb->set_method);
- } else if (!strcmp (obj->vtable->klass->name, "MonoProperty")) {
- *property = *((MonoReflectionProperty *) obj)->property;
- property->name = g_strdup (property->name);
-
- if (property->get)
- property->get = inflate_mono_method (klass, property->get, NULL);
- if (property->set)
- property->set = inflate_mono_method (klass, property->set, NULL);
- } else
- g_assert_not_reached ();
- }
-
- for (i = 0; i < dgclass->count_events; i++) {
- MonoObject *obj = mono_array_get (events, gpointer, i);
- MonoEvent *event = &dgclass->events [i];
-
- if (!strcmp (obj->vtable->klass->name, "EventBuilder")) {
- MonoReflectionEventBuilder *eb = (MonoReflectionEventBuilder *) obj;
-
- event->parent = klass;
- event->attrs = eb->attrs;
- event->name = mono_string_to_utf8 (eb->name);
- if (eb->add_method)
- event->add = inflate_method (type, (MonoObject *) eb->add_method);
- if (eb->remove_method)
- event->remove = inflate_method (type, (MonoObject *) eb->remove_method);
- } else if (!strcmp (obj->vtable->klass->name, "MonoEvent")) {
- *event = *((MonoReflectionMonoEvent *) obj)->event;
- event->name = g_strdup (event->name);
-
- if (event->add)
- event->add = inflate_mono_method (klass, event->add, NULL);
- if (event->remove)
- event->remove = inflate_mono_method (klass, event->remove, NULL);
- } else
- g_assert_not_reached ();
- }
-
dgclass->initialized = TRUE;
}
static void
-ensure_generic_class_runtime_vtable (MonoClass *klass)
+fix_partial_generic_class (MonoClass *klass)
{
MonoClass *gklass = klass->generic_class->container_class;
+ MonoDynamicGenericClass *dgclass;
int i;
if (klass->wastypebuilder)
return;
- ensure_runtime_vtable (gklass);
+ dgclass = (MonoDynamicGenericClass *) klass->generic_class;
+
+ if (!dgclass->initialized)
+ return;
- klass->method.count = gklass->method.count;
- klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
+ if (klass->method.count != gklass->method.count) {
+ klass->method.count = gklass->method.count;
+ klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
- for (i = 0; i < klass->method.count; i++) {
- klass->methods [i] = mono_class_inflate_generic_method_full (
- gklass->methods [i], klass, mono_class_get_context (klass));
+ for (i = 0; i < klass->method.count; i++) {
+ klass->methods [i] = mono_class_inflate_generic_method_full (
+ gklass->methods [i], klass, mono_class_get_context (klass));
+ }
}
- klass->interface_count = gklass->interface_count;
- klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
- for (i = 0; i < klass->interface_count; ++i) {
- MonoType *iface_type = mono_class_inflate_generic_type (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass));
- klass->interfaces [i] = mono_class_from_mono_type (iface_type);
- mono_metadata_free_type (iface_type);
+ if (klass->interface_count && klass->interface_count != gklass->interface_count) {
+ klass->interface_count = gklass->interface_count;
+ klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
+ klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
+
+ for (i = 0; i < gklass->interface_count; ++i) {
+ MonoType *iface_type = mono_class_inflate_generic_type (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass));
+ klass->interfaces [i] = mono_class_from_mono_type (iface_type);
+ mono_metadata_free_type (iface_type);
- ensure_runtime_vtable (klass->interfaces [i]);
+ ensure_runtime_vtable (klass->interfaces [i]);
+ }
+ klass->interfaces_inited = 1;
+ }
+
+ if (klass->field.count != gklass->field.count) {
+ klass->field.count = gklass->field.count;
+ klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
+
+ for (i = 0; i < klass->field.count; i++) {
+ klass->fields [i] = gklass->fields [i];
+ klass->fields [i].parent = klass;
+ klass->fields [i].type = mono_class_inflate_generic_type (gklass->fields [i].type, mono_class_get_context (klass));
+ }
}
- klass->interfaces_inited = 1;
/*We can only finish with this klass once it's parent has as well*/
if (gklass->wastypebuilder)
return;
}
+static void
+ensure_generic_class_runtime_vtable (MonoClass *klass)
+{
+ MonoClass *gklass = klass->generic_class->container_class;
+
+ ensure_runtime_vtable (gklass);
+
+ fix_partial_generic_class (klass);
+}
+
static void
ensure_runtime_vtable (MonoClass *klass)
{
- MonoReflectionTypeBuilder *tb = klass->reflection_info;
+ MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
int i, num, j;
if (!klass->image->dynamic || (!tb && !klass->generic_class) || klass->wastypebuilder)
klass->interface_count = mono_array_length (tb->interfaces);
klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
for (i = 0; i < klass->interface_count; ++i) {
- MonoReflectionType *iface = mono_type_array_get (tb->interfaces, i);
- klass->interfaces [i] = mono_class_from_mono_type (iface->type);
+ MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i);
+ klass->interfaces [i] = mono_class_from_mono_type (iface);
ensure_runtime_vtable (klass->interfaces [i]);
}
klass->interfaces_inited = 1;
for (i = 0; i < klass->method.count; ++i)
klass->methods [i]->slot = i;
+ klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
mono_class_setup_interface_offsets (klass);
mono_class_setup_interface_id (klass);
}
g_assert (klass->image->dynamic);
- if (!klass->reflection_info)
+ if (!mono_class_get_ref_info (klass))
return;
- g_assert (strcmp (((MonoObject*)klass->reflection_info)->vtable->klass->name, "TypeBuilder") == 0);
+ g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
- tb = (MonoReflectionTypeBuilder*)klass->reflection_info;
+ tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
onum = 0;
if (tb->methods) {
}
static void
-typebuilder_setup_fields (MonoClass *klass)
+typebuilder_setup_fields (MonoClass *klass, MonoError *error)
{
- MonoReflectionTypeBuilder *tb = klass->reflection_info;
+ MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
MonoReflectionFieldBuilder *fb;
MonoClassField *field;
MonoImage *image = klass->image;
klass->field.count = tb->num_fields;
klass->field.first = 0;
+ mono_error_init (error);
+
if (tb->class_size) {
g_assert ((tb->packing_size & 0xfffffff0) == 0);
klass->packing_size = tb->packing_size;
klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
mono_class_alloc_ext (klass);
klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
+ /*
+ This is, guess what, a hack.
+ The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
+ On the static path no field class is resolved, only types are built. This is the right thing to do
+ but we suck.
+ Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
+ */
+ klass->size_inited = 1;
for (i = 0; i < klass->field.count; ++i) {
fb = mono_array_get (tb->fields, gpointer, i);
field = &klass->fields [i];
- field->name = mono_string_to_utf8_image (image, fb->name);
+ field->name = mono_string_to_utf8_image (image, fb->name, error);
+ if (!mono_error_ok (error))
+ return;
if (fb->attrs) {
- field->type = mono_metadata_type_dup (klass->image, monotype_cast (fb->type)->type);
+ field->type = mono_metadata_type_dup (klass->image, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
field->type->attrs = fb->attrs;
} else {
- field->type = monotype_cast (fb->type)->type;
+ field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
}
if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data)
klass->ext->field_def_values [i].data = mono_array_addr (fb->rva_data, char, 0);
}
static void
-typebuilder_setup_properties (MonoClass *klass)
+typebuilder_setup_properties (MonoClass *klass, MonoError *error)
{
- MonoReflectionTypeBuilder *tb = klass->reflection_info;
+ MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
MonoReflectionPropertyBuilder *pb;
MonoImage *image = klass->image;
MonoProperty *properties;
int i;
+ mono_error_init (error);
+
if (!klass->ext)
klass->ext = image_g_new0 (image, MonoClassExt, 1);
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);
+ properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
+ if (!mono_error_ok (error))
+ return;
if (pb->get_method)
properties [i].get = pb->get_method->mhandle;
if (pb->set_method)
MonoClass *klass;
int j;
- klass = mono_class_from_mono_type (tb->type.type);
+ klass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)tb));
event->parent = klass;
event->attrs = eb->attrs;
}
static void
-typebuilder_setup_events (MonoClass *klass)
+typebuilder_setup_events (MonoClass *klass, MonoError *error)
{
- MonoReflectionTypeBuilder *tb = klass->reflection_info;
+ MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
MonoReflectionEventBuilder *eb;
MonoImage *image = klass->image;
MonoEvent *events;
int i, j;
+ mono_error_init (error);
+
if (!klass->ext)
klass->ext = image_g_new0 (image, MonoClassExt, 1);
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);
+ events [i].name = mono_string_to_utf8_image (image, eb->name, error);
+ if (!mono_error_ok (error))
+ return;
if (eb->add_method)
events [i].add = eb->add_method->mhandle;
if (eb->remove_method)
}
static gboolean
-remove_instantiations_of (gpointer key,
+remove_instantiations_of_and_ensure_contents (gpointer key,
gpointer value,
gpointer user_data)
{
MonoType *type = (MonoType*)key;
MonoClass *klass = (MonoClass*)user_data;
- if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass))
+ if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
+ fix_partial_generic_class (mono_class_from_mono_type (type)); //Ensure it's safe to use it.
return TRUE;
- else
+ } else
return FALSE;
}
return;
for (i = 0; i < mono_array_length (arr); ++i)
- CHECK_MONOTYPE (mono_array_get (arr, gpointer, i));
+ RESOLVE_ARRAY_TYPE_ELEMENT (arr, i);
}
MonoReflectionType*
mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
{
+ MonoError error;
MonoClass *klass;
MonoDomain* domain;
MonoReflectionType* res;
/*
* Check for user defined Type subclasses.
*/
- CHECK_MONOTYPE (tb->parent);
+ RESOLVE_TYPE (tb->parent);
check_array_for_usertypes (tb->interfaces);
if (tb->fields) {
for (i = 0; i < mono_array_length (tb->fields); ++i) {
MonoReflectionFieldBuilder *fb = mono_array_get (tb->fields, gpointer, i);
if (fb) {
- CHECK_MONOTYPE (fb->type);
+ RESOLVE_TYPE (fb->type);
check_array_for_usertypes (fb->modreq);
check_array_for_usertypes (fb->modopt);
if (fb->marshal_info && fb->marshal_info->marshaltyperef)
- CHECK_MONOTYPE (fb->marshal_info->marshaltyperef);
+ RESOLVE_TYPE (fb->marshal_info->marshaltyperef);
}
}
}
for (i = 0; i < mono_array_length (tb->methods); ++i) {
MonoReflectionMethodBuilder *mb = mono_array_get (tb->methods, gpointer, i);
if (mb) {
- CHECK_MONOTYPE (mb->rtype);
+ RESOLVE_TYPE (mb->rtype);
check_array_for_usertypes (mb->return_modreq);
check_array_for_usertypes (mb->return_modopt);
check_array_for_usertypes (mb->parameters);
for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
mono_class_alloc_ext (klass);
- klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtb->type.type));
+ klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)subtb)));
}
}
}
/* FIXME: handle packing_size and instance_size */
- typebuilder_setup_fields (klass);
+ typebuilder_setup_fields (klass, &error);
+ if (!mono_error_ok (&error))
+ goto failure;
+ typebuilder_setup_properties (klass, &error);
+ if (!mono_error_ok (&error))
+ goto failure;
- typebuilder_setup_properties (klass);
+ typebuilder_setup_events (klass, &error);
+ if (!mono_error_ok (&error))
+ goto failure;
- typebuilder_setup_events (klass);
-
klass->wastypebuilder = TRUE;
/*
* If we are a generic TypeBuilder, there might be instantiations in the type cache
* which have type System.Reflection.MonoGenericClass, but after the type is created,
* we want to return normal System.MonoType objects, so clear these out from the cache.
+ *
+ * Together with this we must ensure the contents of all instances to match the created type.
*/
if (domain->type_hash && klass->generic_container)
- mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of, klass);
+ mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, klass);
mono_domain_unlock (domain);
mono_loader_unlock ();
g_assert (res != (MonoReflectionType*)tb);
return res;
+
+failure:
+ mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ klass->wastypebuilder = TRUE;
+ mono_domain_unlock (domain);
+ mono_loader_unlock ();
+ mono_error_raise_exception (&error);
+ return NULL;
}
void
if (gparam->mbuilder) {
if (!gparam->mbuilder->generic_container) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)gparam->mbuilder->type;
- MonoClass *klass = mono_class_from_mono_type (tb->type.type);
+ MonoClass *klass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)tb));
gparam->mbuilder->generic_container = mono_image_alloc0 (klass->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->image = klass->image;
}
param->param.owner = gparam->mbuilder->generic_container;
} else if (gparam->tbuilder) {
if (!gparam->tbuilder->generic_container) {
- MonoClass *klass = mono_class_from_mono_type (gparam->tbuilder->type.type);
+ MonoClass *klass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder));
gparam->tbuilder->generic_container = mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
gparam->tbuilder->generic_container->owner.klass = klass;
}
gparam->type.type = &pklass->byval_arg;
- MOVING_GC_REGISTER (&pklass->reflection_info);
- pklass->reflection_info = gparam; /* FIXME: GC pin gparam */
+ mono_class_set_ref_info (pklass, gparam);
+ mono_image_lock (image);
+ image->reflection_info_unregister_classes = g_slist_prepend (image->reflection_info_unregister_classes, pklass);
+ mono_image_unlock (image);
}
MonoArray *
mono_reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig)
{
- MonoDynamicImage *assembly = sig->module->dynamic_image;
+ MonoReflectionModuleBuilder *module = sig->module;
+ MonoDynamicImage *assembly = module != NULL ? module->dynamic_image : NULL;
guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
guint32 buflen, i;
MonoArray *result;
sigbuffer_add_value (&buf, 0x07);
sigbuffer_add_value (&buf, na);
- for (i = 0; i < na; ++i) {
- MonoReflectionType *type = mono_type_array_get (sig->arguments, i);
- encode_reflection_type (assembly, type, &buf);
+ if (assembly != NULL){
+ for (i = 0; i < na; ++i) {
+ MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
+ encode_reflection_type (assembly, type, &buf);
+ }
}
buflen = buf.p - buf.buf;
sigbuffer_add_value (&buf, 0x06);
for (i = 0; i < na; ++i) {
- MonoReflectionType *type = mono_type_array_get (sig->arguments, i);
+ MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
encode_reflection_type (assembly, type, &buf);
}
rmb.refs [i + 1] = handle_class;
}
- klass = mb->owner ? mono_class_from_mono_type (mb->owner->type) : mono_defaults.object_class;
+ klass = mb->owner ? mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner)) : mono_defaults.object_class;
mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
mono_loader_unlock ();
if (!obj) {
if (valid_token)
- g_assert_not_reached ();
+ g_error ("Could not find required dynamic token 0x%08x", token);
else
return NULL;
}
static void
ensure_complete_type (MonoClass *klass)
{
- if (klass->image->dynamic && !klass->wastypebuilder) {
- MonoReflectionTypeBuilder *tb = klass->reflection_info;
+ if (klass->image->dynamic && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
+ MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
mono_domain_try_type_resolve (mono_domain_get (), NULL, (MonoObject*)tb);
if (strcmp (obj->vtable->klass->name, "String") == 0) {
result = mono_string_intern ((MonoString*)obj);
- *handle_class = NULL;
+ *handle_class = mono_defaults.string_class;
g_assert (result);
} else if (strcmp (obj->vtable->klass->name, "MonoType") == 0) {
- MonoReflectionType *tb = (MonoReflectionType*)obj;
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj);
if (context) {
- MonoType *inflated = mono_class_inflate_generic_type (tb->type, context);
+ MonoType *inflated = mono_class_inflate_generic_type (type, context);
result = mono_class_from_mono_type (inflated);
mono_metadata_free_type (inflated);
} else {
- result = mono_class_from_mono_type (tb->type);
+ result = mono_class_from_mono_type (type);
}
*handle_class = mono_defaults.typehandle_class;
g_assert (result);
*handle_class = mono_defaults.fieldhandle_class;
} else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb);
MonoClass *klass;
- klass = tb->type.type->data.klass;
+ klass = type->data.klass;
if (klass->wastypebuilder) {
/* Already created */
result = klass;
}
else {
mono_domain_try_type_resolve (mono_domain_get (), NULL, (MonoObject*)tb);
- result = tb->type.type->data.klass;
+ result = type->data.klass;
g_assert (result);
}
*handle_class = mono_defaults.typehandle_class;
sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
sig->hasthis = helper->call_conv & 32 ? 1 : 0;
- if (helper->call_conv == 0) /* unmanaged */
+ if (helper->unmanaged_call_conv) { /* unmanaged */
sig->call_convention = helper->unmanaged_call_conv - 1;
- else
- if (helper->call_conv & 0x02)
- sig->call_convention = MONO_CALL_VARARG;
- else
+ sig->pinvoke = TRUE;
+ } else if (helper->call_conv & 0x02) {
+ sig->call_convention = MONO_CALL_VARARG;
+ } else {
sig->call_convention = MONO_CALL_DEFAULT;
+ }
sig->param_count = nargs;
/* TODO: Copy type ? */
sig->ret = helper->return_type->type;
- for (i = 0; i < nargs; ++i) {
- MonoReflectionType *rt = mono_type_array_get (helper->arguments, i);
- sig->params [i] = rt->type;
- }
+ for (i = 0; i < nargs; ++i)
+ sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i);
result = sig;
*handle_class = NULL;
result = method->mhandle;
*handle_class = mono_defaults.methodhandle_class;
} else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
- MonoReflectionType *tb = (MonoReflectionType*)obj;
- MonoType *type = mono_class_inflate_generic_type (tb->type, context);
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj);
+ type = mono_class_inflate_generic_type (type, context);
result = mono_class_from_mono_type (type);
*handle_class = mono_defaults.typehandle_class;
g_assert (result);
mono_metadata_free_type (type);
} else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
- MonoReflectionGenericClass *ref = (MonoReflectionGenericClass*)obj;
- MonoType *type = mono_class_inflate_generic_type (ref->type.type, context);
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj);
+ type = mono_class_inflate_generic_type (type, context);
result = mono_class_from_mono_type (type);
*handle_class = mono_defaults.typehandle_class;
g_assert (result);
MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
MonoClass *inflated;
MonoType *type;
+ MonoClassField *field;
- type = mono_class_inflate_generic_type (f->inst->type.type, context);
+ if (is_sre_field_builder (mono_object_class (f->fb)))
+ field = ((MonoReflectionFieldBuilder*)f->fb)->handle;
+ else if (is_sr_mono_field (mono_object_class (f->fb)))
+ field = ((MonoReflectionField*)f->fb)->field;
+ else
+ g_error ("resolve_object:: can't handle a FTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (f->fb)));
+
+ type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)f->inst), context);
inflated = mono_class_from_mono_type (type);
- g_assert (f->fb->handle);
- result = mono_class_get_field_from_name (inflated, mono_field_get_name (f->fb->handle));
+ result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
+ ensure_complete_type (field->parent);
g_assert (result);
mono_metadata_free_type (type);
*handle_class = mono_defaults.fieldhandle_class;
} else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
- MonoType *type = mono_class_inflate_generic_type (c->inst->type.type, context);
+ MonoType *type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)c->inst), context);
MonoClass *inflated_klass = mono_class_from_mono_type (type);
- g_assert (c->cb->mhandle);
- result = inflate_mono_method (inflated_klass, c->cb->mhandle, (MonoObject*)c->cb);
+ MonoMethod *method;
+
+ if (is_sre_ctor_builder (mono_object_class (c->cb)))
+ method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
+ else if (is_sr_mono_cmethod (mono_object_class (c->cb)))
+ method = ((MonoReflectionMethod *)c->cb)->method;
+ else
+ g_error ("resolve_object:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (c->cb)));
+
+ result = inflate_mono_method (inflated_klass, method, (MonoObject*)c->cb);
*handle_class = mono_defaults.methodhandle_class;
mono_metadata_free_type (type);
} else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
- MonoType *type = mono_class_inflate_generic_type (m->inst->type.type, context);
- MonoClass *inflated_klass = mono_class_from_mono_type (type);
- g_assert (m->mb->mhandle);
- result = inflate_mono_method (inflated_klass, m->mb->mhandle, (MonoObject*)m->mb);
+ if (m->method_args) {
+ result = mono_reflection_method_on_tb_inst_get_handle (m);
+ } else {
+ MonoType *type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)m->inst), context);
+ MonoClass *inflated_klass = mono_class_from_mono_type (type);
+ MonoMethod *method;
+
+ if (is_sre_method_builder (mono_object_class (m->mb)))
+ method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
+ else if (is_sr_mono_method (mono_object_class (m->mb)))
+ method = ((MonoReflectionMethod *)m->mb)->method;
+ else
+ g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
+
+ result = inflate_mono_method (inflated_klass, method, (MonoObject*)m->mb);
+ mono_metadata_free_type (type);
+ }
*handle_class = mono_defaults.methodhandle_class;
- mono_metadata_free_type (type);
+ } else if (strcmp (obj->vtable->klass->name, "MonoArrayMethod") == 0) {
+ MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
+ MonoType *mtype;
+ MonoClass *klass;
+ MonoMethod *method;
+ gpointer iter;
+ char *name;
+
+ mtype = mono_reflection_type_get_handle (m->parent);
+ klass = mono_class_from_mono_type (mtype);
+
+ /* Find the method */
+
+ name = mono_string_to_utf8 (m->name);
+ iter = NULL;
+ while ((method = mono_class_get_methods (klass, &iter))) {
+ if (!strcmp (method->name, name))
+ break;
+ }
+ g_free (name);
+
+ // FIXME:
+ g_assert (method);
+ // FIXME: Check parameters/return value etc. match
+
+ result = method;
+ *handle_class = mono_defaults.methodhandle_class;
+ } else if (is_sre_array (mono_object_get_class(obj)) ||
+ is_sre_byref (mono_object_get_class(obj)) ||
+ is_sre_pointer (mono_object_get_class(obj))) {
+ MonoReflectionType *ref_type = (MonoReflectionType *)obj;
+ MonoType *type = mono_reflection_type_get_handle (ref_type);
+ result = mono_class_from_mono_type (type);
+ *handle_class = mono_defaults.typehandle_class;
} else {
- g_print (obj->vtable->klass->name);
+ g_print ("%s\n", obj->vtable->klass->name);
g_assert_not_reached ();
}
return result;
g_assert_not_reached ();
}
+void
+mono_image_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
+{
+ g_assert_not_reached ();
+}
+
MonoReflectionModule *
mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
{
return NULL;
}
+MonoType*
+mono_reflection_type_get_handle (MonoReflectionType* ref)
+{
+ if (!ref)
+ return NULL;
+ return ref->type;
+}
+
#endif /* DISABLE_REFLECTION_EMIT */
/* SECURITY_ACTION_* are defined in mono/metadata/tabledefs.h */
/*
* The result of mono_type_get_object () might be a System.MonoType but we
- * need a TypeBuilder so use klass->reflection_info.
+ * need a TypeBuilder so use mono_class_get_ref_info (klass).
*/
- g_assert (klass->reflection_info);
- g_assert (!strcmp (((MonoObject*)(klass->reflection_info))->vtable->klass->name, "TypeBuilder"));
+ g_assert (mono_class_get_ref_info (klass));
+ g_assert (!strcmp (((MonoObject*)(mono_class_get_ref_info (klass)))->vtable->klass->name, "TypeBuilder"));
params [0] = mono_type_get_object (mono_domain_get (), &oklass->byval_arg);
- res = mono_runtime_invoke (method, (MonoObject*)(klass->reflection_info), params, &exc);
+ res = mono_runtime_invoke (method, (MonoObject*)(mono_class_get_ref_info (klass)), params, &exc);
if (exc)
return FALSE;
else