* information might refer to different tables.
*/
-static MonoMetaTable AssemblySchema [] = {
+const static MonoMetaTable AssemblySchema [] = {
{ MONO_MT_UINT32, "HashId" },
{ MONO_MT_UINT16, "Major" },
{ MONO_MT_UINT16, "Minor" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable AssemblyOSSchema [] = {
+const static MonoMetaTable AssemblyOSSchema [] = {
{ MONO_MT_UINT32, "OSPlatformID" },
{ MONO_MT_UINT32, "OSMajor" },
{ MONO_MT_UINT32, "OSMinor" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable AssemblyProcessorSchema [] = {
+const static MonoMetaTable AssemblyProcessorSchema [] = {
{ MONO_MT_UINT32, "Processor" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable AssemblyRefSchema [] = {
+const static MonoMetaTable AssemblyRefSchema [] = {
{ MONO_MT_UINT16, "Major" },
{ MONO_MT_UINT16, "Minor" },
{ MONO_MT_UINT16, "Build" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable AssemblyRefOSSchema [] = {
+const static MonoMetaTable AssemblyRefOSSchema [] = {
{ MONO_MT_UINT32, "OSPlatformID" },
{ MONO_MT_UINT32, "OSMajorVersion" },
{ MONO_MT_UINT32, "OSMinorVersion" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable AssemblyRefProcessorSchema [] = {
+const static MonoMetaTable AssemblyRefProcessorSchema [] = {
{ MONO_MT_UINT32, "Processor" },
{ MONO_MT_TABLE_IDX, "AssemblyRef:AssemblyRef" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable ClassLayoutSchema [] = {
+const static MonoMetaTable ClassLayoutSchema [] = {
{ MONO_MT_UINT16, "PackingSize" },
{ MONO_MT_UINT32, "ClassSize" },
{ MONO_MT_TABLE_IDX, "Parent:TypeDef" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable ConstantSchema [] = {
+const static MonoMetaTable ConstantSchema [] = {
{ MONO_MT_UINT8, "Type" },
{ MONO_MT_UINT8, "PaddingZero" },
{ MONO_MT_CONST_IDX, "Parent" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable CustomAttributeSchema [] = {
+const static MonoMetaTable CustomAttributeSchema [] = {
{ MONO_MT_HASCAT_IDX, "Parent" },
{ MONO_MT_CAT_IDX, "Type" },
{ MONO_MT_BLOB_IDX, "Value" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable DeclSecuritySchema [] = {
+const static MonoMetaTable DeclSecuritySchema [] = {
{ MONO_MT_UINT16, "Action" },
{ MONO_MT_HASDEC_IDX, "Parent" },
{ MONO_MT_BLOB_IDX, "PermissionSet" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable EventMapSchema [] = {
+const static MonoMetaTable EventMapSchema [] = {
{ MONO_MT_TABLE_IDX, "Parent:TypeDef" },
{ MONO_MT_TABLE_IDX, "EventList:Event" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable EventSchema [] = {
+const static MonoMetaTable EventSchema [] = {
{ MONO_MT_UINT16, "EventFlags#EventAttribute" },
{ MONO_MT_STRING_IDX, "Name" },
{ MONO_MT_TABLE_IDX, "EventType" }, /* TypeDef or TypeRef */
{ MONO_MT_END, NULL }
};
-static MonoMetaTable ExportedTypeSchema [] = {
+const static MonoMetaTable ExportedTypeSchema [] = {
{ MONO_MT_UINT32, "Flags" },
{ MONO_MT_TABLE_IDX, "TypeDefId" },
{ MONO_MT_STRING_IDX, "TypeName" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable FieldSchema [] = {
+const static MonoMetaTable FieldSchema [] = {
{ MONO_MT_UINT16, "Flags" },
{ MONO_MT_STRING_IDX, "Name" },
{ MONO_MT_BLOB_IDX, "Signature" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable FieldLayoutSchema [] = {
+const static MonoMetaTable FieldLayoutSchema [] = {
{ MONO_MT_UINT32, "Offset" },
{ MONO_MT_TABLE_IDX, "Field:Field" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable FieldMarshalSchema [] = {
+const static MonoMetaTable FieldMarshalSchema [] = {
{ MONO_MT_HFM_IDX, "Parent" },
{ MONO_MT_BLOB_IDX, "NativeType" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable FieldRVASchema [] = {
+const static MonoMetaTable FieldRVASchema [] = {
{ MONO_MT_UINT32, "RVA" },
{ MONO_MT_TABLE_IDX, "Field:Field" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable FileSchema [] = {
+const static MonoMetaTable FileSchema [] = {
{ MONO_MT_UINT32, "Flags" },
{ MONO_MT_STRING_IDX, "Name" },
{ MONO_MT_BLOB_IDX, "Value" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable ImplMapSchema [] = {
+const static MonoMetaTable ImplMapSchema [] = {
{ MONO_MT_UINT16, "MappingFlag" },
{ MONO_MT_MF_IDX, "MemberForwarded" },
{ MONO_MT_STRING_IDX, "ImportName" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable InterfaceImplSchema [] = {
+const static MonoMetaTable InterfaceImplSchema [] = {
{ MONO_MT_TABLE_IDX, "Class:TypeDef" },
{ MONO_MT_TDOR_IDX, "Interface=TypeDefOrRef" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable ManifestResourceSchema [] = {
+const static MonoMetaTable ManifestResourceSchema [] = {
{ MONO_MT_UINT32, "Offset" },
{ MONO_MT_UINT32, "Flags" },
{ MONO_MT_STRING_IDX, "Name" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable MemberRefSchema [] = {
+const static MonoMetaTable MemberRefSchema [] = {
{ MONO_MT_MRP_IDX, "Class" },
{ MONO_MT_STRING_IDX, "Name" },
{ MONO_MT_BLOB_IDX, "Signature" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable MethodSchema [] = {
+const static MonoMetaTable MethodSchema [] = {
{ MONO_MT_UINT32, "RVA" },
{ MONO_MT_UINT16, "ImplFlags#MethodImplAttributes" },
{ MONO_MT_UINT16, "Flags#MethodAttribute" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable MethodImplSchema [] = {
+const static MonoMetaTable MethodImplSchema [] = {
{ MONO_MT_TABLE_IDX, "Class:TypeDef" },
{ MONO_MT_MDOR_IDX, "MethodBody" },
{ MONO_MT_MDOR_IDX, "MethodDeclaration" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable MethodSemanticsSchema [] = {
+const static MonoMetaTable MethodSemanticsSchema [] = {
{ MONO_MT_UINT16, "MethodSemantic" },
{ MONO_MT_TABLE_IDX, "Method:Method" },
{ MONO_MT_HS_IDX, "Association" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable ModuleSchema [] = {
+const static MonoMetaTable ModuleSchema [] = {
{ MONO_MT_UINT16, "Generation" },
{ MONO_MT_STRING_IDX, "Name" },
{ MONO_MT_GUID_IDX, "MVID" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable ModuleRefSchema [] = {
+const static MonoMetaTable ModuleRefSchema [] = {
{ MONO_MT_STRING_IDX, "Name" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable NestedClassSchema [] = {
+const static MonoMetaTable NestedClassSchema [] = {
{ MONO_MT_TABLE_IDX, "NestedClass:TypeDef" },
{ MONO_MT_TABLE_IDX, "EnclosingClass:TypeDef" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable ParamSchema [] = {
+const static MonoMetaTable ParamSchema [] = {
{ MONO_MT_UINT16, "Flags" },
{ MONO_MT_UINT16, "Sequence" },
{ MONO_MT_STRING_IDX, "Name" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable PropertySchema [] = {
+const static MonoMetaTable PropertySchema [] = {
{ MONO_MT_UINT16, "Flags" },
{ MONO_MT_STRING_IDX, "Name" },
{ MONO_MT_BLOB_IDX, "Type" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable PropertyMapSchema [] = {
+const static MonoMetaTable PropertyMapSchema [] = {
{ MONO_MT_TABLE_IDX, "Parent:TypeDef" },
{ MONO_MT_TABLE_IDX, "PropertyList:Property" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable StandaloneSigSchema [] = {
+const static MonoMetaTable StandaloneSigSchema [] = {
{ MONO_MT_BLOB_IDX, "Signature" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable TypeDefSchema [] = {
+const static MonoMetaTable TypeDefSchema [] = {
{ MONO_MT_UINT32, "Flags" },
{ MONO_MT_STRING_IDX, "Name" },
{ MONO_MT_STRING_IDX, "Namespace" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable TypeRefSchema [] = {
+const static MonoMetaTable TypeRefSchema [] = {
{ MONO_MT_RS_IDX, "ResolutionScope=ResolutionScope" },
{ MONO_MT_STRING_IDX, "Name" },
{ MONO_MT_STRING_IDX, "Namespace" },
{ MONO_MT_END, NULL }
};
-static MonoMetaTable TypeSpecSchema [] = {
+const static MonoMetaTable TypeSpecSchema [] = {
{ MONO_MT_BLOB_IDX, "Signature" },
{ MONO_MT_END, NULL }
};
-static struct {
- MonoMetaTable *table;
+const static MonoMetaTable GenericParamSchema [] = {
+ { MONO_MT_UINT16, "Number" },
+ { MONO_MT_UINT16, "Flags" },
+ { MONO_MT_TABLE_IDX, "Owner" }, /* TypeDef or MethodDef */
+ { MONO_MT_STRING_IDX, "Name" },
+
+ /* soon to be removed */
+ { MONO_MT_TABLE_IDX, "Kind" },
+ { MONO_MT_TABLE_IDX, "DeprecatedConstraint" },
+
+ { MONO_MT_END, NULL }
+};
+
+const static MonoMetaTable MethodSpecSchema [] = {
+ { MONO_MT_MDOR_IDX, "Method" },
+ { MONO_MT_BLOB_IDX, "Signature" },
+ { MONO_MT_END, NULL }
+};
+
+const static MonoMetaTable GenericParamConstraintSchema [] = {
+ { MONO_MT_TABLE_IDX, "GenericParam" },
+ { MONO_MT_TDOR_IDX, "Constraint" },
+ { MONO_MT_END, NULL }
+};
+
+const static struct {
+ const MonoMetaTable *table;
const char *name;
} tables [] = {
/* 0 */ { ModuleSchema, "Module" },
/* 27 */ { ExportedTypeSchema, "ExportedType" },
/* 28 */ { ManifestResourceSchema, "ManifestResource" },
/* 29 */ { NestedClassSchema, "NestedClass" },
- /* 2A */ { NULL, NULL },
- /* 2B */ { NULL, NULL },
+ /* 2A */ { GenericParamSchema, "GenericParam" },
+ /* 2B */ { MethodSpecSchema, "MethodSpec" },
+ /* 2C */ { GenericParamConstraintSchema, "GenericParamConstraint" },
};
/**
const char *
mono_meta_table_name (int table)
{
- if ((table < 0) || (table > 0x29))
+ if ((table < 0) || (table > 0x2c))
return "";
return tables [table].name;
int size = 0, field_size;
int i, n, code;
int shift = 0;
- MonoMetaTable *table = tables [tableindex].table;
+ const MonoMetaTable *table = tables [tableindex].table;
for (i = 0; (code = table [i].code) != MONO_MT_END; i++){
switch (code){
break;
case MONO_TABLE_EXPORTEDTYPE:
g_assert (i == 1);
- field_size = idx_size (MONO_TABLE_TYPEDEF); break;
+ /* the index is in another metadata file, so it must be 4 */
+ field_size = 4; break;
case MONO_TABLE_FIELDLAYOUT:
g_assert (i == 1);
field_size = idx_size (MONO_TABLE_FIELD); break;
case MONO_TABLE_TYPEDEF:
g_assert (i == 4 || i == 5);
field_size = i == 4 ? idx_size (MONO_TABLE_FIELD):
- idx_size(MONO_TABLE_METHOD);
+ idx_size(MONO_TABLE_METHOD);
+ case MONO_TABLE_GENERICPARAM:
+ g_assert (i == 2 || i == 4 || i == 5);
+ if (i == 2)
+ field_size = MAX (idx_size (MONO_TABLE_METHOD), idx_size (MONO_TABLE_TYPEDEF));
+ else if (i == 4)
+ field_size = idx_size (MONO_TABLE_TYPEDEF);
+ else if (i == 5)
+ field_size = idx_size (MONO_TABLE_TYPEDEF);
+ break;
+
+ case MONO_TABLE_GENERICPARAMCONSTRAINT:
+ g_assert (i == 0);
+ field_size = idx_size (MONO_TABLE_GENERICPARAM);
break;
+
default:
g_assert_not_reached ();
}
- if (field_size != idx_size (tableindex))
+ if (tableindex != MONO_TABLE_EXPORTEDTYPE && field_size != idx_size (tableindex))
g_warning ("size changed (%d to %d)", idx_size (tableindex), field_size);
break;
*
* Returns the MonoMetaTable structure for table @table
*/
-MonoMetaTable *
+const MonoMetaTable *
mono_metadata_get_table (MonoMetaTableEnum table)
{
int x = (int) table;
static const char *
dword_align (const char *ptr)
{
+#if SIZEOF_VOID_P == 8
+ return (const char *) (((guint64) (ptr + 3)) & ~3);
+#else
return (const char *) (((guint32) (ptr + 3)) & ~3);
+#endif
}
/**
if (!dest)
dest = &local;
dest->required = *ptr == MONO_TYPE_CMOD_REQD ? 1 : 0;
- dest->token = mono_metadata_parse_typedef_or_ref (m, ptr + 1, &ptr);
+ dest->token = mono_metadata_parse_typedef_or_ref (m, ptr + 1, rptr);
return TRUE;
}
return FALSE;
{
int i;
MonoArrayType *array = g_new0 (MonoArrayType, 1);
+ MonoType *etype;
- array->type = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+ etype = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+ array->eklass = mono_class_from_mono_type (etype);
array->rank = mono_metadata_decode_value (ptr, &ptr);
array->numsizes = mono_metadata_decode_value (ptr, &ptr);
void
mono_metadata_free_array (MonoArrayType *array)
{
- mono_metadata_free_type (array->type);
g_free (array->sizes);
g_free (array->lobounds);
g_free (array);
{{NULL}, 0, MONO_TYPE_I, 0, 1, 0},
{{NULL}, 0, MONO_TYPE_U, 0, 0, 0},
{{NULL}, 0, MONO_TYPE_U, 0, 1, 0},
- {{NULL}, 0, MONO_TYPE_OBJECT, 0, 0, 0},
- {{NULL}, 0, MONO_TYPE_OBJECT, 0, 1, 0}
};
#define NBUILTIN_TYPES() (sizeof (builtin_types) / sizeof (builtin_types [0]))
return 1;
}
+/**
+ * mono_metadata_init:
+ *
+ * Initialize the global variables of this module.
+ */
+void
+mono_metadata_init (void)
+{
+ int i;
+
+ type_cache = g_hash_table_new (mono_type_hash, mono_type_equal);
+
+ for (i = 0; i < NBUILTIN_TYPES (); ++i)
+ g_hash_table_insert (type_cache, &builtin_types [i], &builtin_types [i]);
+}
+
/*
* mono_metadata_parse_type:
* @m: metadata context
{
MonoType *type, *cached;
- if (!type_cache) {
- int i;
- type_cache = g_hash_table_new (mono_type_hash, mono_type_equal);
-
- for (i = 0; i < NBUILTIN_TYPES (); ++i)
- g_hash_table_insert (type_cache, &builtin_types [i], &builtin_types [i]);
- }
-
switch (mode) {
case MONO_PARSE_MOD_TYPE:
case MONO_PARSE_PARAM:
case MONO_PARSE_RET:
+ case MONO_PARSE_LOCAL: /* should not have modifiers according to the spec, but ms tools disagree */
case MONO_PARSE_FIELD: {
/* count the modifiers */
const char *tmp_ptr = ptr;
while (mono_metadata_parse_custom_mod (m, NULL, tmp_ptr, &tmp_ptr))
count++;
if (count) {
- type = g_malloc0 (sizeof (MonoType) + (count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod));
+ type = g_malloc0 (sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod));
type->num_mods = count;
if (count > 64)
g_warning ("got more than 64 modifiers in type");
break;
} /* fall through */
}
- case MONO_PARSE_LOCAL:
case MONO_PARSE_TYPE:
/*
* Later we can avoid doing this allocation.
}
if (rptr)
*rptr = ptr;
+
+ /* No need to use locking since nobody is modifying the hash table */
if (mode != MONO_PARSE_PARAM && !type->num_mods && (cached = g_hash_table_lookup (type_cache, type))) {
mono_metadata_free_type (type);
return cached;
guint32 sig;
const char *ptr;
+ if (image->assembly->dynamic)
+ return mono_lookup_dynamic_token (image, token);
+
g_assert (mono_metadata_token_table(token) == MONO_TABLE_STANDALONESIG);
sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
return mono_metadata_parse_method_signature (image, FALSE, ptr, NULL);
}
+MonoMethodSignature*
+mono_metadata_signature_alloc (MonoImage *m, guint32 nparams)
+{
+ MonoMethodSignature *sig;
+
+ /* later we want to allocate signatures with mempools */
+ sig = g_malloc0 (sizeof (MonoMethodSignature) + ((gint32)nparams - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
+ sig->param_count = nparams;
+
+ return sig;
+}
+
/*
* mono_metadata_parse_method_signature:
* @m: metadata context
- * @def: use #TRUE when parsing MethodDef, #FALSE with MethodRef signatures.
+ * @def: the MethodDef index or 0 for Ref signatures.
* @ptr: pointer to the signature metadata representation
* @rptr: pointer updated to match the end of the decoded stream
*
mono_metadata_parse_method_signature (MonoImage *m, int def, const char *ptr, const char **rptr)
{
MonoMethodSignature *method;
- int i;
+ int i, ret_attrs = 0, *pattrs = NULL;
guint32 hasthis = 0, explicit_this = 0, call_convention, param_count;
+ guint32 gen_param_count = 0;
+ if (*ptr & 0x10)
+ gen_param_count = 1;
if (*ptr & 0x20)
hasthis = 1;
if (*ptr & 0x40)
explicit_this = 1;
call_convention = *ptr & 0x0F;
ptr++;
+ if (gen_param_count)
+ gen_param_count = mono_metadata_decode_value (ptr, &ptr);
param_count = mono_metadata_decode_value (ptr, &ptr);
+ pattrs = g_new0 (int, param_count);
- method = g_malloc0 (sizeof (MonoMethodSignature) + (param_count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
- method->param_count = param_count;
+ if (def) {
+ MonoTableInfo *paramt = &m->tables [MONO_TABLE_PARAM];
+ MonoTableInfo *methodt = &m->tables [MONO_TABLE_METHOD];
+ guint32 cols [MONO_PARAM_SIZE];
+ guint lastp, param_index = mono_metadata_decode_row_col (methodt, def - 1, MONO_METHOD_PARAMLIST);
+
+ if (def < methodt->rows)
+ lastp = mono_metadata_decode_row_col (methodt, def, MONO_METHOD_PARAMLIST);
+ else
+ lastp = paramt->rows + 1;
+ for (i = param_index; i < lastp; ++i) {
+ mono_metadata_decode_row (paramt, i - 1, cols, MONO_PARAM_SIZE);
+ if (!cols [MONO_PARAM_SEQUENCE])
+ ret_attrs = cols [MONO_PARAM_FLAGS];
+ else
+ pattrs [cols [MONO_PARAM_SEQUENCE] - 1] = cols [MONO_PARAM_FLAGS];
+ }
+ }
+ method = mono_metadata_signature_alloc (m, param_count);
method->hasthis = hasthis;
method->explicit_this = explicit_this;
method->call_convention = call_convention;
- method->ret = mono_metadata_parse_type (m, MONO_PARSE_RET, 0, ptr, &ptr);
+ method->generic_param_count = gen_param_count;
+ if (call_convention != 0xa)
+ method->ret = mono_metadata_parse_type (m, MONO_PARSE_RET, ret_attrs, ptr, &ptr);
if (method->param_count) {
method->sentinelpos = -1;
method->sentinelpos = i;
ptr++;
}
- method->params [i] = mono_metadata_parse_type (m, MONO_PARSE_PARAM, 0, ptr, &ptr);
+ method->params [i] = mono_metadata_parse_type (m, MONO_PARSE_PARAM, pattrs [i], ptr, &ptr);
}
}
+ g_free (pattrs);
if (rptr)
*rptr = ptr;
g_free (sig);
}
+static void
+do_mono_metadata_parse_generic_inst (MonoType *type, MonoImage *m, const char *ptr, const char **rptr)
+{
+ MonoGenericInst *generic_inst = g_new0 (MonoGenericInst, 1);
+ int i, count;
+
+ type->data.generic_inst = generic_inst;
+
+ generic_inst->generic_type = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+ generic_inst->type_argc = count = mono_metadata_decode_value (ptr, &ptr);
+ generic_inst->type_argv = g_new0 (MonoType*, count);
+
+ /*
+ * Create the klass before parsing the type arguments.
+ * This is required to support "recursive" definitions.
+ * See mcs/tests/gen-23.cs for an example.
+ */
+
+ generic_inst->klass = mono_class_create_from_generic (m, type);
+
+ for (i = 0; i < generic_inst->type_argc; i++)
+ generic_inst->type_argv [i] = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+
+ mono_class_initialize_generic (generic_inst->klass, TRUE);
+
+ if (rptr)
+ *rptr = ptr;
+}
+
+static MonoGenericParam *
+mono_metadata_parse_generic_param (MonoImage *m, const char *ptr, const char **rptr)
+{
+ MonoGenericParam *generic_param = g_new0 (MonoGenericParam, 1);
+
+ generic_param->num = mono_metadata_decode_value (ptr, &ptr);
+
+ if (rptr)
+ *rptr = ptr;
+
+ return generic_param;
+}
+
/*
* do_mono_metadata_parse_type:
* @type: MonoType to be filled in with the return value
type->data.klass = mono_class_get (m, token);
break;
}
- case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_SZARRAY: {
+ MonoType *etype = mono_metadata_parse_type (m, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
+ type->data.klass = mono_class_from_mono_type (etype);
+ break;
+ }
case MONO_TYPE_PTR:
type->data.type = mono_metadata_parse_type (m, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
break;
case MONO_TYPE_ARRAY:
type->data.array = mono_metadata_parse_array (m, ptr, &ptr);
break;
+
+ case MONO_TYPE_MVAR:
+ case MONO_TYPE_VAR:
+ type->data.generic_param = mono_metadata_parse_generic_param (m, ptr, &ptr);
+ break;
+
+ case MONO_TYPE_GENERICINST:
+ do_mono_metadata_parse_generic_inst (type, m, ptr, &ptr);
+ break;
+
default:
- g_error ("type 0x%02x not handled in mono_metadata_parse_type", type->type);
+ g_error ("type 0x%02x not handled in do_mono_metadata_parse_type", type->type);
}
if (rptr)
if (type >= builtin_types && type < builtin_types + NBUILTIN_TYPES ())
return;
switch (type->type){
- case MONO_TYPE_SZARRAY:
case MONO_TYPE_PTR:
mono_metadata_free_type (type->data.type);
break;
* @index: typedef token
*
* Returns: the 1-based index into the TypeDef table of the first type
- * that is nested inside the type described by @index.
- * Retruns 0 if @index doesn't have nested types.
+ * that is nested inside the type described by @index. The search starts at
+ * @start_index.
+ * Returns 0 if no such type is found.
*/
guint32
-mono_metadata_nesting_typedef (MonoImage *meta, guint32 index)
+mono_metadata_nesting_typedef (MonoImage *meta, guint32 index, guint32 start_index)
{
MonoTableInfo *tdef = &meta->tables [MONO_TABLE_NESTEDCLASS];
- locator_t loc;
guint32 start;
+ guint32 class_index = mono_metadata_token_index (index);
if (!tdef->base)
return 0;
- loc.idx = mono_metadata_token_index (index);
- loc.col_idx = MONO_NESTED_CLASS_ENCLOSING;
- loc.t = tdef;
-
- if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
- return 0;
+ start = start_index;
- start = loc.result;
-
- while (start > 0) {
- if (loc.idx == mono_metadata_decode_row_col (tdef, start - 1, MONO_NESTED_CLASS_ENCLOSING))
- start--;
- else
+ while (start <= tdef->rows) {
+ if (class_index == mono_metadata_decode_row_col (tdef, start - 1, MONO_NESTED_CLASS_ENCLOSING))
break;
+ else
+ start++;
}
- /* loc_result is 0..1, needs to be mapped to table index (that is +1) */
- return start + 1;
+ if (start > tdef->rows)
+ return 0;
+ else
+ return start;
}
/*
return loc.result + 1;
}
+/*
+ * mono_metadata_custom_attrs_from_index:
+ * @meta: metadata context
+ * @index: token representing the parent
+ *
+ * Returns: the 1-based index into the CustomAttribute table of the first
+ * attribute which belongs to the metadata object described by @index.
+ * Returns 0 if no such attribute is found.
+ */
+guint32
+mono_metadata_custom_attrs_from_index (MonoImage *meta, guint32 index)
+{
+ MonoTableInfo *tdef = &meta->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+ locator_t loc;
+
+ if (!tdef->base)
+ return 0;
+
+ loc.idx = index;
+ loc.col_idx = MONO_CUSTOM_ATTR_PARENT;
+ loc.t = tdef;
+
+ if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
+ return 0;
+
+ /* Find the first entry by searching backwards */
+ while ((loc.result > 0) && (mono_metadata_decode_row_col (tdef, loc.result - 1, MONO_CUSTOM_ATTR_PARENT) == index))
+ loc.result --;
+
+ /* loc_result is 0..1, needs to be mapped to table index (that is +1) */
+ return loc.result + 1;
+}
+
+#ifdef DEBUG
+static void
+mono_backtrace (int limit)
+{
+ void *array[limit];
+ char **names;
+ int i;
+ backtrace (array, limit);
+ names = backtrace_symbols (array, limit);
+ for (i =0; i < limit; ++i) {
+ g_print ("\t%s\n", names [i]);
+ }
+ g_free (names);
+}
+#endif
+
#ifndef __GNUC__
-#define __alignof__(a) sizeof(a)
+/*#define __alignof__(a) sizeof(a)*/
+#define __alignof__(type) G_STRUCT_OFFSET(struct { char c; type x; }, x)
#endif
/*
case MONO_TYPE_PTR:
case MONO_TYPE_FNPTR:
case MONO_TYPE_ARRAY:
- case MONO_TYPE_TYPEDBYREF: /* we may want to use a struct {MonoType* type, void *data } instead ...*/
+ *align = __alignof__(gpointer);
+ return sizeof (gpointer);
+ case MONO_TYPE_TYPEDBYREF:
+ return mono_class_value_size (mono_defaults.typed_reference_class, align);
+ case MONO_TYPE_GENERICINST: {
+ MonoClass *iclass = mono_class_from_mono_type (t);
+ return mono_type_size (&iclass->byval_arg, align);
+ }
+ case MONO_TYPE_VAR:
+ case MONO_TYPE_MVAR:
*align = __alignof__(gpointer);
return sizeof (gpointer);
default:
- g_error ("type 0x%02x unknown", t->type);
+ g_error ("mono_type_size: type 0x%02x unknown", t->type);
}
return 0;
}
case MONO_TYPE_PTR:
case MONO_TYPE_FNPTR:
case MONO_TYPE_ARRAY:
- case MONO_TYPE_TYPEDBYREF:
*align = __alignof__(gpointer);
return sizeof (gpointer);
+ case MONO_TYPE_TYPEDBYREF:
+ *align = __alignof__(gpointer);
+ return sizeof (gpointer) * 2;
case MONO_TYPE_R4:
*align = __alignof__(float);
return sizeof (float);
*align = *align + __alignof__(gpointer) - 1;
*align &= ~(__alignof__(gpointer) - 1);
- return size;
- }
- }
- default:
- g_error ("type 0x%02x unknown", t->type);
- }
- return 0;
-}
-
-/*
- * mono_type_native_stack_size:
- * @t: the type to return the size it uses on the stack
- *
- * Returns: the number of bytes required to hold an instance of this
- * type on the native stack
- */
-int
-mono_type_native_stack_size (MonoType *t, gint *align)
-{
- int tmp;
-
- g_assert (t != NULL);
-
- if (!align)
- align = &tmp;
-
- if (t->byref) {
- *align = 4;
- return 4;
- }
-
- switch (t->type){
- 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_I:
- case MONO_TYPE_U:
- case MONO_TYPE_STRING:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_PTR:
- case MONO_TYPE_FNPTR:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_TYPEDBYREF:
- *align = 4;
- return 4;
- case MONO_TYPE_R4:
- *align = 4;
- return 4;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- case MONO_TYPE_R8:
- *align = 4;
- return 8;
- case MONO_TYPE_VALUETYPE: {
- guint32 size;
+ size += sizeof (gpointer) - 1;
+ size &= ~(sizeof (gpointer) - 1);
- if (t->data.klass->enumtype)
- return mono_type_native_stack_size (t->data.klass->enum_basetype, align);
- else {
- size = mono_class_native_size (t->data.klass, align);
- *align = *align + 3;
- *align &= ~3;
-
return size;
}
}
+ case MONO_TYPE_GENERICINST: {
+ MonoClass *iclass = mono_class_from_mono_type (t);
+ return mono_type_stack_size (&iclass->byval_arg, align);
+ }
default:
g_error ("type 0x%02x unknown", t->type);
}
switch (t1->type) {
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_CLASS:
+ case MONO_TYPE_SZARRAY:
/* check if the distribution is good enough */
- return hash << 7 | g_str_hash (t1->data.klass->name);
+ return ((hash << 5) - hash) ^ g_str_hash (t1->data.klass->name);
case MONO_TYPE_PTR:
- case MONO_TYPE_SZARRAY:
- return hash << 7 | mono_metadata_type_hash (t1->data.type);
+ return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.type);
+ case MONO_TYPE_ARRAY:
+ return ((hash << 5) - hash) ^ mono_metadata_type_hash (&t1->data.array->eklass->byval_arg);
+ case MONO_TYPE_GENERICINST:
+ return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.generic_inst->generic_type);
}
return hash;
}
case MONO_TYPE_I:
case MONO_TYPE_U:
case MONO_TYPE_OBJECT:
+ case MONO_TYPE_TYPEDBYREF:
return TRUE;
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_CLASS:
+ case MONO_TYPE_SZARRAY:
return t1->data.klass == t2->data.klass;
case MONO_TYPE_PTR:
- case MONO_TYPE_SZARRAY:
return mono_metadata_type_equal (t1->data.type, t2->data.type);
case MONO_TYPE_ARRAY:
if (t1->data.array->rank != t2->data.array->rank)
return FALSE;
- return mono_metadata_type_equal (t1->data.array->type, t2->data.array->type);
+ return t1->data.array->eklass == t2->data.array->eklass;
+ case MONO_TYPE_GENERICINST: {
+ int i;
+ if (t1->data.generic_inst->type_argc != t2->data.generic_inst->type_argc)
+ return FALSE;
+ if (!mono_metadata_type_equal (t1->data.generic_inst->generic_type, t2->data.generic_inst->generic_type))
+ return FALSE;
+ for (i = 0; i < t1->data.generic_inst->type_argc; ++i) {
+ if (!mono_metadata_type_equal (t1->data.generic_inst->type_argv [i], t2->data.generic_inst->type_argv [i]))
+ return FALSE;
+ }
+ return TRUE;
+ }
+ case MONO_TYPE_VAR:
+ case MONO_TYPE_MVAR:
+ return t1->data.generic_param->num == t2->data.generic_param->num;
default:
g_error ("implement type compare for %0x!", t1->type);
return FALSE;
MonoType *p1 = sig1->params[i];
MonoType *p2 = sig2->params[i];
- if (p1->attrs != p2->attrs)
- return FALSE;
+ //if (p1->attrs != p2->attrs)
+ // return FALSE;
if (!mono_metadata_type_equal (p1, p2))
return FALSE;
if (marshal_spec) {
const char *p;
- tdef = &meta->tables [MONO_TABLE_FIELDMARSHAL];
-
- loc.col_idx = MONO_FIELD_MARSHAL_PARENT;
- loc.t = tdef;
- loc.idx = (loc.idx << HAS_FIELD_MARSHAL_BITS) | HAS_FIELD_MARSHAL_FIELDSREF;
-
- if (tdef->base && bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator)) {
- p = mono_metadata_blob_heap (meta, mono_metadata_decode_row_col (tdef, loc.result, MONO_FIELD_MARSHAL_NATIVE_TYPE));
+ if ((p = mono_metadata_get_marshal_info (meta, index, TRUE))) {
*marshal_spec = mono_metadata_parse_marshal_spec (meta, p);
- } else {
- *marshal_spec = NULL;
}
}
guint32 len;
MonoType *type;
+ mono_loader_lock ();
+
+ if ((type = g_hash_table_lookup (image->typespec_cache, GUINT_TO_POINTER (type_spec)))) {
+ mono_loader_unlock ();
+ return type;
+ }
+
t = &image->tables [MONO_TABLE_TYPESPEC];
mono_metadata_decode_row (t, idx-1, cols, MONO_TYPESPEC_SIZE);
ptr = mono_metadata_blob_heap (image, cols [MONO_TYPESPEC_SIGNATURE]);
len = mono_metadata_decode_value (ptr, &ptr);
- type = mono_metadata_parse_type (image, MONO_PARSE_TYPE, 0, ptr, &ptr);
+
+ type = g_new0 (MonoType, 1);
+
+ g_hash_table_insert (image->typespec_cache, GUINT_TO_POINTER (type_spec), type);
+
+ if (*ptr == MONO_TYPE_BYREF) {
+ type->byref = 1;
+ ptr++;
+ }
+
+ do_mono_metadata_parse_type (type, image, ptr, &ptr);
+
+ mono_loader_unlock ();
return type;
}
if (res->native == MONO_NATIVE_LPARRAY) {
if (ptr - start <= len)
- res->elem_type = *ptr++;
+ res->data.array_data.elem_type = *ptr++;
if (ptr - start <= len)
- res->param_num = mono_metadata_decode_value (ptr, &ptr);
+ res->data.array_data.param_num = mono_metadata_decode_value (ptr, &ptr);
if (ptr - start <= len)
- res->num_elem = mono_metadata_decode_value (ptr, &ptr);
+ res->data.array_data.num_elem = mono_metadata_decode_value (ptr, &ptr);
}
if (res->native == MONO_NATIVE_BYVALTSTR) {
if (ptr - start <= len)
- res->num_elem = mono_metadata_decode_value (ptr, &ptr);
+ res->data.array_data.num_elem = mono_metadata_decode_value (ptr, &ptr);
}
if (res->native == MONO_NATIVE_BYVALARRAY) {
if (ptr - start <= len)
- res->num_elem = mono_metadata_decode_value (ptr, &ptr);
+ res->data.array_data.num_elem = mono_metadata_decode_value (ptr, &ptr);
+ }
+
+ if (res->native == MONO_NATIVE_CUSTOM) {
+ /* skip unused type guid */
+ len = mono_metadata_decode_value (ptr, &ptr);
+ ptr += len;
+ /* skip unused native type name */
+ len = mono_metadata_decode_value (ptr, &ptr);
+ ptr += len;
+ /* read custom marshaler type name */
+ len = mono_metadata_decode_value (ptr, &ptr);
+ res->data.custom_data.custom_name = g_strndup (ptr, len);
+ ptr += len;
+ /* read cookie string */
+ len = mono_metadata_decode_value (ptr, &ptr);
+ res->data.custom_data.cookie = g_strndup (ptr, len);
}
return res;
case MONO_NATIVE_BOOLEAN:
*conv = MONO_MARSHAL_CONV_BOOL_I4;
return MONO_NATIVE_BOOLEAN;
+ case MONO_NATIVE_I1:
case MONO_NATIVE_U1:
- return MONO_NATIVE_U1;
+ return mspec->native;
default:
g_error ("cant marshal bool to native type %02x", mspec->native);
}
g_error ("cant marshal object as native type %02x", mspec->native);
}
}
+ if (t == MONO_TYPE_CLASS && (type->data.klass == mono_defaults.multicastdelegate_class ||
+ type->data.klass == mono_defaults.delegate_class ||
+ type->data.klass->parent == mono_defaults.multicastdelegate_class)) {
+ *conv = MONO_MARSHAL_CONV_DEL_FTN;
+ return MONO_NATIVE_FUNC;
+ }
*conv = MONO_MARSHAL_CONV_OBJECT_STRUCT;
return MONO_NATIVE_STRUCT;
}
return MONO_NATIVE_MAX;
}
-gint32
-mono_marshal_type_size (MonoType *type, MonoMarshalSpec *mspec, gint32 *align,
- gboolean as_field, gboolean unicode)
-{
- MonoMarshalNative native_type = mono_type_to_unmanaged (type, mspec, as_field, unicode, NULL);
- MonoClass *klass;
-
- switch (native_type) {
- case MONO_NATIVE_BOOLEAN:
- *align = 4;
- return 4;
- case MONO_NATIVE_I1:
- case MONO_NATIVE_U1:
- *align = 1;
- return 1;
- case MONO_NATIVE_I2:
- case MONO_NATIVE_U2:
- *align = 2;
- return 2;
- case MONO_NATIVE_I4:
- case MONO_NATIVE_U4:
- case MONO_NATIVE_ERROR:
- *align = 4;
- return 4;
- case MONO_NATIVE_I8:
- case MONO_NATIVE_U8:
- *align = 4;
- return 8;
- case MONO_NATIVE_R4:
- *align = 4;
- return 4;
- case MONO_NATIVE_R8:
- *align = 4;
- return 8;
- case MONO_NATIVE_INT:
- case MONO_NATIVE_UINT:
- case MONO_NATIVE_LPSTR:
- case MONO_NATIVE_LPWSTR:
- case MONO_NATIVE_LPTSTR:
- case MONO_NATIVE_BSTR:
- case MONO_NATIVE_ANSIBSTR:
- case MONO_NATIVE_TBSTR:
- case MONO_NATIVE_LPARRAY:
- case MONO_NATIVE_SAFEARRAY:
- case MONO_NATIVE_IUNKNOWN:
- case MONO_NATIVE_IDISPATCH:
- case MONO_NATIVE_INTERFACE:
- case MONO_NATIVE_ASANY:
- case MONO_NATIVE_VARIANTBOOL:
- case MONO_NATIVE_FUNC:
- case MONO_NATIVE_LPSTRUCT:
- *align = 4;
- return sizeof (gpointer);
- case MONO_NATIVE_STRUCT:
- klass = mono_class_from_mono_type (type);
- return mono_class_native_size (klass, align);
- case MONO_NATIVE_BYVALTSTR: {
- int esize = unicode ? 2: 1;
- g_assert (mspec);
- *align = esize;
- return mspec->num_elem * esize;
- }
- case MONO_NATIVE_BYVALARRAY: {
- int esize;
- klass = mono_class_from_mono_type (type);
- esize = mono_class_native_size (klass->element_class, align);
- g_assert (mspec);
- return mspec->num_elem * esize;
- }
- case MONO_NATIVE_CURRENCY:
- case MONO_NATIVE_VBBYREFSTR:
- case MONO_NATIVE_CUSTOM:
- default:
- g_error ("native type %02x not implemented", native_type);
- break;
- }
- g_assert_not_reached ();
- return 0;
-}
-
const char*
mono_metadata_get_marshal_info (MonoImage *meta, guint32 idx, gboolean is_field)
{
return result;
}
+/**
+ * mono_guid_to_string:
+ *
+ * Converts a 16 byte Microsoft GUID to the standard string representation.
+ */
+char *
+mono_guid_to_string (const guint8 *guid)
+{
+ return g_strdup_printf ("%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ guid[3], guid[2], guid[1], guid[0],
+ guid[5], guid[4],
+ guid[7], guid[6],
+ guid[8], guid[9],
+ guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]);
+}
+
+static MonoClass**
+get_constraints (MonoImage *image, int owner)
+{
+ MonoTableInfo *tdef = &image->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
+ guint32 cols [MONO_GENPARCONSTRAINT_SIZE];
+ guint32 i, token, found;
+ MonoClass *klass, **res;
+ GList *cons = NULL, *tmp;
+
+
+ found = 0;
+ for (i = 0; i < tdef->rows; ++i) {
+ mono_metadata_decode_row (tdef, i, cols, MONO_GENPARCONSTRAINT_SIZE);
+ if (cols [MONO_GENPARCONSTRAINT_GENERICPAR] == owner) {
+ token = mono_metadata_token_from_dor (cols [MONO_GENPARCONSTRAINT_CONSTRAINT]);
+ klass = mono_class_get (image, token);
+ cons = g_list_append (cons, klass);
+ ++found;
+ } else {
+ /* contiguous list finished */
+ if (found)
+ break;
+ }
+ }
+ if (!found)
+ return NULL;
+ res = g_new0 (MonoClass*, found + 1);
+ for (i = 0, tmp = cons; i < found; ++i, tmp = tmp->next) {
+ res [i] = tmp->data;
+ }
+ g_list_free (cons);
+ return res;
+}
+
+MonoGenericParam *
+mono_metadata_load_generic_params (MonoImage *image, guint32 token, guint32 *num)
+{
+ MonoTableInfo *tdef = &image->tables [MONO_TABLE_GENERICPARAM];
+ guint32 cols [MONO_GENERICPARAM_SIZE];
+ guint32 i, owner, last_num, n;
+ MonoGenericParam *params;
+
+ if (mono_metadata_token_table (token) == MONO_TABLE_TYPEDEF)
+ owner = MONO_TYPEORMETHOD_TYPE;
+ else if (mono_metadata_token_table (token) == MONO_TABLE_METHOD)
+ owner = MONO_TYPEORMETHOD_METHOD;
+ else {
+ g_error ("wrong token %x to load_generics_params", token);
+ }
+ owner |= mono_metadata_token_index (token) << MONO_TYPEORMETHOD_BITS;
+ if (num)
+ *num = 0;
+ if (!tdef->base)
+ return NULL;
+
+ for (i = 0; i < tdef->rows; ++i) {
+ mono_metadata_decode_row (tdef, i, cols, MONO_GENERICPARAM_SIZE);
+ if (cols [MONO_GENERICPARAM_OWNER] == owner)
+ break;
+ }
+ last_num = 0;
+ if (i >= tdef->rows)
+ return NULL;
+ params = NULL;
+ n = 1;
+ do {
+ params = g_realloc (params, sizeof (MonoGenericParam) * n);
+ params [n - 1].pklass = NULL;
+ params [n - 1].method = NULL;
+ params [n - 1].flags = cols [MONO_GENERICPARAM_FLAGS];
+ params [n - 1].num = cols [MONO_GENERICPARAM_NUMBER];
+ params [n - 1].name = mono_metadata_string_heap (image, cols [MONO_GENERICPARAM_NAME]);
+ params [n - 1].constraints = get_constraints (image, i + 1);
+ if (++i >= tdef->rows)
+ break;
+ mono_metadata_decode_row (tdef, i, cols, MONO_GENERICPARAM_SIZE);
+ n++;
+ } while (cols [MONO_GENERICPARAM_OWNER] == owner);
+
+ if (num)
+ *num = n;
+ return params;
+}
+