X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Freflection.c;h=3238759cad6d046d8527745af7f117bfb758bc27;hb=9c6da612c7e9aab5a4e8f0b2baf57bae58d5546c;hp=aafd0235a3726851c7ec50a1f2c73c071219e873;hpb=60af003048beac4eaeeccb54457bf2fa9eb97f94;p=mono.git diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index aafd0235a37..3238759cad6 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; @@ -134,6 +138,7 @@ 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); @@ -618,6 +623,8 @@ method_get_signature_size (MonoMethodSignature *sig) if (sig->generic_param_count) size += 4; + if (sig->sentinelpos >= 0) + size++; return size; } @@ -651,8 +658,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); @@ -672,7 +682,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; @@ -689,7 +700,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) { @@ -705,6 +716,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); @@ -739,7 +759,7 @@ encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen) for (i = 0; i < nl; ++i) { MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i); - if (lb->type->type->pinned) + if (lb->is_pinned) mono_metadata_encode_value (MONO_TYPE_PINNED, p, &p); encode_reflection_type (assembly, lb->type, p, &p); @@ -1021,6 +1041,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 @@ -1034,7 +1055,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) @@ -1054,20 +1075,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); 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"); @@ -1106,16 +1127,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 (); @@ -1185,18 +1206,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; + } } } } @@ -1210,6 +1242,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; @@ -1239,6 +1272,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; @@ -1266,6 +1300,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; @@ -1333,14 +1368,14 @@ 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); + values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS); tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method); 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 (); @@ -1382,11 +1417,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] ? ta->aname.public_key_token : "null"); g_free (name); return result; } @@ -1551,7 +1586,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) { @@ -1658,7 +1702,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; @@ -1684,7 +1728,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); } } @@ -1769,14 +1813,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; } } @@ -1821,21 +1865,21 @@ 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; } } @@ -1877,20 +1921,20 @@ encode_new_constraint (MonoDynamicImage *assembly, guint32 owner) alloc_table (table, table->rows); values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE; - owner <<= CUSTOM_ATTR_BITS; - owner |= CUSTOM_ATTR_GENERICPAR; + 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 <<= 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"); @@ -1917,18 +1961,32 @@ 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) @@ -1950,14 +2008,17 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o param = gparam->type.type->data.generic_param; values [MONO_GENERICPARAM_OWNER] = owner; - values [MONO_GENERICPARAM_FLAGS] = param->flags; + if (gparam->has_value_type) + values [MONO_GENERICPARAM_FLAGS] = 0x18; + else if (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 (gparam, table_idx, assembly); } static guint32 @@ -1981,8 +2042,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; @@ -2002,10 +2063,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]; @@ -2014,63 +2072,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; } @@ -2118,7 +2134,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; @@ -2151,7 +2167,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; } @@ -2159,8 +2175,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); } @@ -2172,7 +2188,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); @@ -2194,29 +2210,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; } @@ -2241,6 +2257,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 parent, 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) { @@ -2289,7 +2329,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField * if (token) return token; g_assert (f->field->parent); - type = f->field->generic_type ? f->field->generic_type : f->field->type; + 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)); @@ -2315,7 +2355,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++) @@ -2353,10 +2393,10 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method) 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 (); @@ -2416,6 +2456,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); @@ -2442,8 +2492,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; } @@ -2457,30 +2507,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; } @@ -2594,6 +2648,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; @@ -2826,7 +2881,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); } } @@ -2834,33 +2889,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); } } @@ -2869,7 +2924,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); } } @@ -2884,7 +2939,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) @@ -2970,9 +3025,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); @@ -3080,6 +3135,16 @@ compare_nested (const void *a, const void *b) return a_values [MONO_NESTED_CLASS_NESTED] - b_values [MONO_NESTED_CLASS_NESTED]; } +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; + } +} + /* * 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 @@ -3125,7 +3190,13 @@ build_compressed_metadata (MonoDynamicImage *assembly) /* 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; @@ -3150,6 +3221,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; @@ -3199,8 +3273,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) @@ -3349,7 +3432,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 (); @@ -3393,8 +3478,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); @@ -3402,7 +3487,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; } } } @@ -3458,7 +3543,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); @@ -3608,7 +3693,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)); } } } @@ -3711,7 +3796,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); @@ -3768,6 +3853,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); + 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 @@ -3823,7 +3980,7 @@ 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)); @@ -3843,20 +4000,28 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj) } 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; @@ -3909,7 +4074,11 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, * the support dlls. D'oh! * const char *version = "mono-" VERSION; */ - const char *version = "v1.0.3705"; + /* + * To make binaries default to the .Net 1.0 version + * const char *version = "v1.0.3705"; + */ + const char *version = "v1.1.4322"; #if HAVE_BOEHM_GC image = GC_MALLOC (sizeof (MonoDynamicImage)); @@ -3935,6 +4104,7 @@ 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); @@ -4419,23 +4589,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); } @@ -4707,7 +4879,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; @@ -4790,7 +4962,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); @@ -4945,7 +5117,7 @@ mono_type_get_object (MonoDomain *domain, MonoType *type) 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); @@ -5018,7 +5190,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; @@ -5131,7 +5306,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; @@ -5144,7 +5320,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 != '.') @@ -5161,9 +5337,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 { @@ -5172,26 +5349,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++; @@ -5422,7 +5594,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); @@ -5434,9 +5606,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; } @@ -5457,9 +5656,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; @@ -5467,14 +5671,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; } @@ -5484,7 +5691,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; @@ -5825,11 +6033,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); @@ -5838,9 +6046,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]; @@ -5907,12 +6115,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: @@ -5940,8 +6148,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); } @@ -5954,8 +6162,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); } @@ -5968,8 +6176,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); } @@ -5982,8 +6190,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); } @@ -5996,8 +6204,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); } @@ -6010,8 +6218,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); } @@ -6024,8 +6232,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); } @@ -6051,7 +6259,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; } @@ -6074,8 +6282,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); } @@ -6135,6 +6343,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); @@ -6225,10 +6435,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) { @@ -6238,7 +6459,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) { @@ -6327,7 +6549,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; @@ -6341,8 +6563,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; } @@ -6405,7 +6637,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; @@ -6428,7 +6660,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) @@ -6489,7 +6721,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); } } @@ -6526,12 +6758,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); } } @@ -6562,10 +6796,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) { @@ -6576,6 +6806,21 @@ 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); + 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); @@ -6964,14 +7209,13 @@ 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; @@ -6979,7 +7223,7 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* static MonoType* do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, - MonoType **types, MonoType *nested_in) + MonoType **types) { MonoClass *klass; MonoReflectionTypeBuilder *tb = NULL; @@ -7076,8 +7320,6 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a ginst->ifaces [i] = itype->type; } - ginst->nested_in = nested_in; - mono_class_create_generic (ginst); g_hash_table_insert (klass->image->generic_inst_cache, ginst, geninst); @@ -7090,9 +7332,9 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a MonoType* mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types) { - MonoClass *klass, *pklass = NULL, *oklass = NULL; - MonoReflectionType *parent = NULL, *outer = NULL; - MonoType *geninst, *nested_in = NULL; + MonoClass *klass, *pklass = NULL; + MonoReflectionType *parent = NULL; + MonoType *geninst; MonoReflectionTypeBuilder *tb = NULL; MonoGenericInst *ginst; MonoDomain *domain; @@ -7107,23 +7349,13 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc parent = tb->parent; pklass = mono_class_from_mono_type (parent->type); } - if (tb->nesting_type) { - outer = tb->nesting_type; - oklass = mono_class_from_mono_type (outer->type); - } } else { pklass = klass->parent; if (pklass) parent = mono_type_get_object (domain, &pklass->byval_arg); - oklass = klass->nested_in; - if (oklass) - outer = mono_type_get_object (domain, &oklass->byval_arg); } - if (oklass) - nested_in = mono_reflection_bind_generic_parameters (outer, oklass->num_gen_params, types); - - geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types, nested_in); + geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types); if (!geninst) return NULL; @@ -7135,57 +7367,6 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc return geninst; } -void -mono_reflection_generic_inst_get_nested_types (MonoReflectionGenericInst *type) -{ - MonoReflectionTypeBuilder *tb; - MonoGenericInst *ginst; - int i; - - ginst = type->type.type->data.generic_inst; - if (ginst->nested) - return; - - if (strcmp (((MonoObject *) type->generic_type)->vtable->klass->name, "TypeBuilder")) - return; - - tb = (MonoReflectionTypeBuilder *) type->generic_type; - - ginst->count_nested = tb->subtypes ? mono_array_length (tb->subtypes) : 0; - ginst->nested = g_new0 (MonoType *, ginst->count_nested); - - for (i = 0; i < ginst->count_nested; i++) { - MonoReflectionTypeBuilder *ntype; - MonoType **ntypes; - int ntype_argc, j; - - ntype = mono_array_get (tb->subtypes, gpointer, i); - ntype_argc = ntype->generic_params ? mono_array_length (ntype->generic_params) : 0; - - if (ntype_argc > ginst->type_argc) { - ntypes = g_new0 (MonoType *, ntype_argc); - - for (j = 0; j < ginst->type_argc; j++) - ntypes [j] = ginst->type_argv [j]; - - for (j = ginst->type_argc; j < ntype_argc; j++) { - MonoReflectionGenericParam *ngparam; - MonoType *pt = g_new0 (MonoType, 1); - - ngparam = mono_array_get (ntype->generic_params, gpointer, j); - - pt->type = MONO_TYPE_VAR; - pt->data.generic_param = ngparam->type.type->data.generic_param; - - ntypes [j] = pt; - } - } else - ntypes = ginst->type_argv; - - ginst->nested [i] = mono_reflection_bind_generic_parameters ((MonoReflectionType *) ntype, ntype_argc, ntypes); - } -} - MonoReflectionMethod* mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types) { @@ -7236,12 +7417,24 @@ inflate_mono_method (MonoReflectionGenericInst *type, MonoMethod *method, MonoOb MonoGenericMethod *gmethod; MonoGenericInst *ginst; MonoGenericContext *context; + int i; ginst = type->type.type->data.generic_inst; gmethod = g_new0 (MonoGenericMethod, 1); gmethod->reflection_info = obj; + gmethod->mtype_argc = method->signature->generic_param_count; + gmethod->mtype_argv = g_new0 (MonoType *, gmethod->mtype_argc); + + for (i = 0; i < gmethod->mtype_argc; i++) { + MonoMethodNormal *mn = (MonoMethodNormal *) method; + MonoGenericParam *gparam = &mn->header->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; @@ -7330,6 +7523,7 @@ 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); @@ -7340,8 +7534,12 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type, 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].generic_info = ifield; dginst->fields [i].type = mono_class_inflate_generic_type (field->type, ginst->context); } @@ -7512,14 +7710,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); @@ -7670,75 +7867,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 *