X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Freflection.c;h=dc70fab01662290b310d451fb0e144a6863fddf1;hb=55fcbd4b13267a39db7dadd5ae8c055ce83c9f50;hp=551f376f66f9cee9eac2add4302c85870f535da6;hpb=f764af66a502df82ff20c1df54aab3d6bf3d3e8f;p=mono.git diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index 551f376f66f..dc70fab0166 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -11,10 +11,13 @@ #include "mono/utils/mono-digest.h" #include "mono/metadata/reflection.h" #include "mono/metadata/tabledefs.h" +#include "mono/metadata/metadata-internals.h" +#include "mono/metadata/class-internals.h" #include "mono/metadata/tokentype.h" -#include "mono/metadata/appdomain.h" +#include "mono/metadata/domain-internals.h" #include "mono/metadata/opcodes.h" #include "mono/metadata/assembly.h" +#include "mono/metadata/object-internals.h" #include #include #include @@ -41,6 +44,7 @@ typedef struct { MonoArray *parameters; MonoArray *generic_params; MonoArray *pinfo; + MonoArray *opt_types; guint32 attrs; guint32 iattrs; guint32 call_conv; @@ -59,6 +63,11 @@ typedef struct { gpointer *refs; } ReflectionMethodBuilder; +typedef struct { + guint32 owner; + MonoReflectionGenericParam *gparam; +} GenericParamTableEntry; + const unsigned char table_sizes [64] = { MONO_MODULE_SIZE, MONO_TYPEREF_SIZE, @@ -134,10 +143,13 @@ static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, Mon static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper); static void mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly); static guint32 encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo); +static guint32 encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type); static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass); static void ensure_runtime_vtable (MonoClass *klass); static gpointer resolve_object (MonoImage *image, MonoObject *obj); static void encode_type (MonoDynamicImage *assembly, MonoType *type, char *p, char **endbuf); +static guint32 type_get_signature_size (MonoType *type); + static void alloc_table (MonoDynamicTable *table, guint nrows) @@ -531,6 +543,97 @@ encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArra *endbuf = p; } +static guint32 +generic_inst_get_signature_size (MonoGenericInst *ginst) +{ + guint32 size = 0; + int i; + + if (!ginst) { + g_assert_not_reached (); + } + + size += 1 + type_get_signature_size (ginst->generic_type); + size += 4; + for (i = 0; i < ginst->type_argc; ++i) + size += type_get_signature_size (ginst->type_argv [i]); + + return size; +} + +static guint32 +type_get_signature_size (MonoType *type) +{ + guint32 size = 0; + + if (!type) { + g_assert_not_reached (); + } + + if (type->byref) + size++; + + switch (type->type){ + case MONO_TYPE_VOID: + case MONO_TYPE_BOOLEAN: + case MONO_TYPE_CHAR: + case MONO_TYPE_I1: + case MONO_TYPE_U1: + case MONO_TYPE_I2: + case MONO_TYPE_U2: + case MONO_TYPE_I4: + case MONO_TYPE_U4: + case MONO_TYPE_I8: + case MONO_TYPE_U8: + case MONO_TYPE_R4: + case MONO_TYPE_R8: + case MONO_TYPE_I: + case MONO_TYPE_U: + case MONO_TYPE_STRING: + case MONO_TYPE_OBJECT: + case MONO_TYPE_TYPEDBYREF: + return size + 1; + case MONO_TYPE_PTR: + return size + 1 + type_get_signature_size (type->data.type); + case MONO_TYPE_SZARRAY: + return size + 1 + type_get_signature_size (&type->data.klass->byval_arg); + + case MONO_TYPE_VALUETYPE: + case MONO_TYPE_CLASS: + return size + 5; + + case MONO_TYPE_ARRAY: + return size + 7 + type_get_signature_size (&type->data.array->eklass->byval_arg); + case MONO_TYPE_GENERICINST: + return size + generic_inst_get_signature_size (type->data.generic_inst); + case MONO_TYPE_VAR: + case MONO_TYPE_MVAR: + return size + 5; + + default: + g_error ("need to encode type %x", type->type); + return size; + } +} + +static guint32 +method_get_signature_size (MonoMethodSignature *sig) +{ + guint32 size; + int i; + + size = type_get_signature_size (sig->ret); + for (i = 0; i < sig->param_count; i++) + size += type_get_signature_size (sig->params [i]); + + if (sig->generic_param_count) + size += 4; + if (sig->sentinelpos >= 0) + size++; + + return size; +} + static guint32 method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig) { @@ -538,7 +641,7 @@ method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig) char *p; int i; guint32 nparams = sig->param_count; - guint32 size = 10 + nparams * 10; + guint32 size = 11 + method_get_signature_size (sig); guint32 idx; char blob_size [6]; char *b = blob_size; @@ -560,8 +663,11 @@ method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig) mono_metadata_encode_value (sig->generic_param_count, p, &p); mono_metadata_encode_value (nparams, p, &p); encode_type (assembly, sig->ret, p, &p); - for (i = 0; i < nparams; ++i) + for (i = 0; i < nparams; ++i) { + if (i == sig->sentinelpos) + *p++ = MONO_TYPE_SENTINEL; encode_type (assembly, sig->params [i], p, &p); + } /* store length */ g_assert (p - buf < size); mono_metadata_encode_value (p-buf, b, &b); @@ -581,7 +687,8 @@ method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBui int i; guint32 nparams = mb->parameters ? mono_array_length (mb->parameters): 0; guint32 ngparams = mb->generic_params ? mono_array_length (mb->generic_params): 0; - guint32 size = 21 + nparams * 20; + guint32 notypes = mb->opt_types ? mono_array_length (mb->opt_types): 0; + guint32 size = 21 + nparams * 20 + notypes * 20; guint32 idx; char blob_size [6]; char *b = blob_size; @@ -598,7 +705,7 @@ method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBui p++; if (ngparams) mono_metadata_encode_value (ngparams, p, &p); - mono_metadata_encode_value (nparams, p, &p); + mono_metadata_encode_value (nparams + notypes, p, &p); encode_custom_modifiers (assembly, mb->return_modreq, mb->return_modopt, p, &p); encode_reflection_type (assembly, mb->rtype, p, &p); for (i = 0; i < nparams; ++i) { @@ -614,6 +721,15 @@ method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBui pt = mono_array_get (mb->parameters, MonoReflectionType*, i); encode_reflection_type (assembly, pt, p, &p); } + if (notypes) + *p++ = MONO_TYPE_SENTINEL; + for (i = 0; i < notypes; ++i) { + MonoReflectionType *pt; + + pt = mono_array_get (mb->opt_types, MonoReflectionType*, i); + encode_reflection_type (assembly, pt, p, &p); + } + /* store length */ g_assert (p - buf < size); mono_metadata_encode_value (p-buf, b, &b); @@ -647,6 +763,10 @@ encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen) mono_metadata_encode_value (nl, p, &p); for (i = 0; i < nl; ++i) { MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i); + + if (lb->is_pinned) + mono_metadata_encode_value (MONO_TYPE_PINNED, p, &p); + encode_reflection_type (assembly, lb->type, p, &p); } g_assert (p - buf < size); @@ -759,8 +879,14 @@ method_encode_code (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb) num_exception = method_count_clauses (mb->ilgen); } else { code = mb->code; - if (code == NULL) - mono_raise_exception (mono_get_exception_argument (NULL, "a method does not have any IL associated")); + if (code == NULL){ + char *name = mono_string_to_utf8 (mb->name); + char *str = g_strdup_printf ("Method %s does not have any IL associated", name); + MonoException *exception = mono_get_exception_argument (NULL, "a method does not have any IL associated"); + g_free (str); + g_free (name); + mono_raise_exception (exception); + } code_size = mono_array_length (code); max_stack = 8; /* we probably need to run a verifier on the code... */ @@ -920,6 +1046,7 @@ mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs) dynamic_custom_attrs = g_hash_table_new (NULL, NULL); g_hash_table_insert (dynamic_custom_attrs, obj, ainfo); + ainfo->cached = TRUE; } void @@ -933,7 +1060,7 @@ mono_custom_attrs_free (MonoCustomAttrInfo *ainfo) /* * idx is the table index of the object - * type is one of CUSTOM_ATTR_* + * type is one of MONO_CUSTOM_ATTR_* */ static void mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, MonoArray *cattrs) @@ -953,20 +1080,20 @@ mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, Mo table->rows += count; alloc_table (table, table->rows); values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE; - idx <<= CUSTOM_ATTR_BITS; + idx <<= MONO_CUSTOM_ATTR_BITS; idx |= type; for (i = 0; i < count; ++i) { cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i); values [MONO_CUSTOM_ATTR_PARENT] = idx; - token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor); + token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor, FALSE); type = mono_metadata_token_index (token); - type <<= CUSTOM_ATTR_TYPE_BITS; + type <<= MONO_CUSTOM_ATTR_TYPE_BITS; switch (mono_metadata_token_table (token)) { case MONO_TABLE_METHOD: - type |= CUSTOM_ATTR_TYPE_METHODDEF; + type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF; break; case MONO_TABLE_MEMBERREF: - type |= CUSTOM_ATTR_TYPE_MEMBERREF; + type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF; break; default: g_warning ("got wrong token in custom attr"); @@ -1005,16 +1132,16 @@ mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token, values = table->values + table->next_idx * MONO_DECL_SECURITY_SIZE; idx = mono_metadata_token_index (parent_token); - idx <<= HAS_DECL_SECURITY_BITS; + idx <<= MONO_HAS_DECL_SECURITY_BITS; switch (mono_metadata_token_table (parent_token)) { case MONO_TABLE_TYPEDEF: - idx |= HAS_DECL_SECURITY_TYPEDEF; + idx |= MONO_HAS_DECL_SECURITY_TYPEDEF; break; case MONO_TABLE_METHOD: - idx |= HAS_DECL_SECURITY_METHODDEF; + idx |= MONO_HAS_DECL_SECURITY_METHODDEF; break; case MONO_TABLE_ASSEMBLY: - idx |= HAS_DECL_SECURITY_ASSEMBLY; + idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY; break; default: g_assert_not_reached (); @@ -1084,18 +1211,29 @@ mono_image_basic_method (ReflectionMethodBuilder *mb, MonoDynamicImage *assembly name = mono_string_to_utf8 (pb->name); values [MONO_PARAM_NAME] = string_heap_insert (&assembly->sheap, name); g_free (name); - } - else + } else { values [MONO_PARAM_NAME] = 0; + } values += MONO_PARAM_SIZE; if (pb->marshal_info) { mtable->rows++; alloc_table (mtable, mtable->rows); mvalues = mtable->values + mtable->rows * MONO_FIELD_MARSHAL_SIZE; - mvalues [MONO_FIELD_MARSHAL_PARENT] = (table->next_idx << HAS_FIELD_MARSHAL_BITS) | HAS_FIELD_MARSHAL_PARAMDEF; + mvalues [MONO_FIELD_MARSHAL_PARENT] = (table->next_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_PARAMDEF; mvalues [MONO_FIELD_MARSHAL_NATIVE_TYPE] = encode_marshal_blob (assembly, pb->marshal_info); } pb->table_idx = table->next_idx++; + if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) { + guint32 field_type = 0; + mtable = &assembly->tables [MONO_TABLE_CONSTANT]; + mtable->rows ++; + alloc_table (mtable, mtable->rows); + mvalues = mtable->values + mtable->rows * MONO_CONSTANT_SIZE; + mvalues [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_PARAM | (pb->table_idx << MONO_HASCONSTANT_BITS); + mvalues [MONO_CONSTANT_VALUE] = encode_constant (assembly, pb->def_value, &field_type); + mvalues [MONO_CONSTANT_TYPE] = field_type; + mvalues [MONO_CONSTANT_PADDING] = 0; + } } } } @@ -1109,6 +1247,7 @@ reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, rmb->rtype = mb->rtype; rmb->parameters = mb->parameters; rmb->generic_params = mb->generic_params; + rmb->opt_types = NULL; rmb->pinfo = mb->pinfo; rmb->attrs = mb->attrs; rmb->iattrs = mb->iattrs; @@ -1138,6 +1277,7 @@ reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, rmb->rtype = mono_type_get_object (mono_domain_get (), &mono_defaults.void_class->byval_arg); rmb->parameters = mb->parameters; rmb->generic_params = NULL; + rmb->opt_types = NULL; rmb->pinfo = mb->pinfo; rmb->attrs = mb->attrs; rmb->iattrs = mb->iattrs; @@ -1165,6 +1305,7 @@ reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, rmb->rtype = mb->rtype; rmb->parameters = mb->parameters; rmb->generic_params = NULL; + rmb->opt_types = NULL; rmb->pinfo = NULL; rmb->attrs = mb->attrs; rmb->iattrs = 0; @@ -1232,14 +1373,15 @@ mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *a alloc_table (table, table->rows); values = table->values + table->rows * MONO_METHODIMPL_SIZE; values [MONO_METHODIMPL_CLASS] = tb->table_idx; - values [MONO_METHODIMPL_BODY] = METHODDEFORREF_METHODDEF | (mb->table_idx << METHODDEFORREF_BITS); - tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method); + values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS); + + tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method, FALSE); switch (mono_metadata_token_table (tok)) { case MONO_TABLE_MEMBERREF: - tok = (mono_metadata_token_index (tok) << METHODDEFORREF_BITS ) | METHODDEFORREF_METHODREF; + tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF; break; case MONO_TABLE_METHOD: - tok = (mono_metadata_token_index (tok) << METHODDEFORREF_BITS ) | METHODDEFORREF_METHODDEF; + tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF; break; default: g_assert_not_reached (); @@ -1281,11 +1423,11 @@ type_get_fully_qualified_name (MonoType *type) { klass = my_mono_class_from_mono_type (type); ta = klass->image->assembly; - /* missing public key */ - result = g_strdup_printf ("%s, %s, Version=%d.%d.%d.%d, Culture=%s", + result = g_strdup_printf ("%s, %s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s", name, ta->aname.name, ta->aname.major, ta->aname.minor, ta->aname.build, ta->aname.revision, - ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral"); + ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral", + ta->aname.public_key_token [0] ? (char *)ta->aname.public_key_token : "null"); g_free (name); return result; } @@ -1450,7 +1592,16 @@ encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo) { mono_metadata_encode_value (minfo->type, p, &p); mono_metadata_encode_value (minfo->count, p, &p); break; - /* FIXME: handle ARRAY and other unmanaged types that need extra info */ + case MONO_NATIVE_LPARRAY: + mono_metadata_encode_value (minfo->type, p, &p); + if (minfo->eltype || (minfo->count > 0)) { + mono_metadata_encode_value (minfo->eltype, p, &p); + if (minfo->count > 0) { + mono_metadata_encode_value (0, p, &p); + mono_metadata_encode_value (minfo->count, p, &p); + } + } + break; case MONO_NATIVE_CUSTOM: mono_metadata_encode_value (minfo->type, p, &p); if (minfo->guid) { @@ -1557,7 +1708,7 @@ mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *ass table->rows ++; alloc_table (table, table->rows); values = table->values + table->rows * MONO_CONSTANT_SIZE; - values [MONO_CONSTANT_PARENT] = HASCONSTANT_FIEDDEF | (fb->table_idx << HASCONSTANT_BITS); + values [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_FIEDDEF | (fb->table_idx << MONO_HASCONSTANT_BITS); values [MONO_CONSTANT_VALUE] = encode_constant (assembly, fb->def_value, &field_type); values [MONO_CONSTANT_TYPE] = field_type; values [MONO_CONSTANT_PADDING] = 0; @@ -1583,7 +1734,7 @@ mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *ass table->rows ++; alloc_table (table, table->rows); values = table->values + table->rows * MONO_FIELD_MARSHAL_SIZE; - values [MONO_FIELD_MARSHAL_PARENT] = (fb->table_idx << HAS_FIELD_MARSHAL_BITS) | HAS_FIELD_MARSHAL_FIELDSREF; + values [MONO_FIELD_MARSHAL_PARENT] = (fb->table_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_FIELDSREF; values [MONO_FIELD_MARSHAL_NATIVE_TYPE] = encode_marshal_blob (assembly, fb->marshal_info); } } @@ -1668,14 +1819,14 @@ mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicImag values = table->values + semaidx * MONO_METHOD_SEMA_SIZE; values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_GETTER; values [MONO_METHOD_SEMA_METHOD] = pb->get_method->table_idx; - values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_PROPERTY; + values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY; } if (pb->set_method) { semaidx = table->next_idx ++; values = table->values + semaidx * MONO_METHOD_SEMA_SIZE; values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_SETTER; values [MONO_METHOD_SEMA_METHOD] = pb->set_method->table_idx; - values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_PROPERTY; + values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY; } } @@ -1720,22 +1871,91 @@ mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *ass values = table->values + semaidx * MONO_METHOD_SEMA_SIZE; values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_ADD_ON; values [MONO_METHOD_SEMA_METHOD] = eb->add_method->table_idx; - values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_EVENT; + values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT; } if (eb->remove_method) { semaidx = table->next_idx ++; values = table->values + semaidx * MONO_METHOD_SEMA_SIZE; values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_REMOVE_ON; values [MONO_METHOD_SEMA_METHOD] = eb->remove_method->table_idx; - values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_EVENT; + values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT; } if (eb->raise_method) { semaidx = table->next_idx ++; values = table->values + semaidx * MONO_METHOD_SEMA_SIZE; values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_FIRE; values [MONO_METHOD_SEMA_METHOD] = eb->raise_method->table_idx; - values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_EVENT; + values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT; + } +} + +static void +encode_new_constraint (MonoDynamicImage *assembly, guint32 owner) +{ + static MonoClass *NewConstraintAttr; + static MonoMethod *NewConstraintAttr_ctor; + MonoDynamicTable *table; + guint32 *values; + guint32 token, type; + char blob_size [4] = { 0x01, 0x00, 0x00, 0x00 }; + char *buf, *p; + + if (!NewConstraintAttr) + NewConstraintAttr = mono_class_from_name ( + mono_defaults.corlib, "System.Runtime.CompilerServices", + "NewConstraintAttribute"); + g_assert (NewConstraintAttr); + + if (!NewConstraintAttr_ctor) { + int i; + + for (i = 0; i < NewConstraintAttr->method.count; i++) { + MonoMethod *m = NewConstraintAttr->methods [i]; + + if (strcmp (m->name, ".ctor")) + continue; + + NewConstraintAttr_ctor = m; + break; + } + + g_assert (NewConstraintAttr_ctor); + } + + table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE]; + table->rows += 1; + alloc_table (table, table->rows); + + values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE; + owner <<= MONO_CUSTOM_ATTR_BITS; + owner |= MONO_CUSTOM_ATTR_GENERICPAR; + values [MONO_CUSTOM_ATTR_PARENT] = owner; + + token = mono_image_get_methodref_token (assembly, NewConstraintAttr_ctor); + + type = mono_metadata_token_index (token); + type <<= MONO_CUSTOM_ATTR_TYPE_BITS; + switch (mono_metadata_token_table (token)) { + case MONO_TABLE_METHOD: + type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF; + break; + case MONO_TABLE_MEMBERREF: + type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF; + break; + default: + g_warning ("got wrong token in custom attr"); + return; } + values [MONO_CUSTOM_ATTR_TYPE] = type; + + buf = p = g_malloc (1); + mono_metadata_encode_value (4, p, &p); + g_assert (p-buf == 1); + + values [MONO_CUSTOM_ATTR_VALUE] = add_to_blob_cached (assembly, buf, 1, blob_size, 4); + + values += MONO_CUSTOM_ATTR_SIZE; + ++table->next_idx; } static void @@ -1747,23 +1967,59 @@ encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynam guint32 table_idx; table = &assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT]; - num_constraints = gparam ? mono_array_length (gparam->constraints) : 0; + num_constraints = gparam->iface_constraints ? + mono_array_length (gparam->iface_constraints) : 0; table->rows += num_constraints; + if (gparam->base_type) + table->rows++; alloc_table (table, table->rows); + if (gparam->base_type) { + table_idx = table->next_idx ++; + values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE; + + values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner; + values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref ( + assembly, gparam->base_type->type); + } + for (i = 0; i < num_constraints; i++) { - MonoReflectionType *constraint = mono_array_get (gparam->constraints, gpointer, i); + MonoReflectionType *constraint = mono_array_get ( + gparam->iface_constraints, gpointer, i); table_idx = table->next_idx ++; values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE; values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner; - values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (assembly, constraint->type); + values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref ( + assembly, constraint->type); } + + if (gparam->has_ctor_constraint) + encode_new_constraint (assembly, owner); } static void mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly) +{ + GenericParamTableEntry *entry; + + /* + * The GenericParam table must be sorted according to the `owner' field. + * We need to do this sorting prior to writing the GenericParamConstraint + * table, since we have to use the final GenericParam table indices there + * and they must also be sorted. + */ + + entry = g_new0 (GenericParamTableEntry, 1); + entry->owner = owner; + entry->gparam = gparam; + + g_ptr_array_add (assembly->gen_params, entry); +} + +static void +write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *entry) { MonoDynamicTable *table; MonoGenericParam *param; @@ -1774,17 +2030,20 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o table_idx = table->next_idx ++; values = table->values + table_idx * MONO_GENERICPARAM_SIZE; - param = gparam->type.type->data.generic_param; + param = entry->gparam->type.type->data.generic_param; - values [MONO_GENERICPARAM_OWNER] = owner; - values [MONO_GENERICPARAM_FLAGS] = param->flags; + values [MONO_GENERICPARAM_OWNER] = entry->owner; + if (entry->gparam->has_value_type) + values [MONO_GENERICPARAM_FLAGS] = 0x18; + else if (entry->gparam->has_reference_type) + values [MONO_GENERICPARAM_FLAGS] = 0x04; + else + values [MONO_GENERICPARAM_FLAGS] = 0x00; values [MONO_GENERICPARAM_NUMBER] = param->num; values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, param->name); values [MONO_GENERICPARAM_KIND] = 0; - values [MONO_GENERICPARAM_DEPRECATED_CONSTRAINT] = 0; - if (gparam->constraints) - encode_constraints (gparam, table_idx, assembly); + encode_constraints (entry->gparam, table_idx, assembly); } static guint32 @@ -1808,8 +2067,8 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image) values = table->values + token * MONO_MODULEREF_SIZE; values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name); - token <<= RESOLTION_SCOPE_BITS; - token |= RESOLTION_SCOPE_MODULEREF; + token <<= MONO_RESOLTION_SCOPE_BITS; + token |= MONO_RESOLTION_SCOPE_MODULEREF; g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token)); return token; @@ -1829,10 +2088,7 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image) table->rows ++; alloc_table (table, table->rows); values = table->values + token * MONO_ASSEMBLYREF_SIZE; - if (strcmp ("corlib", image->assembly_name) == 0) - values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, "mscorlib"); - else - values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name); + values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name); values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION]; values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION]; values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER]; @@ -1841,63 +2097,21 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image) values [MONO_ASSEMBLYREF_CULTURE] = 0; values [MONO_ASSEMBLYREF_HASH_VALUE] = 0; + if (strcmp ("", image->assembly->aname.culture)) { + values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap, + image->assembly->aname.culture); + } + if ((pubkey = mono_image_get_public_key (image, &publen))) { guchar pubtoken [9]; pubtoken [0] = 8; mono_digest_get_public_token (pubtoken + 1, pubkey, publen); values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, pubtoken, 9); } else { - /* - * We add the pubtoken from ms, so that the ms runtime can handle our binaries. - * This is currently only a problem with references to System.Xml (see bug#27706), - * but there may be other cases that makes this necessary. Note, we need to set - * the version as well. When/if we sign our assemblies, we'd need to get our pubtoken - * recognized by ms, yuck! - * FIXME: need to add more assembly names, as needed. - */ - if (strcmp (image->assembly_name, "corlib") == 0 || - strcmp (image->assembly_name, "mscorlib") == 0 || - strcmp (image->assembly_name, "System") == 0 || - strcmp (image->assembly_name, "System.Runtime.Remoting") == 0 || - strcmp (image->assembly_name, "System.Xml") == 0 || - strcmp (image->assembly_name, "System.Data") == 0 || - strcmp (image->assembly_name, "System.Windows.Forms") == 0) { - static const guchar ptoken [9] = {8, '\xB7', '\x7A', '\x5C', '\x56', '\x19', '\x34', '\xE0', '\x89'}; - values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, ptoken, 9); - values [MONO_ASSEMBLYREF_MAJOR_VERSION] = 1; - values [MONO_ASSEMBLYREF_BUILD_NUMBER] = 3300; - } else if (strcmp (image->assembly_name, "Accessibility") == 0 || - strcmp (image->assembly_name, "cscompmgd") == 0 || - strcmp (image->assembly_name, "CustomMarshalers") == 0 || - strcmp (image->assembly_name, "Microsoft.JScript") == 0 || - strcmp (image->assembly_name, "Microsoft.VisualBasic") == 0 || - strcmp (image->assembly_name, "Microsoft.VisualBasic.Vsa") == 0 || - strcmp (image->assembly_name, "Microsoft.VisualC") == 0 || - strcmp (image->assembly_name, "Microsoft.Vsa") == 0 || - strcmp (image->assembly_name, "System.Configuration.Install") == 0 || - strcmp (image->assembly_name, "System.DirectoryServices") == 0 || - strcmp (image->assembly_name, "System.Design") == 0 || - strcmp (image->assembly_name, "System.Drawing") == 0 || - strcmp (image->assembly_name, "System.Drawing.Design") == 0 || - strcmp (image->assembly_name, "System.EnterpriseServices") == 0 || - strcmp (image->assembly_name, "System.Management") == 0 || - strcmp (image->assembly_name, "System.Messaging") == 0 || - strcmp (image->assembly_name, "System.Runtime.Serialization.Formatters.Soap") == 0 || - strcmp (image->assembly_name, "System.Security") == 0 || - strcmp (image->assembly_name, "System.ServiceProcess") == 0 || - strcmp (image->assembly_name, "System.Web.Services") == 0 || - strcmp (image->assembly_name, "CustomMarshalers") == 0 || - strcmp (image->assembly_name, "System.Web") == 0) { - static const guchar ptoken [9] = {8, '\xb0', '\x3f', '\x5f', '\x7f', '\x11', '\xd5', '\x0a', '\x3a'}; - values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, ptoken, 9); - values [MONO_ASSEMBLYREF_MAJOR_VERSION] = 1; - values [MONO_ASSEMBLYREF_BUILD_NUMBER] = 3300; - } else { - values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0; - } + values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0; } - token <<= RESOLTION_SCOPE_BITS; - token |= RESOLTION_SCOPE_ASSEMBLYREF; + token <<= MONO_RESOLTION_SCOPE_BITS; + token |= MONO_RESOLTION_SCOPE_ASSEMBLYREF; g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token)); return token; } @@ -1945,7 +2159,7 @@ create_typespec (MonoDynamicImage *assembly, MonoType *type) values [MONO_TYPESPEC_SIGNATURE] = token; } - token = TYPEDEFORREF_TYPESPEC | (table->next_idx << TYPEDEFORREF_BITS); + token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS); g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token)); table->next_idx ++; return token; @@ -1978,7 +2192,7 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type) if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) && (type->type != MONO_TYPE_MVAR)) { MonoReflectionTypeBuilder *tb = klass->reflection_info; - token = TYPEDEFORREF_TYPEDEF | (tb->table_idx << TYPEDEFORREF_BITS); + token = MONO_TYPEDEFORREF_TYPEDEF | (tb->table_idx << MONO_TYPEDEFORREF_BITS); mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), klass->reflection_info); return token; } @@ -1986,8 +2200,8 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type) if (klass->nested_in) { enclosing = mono_image_typedef_or_ref (assembly, &klass->nested_in->byval_arg); /* get the typeref idx of the enclosing type */ - enclosing >>= TYPEDEFORREF_BITS; - scope = (enclosing << RESOLTION_SCOPE_BITS) | RESOLTION_SCOPE_TYPEREF; + enclosing >>= MONO_TYPEDEFORREF_BITS; + scope = (enclosing << MONO_RESOLTION_SCOPE_BITS) | MONO_RESOLTION_SCOPE_TYPEREF; } else { scope = resolution_scope_from_image (assembly, klass->image); } @@ -1999,7 +2213,7 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type) values [MONO_TYPEREF_NAME] = string_heap_insert (&assembly->sheap, klass->name); values [MONO_TYPEREF_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space); } - token = TYPEDEFORREF_TYPEREF | (table->next_idx << TYPEDEFORREF_BITS); /* typeref */ + 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); @@ -2021,29 +2235,29 @@ mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, cons guint32 parent; parent = mono_image_typedef_or_ref (assembly, type); - switch (parent & TYPEDEFORREF_MASK) { - case TYPEDEFORREF_TYPEREF: - pclass = MEMBERREF_PARENT_TYPEREF; + switch (parent & MONO_TYPEDEFORREF_MASK) { + case MONO_TYPEDEFORREF_TYPEREF: + pclass = MONO_MEMBERREF_PARENT_TYPEREF; break; - case TYPEDEFORREF_TYPESPEC: - pclass = MEMBERREF_PARENT_TYPESPEC; + case MONO_TYPEDEFORREF_TYPESPEC: + pclass = MONO_MEMBERREF_PARENT_TYPESPEC; break; - case TYPEDEFORREF_TYPEDEF: - pclass = MEMBERREF_PARENT_TYPEDEF; + case MONO_TYPEDEFORREF_TYPEDEF: + pclass = MONO_MEMBERREF_PARENT_TYPEDEF; break; default: g_warning ("unknown typeref or def token 0x%08x for %s", parent, name); return 0; } /* extract the index */ - parent >>= TYPEDEFORREF_BITS; + parent >>= MONO_TYPEDEFORREF_BITS; table = &assembly->tables [MONO_TABLE_MEMBERREF]; if (assembly->save) { alloc_table (table, table->rows + 1); values = table->values + table->next_idx * MONO_MEMBERREF_SIZE; - values [MONO_MEMBERREF_CLASS] = pclass | (parent << MEMBERREF_PARENT_BITS); + values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS); values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name); values [MONO_MEMBERREF_SIGNATURE] = sig; } @@ -2068,6 +2282,30 @@ mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method) return token; } +static guint32 +mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original, + const gchar *name, guint32 sig) +{ + MonoDynamicTable *table; + guint32 token; + guint32 *values; + + table = &assembly->tables [MONO_TABLE_MEMBERREF]; + + if (assembly->save) { + alloc_table (table, table->rows + 1); + values = table->values + table->next_idx * MONO_MEMBERREF_SIZE; + values [MONO_MEMBERREF_CLASS] = original; + values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name); + values [MONO_MEMBERREF_SIGNATURE] = sig; + } + + token = MONO_TOKEN_MEMBER_REF | table->next_idx; + table->next_idx ++; + + return token; +} + static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb) { @@ -2107,19 +2345,19 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor } static guint32 -mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoClassField *field, MonoClass *klass) +mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *f) { MonoType *type; guint32 token; - token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field)); + token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f)); if (token) return token; - field->parent = klass; - type = field->generic_type ? field->generic_type : field->type; - token = mono_image_get_memberref_token (assembly, &klass->byval_arg, - field->name, fieldref_encode_signature (assembly, type)); - g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token)); + g_assert (f->field->parent); + type = f->field->generic_info ? f->field->generic_info->generic_type : f->field->type; + token = mono_image_get_memberref_token (assembly, &f->klass->byval_arg, + f->field->name, fieldref_encode_signature (assembly, type)); + g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token)); return token; } @@ -2142,7 +2380,7 @@ encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericMethod *gmetho /* * FIXME: vararg, explicit_this, differenc call_conv values... */ - mono_metadata_encode_value (0xa, p, &p); /// FIXME FIXME FIXME + mono_metadata_encode_value (0xa, p, &p); /* FIXME FIXME FIXME */ mono_metadata_encode_value (nparams, p, &p); for (i = 0; i < nparams; i++) @@ -2157,37 +2395,39 @@ encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericMethod *gmetho } static guint32 -method_encode_methodspec (MonoDynamicImage *assembly, MonoGenericMethod *gmethod) +method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method) { MonoDynamicTable *table; guint32 *values; guint32 token, mtoken = 0, sig; - MonoClass *k; + MonoMethodInflated *imethod; + MonoMethod *declaring; table = &assembly->tables [MONO_TABLE_METHODSPEC]; - g_assert (gmethod); - k = gmethod->klass ? gmethod->klass : gmethod->declaring->klass; + g_assert (method->signature->is_inflated); + imethod = (MonoMethodInflated *) method; + declaring = imethod->declaring; - sig = method_encode_signature (assembly, gmethod->declaring->signature); - mtoken = mono_image_get_memberref_token (assembly, &k->byval_arg, - gmethod->declaring->name, sig); + sig = method_encode_signature (assembly, declaring->signature); + mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, + declaring->name, sig); - if (!gmethod->declaring->signature->generic_param_count) + if (!declaring->signature->generic_param_count) return mtoken; switch (mono_metadata_token_table (mtoken)) { case MONO_TABLE_MEMBERREF: - mtoken = (mono_metadata_token_index (mtoken) << METHODDEFORREF_BITS) | METHODDEFORREF_METHODREF; + mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF; break; case MONO_TABLE_METHOD: - mtoken = (mono_metadata_token_index (mtoken) << METHODDEFORREF_BITS) | METHODDEFORREF_METHODDEF; + mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF; break; default: g_assert_not_reached (); } - sig = encode_generic_method_sig (assembly, gmethod); + sig = encode_generic_method_sig (assembly, imethod->context->gmethod); if (assembly->save) { alloc_table (table, table->rows + 1); @@ -2205,27 +2445,42 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoGenericMethod *gmethod static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *m) { - MonoGenericMethod *gmethod; + MonoMethodInflated *imethod; guint32 token; token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, m)); if (token) return token; - g_assert ((gmethod = m->signature->gen_method) != NULL); + g_assert (m->signature->is_inflated); + imethod = (MonoMethodInflated *) m; - if (gmethod->declaring->signature->generic_param_count) - token = method_encode_methodspec (assembly, gmethod); + if (imethod->declaring->signature->generic_param_count) + token = method_encode_methodspec (assembly, m); else { - guint32 sig = method_encode_signature (assembly, gmethod->declaring->signature); + guint32 sig = method_encode_signature ( + assembly, imethod->declaring->signature); token = mono_image_get_memberref_token ( - assembly, &gmethod->klass->byval_arg, gmethod->generic_method->name, sig); + assembly, &m->klass->byval_arg, m->name, sig); } g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER(token)); return token; } +static guint32 +mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m) +{ + MonoMethodInflated *imethod = (MonoMethodInflated *) m; + guint32 sig, token; + + sig = method_encode_signature (assembly, imethod->declaring->signature); + token = mono_image_get_memberref_token ( + assembly, &m->klass->byval_arg, m->name, sig); + + return token; +} + static guint32 create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb) { @@ -2239,6 +2494,16 @@ create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder * char *b = blob_size; int count, i; + /* + * We're creating a TypeSpec for the TypeBuilder of a generic type declaration, + * 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)); + if (token) + return token; + g_assert (tb->generic_params); klass = mono_class_from_mono_type (tb->type.type); @@ -2265,8 +2530,8 @@ create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder * values [MONO_TYPESPEC_SIGNATURE] = token; } - token = TYPEDEFORREF_TYPESPEC | (table->next_idx << TYPEDEFORREF_BITS); - g_hash_table_insert (assembly->typeref, tb->type.type, GUINT_TO_POINTER(token)); + token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS); + g_hash_table_insert (assembly->typespec, tb->type.type, GUINT_TO_POINTER(token)); table->next_idx ++; return token; } @@ -2280,30 +2545,34 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi guint32 token, pclass, parent, sig; gchar *name; + token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, fb)); + if (token) + return token; + klass = mono_class_from_mono_type (fb->typeb->type); name = mono_string_to_utf8 (fb->name); sig = fieldref_encode_signature (assembly, fb->type->type); parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb); - g_assert ((parent & TYPEDEFORREF_MASK) == TYPEDEFORREF_TYPESPEC); + g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC); - pclass = MEMBERREF_PARENT_TYPESPEC; - parent >>= TYPEDEFORREF_BITS; + pclass = MONO_MEMBERREF_PARENT_TYPESPEC; + parent >>= MONO_TYPEDEFORREF_BITS; table = &assembly->tables [MONO_TABLE_MEMBERREF]; if (assembly->save) { alloc_table (table, table->rows + 1); values = table->values + table->next_idx * MONO_MEMBERREF_SIZE; - values [MONO_MEMBERREF_CLASS] = pclass | (parent << MEMBERREF_PARENT_BITS); + values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS); values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name); values [MONO_MEMBERREF_SIGNATURE] = sig; } token = MONO_TOKEN_MEMBER_REF | table->next_idx; table->next_idx ++; - + g_hash_table_insert (assembly->handleref, fb, GUINT_TO_POINTER(token)); return token; } @@ -2417,6 +2686,7 @@ mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMetho nparams = mono_array_length (m->parameters); sig = g_malloc0 (sizeof (MonoMethodSignature) + 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; @@ -2484,7 +2754,8 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon * if we have explicitlayout or sequentiallayouts, output data in the * ClassLayout table. */ - if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) && (tb->class_size != -1)) { + if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) && + ((tb->class_size > 0) || (tb->packing_size > 0))) { table = &assembly->tables [MONO_TABLE_CLASSLAYOUT]; table->rows++; alloc_table (table, table->rows); @@ -2509,19 +2780,6 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon } } - /* handle generic parameters */ - if (tb->generic_params) { - table = &assembly->tables [MONO_TABLE_GENERICPARAM]; - table->rows += mono_array_length (tb->generic_params); - alloc_table (table, table->rows); - for (i = 0; i < mono_array_length (tb->generic_params); ++i) { - guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS); - - mono_image_get_generic_param_info ( - mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly); - } - } - /* handle fields */ if (tb->fields) { table = &assembly->tables [MONO_TABLE_FIELD]; @@ -2582,6 +2840,19 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i), assembly); } + /* handle generic parameters */ + if (tb->generic_params) { + table = &assembly->tables [MONO_TABLE_GENERICPARAM]; + table->rows += mono_array_length (tb->generic_params); + alloc_table (table, table->rows); + for (i = 0; i < mono_array_length (tb->generic_params); ++i) { + guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS); + + mono_image_get_generic_param_info ( + mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly); + } + } + mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx), tb->permissions); @@ -2649,7 +2920,7 @@ params_add_cattrs (MonoDynamicImage *assembly, MonoArray *pinfo) { pb = mono_array_get (pinfo, MonoReflectionParamBuilder *, i); if (!pb) continue; - mono_image_add_cattrs (assembly, pb->table_idx, CUSTOM_ATTR_PARAMDEF, pb->cattrs); + mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PARAMDEF, pb->cattrs); } } @@ -2657,33 +2928,33 @@ static void type_add_cattrs (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb) { int i; - mono_image_add_cattrs (assembly, tb->table_idx, CUSTOM_ATTR_TYPEDEF, tb->cattrs); + mono_image_add_cattrs (assembly, tb->table_idx, MONO_CUSTOM_ATTR_TYPEDEF, tb->cattrs); if (tb->fields) { for (i = 0; i < tb->num_fields; ++i) { MonoReflectionFieldBuilder* fb; fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i); - mono_image_add_cattrs (assembly, fb->table_idx, CUSTOM_ATTR_FIELDDEF, fb->cattrs); + mono_image_add_cattrs (assembly, fb->table_idx, MONO_CUSTOM_ATTR_FIELDDEF, fb->cattrs); } } if (tb->events) { for (i = 0; i < mono_array_length (tb->events); ++i) { MonoReflectionEventBuilder* eb; eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i); - mono_image_add_cattrs (assembly, eb->table_idx, CUSTOM_ATTR_EVENT, eb->cattrs); + mono_image_add_cattrs (assembly, eb->table_idx, MONO_CUSTOM_ATTR_EVENT, eb->cattrs); } } if (tb->properties) { for (i = 0; i < mono_array_length (tb->properties); ++i) { MonoReflectionPropertyBuilder* pb; pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i); - mono_image_add_cattrs (assembly, pb->table_idx, CUSTOM_ATTR_PROPERTY, pb->cattrs); + mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PROPERTY, pb->cattrs); } } if (tb->ctors) { for (i = 0; i < mono_array_length (tb->ctors); ++i) { MonoReflectionCtorBuilder* cb; cb = mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i); - mono_image_add_cattrs (assembly, cb->table_idx, CUSTOM_ATTR_METHODDEF, cb->cattrs); + mono_image_add_cattrs (assembly, cb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, cb->cattrs); params_add_cattrs (assembly, cb->pinfo); } } @@ -2692,7 +2963,7 @@ type_add_cattrs (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb) { for (i = 0; i < tb->num_methods; ++i) { MonoReflectionMethodBuilder* mb; mb = mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i); - mono_image_add_cattrs (assembly, mb->table_idx, CUSTOM_ATTR_METHODDEF, mb->cattrs); + mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, mb->cattrs); params_add_cattrs (assembly, mb->pinfo); } } @@ -2707,7 +2978,7 @@ static void module_add_cattrs (MonoDynamicImage *assembly, MonoReflectionModuleBuilder *mb) { int i; - mono_image_add_cattrs (assembly, mb->table_idx, CUSTOM_ATTR_MODULE, mb->cattrs); + mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_MODULE, mb->cattrs); /* no types in the module */ if (!mb->types) @@ -2793,9 +3064,9 @@ mono_image_fill_export_table_from_class (MonoDomain *domain, MonoClass *klass, values [MONO_EXP_TYPE_FLAGS] = klass->flags; values [MONO_EXP_TYPE_TYPEDEF] = klass->type_token; if (klass->nested_in) - values [MONO_EXP_TYPE_IMPLEMENTATION] = (parent_index << IMPLEMENTATION_BITS) + IMPLEMENTATION_EXP_TYPE; + values [MONO_EXP_TYPE_IMPLEMENTATION] = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE; else - values [MONO_EXP_TYPE_IMPLEMENTATION] = (module_index << IMPLEMENTATION_BITS) + IMPLEMENTATION_FILE; + values [MONO_EXP_TYPE_IMPLEMENTATION] = (module_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_FILE; 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); @@ -2903,6 +3174,30 @@ compare_nested (const void *a, const void *b) return a_values [MONO_NESTED_CLASS_NESTED] - b_values [MONO_NESTED_CLASS_NESTED]; } +static int +compare_genericparam (const void *a, const void *b) +{ + const GenericParamTableEntry **a_entry = (const GenericParamTableEntry **) a; + const GenericParamTableEntry **b_entry = (const GenericParamTableEntry **) b; + + return (*a_entry)->owner - (*b_entry)->owner; +} + +static void +pad_heap (MonoDynamicStream *sh) +{ + if (sh->index & 3) { + int sz = 4 - (sh->index & 3); + memset (sh->data + sh->index, 0, sz); + sh->index += sz; + } +} + +static struct StreamDesc { + const char *name; + MonoDynamicStream *stream; +} stream_desc [5]; + /* * build_compressed_metadata() fills in the blob of data that represents the * raw metadata as it will be saved in the PE file. The five streams are output @@ -2926,10 +3221,11 @@ build_compressed_metadata (MonoDynamicImage *assembly) MonoImage *meta; unsigned char *p; - struct StreamDesc { - const char *name; - MonoDynamicStream *stream; - } stream_desc [5]; + qsort (assembly->gen_params->pdata, assembly->gen_params->len, sizeof (gpointer), compare_genericparam); + for (i = 0; i < assembly->gen_params->len; i++){ + GenericParamTableEntry *entry = g_ptr_array_index (assembly->gen_params, i); + write_generic_param_entry (assembly, entry); + } stream_desc[0].name = "#~"; stream_desc[0].stream = &assembly->tstream; stream_desc[1].name = "#Strings"; stream_desc[1].stream = &assembly->sheap; @@ -2943,12 +3239,18 @@ build_compressed_metadata (MonoDynamicImage *assembly) | ((guint64)1 << MONO_TABLE_FIELDLAYOUT) | ((guint64)1 << MONO_TABLE_FIELDRVA) | ((guint64)1 << MONO_TABLE_IMPLMAP) | ((guint64)1 << MONO_TABLE_NESTEDCLASS) | ((guint64)1 << MONO_TABLE_METHODIMPL) | ((guint64)1 << MONO_TABLE_CUSTOMATTRIBUTE) - | ((guint64)1 << MONO_TABLE_DECLSECURITY); + | ((guint64)1 << MONO_TABLE_DECLSECURITY) | ((guint64)1 << MONO_TABLE_GENERICPARAM); /* Compute table sizes */ /* the MonoImage has already been created in mono_image_basic_init() */ meta = &assembly->image; - + + /* sizes should be multiple of 4 */ + pad_heap (&assembly->blob); + pad_heap (&assembly->guid); + pad_heap (&assembly->sheap); + pad_heap (&assembly->us); + /* Setup the info used by compute_sizes () */ meta->idx_blob_wide = assembly->blob.index >= 65536 ? 1 : 0; meta->idx_guid_wide = assembly->guid.index >= 65536 ? 1 : 0; @@ -2973,6 +3275,9 @@ build_compressed_metadata (MonoDynamicImage *assembly) } heapt_size += 24; /* #~ header size */ heapt_size += ntables * 4; + /* make multiple of 4 */ + heapt_size += 3; + heapt_size &= ~3; meta_size += heapt_size; meta->raw_metadata = g_malloc0 (meta_size); p = meta->raw_metadata; @@ -3022,8 +3327,17 @@ build_compressed_metadata (MonoDynamicImage *assembly) int32val = (guint32*)p; *int32val = GUINT32_TO_LE (0); /* reserved */ p += 4; - *p++ = 1; /* version */ - *p++ = 0; + + if ((assembly->tables [MONO_TABLE_GENERICPARAM].rows > 0) || + (assembly->tables [MONO_TABLE_METHODSPEC].rows > 0) || + (assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT].rows > 0)) { + *p++ = 1; /* version */ + *p++ = 1; + } else { + *p++ = 1; /* version */ + *p++ = 0; + } + if (meta->idx_string_wide) *p |= 0x01; if (meta->idx_guid_wide) @@ -3058,6 +3372,7 @@ build_compressed_metadata (MonoDynamicImage *assembly) if (table->rows) qsort (table->values + MONO_NESTED_CLASS_SIZE, table->rows, sizeof (guint32) * MONO_NESTED_CLASS_SIZE, compare_nested); + /* compress the tables */ for (i = 0; i < 64; i++){ int row, col; @@ -3172,7 +3487,9 @@ fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *asse continue; } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) { MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field; - g_assert (f->generic_type); + g_assert (f->generic_info); + continue; + } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) { continue; } else { g_assert_not_reached (); @@ -3216,8 +3533,8 @@ fixup_cattrs (MonoDynamicImage *assembly) values = table->values + ((i + 1) * MONO_CUSTOM_ATTR_SIZE); type = values [MONO_CUSTOM_ATTR_TYPE]; - if ((type & CUSTOM_ATTR_TYPE_MASK) == CUSTOM_ATTR_TYPE_METHODDEF) { - idx = type >> CUSTOM_ATTR_TYPE_BITS; + if ((type & MONO_CUSTOM_ATTR_TYPE_MASK) == MONO_CUSTOM_ATTR_TYPE_METHODDEF) { + idx = type >> MONO_CUSTOM_ATTR_TYPE_BITS; token = mono_metadata_make_token (MONO_TABLE_METHOD, idx); ctor = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token)); g_assert (ctor); @@ -3225,7 +3542,7 @@ fixup_cattrs (MonoDynamicImage *assembly) if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) { MonoMethod *m = ((MonoReflectionMethod*)ctor)->method; idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, m)); - values [MONO_CUSTOM_ATTR_TYPE] = (idx << CUSTOM_ATTR_TYPE_BITS) | CUSTOM_ATTR_TYPE_METHODDEF; + values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF; } } } @@ -3281,7 +3598,7 @@ assembly_add_resource (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assemb g_free (name); idx = table->next_idx++; rsrc->offset = 0; - idx = IMPLEMENTATION_FILE | (idx << IMPLEMENTATION_BITS); + idx = MONO_IMPLEMENTATION_FILE | (idx << MONO_IMPLEMENTATION_BITS); } else { char sizebuf [4]; offset = mono_array_length (rsrc->data); @@ -3431,7 +3748,7 @@ mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb) int len = mono_array_length (file_module->resources); for (j = 0; j < len; ++j) { MonoReflectionResource* res = (MonoReflectionResource*)mono_array_addr (file_module->resources, MonoReflectionResource, j); - assembly_add_resource_manifest (file_module, assembly, res, IMPLEMENTATION_FILE | (module_index << IMPLEMENTATION_BITS)); + assembly_add_resource_manifest (file_module, assembly, res, MONO_IMPLEMENTATION_FILE | (module_index << MONO_IMPLEMENTATION_BITS)); } } } @@ -3534,7 +3851,7 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb) * table->rows is already set above and in mono_image_fill_module_table. */ /* add all the custom attributes at the end, once all the indexes are stable */ - mono_image_add_cattrs (assembly, 1, CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs); + mono_image_add_cattrs (assembly, 1, MONO_CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs); module_add_cattrs (assembly, moduleb); @@ -3591,6 +3908,78 @@ mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str) return MONO_TOKEN_STRING | idx; } +guint32 +mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, + MonoArray *opt_param_types) +{ + MonoClass *klass; + guint32 token = 0; + + klass = obj->vtable->klass; + if (strcmp (klass->name, "MonoMethod") == 0) { + MonoMethod *method = ((MonoReflectionMethod *)obj)->method; + MonoMethodSignature *sig, *old; + guint32 sig_token, parent; + int nargs, i; + + g_assert (opt_param_types && (method->signature->sentinelpos >= 0)); + + nargs = mono_array_length (opt_param_types); + old = method->signature; + sig = mono_metadata_signature_alloc ( + &assembly->image, old->param_count + nargs); + + sig->hasthis = old->hasthis; + sig->explicit_this = old->explicit_this; + sig->call_convention = old->call_convention; + sig->generic_param_count = old->generic_param_count; + sig->param_count = old->param_count + nargs; + sig->sentinelpos = old->param_count; + sig->ret = old->ret; + + for (i = 0; i < old->param_count; i++) + sig->params [i] = old->params [i]; + + for (i = 0; i < nargs; i++) { + MonoReflectionType *rt = mono_array_get ( + opt_param_types, MonoReflectionType *, i); + sig->params [old->param_count + i] = rt->type; + } + + parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg); + g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF); + parent >>= MONO_TYPEDEFORREF_BITS; + + parent <<= MONO_MEMBERREF_PARENT_BITS; + parent |= MONO_MEMBERREF_PARENT_TYPEREF; + + sig_token = method_encode_signature (assembly, sig); + token = mono_image_get_varargs_method_token ( + assembly, parent, method->name, sig_token); + } else if (strcmp (klass->name, "MethodBuilder") == 0) { + MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj; + ReflectionMethodBuilder rmb; + guint32 parent, sig; + + reflection_methodbuilder_from_method_builder (&rmb, mb); + rmb.opt_types = opt_param_types; + + sig = method_builder_encode_signature (assembly, &rmb); + + parent = mono_image_create_token (assembly, obj, TRUE); + g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD); + + parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS; + parent |= MONO_MEMBERREF_PARENT_METHODDEF; + + token = mono_image_get_varargs_method_token ( + assembly, parent, mono_string_to_utf8 (rmb.name), sig); + } else + g_error ("requested method token for %s\n", klass->name); + + return token; +} + /* * mono_image_create_token: * @assembly: a dynamic assembly @@ -3608,7 +3997,8 @@ mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str) * TypeBuilder */ guint32 -mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj) +mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, + gboolean create_methodspec) { MonoClass *klass; guint32 token = 0; @@ -3646,7 +4036,12 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj) token = tb->table_idx | MONO_TOKEN_TYPE_DEF; } else if (strcmp (klass->name, "MonoType") == 0 || - strcmp (klass->name, "MonoGenericParam") == 0) { + strcmp (klass->name, "GenericTypeParameterBuilder") == 0) { + MonoReflectionType *tb = (MonoReflectionType *)obj; + token = mono_metadata_token_from_dor ( + mono_image_typedef_or_ref (assembly, tb->type)); + } + else if (strcmp (klass->name, "MonoGenericInst") == 0) { MonoReflectionType *tb = (MonoReflectionType *)obj; token = mono_metadata_token_from_dor ( mono_image_typedef_or_ref (assembly, tb->type)); @@ -3654,32 +4049,45 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj) else if (strcmp (klass->name, "MonoCMethod") == 0 || strcmp (klass->name, "MonoMethod") == 0) { MonoReflectionMethod *m = (MonoReflectionMethod *)obj; - if (m->method->signature->gen_method) { - token = mono_image_get_methodspec_token (assembly, m->method); + if (m->method->signature->is_inflated) { + if (create_methodspec) + token = mono_image_get_methodspec_token ( + assembly, m->method); + else + token = mono_image_get_inflated_method_token ( + assembly, m->method); } else if (m->method->signature->generic_param_count) { g_assert_not_reached (); } else if ((m->method->klass->image == &assembly->image) && !m->method->klass->generic_inst) { static guint32 method_table_idx = 0xffffff; - /* - * Each token should have a unique index, but the indexes are - * assigned by managed code, so we don't know about them. An - * easy solution is to count backwards... - */ - method_table_idx --; - token = MONO_TOKEN_METHOD_DEF | method_table_idx; + if (m->method->klass->wastypebuilder) { + /* we use the same token as the one that was assigned + * to the Methodbuilder. + * FIXME: do the equivalent for Fields. + */ + token = m->method->token; + } else { + /* + * Each token should have a unique index, but the indexes are + * assigned by managed code, so we don't know about them. An + * easy solution is to count backwards... + */ + method_table_idx --; + token = MONO_TOKEN_METHOD_DEF | method_table_idx; + } } else token = mono_image_get_methodref_token (assembly, m->method); /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/ } else if (strcmp (klass->name, "MonoField") == 0) { MonoReflectionField *f = (MonoReflectionField *)obj; - if ((f->klass->image == &assembly->image) && !f->field->generic_type) { + if ((f->klass->image == &assembly->image) && !f->field->generic_info) { static guint32 field_table_idx = 0xffffff; field_table_idx --; token = MONO_TOKEN_FIELD_DEF | field_table_idx; } else - token = mono_image_get_fieldref_token (assembly, f->field, f->klass); + token = mono_image_get_fieldref_token (assembly, f); /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/ } else if (strcmp (klass->name, "MonoArrayMethod") == 0) { @@ -3722,12 +4130,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, MonoDynamicImage *image; int i; - /* - * We need to use the current ms version or the ms runtime it won't find - * the support dlls. D'oh! - * const char *version = "mono-" VERSION; - */ - const char *version = "v1.0.3705"; + const char *version = mono_get_runtime_version (); #if HAVE_BOEHM_GC image = GC_MALLOC (sizeof (MonoDynamicImage)); @@ -3753,8 +4156,10 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, image->method_aux_hash = mono_g_hash_table_new (NULL, NULL); image->handleref = g_hash_table_new (NULL, NULL); image->tokens = mono_g_hash_table_new (NULL, NULL); + 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 = mono_g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal); + image->gen_params = g_ptr_array_new (); string_heap_init (&image->sheap); mono_image_add_stream_data (&image->us, "", 1); @@ -4237,23 +4642,25 @@ mono_image_create_pefile (MonoReflectionModuleBuilder *mb) { size &= ~(VIRT_ALIGN - 1); header->nt.pe_image_size = GUINT32_FROM_LE (size); - // + /* // Translate the PEFileKind value to the value expected by the Windows loader - // + */ { - short kind = assemblyb->pekind; + short kind; - // + /* + // PEFileKinds.Dll == 1 // PEFileKinds.ConsoleApplication == 2 // PEFileKinds.WindowApplication == 3 // // need to get: // IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. // IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. - if (kind == 2) - kind = 3; - else if (kind == 3) + */ + if (assemblyb->pekind == 3) kind = 2; + else + kind = 3; header->nt.pe_subsys_required = GUINT16_FROM_LE (kind); } @@ -4525,7 +4932,7 @@ mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb) * 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 = (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)); moduleb->module.image = &image->image; @@ -4608,7 +5015,7 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind res->assembly = (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly); name = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]); - // Check whenever the row has a corresponding row in the moduleref table + /* Check whenever the row has a corresponding row in the moduleref table */ table = &image->tables [MONO_TABLE_MODULEREF]; for (i = 0; i < table->rows; ++i) { name_idx = mono_metadata_decode_row_col (table, i, MONO_MODULEREF_NAME); @@ -4722,6 +5129,8 @@ mono_generic_inst_get_object (MonoDomain *domain, MonoType *geninst) ginst = geninst->data.generic_inst; gklass = mono_class_from_mono_type (ginst->generic_type); + mono_class_init (ginst->klass); + res = (MonoReflectionGenericInst *) mono_object_new (domain, System_Reflection_MonoGenericInst); res->type.type = geninst; @@ -4754,13 +5163,14 @@ mono_type_get_object (MonoDomain *domain, MonoType *type) mono_domain_unlock (domain); return res; } - if (type->type == MONO_TYPE_GENERICINST) { + if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_inst->is_dynamic) { res = (MonoReflectionType *)mono_generic_inst_get_object (domain, type); + mono_g_hash_table_insert (domain->type_hash, type, res); mono_domain_unlock (domain); return res; } if (klass->reflection_info && !klass->wastypebuilder) { - //g_assert_not_reached (); + /* g_assert_not_reached (); */ /* should this be considered an error condition? */ if (!type->byref) { mono_domain_unlock (domain); @@ -4833,7 +5243,10 @@ mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *fie res->klass = klass; res->field = field; res->name = mono_string_new (domain, field->name); - res->attrs = field->type->attrs; + if (field->generic_info) + res->attrs = field->generic_info->generic_type->attrs; + else + res->attrs = field->type->attrs; res->type = mono_type_get_object (domain, field->type); CACHE_OBJECT (field, res, klass); return res; @@ -4946,7 +5359,8 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) { memset (assembly, 0, sizeof (MonoAssemblyName)); assembly->name = p; assembly->culture = ""; - + memset (assembly->public_key_token, 0, MONO_PUBLIC_KEY_TOKEN_LENGTH); + while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@')) p++; found_sep = 0; @@ -4959,7 +5373,7 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) { if (!found_sep) return 1; while (*p) { - if (*p == 'V' && strncmp (p, "Version=", 8) == 0) { + if (*p == 'V' && g_ascii_strncasecmp (p, "Version=", 8) == 0) { p += 8; assembly->major = strtoul (p, &s, 10); if (s == p || *s != '.') @@ -4976,9 +5390,10 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) { assembly->revision = strtoul (p, &s, 10); if (s == p) return 1; - } else if (*p == 'C' && strncmp (p, "Culture=", 8) == 0) { + p = s; + } else if (*p == 'C' && g_ascii_strncasecmp (p, "Culture=", 8) == 0) { p += 8; - if (strncmp (p, "neutral", 7) == 0) { + if (g_ascii_strncasecmp (p, "neutral", 7) == 0) { assembly->culture = ""; p += 7; } else { @@ -4987,26 +5402,21 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) { p++; } } - } else if (*p == 'P' && strncmp (p, "PublicKeyToken=", 15) == 0) { + } else if (*p == 'P' && g_ascii_strncasecmp (p, "PublicKeyToken=", 15) == 0) { p += 15; - s = p; - while (*s && isxdigit (*s)) { - *s = tolower (*s); - s++; - } - assembly->hash_len = s - p; - if (!(s-p) || ((s-p) & 1)) - return 1; - assembly->hash_value = s = p; - while (*s && isxdigit (*s)) { - int val; - val = *s >= '0' && *s <= '9'? *s - '0': *s - 'a' + 10; - s++; - *p = val << 4; - *p |= *s >= '0' && *s <= '9'? *s - '0': *s - 'a' + 10; - p++; + if (strncmp (p, "null", 4) == 0) { + p += 4; + } else { + int len; + gchar *start = p; + while (*p && *p != ',') { + p++; + } + len = (p - start + 1); + if (len > MONO_PUBLIC_KEY_TOKEN_LENGTH) + len = MONO_PUBLIC_KEY_TOKEN_LENGTH; + g_strlcpy (assembly->public_key_token, start, len); } - p = s; } else { while (*p && *p != ',') p++; @@ -5237,7 +5647,7 @@ mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ig if (!mono_domain_has_type_resolve (mono_domain_get ())) return NULL; - // Reconstruct the type name + /* Reconstruct the type name */ fullName = g_string_new (""); if (info->name_space && (info->name_space [0] != '\0')) g_string_printf (fullName, "%s.%s", info->name_space, info->name); @@ -5249,9 +5659,36 @@ mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ig assembly = mono_domain_try_type_resolve ( mono_domain_get (), fullName->str, NULL); - if (assembly && (!image || (assembly->assembly->image == image))) - type = mono_reflection_get_type_internal (assembly->assembly->image, - info, ignorecase); + if (assembly && (!image || (assembly->assembly->image == image))) { + + if (assembly->assembly->dynamic) { + /* Enumerate all modules */ + MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly; + int i; + + type = NULL; + if (abuilder->modules) { + for (i = 0; i < mono_array_length (abuilder->modules); ++i) { + MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i); + type = mono_reflection_get_type_internal (&mb->dynamic_image->image, info, ignorecase); + if (type) + break; + } + } + + if (!type && abuilder->loaded_modules) { + for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) { + MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i); + type = mono_reflection_get_type_internal (mod->image, info, ignorecase); + if (type) + break; + } + } + } + else + type = mono_reflection_get_type_internal (assembly->assembly->image, + info, ignorecase); + } g_string_free (fullName, TRUE); return type; } @@ -5272,9 +5709,14 @@ mono_reflection_type_from_name (char *name, MonoImage *image) MonoType *type; MonoTypeNameParse info; MonoAssembly *assembly; + char *tmp; + + /* Make a copy since parse_type modifies its argument */ + tmp = g_strdup (name); /*g_print ("requested type %s\n", str);*/ - if (!mono_reflection_parse_type (name, &info)) { + if (!mono_reflection_parse_type (tmp, &info)) { + g_free (tmp); g_list_free (info.modifiers); g_list_free (info.nested); return NULL; @@ -5282,14 +5724,17 @@ mono_reflection_type_from_name (char *name, MonoImage *image) if (info.assembly.name) { assembly = mono_assembly_loaded (&info.assembly); - /* do we need to load if it's not already loaded? */ if (!assembly) { - g_list_free (info.modifiers); - g_list_free (info.nested); - return NULL; + /* then we must load the assembly ourselve - see #60439 */ + assembly = mono_assembly_load (&info.assembly, NULL, NULL); + if (!assembly) { + g_free (tmp); + g_list_free (info.modifiers); + g_list_free (info.nested); + return NULL; + } } - else - image = assembly->image; + image = assembly->image; } else if (image == NULL) { image = mono_defaults.corlib; } @@ -5299,7 +5744,8 @@ mono_reflection_type_from_name (char *name, MonoImage *image) image = mono_defaults.corlib; type = mono_reflection_get_type (image, &info, FALSE); } - + + g_free (tmp); g_list_free (info.modifiers); g_list_free (info.nested); return type; @@ -5478,6 +5924,7 @@ handle_type: } break; case MONO_TYPE_CLASS: + case MONO_TYPE_OBJECT: case MONO_TYPE_STRING: for (i = 0; i < alen; i++) { MonoObject *item = load_cattr_value (image, &t->data.klass->byval_arg, p, &p); @@ -5598,10 +6045,17 @@ create_custom_attr (MonoImage *image, MonoMethod *method, MonoObject *attr; void **params; + mono_class_init (method->klass); + + if (len == 0) { + attr = mono_object_new (mono_domain_get (), method->klass); + mono_runtime_invoke (method, attr, NULL, NULL); + return attr; + } + if (len < 2 || read16 (p) != 0x0001) /* Prolog */ return NULL; - mono_class_init (method->klass); /*g_print ("got attr %s\n", method->klass->name);*/ params = g_new (void*, method->signature->param_count); @@ -5633,11 +6087,11 @@ create_custom_attr (MonoImage *image, MonoMethod *method, type_name [type_len] = 0; named += type_len; /* FIXME: lookup the type and check type consistency */ + } else if (data_type == MONO_TYPE_SZARRAY && (named_type == 0x54 || named_type == 0x53)) { + /* this seems to be the type of the element of the array */ + /* g_print ("skipping 0x%02x after prop\n", *named); */ + named++; } - else - if (data_type == MONO_TYPE_SZARRAY) - /* The spec does not mention this */ - named ++; name_len = mono_metadata_decode_blob_size (named, &named); name = g_malloc (name_len + 1); memcpy (name, named, name_len); @@ -5646,9 +6100,9 @@ create_custom_attr (MonoImage *image, MonoMethod *method, if (named_type == 0x53) { MonoClassField *field = mono_class_get_field_from_name (mono_object_class (attr), name); void *val = load_cattr_value (image, field->type, named, &named); - mono_field_set_value (attr, field, val); - if (!type_is_reference (field->type)) - g_free (val); + mono_field_set_value (attr, field, val); + if (!type_is_reference (field->type)) + g_free (val); } else if (named_type == 0x54) { MonoProperty *prop; void *pparams [1]; @@ -5715,12 +6169,12 @@ mono_custom_attrs_from_index (MonoImage *image, guint32 idx) ainfo->image = image; for (i = 0, tmp = list; i < len; ++i, tmp = tmp->next) { mono_metadata_decode_row (ca, GPOINTER_TO_UINT (tmp->data), cols, MONO_CUSTOM_ATTR_SIZE); - mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> CUSTOM_ATTR_TYPE_BITS; - switch (cols [MONO_CUSTOM_ATTR_TYPE] & CUSTOM_ATTR_TYPE_MASK) { - case CUSTOM_ATTR_TYPE_METHODDEF: + mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> MONO_CUSTOM_ATTR_TYPE_BITS; + switch (cols [MONO_CUSTOM_ATTR_TYPE] & MONO_CUSTOM_ATTR_TYPE_MASK) { + case MONO_CUSTOM_ATTR_TYPE_METHODDEF: mtoken |= MONO_TOKEN_METHOD_DEF; break; - case CUSTOM_ATTR_TYPE_MEMBERREF: + case MONO_CUSTOM_ATTR_TYPE_MEMBERREF: mtoken |= MONO_TOKEN_MEMBER_REF; break; default: @@ -5748,8 +6202,8 @@ mono_custom_attrs_from_method (MonoMethod *method) if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, method))) return cinfo; idx = find_method_index (method); - idx <<= CUSTOM_ATTR_BITS; - idx |= CUSTOM_ATTR_METHODDEF; + idx <<= MONO_CUSTOM_ATTR_BITS; + idx |= MONO_CUSTOM_ATTR_METHODDEF; return mono_custom_attrs_from_index (method->klass->image, idx); } @@ -5762,8 +6216,8 @@ mono_custom_attrs_from_class (MonoClass *klass) if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, klass))) return cinfo; idx = mono_metadata_token_index (klass->type_token); - idx <<= CUSTOM_ATTR_BITS; - idx |= CUSTOM_ATTR_TYPEDEF; + idx <<= MONO_CUSTOM_ATTR_BITS; + idx |= MONO_CUSTOM_ATTR_TYPEDEF; return mono_custom_attrs_from_index (klass->image, idx); } @@ -5776,8 +6230,8 @@ mono_custom_attrs_from_assembly (MonoAssembly *assembly) if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, assembly))) return cinfo; idx = 1; /* there is only one assembly */ - idx <<= CUSTOM_ATTR_BITS; - idx |= CUSTOM_ATTR_ASSEMBLY; + idx <<= MONO_CUSTOM_ATTR_BITS; + idx |= MONO_CUSTOM_ATTR_ASSEMBLY; return mono_custom_attrs_from_index (assembly->image, idx); } @@ -5790,8 +6244,8 @@ mono_custom_attrs_from_module (MonoImage *image) if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, image))) return cinfo; idx = 1; /* there is only one module */ - idx <<= CUSTOM_ATTR_BITS; - idx |= CUSTOM_ATTR_MODULE; + idx <<= MONO_CUSTOM_ATTR_BITS; + idx |= MONO_CUSTOM_ATTR_MODULE; return mono_custom_attrs_from_index (image, idx); } @@ -5804,8 +6258,8 @@ mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property) if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, property))) return cinfo; idx = find_property_index (klass, property); - idx <<= CUSTOM_ATTR_BITS; - idx |= CUSTOM_ATTR_PROPERTY; + idx <<= MONO_CUSTOM_ATTR_BITS; + idx |= MONO_CUSTOM_ATTR_PROPERTY; return mono_custom_attrs_from_index (klass->image, idx); } @@ -5818,8 +6272,8 @@ mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event) if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, event))) return cinfo; idx = find_event_index (klass, event); - idx <<= CUSTOM_ATTR_BITS; - idx |= CUSTOM_ATTR_EVENT; + idx <<= MONO_CUSTOM_ATTR_BITS; + idx |= MONO_CUSTOM_ATTR_EVENT; return mono_custom_attrs_from_index (klass->image, idx); } @@ -5832,8 +6286,8 @@ mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field) if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, field))) return cinfo; idx = find_field_index (klass, field); - idx <<= CUSTOM_ATTR_BITS; - idx |= CUSTOM_ATTR_FIELDDEF; + idx <<= MONO_CUSTOM_ATTR_BITS; + idx |= MONO_CUSTOM_ATTR_FIELDDEF; return mono_custom_attrs_from_index (klass->image, idx); } @@ -5859,7 +6313,7 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param) if (method->klass->generic_inst || method->klass->gen_params || method->signature->generic_param_count) { - // FIXME FIXME FIXME + /* FIXME FIXME FIXME */ return NULL; } @@ -5882,8 +6336,8 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param) if (!found) return NULL; idx = i; - idx <<= CUSTOM_ATTR_BITS; - idx |= CUSTOM_ATTR_PARAMDEF; + idx <<= MONO_CUSTOM_ATTR_BITS; + idx |= MONO_CUSTOM_ATTR_PARAMDEF; return mono_custom_attrs_from_index (image, idx); } @@ -5917,13 +6371,13 @@ mono_reflection_get_custom_attrs (MonoObject *obj) cinfo = mono_custom_attrs_from_module (module->image); } else if (strcmp ("MonoProperty", klass->name) == 0) { MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj; - cinfo = mono_custom_attrs_from_property (rprop->klass, rprop->property); + cinfo = mono_custom_attrs_from_property (rprop->property->parent, rprop->property); } else if (strcmp ("MonoEvent", klass->name) == 0) { MonoReflectionEvent *revent = (MonoReflectionEvent*)obj; - cinfo = mono_custom_attrs_from_event (revent->klass, revent->event); + cinfo = mono_custom_attrs_from_event (revent->event->parent, revent->event); } else if (strcmp ("MonoField", klass->name) == 0) { MonoReflectionField *rfield = (MonoReflectionField*)obj; - cinfo = mono_custom_attrs_from_field (rfield->klass, rfield->field); + cinfo = mono_custom_attrs_from_field (rfield->field->parent, rfield->field); } else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) { MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj; cinfo = mono_custom_attrs_from_method (rmethod->method); @@ -5943,6 +6397,8 @@ mono_reflection_get_custom_attrs (MonoObject *obj) if (cinfo) { result = mono_custom_attrs_construct (cinfo); + if (!cinfo->cached) + mono_custom_attrs_free (cinfo); } else { klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute"); result = mono_array_new (mono_domain_get (), klass, 0); @@ -6033,10 +6489,21 @@ get_field_name_and_type (MonoObject *field, char **name, MonoType **type) } } +/* + * Encode a value in a custom attribute stream of bytes. + * The value to encode is either supplied as an object in argument val + * (valuetypes are boxed), or as a pointer to the data in the + * argument argval. + * @type represents the type of the value + * @buffer is the start of the buffer + * @p the current position in the buffer + * @buflen contains the size of the buffer and is used to return the new buffer size + * if this needs to be realloced. + * @retbuffer and @retp return the start and the position of the buffer + */ static void -encode_cattr_value (char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg) +encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval) { - char *argval; MonoTypeEnum simple_type; if ((p-buffer) + 10 >= *buflen) { @@ -6046,7 +6513,8 @@ encode_cattr_value (char *buffer, char *p, char **retbuffer, char **retp, guint3 p = newbuf + (p-buffer); buffer = newbuf; } - argval = ((char*)arg + sizeof (MonoObject)); + if (!argval) + argval = ((char*)arg + sizeof (MonoObject)); simple_type = type->type; handle_enum: switch (simple_type) { @@ -6135,7 +6603,7 @@ handle_type: } case MONO_TYPE_SZARRAY: { int len, i; - MonoClass *eclass; + MonoClass *eclass, *arg_eclass; if (!arg) { *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; @@ -6149,8 +6617,18 @@ handle_type: *retp = p; *retbuffer = buffer; eclass = type->data.klass; - for (i = 0; i < len; ++i) { - encode_cattr_value (buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i)); + arg_eclass = mono_object_class (arg)->element_class; + if (eclass->valuetype && arg_eclass->valuetype) { + char *elptr = mono_array_addr ((MonoArray*)arg, char, 0); + int elsize = mono_class_array_element_size (eclass); + for (i = 0; i < len; ++i) { + encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr); + elptr += elsize; + } + } else { + for (i = 0; i < len; ++i) { + encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL); + } } break; } @@ -6213,7 +6691,7 @@ handle_type: * Returns: a Byte array representing the blob of data. */ MonoArray* -mono_reflection_get_custom_attrs_blob (MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) +mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) { MonoArray *result; MonoMethodSignature *sig; @@ -6236,7 +6714,7 @@ mono_reflection_get_custom_attrs_blob (MonoObject *ctor, MonoArray *ctorArgs, Mo *p++ = 0; for (i = 0; i < sig->param_count; ++i) { arg = mono_array_get (ctorArgs, MonoObject*, i); - encode_cattr_value (buffer, p, &buffer, &p, &buflen, sig->params [i], arg); + encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL); } i = 0; if (properties) @@ -6297,7 +6775,7 @@ mono_reflection_get_custom_attrs_blob (MonoObject *ctor, MonoArray *ctorArgs, Mo mono_metadata_encode_value (len, p, &p); memcpy (p, pname, len); p += len; - encode_cattr_value (buffer, p, &buffer, &p, &buflen, ptype, (MonoObject*)mono_array_get (propValues, gpointer, i)); + encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, ptype, (MonoObject*)mono_array_get (propValues, gpointer, i), NULL); g_free (pname); } } @@ -6334,12 +6812,14 @@ mono_reflection_get_custom_attrs_blob (MonoObject *ctor, MonoArray *ctorArgs, Mo g_free (str); } else { mono_metadata_encode_value (ftype->type, p, &p); + if (ftype->type == MONO_TYPE_SZARRAY) + mono_metadata_encode_value (ftype->data.klass->this_arg.type, p, &p); } len = strlen (fname); mono_metadata_encode_value (len, p, &p); memcpy (p, fname, len); p += len; - encode_cattr_value (buffer, p, &buffer, &p, &buflen, ftype, (MonoObject*)mono_array_get (fieldValues, gpointer, i)); + encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, ftype, (MonoObject*)mono_array_get (fieldValues, gpointer, i), NULL); g_free (fname); } } @@ -6370,10 +6850,6 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb) MONO_ARCH_SAVE_REGS; - klass = g_new0 (MonoClass, 1); - - klass->image = &tb->module->dynamic_image->image; - if (tb->parent) { /* check so we can compile corlib correctly */ if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) { @@ -6384,6 +6860,22 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb) } else parent = NULL; + /* the type has already being created: it means we just have to change the parent */ + if (tb->type.type) { + klass = mono_class_from_mono_type (tb->type.type); + klass->parent = NULL; + /* fool mono_class_setup_parent */ + g_free (klass->supertypes); + klass->supertypes = NULL; + mono_class_setup_parent (klass, parent); + mono_class_setup_mono_type (klass); + return; + } + + klass = g_new0 (MonoClass, 1); + + klass->image = &tb->module->dynamic_image->image; + klass->inited = 1; /* we lie to the runtime */ klass->name = mono_string_to_utf8 (tb->name); klass->name_space = mono_string_to_utf8 (tb->nspace); @@ -6456,8 +6948,6 @@ mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb) MonoReflectionGenericParam *gparam = mono_array_get (tb->generic_params, gpointer, i); klass->gen_params [i] = *gparam->type.type->data.generic_param; } - - ensure_runtime_vtable (klass); } /* @@ -6630,19 +7120,19 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, num_clauses); } - if (rmb->generic_params) { - int count = mono_array_length (rmb->generic_params); - header->gen_params = g_new0 (MonoGenericParam, count); - for (i = 0; i < count; i++) { - MonoReflectionGenericParam *gp = - mono_array_get (rmb->generic_params, - MonoReflectionGenericParam*, i); + pm->header = header; + } + + if (rmb->generic_params) { + int count = mono_array_length (rmb->generic_params); + pm->gen_params = g_new0 (MonoGenericParam, count); + for (i = 0; i < count; i++) { + MonoReflectionGenericParam *gp = + mono_array_get (rmb->generic_params, + MonoReflectionGenericParam*, i); - header->gen_params [i] = *gp->type.type->data.generic_param; - } + pm->gen_params [i] = *gp->type.type->data.generic_param; } - - pm->header = header; } if (rmb->refs) { @@ -6774,48 +7264,47 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* if (fb->def_value) { MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image; field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT; - field->def_value = g_new0 (MonoConstant, 1); - idx = encode_constant (assembly, fb->def_value, &field->def_value->type); + idx = encode_constant (assembly, fb->def_value, &field->def_type); /* Copy the data from the blob since it might get realloc-ed */ p = assembly->blob.data + idx; len = mono_metadata_decode_blob_size (p, &p2); len += p2 - p; - field->def_value->value = g_malloc (len); - memcpy (field->def_value->value, p, len); + field->data = g_malloc (len); + memcpy (field->data, p, len); } return field; } -MonoType* -mono_reflection_bind_generic_parameters (MonoType *type, MonoArray *types) +static MonoType* +do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, + MonoType **types) { - MonoClass *klass, *pklass = NULL; + MonoClass *klass; MonoReflectionTypeBuilder *tb = NULL; - MonoGenericInst *ginst; - MonoType *geninst, *parent = NULL; - int i; + MonoGenericInst *ginst, *cached; + MonoDomain *domain; + MonoType *geninst; + int icount, i; - klass = mono_class_from_mono_type (type); - if (!klass->gen_params && !klass->generic_inst) + klass = mono_class_from_mono_type (type->type); + if (!klass->gen_params && !klass->generic_inst && + !(klass->nested_in && klass->nested_in->gen_params)) return NULL; mono_loader_lock (); + domain = mono_object_domain (type); + ginst = g_new0 (MonoGenericInst, 1); - ginst->is_dynamic = 1; - if (klass->gen_params) { - ginst->type_argc = mono_array_length (types); - ginst->type_argv = g_new0 (MonoType *, ginst->type_argc); + if (!klass->generic_inst) { + ginst->type_argc = type_argc; + ginst->type_argv = types; for (i = 0; i < ginst->type_argc; ++i) { - MonoReflectionType *garg = mono_array_get (types, gpointer, i); - - ginst->type_argv [i] = garg->type; - if (!ginst->is_open) - ginst->is_open = mono_class_is_open_constructed_type (garg->type); + ginst->is_open = mono_class_is_open_constructed_type (types [i]); } ginst->generic_type = &klass->byval_arg; @@ -6828,12 +7317,8 @@ mono_reflection_bind_generic_parameters (MonoType *type, MonoArray *types) for (i = 0; i < ginst->type_argc; i++) { MonoType *t = kginst->type_argv [i]; - if (t->type == MONO_TYPE_VAR) { - int num = t->data.generic_param->num; - MonoReflectionType *garg = mono_array_get (types, gpointer, num); - - t = garg->type; - } + if (t->type == MONO_TYPE_VAR) + t = types [t->data.generic_param->num]; if (!ginst->is_open) ginst->is_open = mono_class_is_open_constructed_type (t); @@ -6844,71 +7329,108 @@ mono_reflection_bind_generic_parameters (MonoType *type, MonoArray *types) ginst->generic_type = kginst->generic_type; } - geninst = g_hash_table_lookup (klass->image->generic_inst_cache, ginst); - if (geninst) { - g_free (ginst->type_argv); + geninst = g_new0 (MonoType, 1); + geninst->type = MONO_TYPE_GENERICINST; + + cached = g_hash_table_lookup (klass->image->generic_inst_cache, ginst); + if (cached) { g_free (ginst); mono_loader_unlock (); + geninst->data.generic_inst = cached; return geninst; } - if (klass->wastypebuilder && klass->reflection_info) { - tb = klass->reflection_info; + geninst->data.generic_inst = ginst; - if (tb->parent) { - parent = tb->parent->type; - pklass = mono_class_from_mono_type (parent); - } - } else { - pklass = klass->parent; - if (pklass) - parent = &pklass->byval_arg; - } + ginst->context = g_new0 (MonoGenericContext, 1); + ginst->context->ginst = ginst; - geninst = g_new0 (MonoType, 1); - geninst->type = MONO_TYPE_GENERICINST; - geninst->data.generic_inst = ginst; + if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) { + tb = (MonoReflectionTypeBuilder *) type; - if (pklass && pklass->generic_inst) - parent = mono_reflection_bind_generic_parameters (parent, types); - else if (!pklass) { - int icount; + icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0; + ginst->is_dynamic = TRUE; + } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericInst")) { + MonoReflectionGenericInst *rgi = (MonoReflectionGenericInst *) type; + MonoReflectionType *rgt = rgi->generic_type; - pklass = mono_defaults.object_class; + g_assert (!strcmp (((MonoObject *) rgt)->vtable->klass->name, "TypeBuilder")); + tb = (MonoReflectionTypeBuilder *) rgt; + icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0; + ginst->is_dynamic = TRUE; + } else icount = klass->interface_count; - ginst->ifaces = g_new0 (MonoType *, icount); - for (i = 0; i < icount; i++) { - MonoType *itype; + ginst->ifaces = g_new0 (MonoType *, icount); + ginst->count_ifaces = icount; - if (tb) - itype = mono_array_get (tb->interfaces, MonoReflectionType *, i)->type; - else - itype = &klass->interfaces [i]->byval_arg; - ginst->ifaces [i] = mono_reflection_bind_generic_parameters (itype, types); - if (!ginst->ifaces [i]) - ginst->ifaces [i] = itype; - } - } + for (i = 0; i < icount; i++) { + MonoReflectionType *itype; - ginst->parent = parent; + if (tb) + itype = mono_array_get (tb->interfaces, MonoReflectionType *, i); + else + itype = mono_type_get_object (domain, &klass->interfaces [i]->byval_arg); + ginst->ifaces [i] = mono_reflection_bind_generic_parameters (itype, type_argc, types); + if (!ginst->ifaces [i]) + ginst->ifaces [i] = itype->type; + } mono_class_create_generic (ginst); - g_hash_table_insert (klass->image->generic_inst_cache, ginst, geninst); + g_hash_table_insert (klass->image->generic_inst_cache, ginst, ginst); mono_loader_unlock (); return geninst; } +MonoType* +mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types) +{ + MonoClass *klass, *pklass = NULL; + MonoReflectionType *parent = NULL; + MonoType *geninst; + MonoReflectionTypeBuilder *tb = NULL; + MonoGenericInst *ginst; + MonoDomain *domain; + + domain = mono_object_domain (type); + klass = mono_class_from_mono_type (type->type); + + if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) { + tb = (MonoReflectionTypeBuilder *) type; + + if (tb->parent) { + parent = tb->parent; + pklass = mono_class_from_mono_type (parent->type); + } + } else { + pklass = klass->parent; + if (pklass) + parent = mono_type_get_object (domain, &pklass->byval_arg); + } + + geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types); + if (!geninst) + return NULL; + + ginst = geninst->data.generic_inst; + + if (pklass && pklass->generic_inst) + ginst->parent = mono_reflection_bind_generic_parameters (parent, type_argc, types); + + return geninst; +} + MonoReflectionMethod* mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types) { - MonoMethod *method, *inflated, *declaring; + MonoMethod *method, *inflated; MonoReflectionMethodBuilder *mb = NULL; MonoGenericMethod *gmethod; + MonoGenericContext *context; int count, i; MONO_ARCH_SAVE_REGS; @@ -6920,16 +7442,15 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M tb = (MonoReflectionTypeBuilder *) mb->type; klass = mono_class_from_mono_type (tb->type.type); - method = declaring = methodbuilder_to_mono_method (klass, mb); + method = methodbuilder_to_mono_method (klass, mb); } else - method = declaring = rmethod->method; + method = rmethod->method; count = method->signature->generic_param_count; if (count != mono_array_length (types)) return NULL; gmethod = g_new0 (MonoGenericMethod, 1); - gmethod->generic_method = method; gmethod->mtype_argc = count; gmethod->mtype_argv = g_new0 (MonoType *, count); for (i = 0; i < count; i++) { @@ -6937,31 +7458,47 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M gmethod->mtype_argv [i] = garg->type; } - gmethod->generic_inst = method->klass->generic_inst; - gmethod->declaring = declaring; - gmethod->klass = method->klass; + gmethod->reflection_info = rmethod; - inflated = mono_class_inflate_generic_method (method, gmethod); + context = g_new0 (MonoGenericContext, 1); + context->ginst = method->klass->generic_inst; + context->gmethod = gmethod; + + inflated = mono_class_inflate_generic_method (method, context, NULL); return mono_method_get_object ( mono_object_domain (rmethod), inflated, NULL); } static MonoMethod * -inflate_mono_method (MonoReflectionGenericInst *type, MonoMethod *method) +inflate_mono_method (MonoReflectionGenericInst *type, MonoMethod *method, MonoObject *obj) { MonoGenericMethod *gmethod; MonoGenericInst *ginst; + MonoGenericContext *context; + int i; ginst = type->type.type->data.generic_inst; gmethod = g_new0 (MonoGenericMethod, 1); - gmethod->generic_method = method; - gmethod->generic_inst = ginst; - gmethod->klass = ginst->klass; - gmethod->declaring = method; + gmethod->reflection_info = obj; + + gmethod->mtype_argc = method->signature->generic_param_count; + gmethod->mtype_argv = g_new0 (MonoType *, gmethod->mtype_argc); - return mono_class_inflate_generic_method (method, gmethod); + for (i = 0; i < gmethod->mtype_argc; i++) { + MonoMethodNormal *mn = (MonoMethodNormal *) method; + MonoGenericParam *gparam = &mn->gen_params [i]; + + g_assert (gparam->pklass); + gmethod->mtype_argv [i] = &gparam->pklass->byval_arg; + } + + context = g_new0 (MonoGenericContext, 1); + context->ginst = ginst; + context->gmethod = gmethod; + + return mono_class_inflate_generic_method (method, context, ginst->klass); } static MonoMethod * @@ -6979,16 +7516,19 @@ inflate_method (MonoReflectionGenericInst *type, MonoObject *obj) else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod")) method = ((MonoReflectionMethod *) obj)->method; - else + else { + method = NULL; /* prevent compiler warning */ g_assert_not_reached (); + } - return inflate_mono_method (type, method); + return inflate_mono_method (type, method, obj); } void mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type, MonoArray *methods, MonoArray *ctors, - MonoArray *fields, MonoArray *properties) + MonoArray *fields, MonoArray *properties, + MonoArray *events) { MonoGenericInst *ginst; MonoDynamicGenericInst *dginst; @@ -7019,11 +7559,13 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type, dginst->count_ctors = ctors ? mono_array_length (ctors) : 0; dginst->count_fields = fields ? mono_array_length (fields) : 0; dginst->count_properties = properties ? mono_array_length (properties) : 0; + dginst->count_events = events ? mono_array_length (events) : 0; dginst->methods = g_new0 (MonoMethod *, dginst->count_methods); dginst->ctors = g_new0 (MonoMethod *, dginst->count_ctors); dginst->fields = g_new0 (MonoClassField, dginst->count_fields); dginst->properties = g_new0 (MonoProperty, dginst->count_properties); + dginst->events = g_new0 (MonoEvent, dginst->count_events); for (i = 0; i < dginst->count_methods; i++) { MonoObject *obj = mono_array_get (methods, gpointer, i); @@ -7040,17 +7582,24 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type, for (i = 0; i < dginst->count_fields; i++) { MonoObject *obj = mono_array_get (fields, gpointer, i); MonoClassField *field; + MonoInflatedField *ifield; if (!strcmp (obj->vtable->klass->name, "FieldBuilder")) field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj); else if (!strcmp (obj->vtable->klass->name, "MonoField")) field = ((MonoReflectionField *) obj)->field; - else + else { + field = NULL; /* prevent compiler warning */ g_assert_not_reached (); + } + + ifield = g_new0 (MonoInflatedField, 1); + ifield->generic_type = field->type; + ifield->reflection_info = obj; dginst->fields [i] = *field; - dginst->fields [i].generic_type = field->type; - dginst->fields [i].type = mono_class_inflate_generic_type (field->type, ginst, NULL); + dginst->fields [i].generic_info = ifield; + dginst->fields [i].type = mono_class_inflate_generic_type (field->type, ginst->context); } for (i = 0; i < dginst->count_properties; i++) { @@ -7060,6 +7609,7 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type, 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) @@ -7070,9 +7620,34 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type, *property = *((MonoReflectionProperty *) obj)->property; if (property->get) - property->get = inflate_mono_method (type, property->get); + property->get = inflate_mono_method (type, property->get, NULL); if (property->set) - property->set = inflate_mono_method (type, property->set); + property->set = inflate_mono_method (type, property->set, NULL); + } else + g_assert_not_reached (); + } + + for (i = 0; i < dginst->count_events; i++) { + MonoObject *obj = mono_array_get (events, gpointer, i); + MonoEvent *event = &dginst->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 = *((MonoReflectionEvent *) obj)->event; + + if (event->add) + event->add = inflate_mono_method (type, event->add, NULL); + if (event->remove) + event->remove = inflate_mono_method (type, event->remove, NULL); } else g_assert_not_reached (); } @@ -7194,14 +7769,13 @@ typebuilder_setup_fields (MonoClass *klass) if (fb->def_value) { MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image; field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT; - field->def_value = g_new0 (MonoConstant, 1); - idx = encode_constant (assembly, fb->def_value, &field->def_value->type); + idx = encode_constant (assembly, fb->def_value, &field->def_type); /* Copy the data from the blob since it might get realloc-ed */ p = assembly->blob.data + idx; len = mono_metadata_decode_blob_size (p, &p2); len += p2 - p; - field->def_value->value = g_malloc (len); - memcpy (field->def_value->value, p, len); + field->data = g_malloc (len); + memcpy (field->data, p, len); } } mono_class_layout_fields (klass); @@ -7221,6 +7795,7 @@ typebuilder_setup_properties (MonoClass *klass) klass->properties = g_new0 (MonoProperty, klass->property.count); for (i = 0; i < klass->property.count; ++i) { pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i); + klass->properties [i].parent = klass; klass->properties [i].attrs = pb->attrs; klass->properties [i].name = mono_string_to_utf8 (pb->name); if (pb->get_method) @@ -7230,6 +7805,38 @@ typebuilder_setup_properties (MonoClass *klass) } } +MonoReflectionEvent * +mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb) +{ + MonoEvent *event = g_new0 (MonoEvent, 1); + MonoClass *klass; + int j; + + klass = my_mono_class_from_mono_type (tb->type.type); + + event->parent = klass; + event->attrs = eb->attrs; + event->name = mono_string_to_utf8 (eb->name); + if (eb->add_method) + event->add = eb->add_method->mhandle; + if (eb->remove_method) + event->remove = eb->remove_method->mhandle; + if (eb->raise_method) + event->raise = eb->raise_method->mhandle; + + if (eb->other_methods) { + event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods)); + for (j = 0; j < mono_array_length (eb->other_methods); ++j) { + MonoReflectionMethodBuilder *mb = + mono_array_get (eb->other_methods, + MonoReflectionMethodBuilder*, j); + event->other [j] = mb->mhandle; + } + } + + return mono_event_get_object (mono_object_domain (tb), klass, event); +} + static void typebuilder_setup_events (MonoClass *klass) { @@ -7244,6 +7851,7 @@ typebuilder_setup_events (MonoClass *klass) klass->events = g_new0 (MonoEvent, klass->event.count); for (i = 0; i < klass->event.count; ++i) { eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i); + klass->events [i].parent = klass; klass->events [i].attrs = eb->attrs; klass->events [i].name = mono_string_to_utf8 (eb->name); if (eb->add_method) @@ -7318,74 +7926,29 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb) return res; } -MonoReflectionGenericParam * -mono_reflection_define_generic_parameter (MonoReflectionTypeBuilder *tb, MonoReflectionMethodBuilder *mb, MonoString *name, guint32 index) -{ - static MonoClass *System_Reflection_MonoGenericParam; - MonoImage *image; - MonoGenericParam *param; - MonoReflectionGenericParam *res; - MonoDomain *domain; - - if (!System_Reflection_MonoGenericParam) { - System_Reflection_MonoGenericParam = mono_class_from_name ( - mono_defaults.corlib, "System.Reflection", "MonoGenericParam"); - g_assert (System_Reflection_MonoGenericParam); - } - - param = g_new0 (MonoGenericParam, 1); - - if (mb) - tb = (MonoReflectionTypeBuilder *) mb->type; - - domain = mono_object_domain (tb); - image = (MonoImage*)tb->module->dynamic_image; - - param->method = NULL; - param->name = mono_string_to_utf8 (name); - param->num = index; - - res = (MonoReflectionGenericParam *)mono_object_new (domain, System_Reflection_MonoGenericParam); - res->type.type = g_new0 (MonoType, 1); - res->type.type->type = mb ? MONO_TYPE_MVAR : MONO_TYPE_VAR; - res->type.type->data.generic_param = param; - - res->refobj = mb ? (MonoObject *) mb : (MonoObject *) tb; - res->index = index; - res->name = name; - - return res; -} - void mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam) { MonoGenericParam *param; - MonoReflectionMethodBuilder *mb = NULL; - MonoReflectionTypeBuilder *tb; MonoImage *image; - int count, i; - param = gparam->type.type->data.generic_param; - count = gparam->constraints ? mono_array_length (gparam->constraints) : 0; - param->constraints = g_new0 (MonoClass *, count + 1); - for (i = 0; i < count; i++) { - MonoReflectionType *constraint = mono_array_get (gparam->constraints, MonoReflectionType *, i); + MONO_ARCH_SAVE_REGS; - param->constraints [i] = mono_class_from_mono_type (constraint->type); - } + param = g_new0 (MonoGenericParam, 1); - if (!strcmp (gparam->refobj->vtable->klass->name, "MethodBuilder")) { - mb = (MonoReflectionMethodBuilder *) gparam->refobj; - tb = (MonoReflectionTypeBuilder *) mb->type; - } else - tb = (MonoReflectionTypeBuilder *) gparam->refobj; + param->method = NULL; + param->name = mono_string_to_utf8 (gparam->name); + param->num = gparam->index; - image = (MonoImage*)tb->module->dynamic_image; + image = &gparam->tbuilder->module->dynamic_image->image; + mono_class_from_generic_parameter (param, image, gparam->mbuilder != NULL); - param->pklass = mono_class_from_generic_parameter (param, image, mb != NULL); + param->pklass->reflection_info = gparam; - gparam->initialized = TRUE; + gparam->type.type = g_new0 (MonoType, 1); + gparam->type.type->type = gparam->mbuilder ? MONO_TYPE_MVAR : MONO_TYPE_VAR; + gparam->type.type->attrs = TYPE_ATTRIBUTE_PUBLIC; + gparam->type.type->data.generic_param = param; } MonoArray *