MonoReflectionType *rtype;
MonoArray *parameters;
MonoArray *generic_params;
+ MonoGenericContainer *generic_container;
MonoArray *pinfo;
MonoArray *opt_types;
guint32 attrs;
MonoMethod *mhandle;
guint32 nrefs;
gpointer *refs;
+ /* for PInvoke */
+ int charset, lasterr, native_cc;
+ MonoString *dll, *dllentry;
} ReflectionMethodBuilder;
+typedef struct {
+ guint32 owner;
+ MonoReflectionGenericParam *gparam;
+} GenericParamTableEntry;
+
const unsigned char table_sizes [64] = {
MONO_MODULE_SIZE,
MONO_TYPEREF_SIZE,
0 /* 0x2D */
};
-/**
- * These macros can be used to allocate long living atomic data so it won't be
- * tracked by the garbage collector. We use libgc because it's apparently faster
- * than g_malloc.
- */
-#ifdef HAVE_BOEHM_GC
-#define ALLOC_ATOMIC(size) GC_MALLOC_ATOMIC (size)
-#define FREE_ATOMIC(ptr)
-#define REALLOC_ATOMIC(ptr, size) GC_REALLOC ((ptr), (size))
-#else
-#define ALLOC_ATOMIC(size) g_malloc (size)
-#define FREE_ATOMIC(ptr) g_free (ptr)
-#define REALLOC_ATOMIC(ptr, size) g_realloc ((ptr), (size))
-#endif
-
static void reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb);
static void reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb);
static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
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 get_default_param_value_blobs (MonoMethod *method, char **blobs);
+static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob);
static void
table->rows = nrows;
g_assert (table->columns);
if (nrows + 1 >= table->alloc_rows) {
- while (nrows + 1 >= table->alloc_rows)
+ while (nrows + 1 >= table->alloc_rows) {
if (table->alloc_rows == 0)
table->alloc_rows = 16;
else
table->alloc_rows *= 2;
+ }
- if (table->values)
- table->values = REALLOC_ATOMIC (table->values, (table->alloc_rows) * table->columns * sizeof (guint32));
- else
- table->values = ALLOC_ATOMIC ((table->alloc_rows) * table->columns * sizeof (guint32));
+ table->values = g_renew (guint32, table->values, (table->alloc_rows) * table->columns);
}
}
static void
make_room_in_stream (MonoDynamicStream *stream, int size)
{
+ if (size <= stream->alloc_size)
+ return;
+
while (stream->alloc_size <= size) {
if (stream->alloc_size < 4096)
stream->alloc_size = 4096;
else
stream->alloc_size *= 2;
}
- if (stream->data)
- stream->data = REALLOC_ATOMIC (stream->data, stream->alloc_size);
- else
- stream->data = ALLOC_ATOMIC (stream->alloc_size);
-}
+
+ stream->data = g_realloc (stream->data, stream->alloc_size);
+}
+
+static void
+mono_dynamic_stream_reset (MonoDynamicStream* stream)
+{
+ stream->alloc_size = stream->index = stream->offset = 0;
+ g_free (stream->data);
+ if (stream->hash)
+ g_hash_table_destroy (stream->hash);
+}
static guint32
string_heap_insert (MonoDynamicStream *sh, const char *str)
len = strlen (str) + 1;
idx = sh->index;
- if (idx + len > sh->alloc_size)
- make_room_in_stream (sh, idx + len);
+
+ make_room_in_stream (sh, idx + len);
/*
* We strdup the string even if we already copy them in sh->data
{
sh->index = 0;
sh->alloc_size = 4096;
- sh->data = ALLOC_ATOMIC (4096);
+ sh->data = g_malloc (4096);
sh->hash = g_hash_table_new (g_str_hash, g_str_equal);
string_heap_insert (sh, "");
}
-#if 0 /* never used */
static void
string_heap_free (MonoDynamicStream *sh)
{
- FREE_ATOMIC (sh->data);
+ g_free (sh->data);
g_hash_table_foreach (sh->hash, (GHFunc)g_free, NULL);
g_hash_table_destroy (sh->hash);
}
-#endif
static guint32
mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
{
guint32 idx;
- if (stream->alloc_size < stream->index + len)
- make_room_in_stream (stream, stream->index + len);
+
+ make_room_in_stream (stream, stream->index + len);
memcpy (stream->data + stream->index, data, len);
idx = stream->index;
stream->index += len;
mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
{
guint32 idx;
- if (stream->alloc_size < stream->index + len)
- make_room_in_stream (stream, stream->index + len);
+
+ make_room_in_stream (stream, stream->index + len);
memset (stream->data + stream->index, 0, len);
idx = stream->index;
stream->index += len;
for (str += 1; str < end; str++)
h = (h << 5) - h + *str;
return h;
- }
- else
+ } else {
return 0;
+ }
}
static gboolean
char *copy;
gpointer oldkey, oldval;
- copy = ALLOC_ATOMIC (s1+s2);
+ copy = g_malloc (s1+s2);
memcpy (copy, b1, s1);
memcpy (copy + s1, b2, s2);
if (mono_g_hash_table_lookup_extended (assembly->blob_cache, copy, &oldkey, &oldval)) {
- FREE_ATOMIC (copy);
+ g_free (copy);
idx = GPOINTER_TO_UINT (oldval);
} else {
idx = mono_image_add_stream_data (&assembly->blob, b1, s1);
}
}
+static MonoClass *
+default_class_from_mono_type (MonoType *type)
+{
+ switch (type->type) {
+ case MONO_TYPE_OBJECT:
+ return mono_defaults.object_class;
+ case MONO_TYPE_VOID:
+ return mono_defaults.void_class;
+ case MONO_TYPE_BOOLEAN:
+ return mono_defaults.boolean_class;
+ case MONO_TYPE_CHAR:
+ return mono_defaults.char_class;
+ case MONO_TYPE_I1:
+ return mono_defaults.sbyte_class;
+ case MONO_TYPE_U1:
+ return mono_defaults.byte_class;
+ case MONO_TYPE_I2:
+ return mono_defaults.int16_class;
+ case MONO_TYPE_U2:
+ return mono_defaults.uint16_class;
+ case MONO_TYPE_I4:
+ return mono_defaults.int32_class;
+ case MONO_TYPE_U4:
+ return mono_defaults.uint32_class;
+ case MONO_TYPE_I:
+ return mono_defaults.int_class;
+ case MONO_TYPE_U:
+ return mono_defaults.uint_class;
+ case MONO_TYPE_I8:
+ return mono_defaults.int64_class;
+ case MONO_TYPE_U8:
+ return mono_defaults.uint64_class;
+ case MONO_TYPE_R4:
+ return mono_defaults.single_class;
+ case MONO_TYPE_R8:
+ return mono_defaults.double_class;
+ case MONO_TYPE_STRING:
+ return mono_defaults.string_class;
+ default:
+ g_warning ("implement me 0x%02x\n", type->type);
+ g_assert_not_reached ();
+ }
+
+ return NULL;
+}
+
static void
-encode_generic_inst (MonoDynamicImage *assembly, MonoGenericInst *ginst, char *p, char **endbuf)
+encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, char *p, char **endbuf)
{
int i;
- if (!ginst) {
+ if (!gclass) {
g_assert_not_reached ();
return;
}
mono_metadata_encode_value (MONO_TYPE_GENERICINST, p, &p);
- encode_type (assembly, ginst->generic_type, p, &p);
- mono_metadata_encode_value (ginst->type_argc, p, &p);
- for (i = 0; i < ginst->type_argc; ++i)
- encode_type (assembly, ginst->type_argv [i], p, &p);
+ encode_type (assembly, gclass->generic_type, p, &p);
+ mono_metadata_encode_value (gclass->inst->type_argc, p, &p);
+ for (i = 0; i < gclass->inst->type_argc; ++i)
+ encode_type (assembly, gclass->inst->type_argv [i], p, &p);
*endbuf = p;
}
mono_metadata_encode_value (type->type, p, &p);
encode_type (assembly, &type->data.klass->byval_arg, p, &p);
break;
-
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_CLASS: {
MonoClass *k = mono_class_from_mono_type (type);
mono_metadata_encode_value (mono_image_typedef_or_ref (assembly, &k->byval_arg), p, &p);
break;
}
-
case MONO_TYPE_ARRAY:
mono_metadata_encode_value (type->type, p, &p);
encode_type (assembly, &type->data.array->eklass->byval_arg, p, &p);
mono_metadata_encode_value (0, p, &p);
break;
case MONO_TYPE_GENERICINST:
- encode_generic_inst (assembly, type->data.generic_inst, p, &p);
+ encode_generic_class (assembly, type->data.generic_class, p, &p);
break;
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
mono_metadata_encode_value (type->type, p, &p);
mono_metadata_encode_value (type->data.generic_param->num, p, &p);
break;
-
default:
g_error ("need to encode type %x", type->type);
}
}
static guint32
-generic_inst_get_signature_size (MonoGenericInst *ginst)
+generic_class_get_signature_size (MonoGenericClass *gclass)
{
guint32 size = 0;
int i;
- if (!ginst) {
+ if (!gclass) {
g_assert_not_reached ();
}
- size += 1 + type_get_signature_size (ginst->generic_type);
+ size += 1 + type_get_signature_size (gclass->generic_type);
size += 4;
- for (i = 0; i < ginst->type_argc; ++i)
- size += type_get_signature_size (ginst->type_argv [i]);
+ for (i = 0; i < gclass->inst->type_argc; ++i)
+ size += type_get_signature_size (gclass->inst->type_argv [i]);
return size;
}
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);
+ return size + generic_class_get_signature_size (type->data.generic_class);
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
return size + 5;
-
default:
g_error ("need to encode type %x", type->type);
return size;
}
static MonoExceptionClause*
-method_encode_clauses (MonoDynamicImage *assembly,
- MonoReflectionILGen *ilgen, guint32 num_clauses)
+method_encode_clauses (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses)
{
MonoExceptionClause *clauses;
MonoExceptionClause *clause;
clause->try_len = ex_info->len;
clause->handler_offset = ex_block->start;
clause->handler_len = ex_block->len;
- clause->token_or_filter = ex_block->extype ? mono_metadata_token_from_dor (
- mono_image_typedef_or_ref (assembly, ex_block->extype->type)): 0;
if (ex_block->extype) {
- mono_g_hash_table_insert (assembly->tokens,
- GUINT_TO_POINTER (clause->token_or_filter),
- ex_block->extype);
+ clause->data.catch_class = mono_class_from_mono_type (ex_block->extype->type);
+ } else {
+ /* FIXME: handle filters */
+ clause->data.filter_offset = 0;
}
finally_start = ex_block->start + ex_block->len;
guint32 header_size = 12;
MonoArray *code;
- if ((mb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
- (mb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
- (mb->iattrs & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
- (mb->attrs & METHOD_ATTRIBUTE_ABSTRACT))
+ if ((mb->attrs & (METHOD_ATTRIBUTE_PINVOKE_IMPL | METHOD_ATTRIBUTE_ABSTRACT)) ||
+ (mb->iattrs & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)))
return 0;
/*if (mb->name)
max_stack = 8; /* we probably need to run a verifier on the code... */
}
+ stream_data_align (&assembly->code);
+
/* check for exceptions, maxstack, locals */
maybe_small = (max_stack <= 8) && (!num_locals) && (!num_exception);
if (maybe_small) {
mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
if (num_exception) {
unsigned char sheader [4];
- MonoExceptionClause clause;
MonoILExceptionInfo * ex_info;
MonoILExceptionBlock * ex_block;
int j;
stream_data_align (&assembly->code);
/* always use fat format for now */
sheader [0] = METHOD_HEADER_SECTION_FAT_FORMAT | METHOD_HEADER_SECTION_EHTABLE;
- num_exception *= sizeof (MonoExceptionClause);
+ num_exception *= 6 * sizeof (guint32);
num_exception += 4; /* include the size of the header */
sheader [1] = num_exception & 0xff;
sheader [2] = (num_exception >> 8) & 0xff;
if (ex_info->handlers) {
int finally_start = ex_info->start + ex_info->len;
for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
+ guint32 val;
ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
- clause.flags = GUINT32_TO_LE (ex_block->type);
- clause.try_offset = GUINT32_TO_LE (ex_info->start);
+ /* the flags */
+ val = GUINT32_TO_LE (ex_block->type);
+ mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
+ /* try offset */
+ val = GUINT32_TO_LE (ex_info->start);
+ mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
/* need fault, too, probably */
if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
- clause.try_len = GUINT32_TO_LE (finally_start - ex_info->start);
+ val = GUINT32_TO_LE (finally_start - ex_info->start);
else
- clause.try_len = GUINT32_TO_LE (ex_info->len);
- clause.handler_offset = GUINT32_TO_LE (ex_block->start);
- clause.handler_len = GUINT32_TO_LE (ex_block->len);
+ val = GUINT32_TO_LE (ex_info->len);
+ mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
+ /* handler offset */
+ val = GUINT32_TO_LE (ex_block->start);
+ mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
+ /* handler len */
+ val = GUINT32_TO_LE (ex_block->len);
+ mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
finally_start = ex_block->start + ex_block->len;
- clause.token_or_filter = ex_block->extype ? mono_metadata_token_from_dor (
- mono_image_typedef_or_ref (assembly, ex_block->extype->type)): 0;
- clause.token_or_filter = GUINT32_TO_LE (clause.token_or_filter);
+ if (ex_block->extype) {
+ val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, ex_block->extype->type));
+ } else {
+ /* FIXME: handle filters */
+ val = 0;
+ }
+ val = GUINT32_TO_LE (val);
+ mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
/*g_print ("out clause %d: from %d len=%d, handler at %d, %d, finally_start=%d, ex_info->start=%d, ex_info->len=%d, ex_block->type=%d, j=%d, i=%d\n",
clause.flags, clause.try_offset, clause.try_len, clause.handler_offset, clause.handler_len, finally_start, ex_info->start, ex_info->len, ex_block->type, j, i);*/
- mono_image_add_stream_data (&assembly->code, (char*)&clause, sizeof (clause));
}
} else {
g_error ("No clauses for ex info block %d", i);
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)) {
}
static void
-mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token,
- MonoArray *permissions)
+mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token, MonoArray *permissions)
{
MonoDynamicTable *table;
guint32 *values;
values [MONO_METHOD_PARAMLIST] = table->next_idx;
mono_image_add_decl_security (assembly,
- mono_metadata_make_token (MONO_TABLE_METHOD, *mb->table_idx),
- mb->permissions);
+ mono_metadata_make_token (MONO_TABLE_METHOD, *mb->table_idx), mb->permissions);
if (mb->pinfo) {
MonoDynamicTable *mtable;
}
static void
-reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb,
- MonoReflectionMethodBuilder *mb)
+reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb)
{
rmb->ilgen = mb->ilgen;
rmb->rtype = mb->rtype;
rmb->parameters = mb->parameters;
rmb->generic_params = mb->generic_params;
+ rmb->generic_container = mb->generic_container;
rmb->opt_types = NULL;
rmb->pinfo = mb->pinfo;
rmb->attrs = mb->attrs;
rmb->mhandle = mb->mhandle;
rmb->nrefs = 0;
rmb->refs = NULL;
+
+ if (mb->dll) {
+ rmb->charset = rmb->charset & 0xf;
+ rmb->lasterr = rmb->charset & 0x40;
+ rmb->native_cc = rmb->native_cc;
+ rmb->dllentry = mb->dllentry;
+ rmb->dll = mb->dll;
+ }
}
static void
-reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb,
- MonoReflectionCtorBuilder *mb)
+reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb)
{
const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
rmb->rtype = mono_type_get_object (mono_domain_get (), &mono_defaults.void_class->byval_arg);
rmb->parameters = mb->parameters;
rmb->generic_params = NULL;
+ rmb->generic_container = NULL;
rmb->opt_types = NULL;
rmb->pinfo = mb->pinfo;
rmb->attrs = mb->attrs;
}
static void
-reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb,
- MonoReflectionDynamicMethod *mb)
+reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
{
rmb->ilgen = mb->ilgen;
rmb->rtype = mb->rtype;
rmb->parameters = mb->parameters;
rmb->generic_params = NULL;
+ rmb->generic_container = NULL;
rmb->opt_types = NULL;
rmb->pinfo = NULL;
rmb->attrs = mb->attrs;
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;
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.public_key_token [0] ? ta->aname.public_key_token : "null");
+ ta->aname.public_key_token [0] ? (char *)ta->aname.public_key_token : "null");
g_free (name);
return result;
}
MonoAssembly *ta;
klass = my_mono_class_from_mono_type (type);
+ if (!klass)
+ return mono_type_get_name (type);
ta = klass->image->assembly;
if (ta == ass || klass->image == mono_defaults.corlib)
return mono_type_get_name (type);
char *buf, *p;
if (!NewConstraintAttr)
- NewConstraintAttr = mono_class_from_name (
- mono_defaults.corlib, "System.Runtime.CompilerServices",
- "NewConstraintAttribute");
+ NewConstraintAttr = mono_class_from_name ( mono_defaults.corlib,
+ "System.Runtime.CompilerServices", "NewConstraintAttribute");
g_assert (NewConstraintAttr);
if (!NewConstraintAttr_ctor) {
assembly, constraint->type);
}
- if (gparam->has_ctor_constraint)
+ if (gparam->attrs & GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT)
encode_new_constraint (assembly, owner);
}
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_FLAGS] = 0x18;
- else if (gparam->has_reference_type)
- values [MONO_GENERICPARAM_FLAGS] = 0x04;
- else
- values [MONO_GENERICPARAM_FLAGS] = 0x00;
+ values [MONO_GENERICPARAM_OWNER] = entry->owner;
+ values [MONO_GENERICPARAM_FLAGS] = entry->gparam->attrs;
values [MONO_GENERICPARAM_NUMBER] = param->num;
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
case MONO_TYPE_CLASS:
case MONO_TYPE_VALUETYPE: {
MonoClass *k = mono_class_from_mono_type (type);
- if (!k || !k->generic_inst)
+ if (!k || !k->generic_class)
return 0;
- encode_generic_inst (assembly, k->generic_inst, p, &p);
+ encode_generic_class (assembly, k->generic_class, p, &p);
break;
}
default:
/*
* If it's in the same module and not a generic type parameter:
*/
- if ((klass->image == &assembly->image) &&
- (type->type != MONO_TYPE_VAR) && (type->type != MONO_TYPE_MVAR)) {
+ if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) &&
+ (type->type != MONO_TYPE_MVAR)) {
MonoReflectionTypeBuilder *tb = klass->reflection_info;
token = MONO_TYPEDEFORREF_TYPEDEF | (tb->table_idx << MONO_TYPEDEFORREF_BITS);
mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), klass->reflection_info);
mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method)
{
guint32 token;
+ MonoMethodSignature *sig;
token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
if (token)
return token;
+
+ /*
+ * A methodref signature can't contain an unmanaged calling convention.
+ */
+ sig = mono_metadata_signature_dup (method->signature);
+ if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
+ sig->call_convention = MONO_CALL_DEFAULT;
token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
- method->name, method_encode_signature (assembly, method->signature));
+ method->name, method_encode_signature (assembly, sig));
+ g_free (sig);
g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
return token;
}
const gchar *name, guint32 sig)
{
MonoDynamicTable *table;
- guint32 parent, token;
+ guint32 token;
guint32 *values;
table = &assembly->tables [MONO_TABLE_MEMBERREF];
reflection_methodbuilder_from_method_builder (&rmb, mb);
token = mono_image_get_memberref_token (assembly, ((MonoReflectionTypeBuilder*)rmb.type)->type.type,
- mono_string_to_utf8 (rmb.name),
- method_builder_encode_signature (assembly, &rmb));
+ mono_string_to_utf8 (rmb.name), method_builder_encode_signature (assembly, &rmb));
g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
return token;
}
reflection_methodbuilder_from_ctor_builder (&rmb, mb);
token = mono_image_get_memberref_token (assembly, ((MonoReflectionTypeBuilder*)rmb.type)->type.type,
- mono_string_to_utf8 (rmb.name),
- method_builder_encode_signature (assembly, &rmb));
+ mono_string_to_utf8 (rmb.name), method_builder_encode_signature (assembly, &rmb));
g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
return token;
}
char *buf;
char *p;
int i;
- guint32 nparams = gmethod->mtype_argc;
+ guint32 nparams = gmethod->inst->type_argc;
guint32 size = 10 + nparams * 10;
guint32 idx;
char blob_size [6];
mono_metadata_encode_value (nparams, p, &p);
for (i = 0; i < nparams; i++)
- encode_type (assembly, gmethod->mtype_argv [i], p, &p);
+ encode_type (assembly, gmethod->inst->type_argv [i], p, &p);
/* store length */
g_assert (p - buf < size);
declaring = imethod->declaring;
sig = method_encode_signature (assembly, declaring->signature);
- mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
- declaring->name, sig);
+ mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
if (!declaring->signature->generic_param_count)
return mtoken;
g_assert (m->signature->is_inflated);
imethod = (MonoMethodInflated *) m;
- if (imethod->declaring->signature->generic_param_count)
+ if (imethod->declaring->signature->generic_param_count) {
token = method_encode_methodspec (assembly, m);
- else {
+ } else {
guint32 sig = method_encode_signature (
assembly, imethod->declaring->signature);
token = mono_image_get_memberref_token (
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)
{
if (helper->call_conv & 0x40)
helper->call_conv &= 0x20;
- if (helper->call_conv == 0) /* Unmanaged */
+ if (helper->call_conv == 0) { /* Unmanaged */
*p = helper->unmanaged_call_conv - 1;
- else {
+ } else {
/* Managed */
*p = helper->call_conv & 0x60; /* has_this + explicit_this */
if (helper->call_conv & 0x02) /* varargs */
am->name = name;
am->sig = sig;
am->parent = m->parent->type;
- am->token = mono_image_get_memberref_token (assembly, am->parent,
- name, method_encode_signature (assembly, sig));
+ am->token = mono_image_get_memberref_token (assembly, am->parent, name,
+ method_encode_signature (assembly, sig));
assembly->array_methods = g_list_prepend (assembly->array_methods, am);
m->table_idx = am->token & 0xffffff;
return am->token;
values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, n);
g_free (n);
if (tb->parent && !(is_system && is_object) &&
- !(tb->attrs & TYPE_ATTRIBUTE_INTERFACE)) { /* interfaces don't have a parent */
+ !(tb->attrs & TYPE_ATTRIBUTE_INTERFACE)) { /* interfaces don't have a parent */
values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, tb->parent->type);
- } else
+ } else {
values [MONO_TYPEDEF_EXTENDS] = 0;
+ }
values [MONO_TYPEDEF_FIELD_LIST] = assembly->tables [MONO_TABLE_FIELD].next_idx;
values [MONO_TYPEDEF_METHOD_LIST] = assembly->tables [MONO_TABLE_METHOD].next_idx;
* ClassLayout table.
*/
if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) &&
- ((tb->class_size > 0) || (tb->packing_size > 0))) {
+ ((tb->class_size > 0) || (tb->packing_size > 0))) {
table = &assembly->tables [MONO_TABLE_CLASSLAYOUT];
table->rows++;
alloc_table (table, table->rows);
}
}
- /* 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);
+ mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx), tb->permissions);
if (tb->subtypes) {
MonoDynamicTable *ntable;
}
static gint
-compare_types_by_table_idx (MonoReflectionTypeBuilder **type1,
- MonoReflectionTypeBuilder **type2)
+compare_types_by_table_idx (MonoReflectionTypeBuilder **type1, MonoReflectionTypeBuilder **type2)
{
if ((*type1)->table_idx < (*type2)->table_idx)
return -1;
}
static void
-mono_image_fill_file_table (MonoDomain *domain, MonoReflectionModule *module,
- MonoDynamicImage *assembly)
+mono_image_fill_file_table (MonoDomain *domain, MonoReflectionModule *module, MonoDynamicImage *assembly)
{
MonoDynamicTable *table;
guint32 *values;
/* This depends on the fact that the main module is emitted last */
dir = mono_string_to_utf8 (((MonoReflectionModuleBuilder*)module)->assemblyb->dir);
path = g_strdup_printf ("%s%c%s", dir, G_DIR_SEPARATOR, module->image->module_name);
- }
- else {
+ } else {
dir = NULL;
path = g_strdup (module->image->name);
}
static guint32
mono_image_fill_export_table_from_class (MonoDomain *domain, MonoClass *klass,
- guint32 module_index, guint32 parent_index,
- MonoDynamicImage *assembly)
+ guint32 module_index, guint32 parent_index, MonoDynamicImage *assembly)
{
MonoDynamicTable *table;
guint32 *values;
static void
mono_image_fill_export_table (MonoDomain *domain, MonoReflectionTypeBuilder *tb,
- guint32 module_index, guint32 parent_index,
- MonoDynamicImage *assembly)
+ guint32 module_index, guint32 parent_index, MonoDynamicImage *assembly)
{
MonoClass *klass;
guint32 idx, i;
static void
mono_image_fill_export_table_from_module (MonoDomain *domain, MonoReflectionModule *module,
- guint32 module_index,
- MonoDynamicImage *assembly)
+ guint32 module_index, MonoDynamicImage *assembly)
{
MonoImage *image = module->image;
MonoTableInfo *t;
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;
+
+ if ((*b_entry)->owner == (*a_entry)->owner)
+ return
+ (*a_entry)->gparam->type.type->data.generic_param->num -
+ (*b_entry)->gparam->type.type->data.generic_param->num;
+ else
+ return (*b_entry)->owner - (*a_entry)->owner;
+}
+
+static int
+compare_declsecurity_attrs (const void *a, const void *b)
+{
+ const guint32 *a_values = a;
+ const guint32 *b_values = b;
+
+ return a_values [MONO_DECL_SECURITY_PARENT] - b_values [MONO_DECL_SECURITY_PARENT];
+}
+
static void
pad_heap (MonoDynamicStream *sh)
{
}
}
+struct StreamDesc {
+ const char *name;
+ MonoDynamicStream *stream;
+};
+
/*
* 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
guint16 *int16val;
MonoImage *meta;
unsigned char *p;
-
- struct StreamDesc {
- const char *name;
- MonoDynamicStream *stream;
- } stream_desc [5];
-
- stream_desc[0].name = "#~"; stream_desc[0].stream = &assembly->tstream;
- stream_desc[1].name = "#Strings"; stream_desc[1].stream = &assembly->sheap;
- stream_desc[2].name = "#US"; stream_desc[2].stream = &assembly->us;
- stream_desc[3].name = "#Blob"; stream_desc[3].stream = &assembly->blob;
- stream_desc[4].name = "#GUID"; stream_desc[4].stream = &assembly->guid;
+ struct StreamDesc 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;
+ stream_desc [2].name = "#US";
+ stream_desc [2].stream = &assembly->us;
+ stream_desc [3].name = "#Blob";
+ stream_desc [3].stream = &assembly->blob;
+ stream_desc [4].name = "#GUID";
+ stream_desc [4].stream = &assembly->guid;
/* tables that are sorted */
sorted_mask = ((guint64)1 << MONO_TABLE_CONSTANT) | ((guint64)1 << MONO_TABLE_FIELDMARSHAL)
| ((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() */
int32val = (guint32*)p;
*int32val = GUINT32_TO_LE ((strlen (meta->version) + 3) & (~3)); /* needs to be multiple of 4 */
p += 4;
- memcpy (p, meta->version, GUINT32_FROM_LE (*int32val));
+ memcpy (p, meta->version, strlen (meta->version));
p += GUINT32_FROM_LE (*int32val);
align_pointer (meta->raw_metadata, p);
int16val = (guint16*)p;
p += 4;
if ((assembly->tables [MONO_TABLE_GENERICPARAM].rows > 0) ||
- (assembly->tables [MONO_TABLE_METHODSPEC].rows > 0) ||
- (assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT].rows > 0)) {
+ (assembly->tables [MONO_TABLE_METHODSPEC].rows > 0) ||
+ (assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT].rows > 0)) {
*p++ = 1; /* version */
*p++ = 1;
} else {
if (meta->idx_blob_wide)
*p |= 0x04;
++p;
- *p++ = 0; /* reserved */
+ *p++ = 1; /* reserved */
int64val = (guint64*)p;
*int64val++ = GUINT64_TO_LE (valid_mask);
*int64val++ = GUINT64_TO_LE (valid_mask & sorted_mask); /* bitvector of sorted tables */
table = &assembly->tables [MONO_TABLE_NESTEDCLASS];
if (table->rows)
qsort (table->values + MONO_NESTED_CLASS_SIZE, table->rows, sizeof (guint32) * MONO_NESTED_CLASS_SIZE, compare_nested);
+ /* Section 21.11 DeclSecurity in Partition II doesn't specify this to be sorted by MS implementation requires it */
+ table = &assembly->tables [MONO_TABLE_DECLSECURITY];
+ if (table->rows)
+ qsort (table->values + MONO_DECL_SECURITY_SIZE, table->rows, sizeof (guint32) * MONO_DECL_SECURITY_SIZE, compare_declsecurity_attrs);
/* compress the tables */
for (i = 0; i < 64; i++){
} else if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod") ||
!strcmp (iltoken->member->vtable->klass->name, "MonoCMethod")) {
MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
- g_assert (m->klass->generic_inst);
+ g_assert (m->klass->generic_class);
continue;
} else if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
continue;
if (file_module->types) {
for (j = 0; j < file_module->num_types; ++j) {
MonoReflectionTypeBuilder *tb = mono_array_get (file_module->types, MonoReflectionTypeBuilder*, j);
- mono_image_fill_export_table (domain, tb, module_index, 0,
- assembly);
+ mono_image_fill_export_table (domain, tb, module_index, 0, assembly);
}
}
}
alloc_table (table, table->rows);
for (i = 0; i < mono_array_length (moduleb->global_methods); ++i)
mono_image_get_method_info (
- mono_array_get (moduleb->global_methods, MonoReflectionMethodBuilder*, i), assembly);
+ mono_array_get (moduleb->global_methods, MonoReflectionMethodBuilder*, i), assembly);
}
if (moduleb->global_fields) {
table = &assembly->tables [MONO_TABLE_FIELD];
alloc_table (table, table->rows);
for (i = 0; i < mono_array_length (moduleb->global_fields); ++i)
mono_image_get_field_info (
- mono_array_get (moduleb->global_fields, MonoReflectionFieldBuilder*, i), assembly);
+ mono_array_get (moduleb->global_fields, MonoReflectionFieldBuilder*, i), assembly);
}
table = &assembly->tables [MONO_TABLE_MODULE];
/* add all the custom attributes at the end, once all the indexes are stable */
mono_image_add_cattrs (assembly, 1, MONO_CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs);
+ /* CAS assembly permissions */
+ if (assemblyb->permissions_minimum)
+ mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_minimum);
+ if (assemblyb->permissions_optional)
+ mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_optional);
+ if (assemblyb->permissions_refused)
+ mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_refused);
+
module_add_cattrs (assembly, moduleb);
/* fixup tokens */
g_free (swapped);
}
#else
- mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
+ mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
#endif
- mono_image_add_stream_data (&assembly->us, "", 1);
- }
- else
+ mono_image_add_stream_data (&assembly->us, "", 1);
+ } else {
idx = assembly->us.index ++;
+ }
- mono_g_hash_table_insert (assembly->tokens,
- GUINT_TO_POINTER (MONO_TOKEN_STRING | idx), str);
+ mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (MONO_TOKEN_STRING | idx), str);
return MONO_TOKEN_STRING | idx;
}
guint32
-mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj,
- MonoArray *opt_param_types)
+mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types)
{
MonoClass *klass;
guint32 token = 0;
nargs = mono_array_length (opt_param_types);
old = method->signature;
- sig = mono_metadata_signature_alloc (
- &assembly->image, old->param_count + nargs);
+ sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
sig->hasthis = old->hasthis;
sig->explicit_this = old->explicit_this;
sig->params [i] = old->params [i];
for (i = 0; i < nargs; i++) {
- MonoReflectionType *rt = mono_array_get (
- opt_param_types, MonoReflectionType *, i);
+ MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
sig->params [old->param_count + i] = rt->type;
}
parent |= MONO_MEMBERREF_PARENT_TYPEREF;
sig_token = method_encode_signature (assembly, sig);
- token = mono_image_get_varargs_method_token (
- assembly, parent, method->name, sig_token);
+ token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
} else if (strcmp (klass->name, "MethodBuilder") == 0) {
MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
ReflectionMethodBuilder rmb;
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;
token = mono_image_get_varargs_method_token (
assembly, parent, mono_string_to_utf8 (rmb.name), sig);
- } else
+ } else {
g_error ("requested method token for %s\n", klass->name);
+ }
return token;
}
* 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;
else
token = mono_image_get_methodbuilder_token (assembly, mb);
/*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
- }
- else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
+ } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
if (((MonoReflectionTypeBuilder*)mb->type)->module->dynamic_image == assembly)
else
token = mono_image_get_ctorbuilder_token (assembly, mb);
/*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
- }
- else if (strcmp (klass->name, "FieldBuilder") == 0) {
+ } else if (strcmp (klass->name, "FieldBuilder") == 0) {
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
if (tb->generic_params) {
} else {
token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
}
- }
- else if (strcmp (klass->name, "TypeBuilder") == 0) {
+ } else if (strcmp (klass->name, "TypeBuilder") == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
- }
- else if (strcmp (klass->name, "MonoType") == 0 ||
+ } else if (strcmp (klass->name, "MonoType") == 0 ||
strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
MonoReflectionType *tb = (MonoReflectionType *)obj;
token = mono_metadata_token_from_dor (
mono_image_typedef_or_ref (assembly, tb->type));
- }
- else if (strcmp (klass->name, "MonoGenericInst") == 0) {
+ } else if (strcmp (klass->name, "MonoGenericClass") == 0) {
MonoReflectionType *tb = (MonoReflectionType *)obj;
token = mono_metadata_token_from_dor (
mono_image_typedef_or_ref (assembly, tb->type));
- }
- else if (strcmp (klass->name, "MonoCMethod") == 0 ||
+ } else if (strcmp (klass->name, "MonoCMethod") == 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);
- } else if (m->method->signature->generic_param_count) {
- g_assert_not_reached ();
+ 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->klass->image == &assembly->image) &&
- !m->method->klass->generic_inst) {
+ !m->method->klass->generic_class) {
static guint32 method_table_idx = 0xffffff;
if (m->method->klass->wastypebuilder) {
/* we use the same token as the one that was assigned
method_table_idx --;
token = MONO_TOKEN_METHOD_DEF | method_table_idx;
}
- } else
+ } else {
token = mono_image_get_methodref_token (assembly, m->method);
+ }
/*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
- }
- else if (strcmp (klass->name, "MonoField") == 0) {
+ } else if (strcmp (klass->name, "MonoField") == 0) {
MonoReflectionField *f = (MonoReflectionField *)obj;
if ((f->klass->image == &assembly->image) && !f->field->generic_info) {
static guint32 field_table_idx = 0xffffff;
field_table_idx --;
token = MONO_TOKEN_FIELD_DEF | field_table_idx;
- } else
+ } else {
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) {
+ } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
token = mono_image_get_array_token (assembly, m);
- }
- else if (strcmp (klass->name, "SignatureHelper") == 0) {
+ } else if (strcmp (klass->name, "SignatureHelper") == 0) {
MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s);
- }
- else
+ } else {
g_error ("requested token for %s\n", klass->name);
+ }
- mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token),
- obj);
+ mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj);
return token;
}
static void register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
static MonoDynamicImage*
-create_dynamic_mono_image (MonoDynamicAssembly *assembly,
- char *assembly_name, char *module_name)
+create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, char *module_name)
{
static const guchar entrycode [16] = {0xff, 0x25, 0};
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);
mono_image_add_stream_data (&image->code, entrycode, sizeof (entrycode));
image->iat_offset = mono_image_add_stream_zero (&image->code, 8); /* two IAT entries */
image->idt_offset = mono_image_add_stream_zero (&image->code, 2 * sizeof (MonoIDT)); /* two IDT entries */
- mono_image_add_stream_zero (&image->code, 2); /* flags for name entry */
- image->imp_names_offset = mono_image_add_stream_data (&image->code, "_CorExeMain", 12);
+ image->imp_names_offset = mono_image_add_stream_zero (&image->code, 2); /* flags for name entry */
+ mono_image_add_stream_data (&image->code, "_CorExeMain", 12);
mono_image_add_stream_data (&image->code, "mscoree.dll", 12);
image->ilt_offset = mono_image_add_stream_zero (&image->code, 8); /* two ILT entries */
stream_data_align (&image->code);
image->image.assembly = (MonoAssembly*)assembly;
image->run = assembly->run;
image->save = assembly->save;
+ image->pe_kind = 0x1; /* ILOnly */
+ image->machine = 0x14c; /* I386 */
return image;
}
#endif
assembly->assembly.dynamic = TRUE;
+ assembly->assembly.corlib_internal = assemblyb->corlib_internal;
assemblyb->assembly.assembly = (MonoAssembly*)assembly;
assembly->assembly.basedir = mono_string_to_utf8 (assemblyb->dir);
if (assemblyb->culture)
assembly->save = assemblyb->access != 1;
image = create_dynamic_mono_image (assembly, mono_string_to_utf8 (assemblyb->name), g_strdup ("RefEmit_YouForgotToDefineAModule"));
+ image->initial_image = TRUE;
assembly->assembly.aname.name = image->image.name;
assembly->assembly.image = &image->image;
* The resource types have to be sorted otherwise
* Windows Explorer can't display the version information.
*/
- tree->children = g_slist_insert_sorted (tree->children, type_node,
- resource_tree_compare_by_id);
+ tree->children = g_slist_insert_sorted (tree->children,
+ type_node, resource_tree_compare_by_id);
}
/* Create res node if neccesary */
memcpy (p, mono_array_addr (child->win32_res->res_data, char, 0), data_entry.rde_size);
p += data_entry.rde_size;
- }
- else
+ } else {
resource_tree_encode (child, begin, p, &p);
+ }
}
/* IMAGE_RESOURCE_ENTRY */
for (i = 0; i < dir->res_named_entries + dir->res_id_entries; ++i) {
MonoPEResourceDirEntry *dir_entry = (MonoPEResourceDirEntry*)p;
char *child = res_section + (GUINT32_FROM_LE (dir_entry->dir_offset));
- if (dir_entry->is_dir)
+ if (dir_entry->is_dir) {
fixup_resource_directory (res_section, child, rva);
- else {
+ } else {
MonoPEResourceDataEntry *data_entry = (MonoPEResourceDataEntry*)child;
data_entry->rde_data_offset = GUINT32_TO_LE (GUINT32_FROM_LE (data_entry->rde_data_offset) + rva);
}
}
}
+static void
+checked_write_file (HANDLE f, gconstpointer buffer, guint32 numbytes)
+{
+ guint32 dummy;
+ if (!WriteFile (f, buffer, numbytes, &dummy, NULL))
+ g_error ("WriteFile returned %d\n", GetLastError ());
+}
+
/*
* mono_image_create_pefile:
* @mb: a module builder object
* assembly->pefile where it can be easily retrieved later in chunks.
*/
void
-mono_image_create_pefile (MonoReflectionModuleBuilder *mb) {
+mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file) {
MonoMSDOSHeader *msdos;
MonoDotNetHeader *header;
MonoSectionTable *section;
guint32 header_start, section_start, file_offset, virtual_offset;
MonoDynamicImage *assembly;
MonoReflectionAssemblyBuilder *assemblyb;
- MonoDynamicStream *pefile;
+ MonoDynamicStream pefile_stream = {0};
+ MonoDynamicStream *pefile = &pefile_stream;
int i, nsections;
guint32 *rva, value;
- guint16 *data16;
guchar *p;
static const unsigned char msheader[] = {
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
mono_image_basic_init (assemblyb);
assembly = mb->dynamic_image;
- /* already created */
- if (assembly->pefile.index)
- return;
+ assembly->pe_kind = assemblyb->pe_kind;
+ assembly->machine = assemblyb->machine;
+ ((MonoDynamicImage*)assemblyb->dynamic_assembly->assembly.image)->pe_kind = assemblyb->pe_kind;
+ ((MonoDynamicImage*)assemblyb->dynamic_assembly->assembly.image)->machine = assemblyb->machine;
mono_image_build_metadata (mb);
assembly_add_win32_resources (assembly, assemblyb);
nsections = calc_section_size (assembly);
-
- pefile = &assembly->pefile;
-
+
/* The DOS header and stub */
g_assert (sizeof (MonoMSDOSHeader) == sizeof (msheader));
mono_image_add_stream_data (pefile, msheader, sizeof (msheader));
file_offset += FILE_ALIGN - 1;
file_offset &= ~(FILE_ALIGN - 1);
- mono_image_add_stream_zero (pefile, file_offset - pefile->index);
image_size += section_start + sizeof (MonoSectionTable) * nsections;
header->pesig [0] = 'P';
header->pesig [1] = 'E';
- header->coff.coff_machine = GUINT16_FROM_LE (0x14c);
+ header->coff.coff_machine = GUINT16_FROM_LE (assemblyb->machine);
header->coff.coff_sections = GUINT16_FROM_LE (nsections);
header->coff.coff_time = GUINT32_FROM_LE (time (NULL));
header->coff.coff_opt_header_size = GUINT16_FROM_LE (sizeof (MonoDotNetHeader) - sizeof (MonoCOFFHeader) - 4);
header->datadir.pe_cli_header.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->cli_header_offset);
header->datadir.pe_iat.size = GUINT32_FROM_LE (8);
header->datadir.pe_iat.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->iat_offset);
+ /* patch entrypoint name */
+ if (assemblyb->pekind == 1)
+ memcpy (assembly->code.data + assembly->imp_names_offset + 2, "_CorDllMain", 12);
+ else
+ memcpy (assembly->code.data + assembly->imp_names_offset + 2, "_CorExeMain", 12);
/* patch imported function RVA name */
rva = (guint32*)(assembly->code.data + assembly->iat_offset);
*rva = GUINT32_FROM_LE (assembly->text_rva + assembly->imp_names_offset);
header->datadir.pe_import_table.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->idt_offset);
/* patch imported dll RVA name and other entries in the dir */
rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, name_rva));
- *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->imp_names_offset + 12); /* 12 is strlen+1 of func name */
+ *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->imp_names_offset + 14); /* 14 is hint+strlen+1 of func name */
rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, import_address_table_rva));
*rva = GUINT32_FROM_LE (assembly->text_rva + assembly->iat_offset);
rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, import_lookup_table));
*rva = GUINT32_FROM_LE (assembly->text_rva + assembly->ilt_offset);
p = (assembly->code.data + assembly->ilt_offset);
- value = (assembly->text_rva + assembly->imp_names_offset - 2);
+ value = (assembly->text_rva + assembly->imp_names_offset);
*p++ = (value) & 0xff;
*p++ = (value >> 8) & (0xff);
*p++ = (value >> 16) & (0xff);
cli_header = (MonoCLIHeader*)(assembly->code.data + assembly->cli_header_offset);
cli_header->ch_size = GUINT32_FROM_LE (72);
cli_header->ch_runtime_major = GUINT16_FROM_LE (2);
- cli_header->ch_flags = GUINT32_FROM_LE (CLI_FLAGS_ILONLY);
+ cli_header->ch_flags = GUINT32_FROM_LE (assemblyb->pe_kind);
if (assemblyb->entry_point) {
guint32 table_idx = 0;
if (!strcmp (assemblyb->entry_point->object.vtable->klass->name, "MethodBuilder")) {
MonoReflectionMethodBuilder *methodb = (MonoReflectionMethodBuilder*)assemblyb->entry_point;
table_idx = methodb->table_idx;
- }
- else
+ } else {
table_idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, assemblyb->entry_point->method));
+ }
cli_header->ch_entry_point = GUINT32_FROM_LE (table_idx | MONO_TOKEN_METHOD_DEF);
- }
- else
+ } else {
cli_header->ch_entry_point = GUINT32_FROM_LE (0);
+ }
/* The embedded managed resources */
text_offset = assembly->text_rva + assembly->code.index;
cli_header->ch_resources.rva = GUINT32_FROM_LE (text_offset);
section->st_raw_data_size &= GUINT32_FROM_LE (~(FILE_ALIGN - 1));
section->st_raw_data_ptr = GUINT32_FROM_LE (assembly->sections [i].offset);
section->st_flags = GUINT32_FROM_LE (assembly->sections [i].attrs);
+ section ++;
+ }
+
+ checked_write_file (file, pefile->data, pefile->index);
+
+ mono_dynamic_stream_reset (pefile);
+
+ for (i = 0; i < MONO_SECTION_MAX; ++i) {
+ if (!assembly->sections [i].size)
+ continue;
+
+ if (SetFilePointer (file, assembly->sections [i].offset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+ g_error ("SetFilePointer returned %d\n", GetLastError ());
+
switch (i) {
case MONO_SECTION_TEXT:
/* patch entry point */
*p++ = (value >> 8) & 0xff;
*p++ = (value >> 16) & 0xff;
*p++ = (value >> 24) & 0xff;
-
- text_offset = assembly->sections [i].offset;
- memcpy (pefile->data + text_offset, assembly->code.data, assembly->code.index);
- text_offset += assembly->code.index;
- memcpy (pefile->data + text_offset, assembly->resources.data, assembly->resources.index);
- text_offset += assembly->resources.index;
- memcpy (pefile->data + text_offset, assembly->image.raw_metadata, assembly->meta_size);
- text_offset += assembly->meta_size;
- memcpy (pefile->data + text_offset, assembly->strong_name, assembly->strong_name_size);
+
+ checked_write_file (file, assembly->code.data, assembly->code.index);
+ checked_write_file (file, assembly->resources.data, assembly->resources.index);
+ checked_write_file (file, assembly->image.raw_metadata, assembly->meta_size);
+ checked_write_file (file, assembly->strong_name, assembly->strong_name_size);
+
g_free (assembly->image.raw_metadata);
break;
- case MONO_SECTION_RELOC:
- rva = (guint32*)(pefile->data + assembly->sections [i].offset);
- *rva = GUINT32_FROM_LE (assembly->text_rva);
- ++rva;
- *rva = GUINT32_FROM_LE (12);
- ++rva;
- data16 = (guint16*)rva;
+ case MONO_SECTION_RELOC: {
+ struct {
+ guint32 page_rva;
+ guint32 block_size;
+ guint16 type_and_offset;
+ guint16 term;
+ } reloc;
+
+ g_assert (sizeof (reloc) == 12);
+
+ reloc.page_rva = GUINT32_FROM_LE (assembly->text_rva);
+ reloc.block_size = GUINT32_FROM_LE (12);
+
/*
* the entrypoint is always at the start of the text section
* 3 is IMAGE_REL_BASED_HIGHLOW
* 2 is patch_size_rva - text_rva
*/
- *data16 = GUINT16_FROM_LE ((3 << 12) + (2));
- data16++;
- *data16 = 0; /* terminate */
+ reloc.type_and_offset = GUINT16_FROM_LE ((3 << 12) + (2));
+ reloc.term = 0;
+
+ checked_write_file (file, &reloc, sizeof (reloc));
+
break;
+ }
case MONO_SECTION_RSRC:
if (assembly->win32_res) {
- text_offset = assembly->sections [i].offset;
/* Fixup the offsets in the IMAGE_RESOURCE_DATA_ENTRY structures */
fixup_resource_directory (assembly->win32_res, assembly->win32_res, assembly->sections [i].rva);
-
- memcpy (pefile->data + text_offset, assembly->win32_res, assembly->win32_res_size);
+ checked_write_file (file, assembly->win32_res, assembly->win32_res_size);
}
break;
default:
g_assert_not_reached ();
}
- section++;
}
/* check that the file is properly padded */
-#if 0
- {
- FILE *f = fopen ("mypetest.exe", "w");
- fwrite (pefile->data, pefile->index, 1, f);
- fclose (f);
- }
-#endif
+ if (SetFilePointer (file, file_offset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+ g_error ("SetFilePointer returned %d\n", GetLastError ());
+ if (! SetEndOfFile (file))
+ g_error ("SetEndOfFile returned %d\n", GetLastError ());
+
+ mono_dynamic_stream_reset (&assembly->code);
+ mono_dynamic_stream_reset (&assembly->us);
+ mono_dynamic_stream_reset (&assembly->blob);
+ mono_dynamic_stream_reset (&assembly->guid);
+ string_heap_free (&assembly->sheap);
+
+ mono_g_hash_table_foreach (assembly->blob_cache, (GHFunc)g_free, NULL);
+ mono_g_hash_table_destroy (assembly->blob_cache);
}
MonoReflectionModule *
MonoImage *image;
MonoImageOpenStatus status;
MonoDynamicAssembly *assembly;
+ guint32 module_count;
+ MonoImage **new_modules;
name = mono_string_to_utf8 (fileName);
assembly = ab->dynamic_assembly;
image->assembly = (MonoAssembly*)assembly;
+ module_count = image->assembly->image->module_count;
+ new_modules = g_new0 (MonoImage *, module_count + 1);
+
+ if (image->assembly->image->modules)
+ memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *));
+ new_modules [module_count] = image;
+
+ g_free (image->assembly->image->modules);
+ image->assembly->image->modules = new_modules;
+ image->assembly->image->module_count ++;
+
mono_assembly_load_references (image, &status);
if (status) {
mono_image_close (image);
mono_defaults.corlib, "System.Reflection", "Assembly");
res = (MonoReflectionAssembly *)mono_object_new (domain, System_Reflection_Assembly);
res->assembly = assembly;
+
CACHE_OBJECT (assembly, res, NULL);
return res;
}
{
static MonoClass *System_Reflection_Module;
MonoReflectionModule *res;
+ char* basename;
CHECK_OBJECT (MonoReflectionModule *, image, NULL);
if (!System_Reflection_Module)
res->assembly = (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly);
res->fqname = mono_string_new (domain, image->name);
- res->name = mono_string_new (domain, g_path_get_basename (image->name));
+ res->name = mono_string_new (domain, basename = g_path_get_basename (image->name));
res->scopename = mono_string_new (domain, image->module_name);
+
+ g_free (basename);
+
+ if (image->assembly->image == image) {
+ res->token = mono_metadata_make_token (MONO_TABLE_MODULE, 1);
+ } else {
+ int i;
+ g_assert (image->assembly->image->modules);
+ res->token = 0;
+ for (i = 0; i < image->assembly->image->module_count; i++) {
+ if (image->assembly->image->modules [i] == image)
+ res->token = mono_metadata_make_token (MONO_TABLE_MODULEREF, i + 1);
+ }
+ g_assert (res->token);
+ }
mono_image_addref (image);
res->name = mono_string_new (domain, name);
res->scopename = mono_string_new (domain, name);
res->is_resource = cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA;
+ res->token = mono_metadata_make_token (MONO_TABLE_FILE, table_index + 1);
return res;
}
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)
+ if (t1->data.generic_class->inst->type_argc != t2->data.generic_class->inst->type_argc)
return FALSE;
- if (!mono_metadata_type_equal (t1->data.generic_inst->generic_type, t2->data.generic_inst->generic_type))
+ if (!mono_metadata_type_equal (t1->data.generic_class->generic_type, t2->data.generic_class->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]))
+ for (i = 0; i < t1->data.generic_class->inst->type_argc; ++i) {
+ if (!mono_metadata_type_equal (t1->data.generic_class->inst->type_argv [i], t2->data.generic_class->inst->type_argv [i]))
return FALSE;
}
return TRUE;
return hash;
}
-static MonoReflectionGenericInst*
-mono_generic_inst_get_object (MonoDomain *domain, MonoType *geninst)
+static MonoReflectionGenericClass*
+mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst)
{
- static MonoClass *System_Reflection_MonoGenericInst;
- MonoReflectionGenericInst *res;
- MonoGenericInst *ginst;
+ static MonoClass *System_Reflection_MonoGenericClass;
+ MonoReflectionGenericClass *res;
+ MonoGenericClass *gclass;
MonoClass *gklass;
- if (!System_Reflection_MonoGenericInst) {
- System_Reflection_MonoGenericInst = mono_class_from_name (
- mono_defaults.corlib, "System.Reflection", "MonoGenericInst");
- g_assert (System_Reflection_MonoGenericInst);
+ if (!System_Reflection_MonoGenericClass) {
+ System_Reflection_MonoGenericClass = mono_class_from_name (
+ mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
+ g_assert (System_Reflection_MonoGenericClass);
}
- ginst = geninst->data.generic_inst;
- gklass = mono_class_from_mono_type (ginst->generic_type);
+ gclass = geninst->data.generic_class;
+ gklass = mono_class_from_mono_type (gclass->generic_type);
- mono_class_init (ginst->klass);
+ mono_class_init (gclass->klass);
- res = (MonoReflectionGenericInst *) mono_object_new (domain, System_Reflection_MonoGenericInst);
+ res = (MonoReflectionGenericClass *) mono_object_new (domain, System_Reflection_MonoGenericClass);
res->type.type = geninst;
if (gklass->wastypebuilder && gklass->reflection_info)
res->generic_type = gklass->reflection_info;
else
- res->generic_type = mono_type_get_object (domain, ginst->generic_type);
+ res->generic_type = mono_type_get_object (domain, gclass->generic_type);
return res;
}
mono_domain_unlock (domain);
return res;
}
- if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_inst->is_dynamic) {
- res = (MonoReflectionType *)mono_generic_inst_get_object (domain, type);
+ if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic) {
+ res = (MonoReflectionType *)mono_generic_class_get_object (domain, type);
mono_g_hash_table_insert (domain->type_hash, type, res);
mono_domain_unlock (domain);
return res;
res->klass = klass;
res->field = field;
res->name = mono_string_new (domain, field->name);
- res->attrs = field->type->attrs;
+ if (field->generic_info)
+ res->attrs = field->generic_info->generic_type->attrs;
+ else
+ res->attrs = field->type->attrs;
res->type = mono_type_get_object (domain, field->type);
CACHE_OBJECT (field, res, klass);
return res;
mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
{
static MonoClass *System_Reflection_ParameterInfo;
- static MonoClassField *dbnull_value_field;
- MonoClass *klass;
MonoArray *res = NULL;
MonoReflectionMethod *member = NULL;
MonoReflectionParameter *param = NULL;
- char **names;
+ char **names, **blobs = NULL;
+ MonoObject *dbnull = mono_get_dbnull_object (domain);
+ MonoMarshalSpec **mspecs;
int i;
- if (!dbnull_value_field) {
- klass = mono_class_from_name (mono_defaults.corlib, "System", "DBNull");
- mono_class_init (klass);
- dbnull_value_field = mono_class_get_field_from_name (klass, "Value");
- g_assert (dbnull_value_field);
- }
-
if (!System_Reflection_ParameterInfo)
System_Reflection_ParameterInfo = mono_class_from_name (
mono_defaults.corlib, "System.Reflection", "ParameterInfo");
names = g_new (char *, method->signature->param_count);
mono_method_get_param_names (method, (const char **) names);
+ mspecs = g_new (MonoMarshalSpec*, method->signature->param_count + 1);
+ mono_method_get_marshal_info (method, mspecs);
+
res = mono_array_new (domain, System_Reflection_ParameterInfo, method->signature->param_count);
for (i = 0; i < method->signature->param_count; ++i) {
- param = (MonoReflectionParameter *)mono_object_new (domain,
- System_Reflection_ParameterInfo);
+ param = (MonoReflectionParameter *)mono_object_new (domain, System_Reflection_ParameterInfo);
param->ClassImpl = mono_type_get_object (domain, method->signature->params [i]);
- param->DefaultValueImpl = mono_field_get_value_object (domain, dbnull_value_field, NULL); /* FIXME */
param->MemberImpl = (MonoObject*)member;
param->NameImpl = mono_string_new (domain, names [i]);
param->PositionImpl = i;
param->AttrsImpl = method->signature->params [i]->attrs;
+
+ if (!(param->AttrsImpl & PARAM_ATTRIBUTE_HAS_DEFAULT)) {
+ param->DefaultValueImpl = dbnull;
+ } else {
+ MonoType *type = param->ClassImpl->type;
+
+ if (!blobs) {
+ blobs = g_new0 (char *, method->signature->param_count);
+ get_default_param_value_blobs (method, blobs);
+ }
+
+ param->DefaultValueImpl = mono_get_object_from_blob (domain, type, blobs [i]);
+
+ if (!param->DefaultValueImpl) {
+ param->DefaultValueImpl = dbnull;
+ }
+ }
+
+ if (mspecs [i + 1])
+ param->MarshalAsImpl = (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1]);
+
mono_array_set (res, gpointer, i, param);
}
g_free (names);
+ g_free (blobs);
+
+ for (i = method->signature->param_count; i >= 0; i--)
+ if (mspecs [i])
+ mono_metadata_free_marshal_spec (mspecs [i]);
+ g_free (mspecs);
+
CACHE_OBJECT (&(method->signature), res, NULL);
return res;
}
-static int
-assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
+/*
+ * mono_method_body_get_object:
+ * @domain: an app domain
+ * @method: a method
+ *
+ * Return an System.Reflection.MethodBody object representing the method @method.
+ */
+MonoReflectionMethodBody*
+mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
+{
+ static MonoClass *System_Reflection_MethodBody = NULL;
+ static MonoClass *System_Reflection_LocalVariableInfo = NULL;
+ MonoReflectionMethodBody *ret;
+ MonoMethodNormal *mn;
+ MonoMethodHeader *header;
+ int i;
+
+ if (!System_Reflection_MethodBody)
+ System_Reflection_MethodBody = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MethodBody");
+ if (!System_Reflection_LocalVariableInfo)
+ System_Reflection_LocalVariableInfo = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "LocalVariableInfo");
+
+ CHECK_OBJECT (MonoReflectionMethodBody *, method, NULL);
+
+ if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
+ (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
+ return NULL;
+ mn = (MonoMethodNormal *)method;
+ header = mono_method_get_header (method);
+
+ ret = (MonoReflectionMethodBody*)mono_object_new (domain, System_Reflection_MethodBody);
+ /* FIXME: Other fields */
+ ret->init_locals = header->init_locals;
+ ret->max_stack = header->max_stack;
+ ret->il = mono_array_new (domain, mono_defaults.byte_class, header->code_size);
+ memcpy (mono_array_addr (ret->il, guint8*, 0), header->code, header->code_size);
+ ret->locals = mono_array_new (domain, System_Reflection_LocalVariableInfo, header->num_locals);
+ for (i = 0; i < header->num_locals; ++i) {
+ MonoReflectionLocalVariableInfo *info = (MonoReflectionLocalVariableInfo*)mono_object_new (domain, System_Reflection_LocalVariableInfo);
+ info->local_type = mono_type_get_object (domain, header->locals [i]);
+ info->is_pinned = header->locals [i]->pinned;
+ info->local_index = 0;
+ }
+
+ CACHE_OBJECT (method, ret, NULL);
+ return ret;
+}
+
+MonoObject *
+mono_get_dbnull_object (MonoDomain *domain)
+{
+ MonoObject *obj;
+ MonoClass *klass;
+ static MonoClassField *dbnull_value_field = NULL;
+
+ if (!dbnull_value_field) {
+ klass = mono_class_from_name (mono_defaults.corlib, "System", "DBNull");
+ mono_class_init (klass);
+ dbnull_value_field = mono_class_get_field_from_name (klass, "Value");
+ g_assert (dbnull_value_field);
+ }
+ obj = mono_field_get_value_object (domain, dbnull_value_field, NULL);
+ g_assert (obj);
+ return obj;
+}
+
+
+static void
+get_default_param_value_blobs (MonoMethod *method, char **blobs)
+{
+ guint32 param_index, i, lastp, crow = 0;
+ guint32 param_cols [MONO_PARAM_SIZE], const_cols [MONO_CONSTANT_SIZE];
+ gint32 idx = -1;
+
+ MonoClass *klass = method->klass;
+ MonoImage *image = klass->image;
+ MonoMethodSignature *methodsig = method->signature;
+
+ MonoTableInfo *constt;
+ MonoTableInfo *methodt;
+ MonoTableInfo *paramt;
+
+ if (!methodsig->param_count)
+ return;
+
+ if (klass->generic_class) {
+ return; /* FIXME - ??? */
+ }
+
+ mono_class_init (klass);
+
+ if (klass->image->dynamic) {
+ MonoReflectionMethodAux *aux = mono_g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+ if (aux && aux->param_defaults)
+ memcpy (blobs, &(aux->param_defaults [1]), methodsig->param_count * sizeof (char*));
+ return;
+ }
+
+ methodt = &klass->image->tables [MONO_TABLE_METHOD];
+ paramt = &klass->image->tables [MONO_TABLE_PARAM];
+ constt = &image->tables [MONO_TABLE_CONSTANT];
+
+ for (i = 0; i < klass->method.count; ++i) {
+ if (method == klass->methods [i]) {
+ idx = klass->method.first + i;
+ break;
+ }
+ }
+
+ g_assert (idx != -1);
+
+ param_index = mono_metadata_decode_row_col (methodt, idx, MONO_METHOD_PARAMLIST);
+ if (idx + 1 < methodt->rows)
+ lastp = mono_metadata_decode_row_col (methodt, idx + 1, MONO_METHOD_PARAMLIST);
+ else
+ lastp = paramt->rows + 1;
+
+ for (i = param_index; i < lastp; ++i) {
+ guint32 paramseq;
+
+ mono_metadata_decode_row (paramt, i - 1, param_cols, MONO_PARAM_SIZE);
+ paramseq = param_cols [MONO_PARAM_SEQUENCE];
+
+ if (!param_cols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_DEFAULT)
+ continue;
+
+ crow = mono_metadata_get_constant_index (image, MONO_TOKEN_PARAM_DEF | i, crow + 1);
+ if (!crow) {
+ continue;
+ }
+
+ mono_metadata_decode_row (constt, crow - 1, const_cols, MONO_CONSTANT_SIZE);
+ blobs [paramseq - 1] = (gpointer) mono_metadata_blob_heap (image, const_cols [MONO_CONSTANT_VALUE]);
+ }
+
+ return;
+}
+
+static MonoObject *
+mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob)
+{
+ void *retval;
+ MonoClass *klass;
+ MonoObject *object;
+
+ if (!blob)
+ return NULL;
+
+ klass = mono_class_from_mono_type (type);
+ if (klass->valuetype) {
+ object = mono_object_new (domain, klass);
+ retval = ((gchar *) object + sizeof (MonoObject));
+ } else {
+ retval = &object;
+ }
+
+ if (!mono_get_constant_value_from_blob (domain, type->type, blob, retval))
+ return object;
+ else
+ return NULL;
+}
+
+static int
+assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
int found_sep;
char *s;
while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@'))
p++;
found_sep = 0;
- while (*p == ' ' || *p == ',') {
+ while (g_ascii_isspace (*p) || *p == ',') {
*p++ = 0;
found_sep = 1;
continue;
p++;
}
found_sep = 0;
- while (*p == ' ' || *p == ',') {
+ while (g_ascii_isspace (*p) || *p == ',') {
*p++ = 0;
found_sep = 1;
continue;
* extracted in the info structure.
* the name param will be mangled, so, make a copy before passing it to this function.
* The fields in info will be valid until the memory pointed to by name is valid.
- * Returns 0 on parse error.
+ *
* See also mono_type_get_name () below.
+ *
+ * Returns: 0 on parse error.
*/
int
mono_reflection_parse_type (char *name, MonoTypeNameParse *info) {
case ',':
*p++ = 0;
while (*p) {
- if (*p == ' ') {
+ if (g_ascii_isspace (*p)) {
++p;
continue;
}
* @image: a metadata context
* @info: type description structure
* @ignorecase: flag for case-insensitive string compares
+ * @type_resolve: whenever type resolve was already tried
*
* Build a MonoType from the type description in @info.
*
*/
MonoType*
-mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase)
+mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve)
{
MonoType *type;
MonoReflectionAssembly *assembly;
return type;
if (!mono_domain_has_type_resolve (mono_domain_get ()))
return NULL;
+
+ if (type_resolve) {
+ if (*type_resolve)
+ return NULL;
+ else
+ *type_resolve = TRUE;
+ }
/* Reconstruct the type name */
fullName = g_string_new ("");
for (mod = info->nested; mod; mod = mod->next)
g_string_append_printf (fullName, "+%s", (char*)mod->data);
- assembly =
- mono_domain_try_type_resolve (
- mono_domain_get (), fullName->str, NULL);
- if (assembly && (!image || (assembly->assembly->image == image))) {
-
+ assembly = mono_domain_try_type_resolve ( mono_domain_get (), fullName->str, NULL);
+ if (assembly) {
if (assembly->assembly->dynamic) {
/* Enumerate all modules */
MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
MonoTypeNameParse info;
MonoAssembly *assembly;
char *tmp;
+ gboolean type_resolve = FALSE;
/* Make a copy since parse_type modifies its argument */
tmp = g_strdup (name);
image = mono_defaults.corlib;
}
- type = mono_reflection_get_type (image, &info, FALSE);
+ type = mono_reflection_get_type (image, &info, FALSE, &type_resolve);
if (type == NULL && !info.assembly.name && image != mono_defaults.corlib) {
image = mono_defaults.corlib;
- type = mono_reflection_get_type (image, &info, FALSE);
+ type = mono_reflection_get_type (image, &info, FALSE, &type_resolve);
}
g_free (tmp);
return type;
}
+/*
+ * mono_reflection_get_token:
+ *
+ * Return the metadata token of OBJ which should be an object
+ * representing a metadata element.
+ */
+guint32
+mono_reflection_get_token (MonoObject *obj)
+{
+ MonoClass *klass;
+ guint32 token = 0;
+
+ klass = obj->vtable->klass;
+
+ if (strcmp (klass->name, "MethodBuilder") == 0) {
+ MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
+
+ token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
+ } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
+ MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
+
+ token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
+ } else if (strcmp (klass->name, "FieldBuilder") == 0) {
+ MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
+ if (tb->generic_params) {
+ g_assert_not_reached ();
+ } else {
+ token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
+ }
+ } else if (strcmp (klass->name, "TypeBuilder") == 0) {
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
+ token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
+ } else if (strcmp (klass->name, "MonoType") == 0) {
+ MonoReflectionType *tb = (MonoReflectionType *)obj;
+ token = mono_class_from_mono_type (tb->type)->type_token;
+ } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
+ strcmp (klass->name, "MonoMethod") == 0) {
+ MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
+ if (m->method->signature->is_inflated) {
+ g_assert_not_reached ();
+ } else if (m->method->signature->generic_param_count) {
+ g_assert_not_reached ();
+ } else if (m->method->klass->generic_class) {
+ g_assert_not_reached ();
+ } else {
+ token = m->method->token;
+ }
+ } else if (strcmp (klass->name, "MonoField") == 0) {
+ MonoReflectionField *f = (MonoReflectionField*)obj;
+
+ token = mono_class_get_field_token (f->field);
+ } else if (strcmp (klass->name, "MonoProperty") == 0) {
+ MonoReflectionProperty *p = (MonoReflectionProperty*)obj;
+
+ token = mono_class_get_property_token (p->property);
+ } else if (strcmp (klass->name, "MonoEvent") == 0) {
+ MonoReflectionEvent *p = (MonoReflectionEvent*)obj;
+
+ token = mono_class_get_event_token (p->event);
+ } else if (strcmp (klass->name, "ParameterInfo") == 0) {
+ MonoReflectionParameter *p = (MonoReflectionParameter*)obj;
+
+ token = mono_method_get_param_token (((MonoReflectionMethod*)p->MemberImpl)->method, p->PositionImpl);
+ } else if (strcmp (klass->name, "Module") == 0) {
+ MonoReflectionModule *m = (MonoReflectionModule*)obj;
+
+ token = m->token;
+ } else if (strcmp (klass->name, "Assembly") == 0) {
+ token = mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1);
+ } else {
+ gchar *msg = g_strdup_printf ("MetadataToken is not supported for type '%s.%s'", klass->name_space, klass->name);
+ MonoException *ex = mono_get_exception_not_implemented (msg);
+ g_free (msg);
+ mono_raise_exception (ex);
+ }
+
+ return token;
+}
+
static void*
load_cattr_value (MonoImage *image, MonoType *t, const char *p, const char **end)
{
g_free (val);
return obj;
}
- case MONO_TYPE_SZARRAY:
- {
+ case MONO_TYPE_SZARRAY: {
MonoArray *arr;
guint32 i, alen, basetype;
alen = read32 (p);
case MONO_TYPE_U1:
case MONO_TYPE_I1:
case MONO_TYPE_BOOLEAN:
- for (i=0;i<alen;i++)
- {
- MonoBoolean val=*p++;
- mono_array_set(arr,MonoBoolean,i,val);
+ for (i = 0; i < alen; i++) {
+ MonoBoolean val = *p++;
+ mono_array_set (arr, MonoBoolean, i, val);
}
break;
case MONO_TYPE_CHAR:
case MONO_TYPE_U2:
case MONO_TYPE_I2:
- for (i=0;i<alen;i++)
- {
- guint16 val=read16(p);
- mono_array_set(arr,guint16,i,val);
- p+=2;
+ for (i = 0; i < alen; i++) {
+ guint16 val = read16 (p);
+ mono_array_set (arr, guint16, i, val);
+ p += 2;
}
break;
case MONO_TYPE_R4:
case MONO_TYPE_U4:
case MONO_TYPE_I4:
- for (i=0;i<alen;i++)
- {
- guint32 val=read32(p);
- mono_array_set(arr,guint32,i,val);
- p+=4;
+ for (i = 0; i < alen; i++) {
+ guint32 val = read32 (p);
+ mono_array_set (arr, guint32, i, val);
+ p += 4;
}
break;
case MONO_TYPE_R8:
case MONO_TYPE_U8:
case MONO_TYPE_I8:
- for (i=0;i<alen;i++)
- {
- guint64 val=read64(p);
- mono_array_set(arr,guint64,i,val);
- p+=8;
+ for (i = 0; i < alen; i++) {
+ guint64 val = read64 (p);
+ mono_array_set (arr, guint64, i, val);
+ p += 8;
}
break;
case MONO_TYPE_CLASS:
}
static MonoObject*
-create_custom_attr (MonoImage *image, MonoMethod *method,
- const char *data, guint32 len)
+create_custom_attr (MonoImage *image, MonoMethod *method, const char *data, guint32 len)
{
const char *p = data;
const char *named;
method_index = find_method_index (method);
ca = &image->tables [MONO_TABLE_METHOD];
- if (method->klass->generic_inst || method->klass->gen_params ||
+ if (method->klass->generic_class || method->klass->generic_container ||
method->signature->generic_param_count) {
/* FIXME FIXME FIXME */
return NULL;
MONO_ARCH_SAVE_REGS;
klass = obj->vtable->klass;
- /* FIXME: need to handle: Module */
if (klass == mono_defaults.monotype_class) {
MonoReflectionType *rtype = (MonoReflectionType*)obj;
klass = mono_class_from_mono_type (rtype->type);
} else if (strcmp ("TypeBuilder", klass->name) == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
cinfo = mono_custom_attrs_from_builders (&tb->module->dynamic_image->image, tb->cattrs);
+ } else if (strcmp ("ModuleBuilder", klass->name) == 0) {
+ MonoReflectionModuleBuilder *mb = (MonoReflectionModuleBuilder*)obj;
+ cinfo = mono_custom_attrs_from_builders (&mb->dynamic_image->image, mb->cattrs);
} else { /* handle other types here... */
g_error ("get custom attrs not yet supported for %s", klass->name);
}
break;
}
/* it may be a boxed value or a Type */
- case MONO_TYPE_OBJECT: {
- MonoClass *klass = mono_object_class (arg);
+ case MONO_TYPE_OBJECT: {\r
+ MonoClass *klass;
char *str;
guint32 slen;
+\r
+ if (arg == NULL) {\r
+ *p++ = MONO_TYPE_STRING; // It's same hack as MS uses\r
+ *p++ = 0xFF;\r
+ break;\r
+ }\r
+ klass = mono_object_class (arg);
+
if (mono_object_isinst (arg, mono_defaults.monotype_class)) {
*p++ = 0x50;
goto handle_type;
} else {
g_error ("unhandled type in custom attr");
}
- str = type_get_qualified_name (klass->enum_basetype, NULL);
+ str = type_get_qualified_name (mono_class_get_type(klass), NULL);
slen = strlen (str);
if ((p-buffer) + 10 + slen >= *buflen) {
char *newbuf;
if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
/* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
parent = tb->parent->type->data.klass;
- } else
+ } else {
parent = my_mono_class_from_mono_type (tb->parent->type);
- } else
+ }
+ } else {
parent = NULL;
+ }
/* the type has already being created: it means we just have to change the parent */
if (tb->type.type) {
g_free (klass->supertypes);
klass->supertypes = NULL;
mono_class_setup_parent (klass, parent);
+ mono_class_setup_mono_type (klass);
return;
}
klass->reflection_info = tb; /* need to pin. */
/* Put into cache so mono_class_get () will find it */
- mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name,
- tb->table_idx);
+ mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
mono_g_hash_table_insert (tb->module->dynamic_image->tokens,
- GUINT_TO_POINTER (MONO_TOKEN_TYPE_DEF | tb->table_idx),
- tb);
+ GUINT_TO_POINTER (MONO_TOKEN_TYPE_DEF | tb->table_idx), tb);
- if (parent != NULL)
+ if (parent != NULL) {
mono_class_setup_parent (klass, parent);
- else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
+ } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
const char *old_n = klass->name;
/* trick to get relative numbering right when compiling corlib */
klass->name = "BuildingObject";
mono_class_setup_parent (klass, mono_defaults.object_class);
klass->name = old_n;
}
+
+ if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
+ (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
+ (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
+ klass->instance_size = sizeof (MonoObject);
+ klass->size_inited = 1;
+ mono_class_setup_vtable (klass, NULL, 0);
+ }
+
mono_class_setup_mono_type (klass);
mono_class_setup_supertypes (klass);
* mono_reflection_setup_generic_class:
* @tb: a TypeBuilder object
*
- * Setup the generic class after all generic parameters have been added.
+ * Setup the generic class before adding the first generic parameter.
*/
void
mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb)
+{
+ MonoClass *klass;
+
+ MONO_ARCH_SAVE_REGS;
+
+ klass = my_mono_class_from_mono_type (tb->type.type);
+ if (tb->generic_container)
+ return;
+
+ tb->generic_container = g_new0 (MonoGenericContainer, 1);
+ tb->generic_container->klass = klass;
+
+ tb->generic_container->context.container = tb->generic_container;
+}
+
+/*
+ * mono_reflection_create_generic_class:
+ * @tb: a TypeBuilder object
+ *
+ * Creates the generic class after all generic parameters have been added.
+ */
+void
+mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb)
{
MonoClass *klass;
int count, i;
count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
- if (klass->gen_params || (count == 0))
+ if (klass->generic_container || (count == 0))
return;
- klass->num_gen_params = count;
- klass->gen_params = g_new0 (MonoGenericParam, count);
+ g_assert (tb->generic_container && (tb->generic_container->klass == klass));
+
+ klass->generic_container = tb->generic_container;
+
+ klass->generic_container->type_argc = count;
+ klass->generic_container->type_params = g_new0 (MonoGenericParam, count);
for (i = 0; i < count; i++) {
MonoReflectionGenericParam *gparam = mono_array_get (tb->generic_params, gpointer, i);
- klass->gen_params [i] = *gparam->type.type->data.generic_param;
+ klass->generic_container->type_params [i] = *gparam->type.type->data.generic_param;
+ g_assert (klass->generic_container->type_params [i].owner);
}
}
if (klass->enumtype && klass->enum_basetype == NULL) {
MonoReflectionFieldBuilder *fb;
+ MonoClass *ec;
g_assert (tb->fields != NULL);
g_assert (mono_array_length (tb->fields) >= 1);
klass->element_class = my_mono_class_from_mono_type (klass->enum_basetype);
if (!klass->element_class)
klass->element_class = mono_class_from_mono_type (klass->enum_basetype);
- klass->instance_size = klass->element_class->instance_size;
+
+ /*
+ * get the element_class from the current corlib.
+ */
+ ec = default_class_from_mono_type (klass->enum_basetype);
+ klass->instance_size = ec->instance_size;
klass->size_inited = 1;
/*
* this is almost safe to do with enums and it's needed to be able
return res;
}
+MonoReflectionMarshal*
+mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
+ MonoMarshalSpec *spec)
+{
+ static MonoClass *System_Reflection_Emit_UnmanagedMarshalClass;
+ MonoReflectionMarshal *minfo;
+ MonoType *mtype;
+
+ if (!System_Reflection_Emit_UnmanagedMarshalClass) {
+ System_Reflection_Emit_UnmanagedMarshalClass = mono_class_from_name (
+ mono_defaults.corlib, "System.Reflection.Emit", "UnmanagedMarshal");
+ g_assert (System_Reflection_Emit_UnmanagedMarshalClass);
+ }
+
+ minfo = (MonoReflectionMarshal*)mono_object_new (domain, System_Reflection_Emit_UnmanagedMarshalClass);
+ minfo->type = spec->native;
+
+ switch (minfo->type) {
+ case MONO_NATIVE_LPARRAY:
+ minfo->eltype = spec->data.array_data.elem_type;
+ minfo->count = spec->data.array_data.num_elem;
+ break;
+
+ case MONO_NATIVE_BYVALTSTR:
+ case MONO_NATIVE_BYVALARRAY:
+ minfo->count = spec->data.array_data.num_elem;
+ break;
+
+ case MONO_NATIVE_CUSTOM:
+ if (spec->data.custom_data.custom_name) {
+ mtype = mono_reflection_type_from_name (spec->data.custom_data.custom_name, klass->image);
+ if (mtype)
+ minfo->marshaltyperef = mono_type_get_object (domain, mtype);
+
+ minfo->marshaltype = mono_string_new (domain, spec->data.custom_data.custom_name);
+ }
+ if (spec->data.custom_data.cookie)
+ minfo->mcookie = mono_string_new (domain, spec->data.custom_data.cookie);
+ break;
+
+ default:
+ break;
+ }
+
+ return minfo;
+}
+
static MonoMethod*
reflection_methodbuilder_to_mono_method (MonoClass *klass,
ReflectionMethodBuilder *rmb,
int i;
if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
- (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
+ (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
m = (MonoMethod *)g_new0 (MonoMethodPInvoke, 1);
- else
- if (rmb->refs)
- m = (MonoMethod *)g_new0 (MonoMethodWrapper, 1);
+ else if (rmb->refs)
+ m = (MonoMethod *)g_new0 (MonoMethodWrapper, 1);
else
m = (MonoMethod *)g_new0 (MonoMethodNormal, 1);
m->signature->pinvoke = 1;
} else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
- /* TODO */
m->signature->pinvoke = 1;
+
+ method_aux = g_new0 (MonoReflectionMethodAux, 1);
+
+ method_aux->dllentry = g_strdup (mono_string_to_utf8 (rmb->dllentry));
+ method_aux->dll = g_strdup (mono_string_to_utf8 (rmb->dll));
+
+ ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 1) | rmb->lasterr;
+
+ if (klass->image->dynamic)
+ mono_g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
+
return m;
} else if (!m->klass->dummy &&
!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
}
header = g_malloc0 (sizeof (MonoMethodHeader) +
- (num_locals - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
+ (num_locals - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
header->code_size = code_size;
header->code = g_malloc (code_size);
memcpy ((char*)header->code, code, code_size);
for (i = 0; i < num_locals; ++i) {
MonoReflectionLocalBuilder *lb =
- mono_array_get (rmb->ilgen->locals,
- MonoReflectionLocalBuilder*, i);
+ mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
header->locals [i] = g_new0 (MonoType, 1);
memcpy (header->locals [i], lb->type->type, sizeof (MonoType));
header->num_clauses = num_clauses;
if (num_clauses) {
header->clauses = method_encode_clauses ((MonoDynamicImage*)klass->image,
- rmb->ilgen,
- num_clauses);
+ rmb->ilgen, 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;
+ }
- header->gen_params [i] = *gp->type.type->data.generic_param;
- }
- }
+ if (rmb->generic_params) {
+ int count = mono_array_length (rmb->generic_params);
+ MonoGenericContainer *container;
- pm->header = header;
+ pm->generic_container = container = rmb->generic_container;
+ container->type_argc = count;
+ container->type_params = g_new0 (MonoGenericParam, count);
+
+ for (i = 0; i < count; i++) {
+ MonoReflectionGenericParam *gp =
+ mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
+
+ container->type_params [i] = *gp->type.type->data.generic_param;
+ }
}
if (rmb->refs) {
method_aux = NULL;
- /* Parameter names */
+ /* Parameter info */
if (rmb->pinfo) {
if (!method_aux)
method_aux = g_new0 (MonoReflectionMethodAux, 1);
for (i = 0; i <= m->signature->param_count; ++i) {
MonoReflectionParamBuilder *pb;
if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
+ if (i > 0)
+ m->signature->params [i - 1]->attrs = pb->attrs;
+
+ if (pb->def_value) {
+ MonoDynamicImage *assembly;
+ guint32 idx, def_type, len;
+ char *p;
+ const char *p2;
+
+ if (!method_aux->param_defaults)
+ method_aux->param_defaults = g_new0 (guint8*, m->signature->param_count + 1);
+ assembly = (MonoDynamicImage*)klass->image;
+ idx = encode_constant (assembly, pb->def_value, &def_type);
+ /* Copy the data from the blob since it might get realloc-ed */
+ p = assembly->blob.data + idx;
+ len = mono_metadata_decode_blob_size (p, &p2);
+ len += p2 - p;
+ method_aux->param_defaults [i] = g_malloc (len);
+ memcpy ((gpointer)method_aux->param_defaults [i], p, len);
+ }
+
if (pb->name)
method_aux->param_names [i] = mono_string_to_utf8 (pb->name);
if (pb->cattrs) {
if (fb->def_value) {
MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
- field->def_value = g_new0 (MonoConstant, 1);
- idx = encode_constant (assembly, fb->def_value, &field->def_value->type);
+ idx = encode_constant (assembly, fb->def_value, &field->def_type);
/* Copy the data from the blob since it might get realloc-ed */
p = assembly->blob.data + idx;
len = mono_metadata_decode_blob_size (p, &p2);
len += p2 - p;
- field->def_value->value = g_malloc (len);
- memcpy (field->def_value->value, p, len);
+ field->data = g_malloc (len);
+ memcpy ((gpointer)field->data, p, len);
}
return field;
}
static MonoType*
-do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc,
- MonoType **types)
+do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types,
+ MonoType *parent)
{
- MonoClass *klass;
+ MonoClass *klass, *gklass;
MonoReflectionTypeBuilder *tb = NULL;
- MonoGenericInst *ginst;
+ MonoGenericClass *gclass, *cached;
MonoDomain *domain;
MonoType *geninst;
int icount, i;
klass = mono_class_from_mono_type (type->type);
- if (!klass->gen_params && !klass->generic_inst &&
- !(klass->nested_in && klass->nested_in->gen_params))
+ if (!klass->generic_container && !klass->generic_class &&
+ !(klass->nested_in && klass->nested_in->generic_container))
return NULL;
mono_loader_lock ();
domain = mono_object_domain (type);
- ginst = g_new0 (MonoGenericInst, 1);
+ gclass = g_new0 (MonoGenericClass, 1);
+ gclass->inst = g_new0 (MonoGenericInst, 1);
- if (!klass->generic_inst) {
- ginst->type_argc = type_argc;
- ginst->type_argv = types;
+ gclass->inst->type_argc = type_argc;
+ gclass->inst->type_argv = types;
- for (i = 0; i < ginst->type_argc; ++i) {
- if (!ginst->is_open)
- ginst->is_open = mono_class_is_open_constructed_type (types [i]);
- }
+ for (i = 0; i < gclass->inst->type_argc; ++i) {
+ if (!gclass->inst->is_open)
+ gclass->inst->is_open = mono_class_is_open_constructed_type (types [i]);
+ }
- ginst->generic_type = &klass->byval_arg;
- } else {
- MonoGenericInst *kginst = klass->generic_inst;
+ gclass->generic_type = &klass->byval_arg;
- ginst->type_argc = kginst->type_argc;
- ginst->type_argv = g_new0 (MonoType *, ginst->type_argc);
+ if (klass->generic_class) {
+ MonoGenericClass *kgclass = klass->generic_class;
+ MonoGenericClass *ogclass = gclass;
- for (i = 0; i < ginst->type_argc; i++) {
- MonoType *t = kginst->type_argv [i];
+ ogclass->context = g_new0 (MonoGenericContext, 1);
+ ogclass->context->container = ogclass->container;
+ ogclass->context->gclass = ogclass;
- if (t->type == MONO_TYPE_VAR)
- t = types [t->data.generic_param->num];
+ gclass = g_new0 (MonoGenericClass, 1);
+ gclass->inst = g_new0 (MonoGenericInst, 1);
- if (!ginst->is_open)
- ginst->is_open = mono_class_is_open_constructed_type (t);
+ gclass->inst->type_argc = kgclass->inst->type_argc;
+ gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
- ginst->type_argv [i] = t;
+ for (i = 0; i < gclass->inst->type_argc; i++) {
+ MonoType *t = kgclass->inst->type_argv [i];
+
+ t = mono_class_inflate_generic_type (t, ogclass->context);
+
+ if (!gclass->inst->is_open)
+ gclass->inst->is_open = mono_class_is_open_constructed_type (t);
+
+ gclass->inst->type_argv [i] = t;
}
- ginst->generic_type = kginst->generic_type;
+ gclass->generic_type = kgclass->generic_type;
}
- geninst = g_hash_table_lookup (klass->image->generic_inst_cache, ginst);
- if (geninst) {
- g_free (ginst);
+ geninst = g_new0 (MonoType, 1);
+ geninst->type = MONO_TYPE_GENERICINST;
+
+ cached = mono_metadata_lookup_generic_class (gclass);
+ if (cached) {
+ g_free (gclass);
mono_loader_unlock ();
+ geninst->data.generic_class = cached;
return geninst;
}
- ginst->context = g_new0 (MonoGenericContext, 1);
- ginst->context->ginst = ginst;
+ gklass = mono_class_from_mono_type (gclass->generic_type);
+ g_assert ((gclass->container = gklass->generic_container) != NULL);
- geninst = g_new0 (MonoType, 1);
- geninst->type = MONO_TYPE_GENERICINST;
- geninst->data.generic_inst = ginst;
+ geninst->data.generic_class = gclass;
+
+ gclass->parent = parent;
+
+ gclass->context = g_new0 (MonoGenericContext, 1);
+ gclass->context->container = gclass->container;
+ gclass->context->gclass = gclass;
if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
tb = (MonoReflectionTypeBuilder *) type;
icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
- ginst->is_dynamic = TRUE;
- } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericInst")) {
- MonoReflectionGenericInst *rgi = (MonoReflectionGenericInst *) type;
+ gclass->is_dynamic = TRUE;
+ } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericClass")) {
+ MonoReflectionGenericClass *rgi = (MonoReflectionGenericClass *) 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
+ gclass->is_dynamic = TRUE;
+ } else {
icount = klass->interface_count;
+ }
- ginst->ifaces = g_new0 (MonoType *, icount);
- ginst->count_ifaces = icount;
+ gclass->ifaces = g_new0 (MonoType *, icount);
+ gclass->count_ifaces = icount;
for (i = 0; i < icount; i++) {
MonoReflectionType *itype;
itype = mono_array_get (tb->interfaces, MonoReflectionType *, i);
else
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->type;
+ gclass->ifaces [i] = mono_reflection_bind_generic_parameters (itype, type_argc, types);
+ if (!gclass->ifaces [i])
+ gclass->ifaces [i] = itype->type;
}
- mono_class_create_generic (ginst);
-
- g_hash_table_insert (klass->image->generic_inst_cache, ginst, geninst);
+ mono_class_create_generic (gclass);
+ mono_class_create_generic_2 (gclass);
mono_loader_unlock ();
{
MonoClass *klass, *pklass = NULL;
MonoReflectionType *parent = NULL;
- MonoType *geninst;
+ MonoType *the_parent = NULL, *geninst;
MonoReflectionTypeBuilder *tb = NULL;
- MonoGenericInst *ginst;
+ MonoGenericClass *gclass;
MonoDomain *domain;
domain = mono_object_domain (type);
pklass = klass->parent;
if (pklass)
parent = mono_type_get_object (domain, &pklass->byval_arg);
+ else if (klass->generic_class && klass->generic_class->parent) {
+ parent = mono_type_get_object (domain, klass->generic_class->parent);
+ pklass = mono_class_from_mono_type (klass->generic_class->parent);
+ }
}
- geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types);
+ if (pklass && pklass->generic_class)
+ the_parent = mono_reflection_bind_generic_parameters (parent, type_argc, types);
+
+ geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types, the_parent);
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);
+ gclass = geninst->data.generic_class;
return geninst;
}
+static MonoType*
+dup_type (const MonoType *original)
+{
+ MonoType *r = g_new0 (MonoType, 1);
+ *r = *original;
+ r->attrs = original->attrs;
+ r->byref = original->byref;
+ mono_stats.generics_metadata_size += sizeof (MonoType);
+ return r;
+}
+
MonoReflectionMethod*
mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types)
{
MonoMethod *method, *inflated;
MonoReflectionMethodBuilder *mb = NULL;
+ MonoGenericContainer *container;
MonoGenericMethod *gmethod;
MonoGenericContext *context;
+ MonoGenericInst *ginst;
int count, i;
MONO_ARCH_SAVE_REGS;
klass = mono_class_from_mono_type (tb->type.type);
method = methodbuilder_to_mono_method (klass, mb);
- } else
+ } else {
method = rmethod->method;
+ }
count = method->signature->generic_param_count;
if (count != mono_array_length (types))
return NULL;
- gmethod = g_new0 (MonoGenericMethod, 1);
- gmethod->mtype_argc = count;
- gmethod->mtype_argv = g_new0 (MonoType *, count);
+ container = ((MonoMethodNormal*) method)->generic_container;
+ g_assert (container);
+
+ if (!container->method_hash)
+ container->method_hash = g_hash_table_new (
+ (GHashFunc) mono_metadata_generic_method_hash,
+ (GCompareFunc) mono_metadata_generic_method_equal);
+
+ ginst = g_new0 (MonoGenericInst,1 );
+ ginst->type_argc = count;
+ ginst->type_argv = g_new0 (MonoType *, count);
for (i = 0; i < count; i++) {
MonoReflectionType *garg = mono_array_get (types, gpointer, i);
- gmethod->mtype_argv [i] = garg->type;
+ ginst->type_argv [i] = dup_type (garg->type);
+
+ if (!ginst->is_open)
+ ginst->is_open = mono_class_is_open_constructed_type (ginst->type_argv [i]);
}
+ ginst = mono_metadata_lookup_generic_inst (ginst);
+
+ gmethod = g_new0 (MonoGenericMethod, 1);
+ gmethod->container = container;
+ gmethod->inst = ginst;
+
+ inflated = g_hash_table_lookup (container->method_hash, gmethod);
+ if (inflated) {
+ g_free (gmethod);
+
+ return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
+ }
+
+ gmethod->reflection_info = rmethod;
context = g_new0 (MonoGenericContext, 1);
- context->ginst = method->klass->generic_inst;
+ context->container = container;
+ context->gclass = method->klass->generic_class;
context->gmethod = gmethod;
inflated = mono_class_inflate_generic_method (method, context, NULL);
+ g_hash_table_insert (container->method_hash, gmethod, inflated);
- return mono_method_get_object (
- mono_object_domain (rmethod), inflated, NULL);
+ return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
}
static MonoMethod *
-inflate_mono_method (MonoReflectionGenericInst *type, MonoMethod *method, MonoObject *obj)
+inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoObject *obj)
{
MonoGenericMethod *gmethod;
- MonoGenericInst *ginst;
+ MonoGenericClass *gclass;
MonoGenericContext *context;
int i;
- ginst = type->type.type->data.generic_inst;
+ gclass = type->type.type->data.generic_class;
gmethod = g_new0 (MonoGenericMethod, 1);
+ gmethod->inst = g_new0 (MonoGenericInst, 1);
gmethod->reflection_info = obj;
- gmethod->mtype_argc = method->signature->generic_param_count;
- gmethod->mtype_argv = g_new0 (MonoType *, gmethod->mtype_argc);
+ gmethod->inst->type_argc = method->signature->generic_param_count;
+ gmethod->inst->type_argv = g_new0 (MonoType *, gmethod->inst->type_argc);
- for (i = 0; i < gmethod->mtype_argc; i++) {
+ for (i = 0; i < gmethod->inst->type_argc; i++) {
MonoMethodNormal *mn = (MonoMethodNormal *) method;
- MonoGenericParam *gparam = &mn->header->gen_params [i];
+ MonoGenericParam *gparam = &mn->generic_container->type_params [i];
g_assert (gparam->pklass);
- gmethod->mtype_argv [i] = &gparam->pklass->byval_arg;
+ gmethod->inst->type_argv [i] = &gparam->pklass->byval_arg;
}
context = g_new0 (MonoGenericContext, 1);
- context->ginst = ginst;
+ context->container = gclass->container;
+ context->gclass = gclass;
context->gmethod = gmethod;
- return mono_class_inflate_generic_method (method, context, ginst->klass);
+ return mono_class_inflate_generic_method (method, context, gclass->klass);
}
static MonoMethod *
-inflate_method (MonoReflectionGenericInst *type, MonoObject *obj)
+inflate_method (MonoReflectionGenericClass *type, MonoObject *obj)
{
MonoMethod *method;
MonoClass *klass;
method = methodbuilder_to_mono_method (klass, (MonoReflectionMethodBuilder *) obj);
else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder"))
method = ctorbuilder_to_mono_method (klass, (MonoReflectionCtorBuilder *) obj);
- else if (!strcmp (obj->vtable->klass->name, "MonoMethod") ||
- !strcmp (obj->vtable->klass->name, "MonoCMethod"))
+ else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod"))
method = ((MonoReflectionMethod *) obj)->method;
else {
method = NULL; /* prevent compiler warning */
}
void
-mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
- MonoArray *methods, MonoArray *ctors,
- MonoArray *fields, MonoArray *properties,
- MonoArray *events)
+mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods,
+ MonoArray *ctors, MonoArray *fields, MonoArray *properties,
+ MonoArray *events)
{
- MonoGenericInst *ginst;
- MonoDynamicGenericInst *dginst;
+ MonoGenericClass *gclass;
+ MonoDynamicGenericClass *dgclass;
MonoClass *klass, *gklass, *pklass;
int i;
MONO_ARCH_SAVE_REGS;
klass = mono_class_from_mono_type (type->type.type);
- ginst = type->type.type->data.generic_inst;
+ gclass = type->type.type->data.generic_class;
- if (ginst->initialized)
+ if (gclass->initialized)
return;
- dginst = ginst->dynamic_info = g_new0 (MonoDynamicGenericInst, 1);
+ dgclass = gclass->dynamic_info = g_new0 (MonoDynamicGenericClass, 1);
- gklass = mono_class_from_mono_type (ginst->generic_type);
+ gklass = mono_class_from_mono_type (gclass->generic_type);
mono_class_init (gklass);
- if (ginst->parent)
- pklass = mono_class_from_mono_type (ginst->parent);
+ if (gclass->parent)
+ pklass = mono_class_from_mono_type (gclass->parent);
else
pklass = gklass->parent;
mono_class_setup_parent (klass, pklass);
- dginst->count_methods = methods ? mono_array_length (methods) : 0;
- 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;
+ dgclass->count_methods = methods ? mono_array_length (methods) : 0;
+ dgclass->count_ctors = ctors ? mono_array_length (ctors) : 0;
+ dgclass->count_fields = fields ? mono_array_length (fields) : 0;
+ dgclass->count_properties = properties ? mono_array_length (properties) : 0;
+ dgclass->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);
+ dgclass->methods = g_new0 (MonoMethod *, dgclass->count_methods);
+ dgclass->ctors = g_new0 (MonoMethod *, dgclass->count_ctors);
+ dgclass->fields = g_new0 (MonoClassField, dgclass->count_fields);
+ dgclass->properties = g_new0 (MonoProperty, dgclass->count_properties);
+ dgclass->events = g_new0 (MonoEvent, dgclass->count_events);
- for (i = 0; i < dginst->count_methods; i++) {
+ for (i = 0; i < dgclass->count_methods; i++) {
MonoObject *obj = mono_array_get (methods, gpointer, i);
- dginst->methods [i] = inflate_method (type, obj);
+ dgclass->methods [i] = inflate_method (type, obj);
}
- for (i = 0; i < dginst->count_ctors; i++) {
+ for (i = 0; i < dgclass->count_ctors; i++) {
MonoObject *obj = mono_array_get (ctors, gpointer, i);
- dginst->ctors [i] = inflate_method (type, obj);
+ dgclass->ctors [i] = inflate_method (type, obj);
}
- for (i = 0; i < dginst->count_fields; i++) {
+ for (i = 0; i < dgclass->count_fields; i++) {
MonoObject *obj = mono_array_get (fields, gpointer, i);
MonoClassField *field;
MonoInflatedField *ifield;
ifield->generic_type = field->type;
ifield->reflection_info = obj;
- dginst->fields [i] = *field;
- dginst->fields [i].generic_info = ifield;
- dginst->fields [i].type = mono_class_inflate_generic_type (field->type, ginst->context);
+ dgclass->fields [i] = *field;
+ dgclass->fields [i].generic_info = ifield;
+ dgclass->fields [i].type = mono_class_inflate_generic_type (field->type, gclass->context);
}
- for (i = 0; i < dginst->count_properties; i++) {
+ for (i = 0; i < dgclass->count_properties; i++) {
MonoObject *obj = mono_array_get (properties, gpointer, i);
- MonoProperty *property = &dginst->properties [i];
+ MonoProperty *property = &dgclass->properties [i];
if (!strcmp (obj->vtable->klass->name, "PropertyBuilder")) {
MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *) obj;
g_assert_not_reached ();
}
- for (i = 0; i < dginst->count_events; i++) {
+ for (i = 0; i < dgclass->count_events; i++) {
MonoObject *obj = mono_array_get (events, gpointer, i);
- MonoEvent *event = &dginst->events [i];
+ MonoEvent *event = &dgclass->events [i];
if (!strcmp (obj->vtable->klass->name, "EventBuilder")) {
MonoReflectionEventBuilder *eb = (MonoReflectionEventBuilder *) obj;
g_assert_not_reached ();
}
- ginst->initialized = TRUE;
+ gclass->initialized = TRUE;
}
static void
for (i = 0; i < num; ++i)
klass->methods [j++] = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i));
- klass->wastypebuilder = TRUE;
if (tb->interfaces) {
klass->interface_count = mono_array_length (tb->interfaces);
klass->interfaces = g_new (MonoClass*, klass->interface_count);
}
}
- overrides = (MonoMethod**)g_new0 (MonoMethod, onum * 2);
+ overrides = g_new0 (MonoMethod*, onum * 2);
if (tb->methods) {
onum = 0;
}
mono_class_setup_vtable (klass, overrides, onum);
+ g_free (overrides);
}
static void
if (fb->def_value) {
MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
- field->def_value = g_new0 (MonoConstant, 1);
- idx = encode_constant (assembly, fb->def_value, &field->def_value->type);
+ idx = encode_constant (assembly, fb->def_value, &field->def_type);
/* Copy the data from the blob since it might get realloc-ed */
p = assembly->blob.data + idx;
len = mono_metadata_decode_blob_size (p, &p2);
len += p2 - p;
- field->def_value->value = g_malloc (len);
- memcpy (field->def_value->value, p, len);
+ field->data = g_malloc (len);
+ memcpy ((gpointer)field->data, p, len);
}
}
mono_class_layout_fields (klass);
event->raise = eb->raise_method->mhandle;
if (eb->other_methods) {
- event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods));
+ event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
MonoReflectionMethodBuilder *mb =
mono_array_get (eb->other_methods,
klass->events [i].raise = eb->raise_method->mhandle;
if (eb->other_methods) {
- klass->events [i].other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods));
+ klass->events [i].other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
MonoReflectionMethodBuilder *mb =
mono_array_get (eb->other_methods,
typebuilder_setup_events (klass);
+ klass->wastypebuilder = TRUE;
+
res = mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
- /* with enums res == tb: need to fix that. */
- if (!klass->enumtype)
- g_assert (res != (MonoReflectionType*)tb);
+ g_assert (res != (MonoReflectionType*)tb);
return res;
}
param = g_new0 (MonoGenericParam, 1);
+ if (gparam->mbuilder) {
+ if (!gparam->mbuilder->generic_container)
+ gparam->mbuilder->generic_container = g_new0 (MonoGenericContainer, 1);
+ param->owner = gparam->mbuilder->generic_container;
+ } else if (gparam->tbuilder) {
+ MonoReflectionTypeBuilder *nesting = (MonoReflectionTypeBuilder*) gparam->tbuilder->nesting_type;
+ MonoGenericContainer *container = gparam->tbuilder->generic_container;
+
+ while (nesting) {
+ int count;
+
+ count = nesting->generic_params ? mono_array_length (nesting->generic_params) : 0;
+ if (gparam->index >= count)
+ break;
+
+ container = nesting->generic_container;
+ nesting = (MonoReflectionTypeBuilder*) nesting->nesting_type;
+ }
+
+ g_assert (container);
+ param->owner = container;
+ }
+
param->method = NULL;
param->name = mono_string_to_utf8 (gparam->name);
param->num = gparam->index;
/**
* mono_reflection_lookup_dynamic_token:
*
- * Finish the Builder object pointed to by TOKEN and return the corresponding
+ * Finish the Builder object pointed to by TOKEN and return the corresponding
* runtime structure.
*/
gpointer
if (strcmp (obj->vtable->klass->name, "String") == 0) {
result = mono_string_intern ((MonoString*)obj);
g_assert (result);
- }
- else if (strcmp (obj->vtable->klass->name, "MonoType") == 0) {
+ } else if (strcmp (obj->vtable->klass->name, "MonoType") == 0) {
MonoReflectionType *tb = (MonoReflectionType*)obj;
result = mono_class_from_mono_type (tb->type);
g_assert (result);
- }
- else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0) {
+ } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0) {
result = ((MonoReflectionMethod*)obj)->method;
g_assert (result);
- }
- else if (strcmp (obj->vtable->klass->name, "MonoCMethod") == 0) {
+ } else if (strcmp (obj->vtable->klass->name, "MonoCMethod") == 0) {
result = ((MonoReflectionMethod*)obj)->method;
g_assert (result);
- }
- else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
+ } else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
result = mb->mhandle;
if (!result) {
* Hopefully this has been filled in by calling CreateType() on the
* TypeBuilder.
*/
- /**
+ /*
* TODO: This won't work if the application finishes another
* TypeBuilder instance instead of this one.
*/
result = mb->mhandle;
}
- }
- else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
+ } else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
result = cb->mhandle;
mono_domain_try_type_resolve (mono_domain_get (), NULL, (MonoObject*)tb);
result = cb->mhandle;
}
- }
- else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
+ } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
result = ((MonoReflectionField*)obj)->field;
g_assert (result);
- }
- else if (strcmp (obj->vtable->klass->name, "FieldBuilder") == 0) {
+ } else if (strcmp (obj->vtable->klass->name, "FieldBuilder") == 0) {
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
result = fb->handle;
mono_domain_try_type_resolve (mono_domain_get (), NULL, (MonoObject*)tb);
result = fb->handle;
}
- }
- else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
+ } else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
MonoClass *klass;
result = tb->type.type->data.klass;
g_assert (result);
}
- }
- else if (strcmp (obj->vtable->klass->name, "SignatureHelper") == 0) {
+ } else if (strcmp (obj->vtable->klass->name, "SignatureHelper") == 0) {
MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
MonoMethodSignature *sig;
int nargs, i;
}
result = sig;
- }
- else {
+ } else {
g_print (obj->vtable->klass->name);
g_assert_not_reached ();
}
return result;
}
+
+
+/* SECURITY_ACTION_* are defined in mono/metadata/tabledefs.h */
+const static guint32 declsec_flags_map[] = {
+ 0x00000000, /* empty */
+ MONO_DECLSEC_FLAG_REQUEST, /* SECURITY_ACTION_REQUEST (x01) */
+ MONO_DECLSEC_FLAG_DEMAND, /* SECURITY_ACTION_DEMAND (x02) */
+ MONO_DECLSEC_FLAG_ASSERT, /* SECURITY_ACTION_ASSERT (x03) */
+ MONO_DECLSEC_FLAG_DENY, /* SECURITY_ACTION_DENY (x04) */
+ MONO_DECLSEC_FLAG_PERMITONLY, /* SECURITY_ACTION_PERMITONLY (x05) */
+ MONO_DECLSEC_FLAG_LINKDEMAND, /* SECURITY_ACTION_LINKDEMAND (x06) */
+ MONO_DECLSEC_FLAG_INHERITANCEDEMAND, /* SECURITY_ACTION_INHERITANCEDEMAND (x07) */
+ MONO_DECLSEC_FLAG_REQUEST_MINIMUM, /* SECURITY_ACTION_REQUEST_MINIMUM (x08) */
+ MONO_DECLSEC_FLAG_REQUEST_OPTIONAL, /* SECURITY_ACTION_REQUEST_OPTIONAL (x09) */
+ MONO_DECLSEC_FLAG_REQUEST_REFUSE, /* SECURITY_ACTION_REQUEST_REFUSE (x0A) */
+ MONO_DECLSEC_FLAG_PREJIT_GRANT, /* SECURITY_ACTION_PREJIT_GRANT (x0B) */
+ MONO_DECLSEC_FLAG_PREJIT_DENY, /* SECURITY_ACTION_PREJIT_DENY (x0C) */
+ MONO_DECLSEC_FLAG_NONCAS_DEMAND, /* SECURITY_ACTION_NONCAS_DEMAND (x0D) */
+ MONO_DECLSEC_FLAG_NONCAS_LINKDEMAND, /* SECURITY_ACTION_NONCAS_LINKDEMAND (x0E) */
+ MONO_DECLSEC_FLAG_NONCAS_INHERITANCEDEMAND, /* SECURITY_ACTION_NONCAS_INHERITANCEDEMAND (x0F) */
+ MONO_DECLSEC_FLAG_LINKDEMAND_CHOICE, /* SECURITY_ACTION_LINKDEMAND_CHOICE (x10) */
+ MONO_DECLSEC_FLAG_INHERITANCEDEMAND_CHOICE, /* SECURITY_ACTION_INHERITANCEDEMAND_CHOICE (x11) */
+ MONO_DECLSEC_FLAG_DEMAND_CHOICE, /* SECURITY_ACTION_DEMAND_CHOICE (x12) */
+};
+
+/*
+ * Returns flags that includes all available security action associated to the handle.
+ * @token: metadata token (either for a class or a method)
+ * @image: image where resides the metadata.
+ */
+static guint32
+mono_declsec_get_flags (MonoImage *image, guint32 token)
+{
+ guint32 index = mono_metadata_declsec_from_index (image, token);
+ MonoTableInfo *t = &image->tables [MONO_TABLE_DECLSECURITY];
+ guint32 result = 0;
+ guint32 action;
+ int i;
+
+ for (i = index; i < t->rows; i++) {
+ guint32 cols [MONO_DECL_SECURITY_SIZE];
+
+ mono_metadata_decode_row (t, i, cols, MONO_DECL_SECURITY_SIZE);
+ if (cols [MONO_DECL_SECURITY_PARENT] != token)
+ break;
+
+ action = cols [MONO_DECL_SECURITY_ACTION];
+ if ((action >= MONO_DECLSEC_ACTION_MIN) && (action <= MONO_DECLSEC_ACTION_MAX)) {
+ result |= declsec_flags_map [action];
+ } else {
+ g_assert_not_reached ();
+ }
+ }
+ return result;
+}
+
+/*
+ * Get the security actions (in the form of flags) associated with the specified method.
+ *
+ * @method: The method for which we want the declarative security flags.
+ * Return the declarative security flags for the method (only).
+ *
+ * Note: To keep MonoMethod size down we do not cache the declarative security flags
+ * (except for the stack modifiers which are kept in the MonoJitInfo structure)
+ */
+guint32
+mono_declsec_flags_from_method (MonoMethod *method)
+{
+ if (method->flags & METHOD_ATTRIBUTE_HAS_SECURITY) {
+ /* FIXME: No cache (for the moment) */
+ guint32 idx = find_method_index (method);
+ idx <<= MONO_HAS_DECL_SECURITY_BITS;
+ idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
+ return mono_declsec_get_flags (method->klass->image, idx);
+ }
+ return 0;
+}
+
+/*
+ * Get the security actions (in the form of flags) associated with the specified class.
+ *
+ * @klass: The class for which we want the declarative security flags.
+ * Return the declarative security flags for the class.
+ *
+ * Note: We cache the flags inside the MonoClass structure as this will get
+ * called very often (at least for each method).
+ */
+guint32
+mono_declsec_flags_from_class (MonoClass *klass)
+{
+ if (klass->flags & TYPE_ATTRIBUTE_HAS_SECURITY) {
+ if (!klass->declsec_flags) {
+ guint32 idx = mono_metadata_token_index (klass->type_token);
+ idx <<= MONO_HAS_DECL_SECURITY_BITS;
+ idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
+ /* we cache the flags on classes */
+ klass->declsec_flags = mono_declsec_get_flags (klass->image, idx);
+ }
+ return klass->declsec_flags;
+ }
+ return 0;
+}
+
+/*
+ * Get the security actions (in the form of flags) associated with the specified assembly.
+ *
+ * @assembly: The assembly for which we want the declarative security flags.
+ * Return the declarative security flags for the assembly.
+ */
+guint32
+mono_declsec_flags_from_assembly (MonoAssembly *assembly)
+{
+ guint32 idx = 1; /* there is only one assembly */
+ idx <<= MONO_HAS_DECL_SECURITY_BITS;
+ idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
+ return mono_declsec_get_flags (assembly->image, idx);
+}