* 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){
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 ();
}
*
* 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
}
/**
{
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);
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:
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");
}
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;
MonoMethodSignature *sig;
/* later we want to allocate signatures with mempools */
- sig = g_malloc0 (sizeof (MonoMethodSignature) + (nparams - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
+ sig = g_malloc0 (sizeof (MonoMethodSignature) + ((gint32)nparams - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
sig->param_count = nparams;
return sig;
MonoMethodSignature *method;
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);
if (def < methodt->rows)
lastp = mono_metadata_decode_row_col (methodt, def, MONO_METHOD_PARAMLIST);
else
- lastp = paramt->rows;
+ 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])
method->hasthis = hasthis;
method->explicit_this = explicit_this;
method->call_convention = call_convention;
- method->ret = mono_metadata_parse_type (m, MONO_PARSE_RET, ret_attrs, 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;
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;
{
MonoTableInfo *tdef = &meta->tables [MONO_TABLE_NESTEDCLASS];
guint32 start;
+ guint32 class_index = mono_metadata_token_index (index);
if (!tdef->base)
return 0;
start = start_index;
while (start <= tdef->rows) {
- if (index == mono_metadata_decode_row_col (tdef, start - 1, MONO_NESTED_CLASS_ENCLOSING))
+ if (class_index == mono_metadata_decode_row_col (tdef, start - 1, MONO_NESTED_CLASS_ENCLOSING))
break;
else
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;
-}
+ size += sizeof (gpointer) - 1;
+ size &= ~(sizeof (gpointer) - 1);
-/*
- * 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;
-
- 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 << 5) - hash) ^ g_str_hash (t1->data.klass->name);
case MONO_TYPE_PTR:
return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.type);
- case MONO_TYPE_SZARRAY:
- if (t1->data.type->type == MONO_TYPE_OBJECT)
- return ((hash << 5) - hash);
- return ((hash << 5) - hash) ^ (gint32)(t1->data.type->data.klass);
case MONO_TYPE_ARRAY:
- return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.array->type);
+ 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;
}
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:
return mono_metadata_type_equal (t1->data.type, t2->data.type);
- case MONO_TYPE_SZARRAY:
-retry_sz:
- if (t1->data.type->type != t2->data.type->type)
- return FALSE;
- if (t1->data.type->type == MONO_TYPE_CLASS || t1->data.type->type == MONO_TYPE_VALUETYPE)
- return t1->data.type->data.klass == t2->data.type->data.klass;
- if (t1->data.type->type == MONO_TYPE_SZARRAY) {
- t1 = t1->data.type;
- t2 = t2->data.type;
- goto retry_sz;
- }
- 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;
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 (type->data.klass->parent == mono_defaults.multicastdelegate_class) {
+ 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;
}
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)
{
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;
+}
+