string_heap_insert (sh, "");
}
-#if 0 /* never used */
static void
string_heap_free (MonoDynamicStream *sh)
{
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)
}
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 (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:
}
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;
}
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;
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:
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);
const GenericParamTableEntry **a_entry = (const GenericParamTableEntry **) a;
const GenericParamTableEntry **b_entry = (const GenericParamTableEntry **) b;
- return (*b_entry)->owner - (*a_entry)->owner;
+ 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
} 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;
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
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
#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)
mono_dynamic_stream_reset (&assembly->us);
mono_dynamic_stream_reset (&assembly->blob);
mono_dynamic_stream_reset (&assembly->guid);
- mono_dynamic_stream_reset (&assembly->sheap);
+ 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 *
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;
}
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;
if (!methodsig->param_count)
return;
- if (klass->generic_inst) {
+ if (klass->generic_class) {
return; /* FIXME - ??? */
}
* 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) {
g_assert_not_reached ();
} else if (m->method->signature->generic_param_count) {
g_assert_not_reached ();
- } else if (m->method->klass->generic_inst) {
+ } else if (m->method->klass->generic_class) {
g_assert_not_reached ();
} else {
token = m->method->token;
method_index = find_method_index (method);
ca = &image->tables [MONO_TABLE_METHOD];
- if (method->klass->generic_inst || method->klass->generic_container ||
+ if (method->klass->generic_class || method->klass->generic_container ||
method->signature->generic_param_count) {
/* FIXME FIXME FIXME */
return NULL;
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;
tb->generic_container = g_new0 (MonoGenericContainer, 1);
tb->generic_container->klass = klass;
- tb->generic_container->context = g_new0 (MonoGenericContext, 1);
- tb->generic_container->context->container = tb->generic_container;
+ tb->generic_container->context.container = tb->generic_container;
}
/*
{
MonoClass *klass, *gklass;
MonoReflectionTypeBuilder *tb = NULL;
- MonoGenericInst *ginst, *cached;
+ MonoGenericClass *gclass, *cached;
MonoDomain *domain;
MonoType *geninst;
int icount, i;
klass = mono_class_from_mono_type (type->type);
- if (!klass->generic_container && !klass->generic_inst &&
+ if (!klass->generic_container && !klass->generic_class &&
!(klass->nested_in && klass->nested_in->generic_container))
return NULL;
domain = mono_object_domain (type);
- ginst = g_new0 (MonoGenericInst, 1);
+ gclass = g_new0 (MonoGenericClass, 1);
+ gclass->inst = g_new0 (MonoGenericInst, 1);
- 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;
+ gclass->generic_type = &klass->byval_arg;
- if (klass->generic_inst) {
- MonoGenericInst *kginst = klass->generic_inst;
- MonoGenericInst *oginst = ginst;
+ if (klass->generic_class) {
+ MonoGenericClass *kgclass = klass->generic_class;
+ MonoGenericClass *ogclass = gclass;
- oginst->context = g_new0 (MonoGenericContext, 1);
- oginst->context->ginst = oginst;
+ ogclass->context = g_new0 (MonoGenericContext, 1);
+ ogclass->context->container = ogclass->container;
+ ogclass->context->gclass = ogclass;
- ginst = g_new0 (MonoGenericInst, 1);
+ gclass = g_new0 (MonoGenericClass, 1);
+ gclass->inst = g_new0 (MonoGenericInst, 1);
- ginst->type_argc = kginst->type_argc;
- ginst->type_argv = g_new0 (MonoType *, ginst->type_argc);
+ gclass->inst->type_argc = kgclass->inst->type_argc;
+ gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
- for (i = 0; i < ginst->type_argc; i++) {
- MonoType *t = kginst->type_argv [i];
+ for (i = 0; i < gclass->inst->type_argc; i++) {
+ MonoType *t = kgclass->inst->type_argv [i];
- t = mono_class_inflate_generic_type (t, oginst->context);
+ t = mono_class_inflate_generic_type (t, ogclass->context);
- if (!ginst->is_open)
- ginst->is_open = mono_class_is_open_constructed_type (t);
+ if (!gclass->inst->is_open)
+ gclass->inst->is_open = mono_class_is_open_constructed_type (t);
- ginst->type_argv [i] = t;
+ gclass->inst->type_argv [i] = t;
}
- ginst->generic_type = kginst->generic_type;
+ gclass->generic_type = kgclass->generic_type;
}
geninst = g_new0 (MonoType, 1);
geninst->type = MONO_TYPE_GENERICINST;
- cached = g_hash_table_lookup (klass->image->generic_inst_cache, ginst);
+ cached = mono_metadata_lookup_generic_class (gclass);
if (cached) {
- g_free (ginst);
+ g_free (gclass);
mono_loader_unlock ();
- geninst->data.generic_inst = cached;
+ geninst->data.generic_class = cached;
return geninst;
}
- gklass = mono_class_from_mono_type (ginst->generic_type);
- g_assert ((ginst->container = gklass->generic_container) != NULL);
+ gklass = mono_class_from_mono_type (gclass->generic_type);
+ g_assert ((gclass->container = gklass->generic_container) != NULL);
- geninst->data.generic_inst = ginst;
+ geninst->data.generic_class = gclass;
- ginst->parent = parent;
+ gclass->parent = parent;
- ginst->context = g_new0 (MonoGenericContext, 1);
- ginst->context->ginst = ginst;
+ 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;
+ 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);
- mono_class_create_generic_2 (ginst);
-
- g_hash_table_insert (klass->image->generic_inst_cache, ginst, ginst);
+ mono_class_create_generic (gclass);
+ mono_class_create_generic_2 (gclass);
mono_loader_unlock ();
MonoReflectionType *parent = NULL;
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_inst && klass->generic_inst->parent) {
- parent = mono_type_get_object (domain, klass->generic_inst->parent);
- pklass = mono_class_from_mono_type (klass->generic_inst->parent);
+ 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);
}
}
- if (pklass && pklass->generic_inst)
+ 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;
+ 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)
{
MonoGenericContainer *container;
MonoGenericMethod *gmethod;
MonoGenericContext *context;
+ MonoGenericInst *ginst;
int count, i;
MONO_ARCH_SAVE_REGS;
if (!container->method_hash)
container->method_hash = g_hash_table_new (
- mono_metadata_generic_method_hash, mono_metadata_generic_method_equal);
+ (GHashFunc) mono_metadata_generic_method_hash,
+ (GCompareFunc) mono_metadata_generic_method_equal);
- gmethod = g_new0 (MonoGenericMethod, 1);
- gmethod->mtype_argc = count;
- gmethod->mtype_argv = g_new0 (MonoType *, count);
+ 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->mtype_argv);
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);
}
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->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;
}
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
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);
+}