gpointer *refs;
} ReflectionMethodBuilder;
+typedef struct {
+ guint32 owner;
+ MonoReflectionGenericParam *gparam;
+} GenericParamTableEntry;
+
const unsigned char table_sizes [64] = {
MONO_MODULE_SIZE,
MONO_TYPEREF_SIZE,
for (i = 0; i < count; ++i) {
cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
values [MONO_CUSTOM_ATTR_PARENT] = idx;
- token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor);
+ token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor, FALSE);
type = mono_metadata_token_index (token);
type <<= MONO_CUSTOM_ATTR_TYPE_BITS;
switch (mono_metadata_token_table (token)) {
values = table->values + table->rows * MONO_METHODIMPL_SIZE;
values [MONO_METHODIMPL_CLASS] = tb->table_idx;
values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
- tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method);
+
+ tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method, FALSE);
switch (mono_metadata_token_table (tok)) {
case MONO_TABLE_MEMBERREF:
tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
static void
mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
+{
+ GenericParamTableEntry *entry;
+
+ /*
+ * The GenericParam table must be sorted according to the `owner' field.
+ * We need to do this sorting prior to writing the GenericParamConstraint
+ * table, since we have to use the final GenericParam table indices there
+ * and they must also be sorted.
+ */
+
+ entry = g_new0 (GenericParamTableEntry, 1);
+ entry->owner = owner;
+ entry->gparam = gparam;
+
+ g_ptr_array_add (assembly->gen_params, entry);
+}
+
+static void
+write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *entry)
{
MonoDynamicTable *table;
MonoGenericParam *param;
table_idx = table->next_idx ++;
values = table->values + table_idx * MONO_GENERICPARAM_SIZE;
- param = gparam->type.type->data.generic_param;
+ param = entry->gparam->type.type->data.generic_param;
- values [MONO_GENERICPARAM_OWNER] = owner;
- if (gparam->has_value_type)
+ values [MONO_GENERICPARAM_OWNER] = entry->owner;
+ if (entry->gparam->has_value_type)
values [MONO_GENERICPARAM_FLAGS] = 0x18;
- else if (gparam->has_reference_type)
+ else if (entry->gparam->has_reference_type)
values [MONO_GENERICPARAM_FLAGS] = 0x04;
else
values [MONO_GENERICPARAM_FLAGS] = 0x00;
values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, param->name);
values [MONO_GENERICPARAM_KIND] = 0;
- encode_constraints (gparam, table_idx, assembly);
+ encode_constraints (entry->gparam, table_idx, assembly);
}
static guint32
const gchar *name, guint32 sig)
{
MonoDynamicTable *table;
- guint32 parent, token;
+ guint32 token;
guint32 *values;
table = &assembly->tables [MONO_TABLE_MEMBERREF];
return token;
}
+static guint32
+mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
+{
+ MonoMethodInflated *imethod = (MonoMethodInflated *) m;
+ guint32 sig, token;
+
+ sig = method_encode_signature (assembly, imethod->declaring->signature);
+ token = mono_image_get_memberref_token (
+ assembly, &m->klass->byval_arg, m->name, sig);
+
+ return token;
+}
+
static guint32
create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb)
{
}
}
- /* handle generic parameters */
- if (tb->generic_params) {
- table = &assembly->tables [MONO_TABLE_GENERICPARAM];
- table->rows += mono_array_length (tb->generic_params);
- alloc_table (table, table->rows);
- for (i = 0; i < mono_array_length (tb->generic_params); ++i) {
- guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS);
-
- mono_image_get_generic_param_info (
- mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly);
- }
- }
-
/* handle fields */
if (tb->fields) {
table = &assembly->tables [MONO_TABLE_FIELD];
mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i), assembly);
}
+ /* handle generic parameters */
+ if (tb->generic_params) {
+ table = &assembly->tables [MONO_TABLE_GENERICPARAM];
+ table->rows += mono_array_length (tb->generic_params);
+ alloc_table (table, table->rows);
+ for (i = 0; i < mono_array_length (tb->generic_params); ++i) {
+ guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS);
+
+ mono_image_get_generic_param_info (
+ mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly);
+ }
+ }
+
mono_image_add_decl_security (assembly,
mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx),
tb->permissions);
return a_values [MONO_NESTED_CLASS_NESTED] - b_values [MONO_NESTED_CLASS_NESTED];
}
+static int
+compare_genericparam (const void *a, const void *b)
+{
+ const GenericParamTableEntry **a_entry = (const GenericParamTableEntry **) a;
+ const GenericParamTableEntry **b_entry = (const GenericParamTableEntry **) b;
+
+ return (*a_entry)->owner - (*b_entry)->owner;
+}
+
static void
pad_heap (MonoDynamicStream *sh)
{
}
}
+static struct StreamDesc {
+ const char *name;
+ MonoDynamicStream *stream;
+} stream_desc [5];
+
/*
* build_compressed_metadata() fills in the blob of data that represents the
* raw metadata as it will be saved in the PE file. The five streams are output
MonoImage *meta;
unsigned char *p;
- struct StreamDesc {
- const char *name;
- MonoDynamicStream *stream;
- } stream_desc [5];
+ qsort (assembly->gen_params->pdata, assembly->gen_params->len, sizeof (gpointer), compare_genericparam);
+ for (i = 0; i < assembly->gen_params->len; i++){
+ GenericParamTableEntry *entry = g_ptr_array_index (assembly->gen_params, i);
+ write_generic_param_entry (assembly, entry);
+ }
stream_desc[0].name = "#~"; stream_desc[0].stream = &assembly->tstream;
stream_desc[1].name = "#Strings"; stream_desc[1].stream = &assembly->sheap;
| ((guint64)1 << MONO_TABLE_FIELDLAYOUT) | ((guint64)1 << MONO_TABLE_FIELDRVA)
| ((guint64)1 << MONO_TABLE_IMPLMAP) | ((guint64)1 << MONO_TABLE_NESTEDCLASS)
| ((guint64)1 << MONO_TABLE_METHODIMPL) | ((guint64)1 << MONO_TABLE_CUSTOMATTRIBUTE)
- | ((guint64)1 << MONO_TABLE_DECLSECURITY);
+ | ((guint64)1 << MONO_TABLE_DECLSECURITY) | ((guint64)1 << MONO_TABLE_GENERICPARAM);
/* Compute table sizes */
/* the MonoImage has already been created in mono_image_basic_init() */
if (table->rows)
qsort (table->values + MONO_NESTED_CLASS_SIZE, table->rows, sizeof (guint32) * MONO_NESTED_CLASS_SIZE, compare_nested);
+
/* compress the tables */
for (i = 0; i < 64; i++){
int row, col;
sig = method_builder_encode_signature (assembly, &rmb);
- parent = mono_image_create_token (assembly, obj);
+ parent = mono_image_create_token (assembly, obj, TRUE);
g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
* TypeBuilder
*/
guint32
-mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
+mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
+ gboolean create_methodspec)
{
MonoClass *klass;
guint32 token = 0;
strcmp (klass->name, "MonoMethod") == 0) {
MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
if (m->method->signature->is_inflated) {
- token = mono_image_get_methodspec_token (assembly, m->method);
+ if (create_methodspec)
+ token = mono_image_get_methodspec_token (
+ assembly, m->method);
+ else
+ token = mono_image_get_inflated_method_token (
+ assembly, m->method);
} else if (m->method->signature->generic_param_count) {
g_assert_not_reached ();
} else if ((m->method->klass->image == &assembly->image) &&
MonoDynamicImage *image;
int i;
- /*
- * We need to use the current ms version or the ms runtime it won't find
- * the support dlls. D'oh!
- * const char *version = "mono-" VERSION;
- */
- /*
- * To make binaries default to the .Net 1.0 version
- * const char *version = "v1.0.3705";
- */
- const char *version = "v1.1.4322";
+ const char *version = mono_get_runtime_version ();
#if HAVE_BOEHM_GC
image = GC_MALLOC (sizeof (MonoDynamicImage));
image->typespec = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
image->blob_cache = mono_g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
+ image->gen_params = g_ptr_array_new ();
string_heap_init (&image->sheap);
mono_image_add_stream_data (&image->us, "", 1);
}
break;
case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
for (i = 0; i < alen; i++) {
MonoObject *item = load_cattr_value (image, &t->data.klass->byval_arg, p, &p);
g_free (klass->supertypes);
klass->supertypes = NULL;
mono_class_setup_parent (klass, parent);
+ mono_class_setup_mono_type (klass);
return;
}
num_clauses);
}
- if (rmb->generic_params) {
- int count = mono_array_length (rmb->generic_params);
- header->gen_params = g_new0 (MonoGenericParam, count);
- for (i = 0; i < count; i++) {
- MonoReflectionGenericParam *gp =
- mono_array_get (rmb->generic_params,
- MonoReflectionGenericParam*, i);
+ pm->header = header;
+ }
+
+ if (rmb->generic_params) {
+ int count = mono_array_length (rmb->generic_params);
+ pm->gen_params = g_new0 (MonoGenericParam, count);
+ for (i = 0; i < count; i++) {
+ MonoReflectionGenericParam *gp =
+ mono_array_get (rmb->generic_params,
+ MonoReflectionGenericParam*, i);
- header->gen_params [i] = *gp->type.type->data.generic_param;
- }
+ pm->gen_params [i] = *gp->type.type->data.generic_param;
}
-
- pm->header = header;
}
if (rmb->refs) {
{
MonoClass *klass;
MonoReflectionTypeBuilder *tb = NULL;
- MonoGenericInst *ginst;
+ MonoGenericInst *ginst, *cached;
MonoDomain *domain;
MonoType *geninst;
int icount, i;
ginst->generic_type = kginst->generic_type;
}
- geninst = g_hash_table_lookup (klass->image->generic_inst_cache, ginst);
- if (geninst) {
+ geninst = g_new0 (MonoType, 1);
+ geninst->type = MONO_TYPE_GENERICINST;
+
+ cached = g_hash_table_lookup (klass->image->generic_inst_cache, ginst);
+ if (cached) {
g_free (ginst);
mono_loader_unlock ();
+ geninst->data.generic_inst = cached;
return geninst;
}
+ geninst->data.generic_inst = ginst;
+
ginst->context = g_new0 (MonoGenericContext, 1);
ginst->context->ginst = ginst;
- geninst = g_new0 (MonoType, 1);
- geninst->type = MONO_TYPE_GENERICINST;
- geninst->data.generic_inst = ginst;
-
if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
tb = (MonoReflectionTypeBuilder *) type;
mono_class_create_generic (ginst);
- g_hash_table_insert (klass->image->generic_inst_cache, ginst, geninst);
+ g_hash_table_insert (klass->image->generic_inst_cache, ginst, ginst);
mono_loader_unlock ();
for (i = 0; i < gmethod->mtype_argc; i++) {
MonoMethodNormal *mn = (MonoMethodNormal *) method;
- MonoGenericParam *gparam = &mn->header->gen_params [i];
+ MonoGenericParam *gparam = &mn->gen_params [i];
g_assert (gparam->pklass);
gmethod->mtype_argv [i] = &gparam->pklass->byval_arg;