X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Freflection.c;h=d7c958f1bd2442d782558548316f59bfe94b7882;hb=0f128ab73f1d67e6847eed513038b338fe780099;hp=ec146d21a1563ddd90c3f623eacc8ecf29a4d7a6;hpb=729787202bb2aa18d595309138e5366bff4596a6;p=mono.git diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index ec146d21a15..d7c958f1bd2 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -138,6 +138,8 @@ 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 +533,95 @@ 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; + + return size; +} + static guint32 method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig) { @@ -538,7 +629,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; @@ -647,6 +738,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); @@ -1287,11 +1382,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_tok_value ? ta->aname.public_tok_value : "null"); g_free (name); return result; } @@ -1456,7 +1551,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) { @@ -1744,6 +1848,75 @@ mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *ass } } +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 <<= CUSTOM_ATTR_BITS; + owner |= 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; + switch (mono_metadata_token_table (token)) { + case MONO_TABLE_METHOD: + type |= CUSTOM_ATTR_TYPE_METHODDEF; + break; + case MONO_TABLE_MEMBERREF: + type |= 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 encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly) { @@ -1753,19 +1926,36 @@ 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 @@ -1783,14 +1973,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 @@ -1835,10 +2028,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]; @@ -1847,6 +2037,11 @@ 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; @@ -1861,8 +2056,7 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image) * 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 || + if (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 || @@ -2113,19 +2307,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_type ? f->field->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; } @@ -2168,20 +2362,20 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method) MonoDynamicTable *table; guint32 *values; guint32 token, mtoken = 0, sig; - MonoGenericMethod *gmethod; + MonoMethodInflated *imethod; MonoMethod *declaring; table = &assembly->tables [MONO_TABLE_METHODSPEC]; - g_assert ((gmethod = method->signature->gen_method) != NULL); - declaring = gmethod->generic_method; - if (declaring->signature->gen_method) - declaring = declaring->signature->gen_method->generic_method; + g_assert (method->signature->is_inflated); + imethod = (MonoMethodInflated *) method; + declaring = imethod->declaring; + sig = method_encode_signature (assembly, declaring->signature); mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig); - if (!gmethod->generic_method->signature->generic_param_count) + if (!declaring->signature->generic_param_count) return mtoken; switch (mono_metadata_token_table (mtoken)) { @@ -2195,7 +2389,7 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method) 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); @@ -2213,21 +2407,23 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method) 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->generic_method->signature->generic_param_count) + if (imethod->declaring->signature->generic_param_count) token = method_encode_methodspec (assembly, m); else { - guint32 sig = method_encode_signature (assembly, gmethod->generic_method->signature); + guint32 sig = method_encode_signature ( + assembly, imethod->declaring->signature); token = mono_image_get_memberref_token ( - assembly, &m->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)); @@ -2247,6 +2443,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); @@ -2274,7 +2480,7 @@ create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder * } token = TYPEDEFORREF_TYPESPEC | (table->next_idx << TYPEDEFORREF_BITS); - g_hash_table_insert (assembly->typeref, tb->type.type, GUINT_TO_POINTER(token)); + g_hash_table_insert (assembly->typespec, tb->type.type, GUINT_TO_POINTER(token)); table->next_idx ++; return token; } @@ -2288,6 +2494,10 @@ 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); @@ -2311,7 +2521,7 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi token = MONO_TOKEN_MEMBER_REF | table->next_idx; table->next_idx ++; - + g_hash_table_insert (assembly->handleref, fb, GUINT_TO_POINTER(token)); return token; } @@ -3030,8 +3240,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) @@ -3654,7 +3873,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)); @@ -3667,7 +3886,7 @@ 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) { + if (m->method->signature->is_inflated) { token = mono_image_get_methodspec_token (assembly, m->method); } else if (m->method->signature->generic_param_count) { g_assert_not_reached (); @@ -3692,7 +3911,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj) 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) { @@ -3766,6 +3985,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); @@ -4735,6 +4955,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; @@ -4767,7 +4989,7 @@ 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); @@ -4960,7 +5182,8 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) { memset (assembly, 0, sizeof (MonoAssemblyName)); assembly->name = p; assembly->culture = ""; - + assembly->public_tok_value = NULL; + while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@')) p++; found_sep = 0; @@ -4973,7 +5196,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 != '.') @@ -4990,10 +5213,11 @@ 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) { - assembly->culture = ""; + if (g_ascii_strncasecmp (p, "neutral", 7) == 0) { + assembly->culture = g_strdup (""); p += 7; } else { assembly->culture = p; @@ -5001,26 +5225,16 @@ 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 { + assembly->public_tok_value = p; + while (*p && *p != ',') { + p++; + } } - p = s; } else { while (*p && *p != ',') p++; @@ -5263,9 +5477,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; } @@ -5612,10 +5853,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); @@ -5931,13 +6179,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); @@ -6470,8 +6718,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); } /* @@ -6801,35 +7047,35 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* 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; + 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; @@ -6842,12 +7088,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); @@ -6860,52 +7102,50 @@ mono_reflection_bind_generic_parameters (MonoType *type, MonoArray *types) geninst = g_hash_table_lookup (klass->image->generic_inst_cache, ginst); if (geninst) { - g_free (ginst->type_argv); g_free (ginst); mono_loader_unlock (); return geninst; } - if (klass->wastypebuilder && klass->reflection_info) { - tb = klass->reflection_info; - - 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 (pklass && pklass->generic_inst) - parent = mono_reflection_bind_generic_parameters (parent, types); + if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) { + tb = (MonoReflectionTypeBuilder *) type; - if (tb) icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0; - else + ginst->is_dynamic = TRUE; + } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericInst")) { + MonoReflectionGenericInst *rgi = (MonoReflectionGenericInst *) type; + MonoReflectionType *rgt = rgi->generic_type; + + 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); + ginst->count_ifaces = icount; for (i = 0; i < icount; i++) { - MonoType *itype; + MonoReflectionType *itype; if (tb) - itype = mono_array_get (tb->interfaces, MonoReflectionType *, i)->type; + itype = mono_array_get (tb->interfaces, MonoReflectionType *, i); else - itype = &klass->interfaces [i]->byval_arg; - ginst->ifaces [i] = mono_reflection_bind_generic_parameters (itype, types); + 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; + ginst->ifaces [i] = itype->type; } - ginst->parent = parent; - mono_class_create_generic (ginst); g_hash_table_insert (klass->image->generic_inst_cache, ginst, geninst); @@ -6915,12 +7155,51 @@ mono_reflection_bind_generic_parameters (MonoType *type, MonoArray *types) 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; MonoReflectionMethodBuilder *mb = NULL; MonoGenericMethod *gmethod; + MonoGenericContext *context; int count, i; MONO_ARCH_SAVE_REGS; @@ -6941,7 +7220,6 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M 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++) { @@ -6949,27 +7227,45 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M gmethod->mtype_argv [i] = garg->type; } - gmethod->generic_inst = method->klass->generic_inst; + context = g_new0 (MonoGenericContext, 1); + context->ginst = method->klass->generic_inst; + context->gmethod = gmethod; - inflated = mono_class_inflate_generic_method (method, gmethod, NULL); + 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->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; + } - return mono_class_inflate_generic_method (method, gmethod, ginst->klass); + context = g_new0 (MonoGenericContext, 1); + context->ginst = ginst; + context->gmethod = gmethod; + + return mono_class_inflate_generic_method (method, context, ginst->klass); } static MonoMethod * @@ -6987,16 +7283,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; @@ -7027,11 +7326,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); @@ -7053,12 +7354,14 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type, 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 (); + } 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].type = mono_class_inflate_generic_type (field->type, ginst->context); } for (i = 0; i < dginst->count_properties; i++) { @@ -7068,6 +7371,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) @@ -7078,9 +7382,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 (); } @@ -7229,6 +7558,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) @@ -7238,6 +7568,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) { @@ -7252,6 +7614,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) @@ -7326,74 +7689,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 *