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)) {
+ if (g_hash_table_lookup_extended (assembly->blob_cache, copy, &oldkey, &oldval)) {
g_free (copy);
idx = GPOINTER_TO_UINT (oldval);
} else {
idx = mono_image_add_stream_data (&assembly->blob, b1, s1);
mono_image_add_stream_data (&assembly->blob, b2, s2);
- mono_g_hash_table_insert (assembly->blob_cache, copy, GUINT_TO_POINTER (idx));
+ g_hash_table_insert (assembly->blob_cache, copy, GUINT_TO_POINTER (idx));
}
return idx;
}
}
mono_metadata_encode_value (MONO_TYPE_GENERICINST, p, &p);
- encode_type (assembly, gclass->generic_type, p, &p);
+ encode_type (assembly, &gclass->container_class->byval_arg, 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);
g_assert_not_reached ();
}
- size += 1 + type_get_signature_size (gclass->generic_type);
+ size += 1 + type_get_signature_size (&gclass->container_class->byval_arg);
size += 4;
for (i = 0; i < gclass->inst->type_argc; ++i)
size += type_get_signature_size (gclass->inst->type_argv [i]);
/* room in this table is already allocated */
table = &assembly->tables [MONO_TABLE_METHOD];
*mb->table_idx = table->next_idx ++;
- mono_g_hash_table_insert (assembly->method_to_table_idx, mb->mhandle, GUINT_TO_POINTER ((*mb->table_idx)));
+ g_hash_table_insert (assembly->method_to_table_idx, mb->mhandle, GUINT_TO_POINTER ((*mb->table_idx)));
values = table->values + *mb->table_idx * MONO_METHOD_SIZE;
name = mono_string_to_utf8 (mb->name);
values [MONO_METHOD_NAME] = string_heap_insert (&assembly->sheap, name);
rmb->refs = NULL;
if (mb->dll) {
- rmb->charset = rmb->charset & 0xf;
- rmb->lasterr = rmb->charset & 0x40;
- rmb->native_cc = rmb->native_cc;
+ rmb->charset = mb->charset & 0xf;
+ rmb->lasterr = mb->charset & 0x40;
+ rmb->native_cc = mb->native_cc;
rmb->dllentry = mb->dllentry;
rmb->dll = mb->dll;
}
fb->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
table = &assembly->tables [MONO_TABLE_FIELD];
fb->table_idx = table->next_idx ++;
- mono_g_hash_table_insert (assembly->field_to_table_idx, fb->handle, GUINT_TO_POINTER (fb->table_idx));
+ g_hash_table_insert (assembly->field_to_table_idx, fb->handle, GUINT_TO_POINTER (fb->table_idx));
values = table->values + fb->table_idx * MONO_FIELD_SIZE;
name = mono_string_to_utf8 (fb->name);
values [MONO_FIELD_NAME] = string_heap_insert (&assembly->sheap, name);
MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
encode_reflection_type (assembly, pt, p, &p);
}
- } else {
+ } else if (smb) {
/* the property type is the last param */
encode_reflection_type (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), p, &p);
for (i = 0; i < nparams; ++i) {
encode_reflection_type (assembly, pt, p, &p);
}
}
+ else {
+ encode_reflection_type (assembly, fb->type, p, &p);
+ }
+
/* store length */
g_assert (p - buf < size);
mono_metadata_encode_value (p-buf, b, &b);
table = &assembly->tables [MONO_TABLE_METHODSPEC];
- g_assert (method->signature->is_inflated);
+ g_assert (method->is_inflated);
+ method = mono_get_inflated_method (method);
imethod = (MonoMethodInflated *) method;
declaring = imethod->declaring;
if (token)
return token;
- g_assert (m->signature->is_inflated);
+ g_assert (m->is_inflated);
+ m = mono_get_inflated_method (m);
imethod = (MonoMethodInflated *) m;
if (imethod->declaring->signature->generic_param_count) {
(p) += 4 - (__diff & 3);\
} while (0)
+static int
+compare_constants (const void *a, const void *b)
+{
+ const guint32 *a_values = a;
+ const guint32 *b_values = b;
+ return a_values [MONO_CONSTANT_PARENT] - b_values [MONO_CONSTANT_PARENT];
+}
+
static int
compare_semantics (const void *a, const void *b)
{
(*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;
+ return (*a_entry)->owner - (*b_entry)->owner;
}
static int
p = (unsigned char*)int32val;
/* sort the tables that still need sorting */
+ table = &assembly->tables [MONO_TABLE_CONSTANT];
+ if (table->rows)
+ qsort (table->values + MONO_CONSTANT_SIZE, table->rows, sizeof (guint32) * MONO_CONSTANT_SIZE, compare_constants);
table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
if (table->rows)
qsort (table->values + MONO_METHOD_SEMA_SIZE, table->rows, sizeof (guint32) * MONO_METHOD_SEMA_SIZE, compare_semantics);
idx = field->table_idx;
} else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
- idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->field_to_table_idx, f));
+ idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->field_to_table_idx, f));
} else {
g_assert_not_reached ();
}
} else if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod") ||
!strcmp (iltoken->member->vtable->klass->name, "MonoCMethod")) {
MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
- idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, m));
+ idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
} else {
g_assert_not_reached ();
}
am = (MonoReflectionArrayMethod*)iltoken->member;
idx = am->table_idx;
} else if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod") ||
- !strcmp (iltoken->member->vtable->klass->name, "MonoCMethod")) {
+ !strcmp (iltoken->member->vtable->klass->name, "MonoCMethod") ||
+ !strcmp (iltoken->member->vtable->klass->name, "MonoGenericMethod") ||
+ !strcmp (iltoken->member->vtable->klass->name, "MonoGenericCMethod")) {
MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
- g_assert (m->klass->generic_class);
+ g_assert (m->klass->generic_class || m->klass->generic_container);
continue;
} else if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
continue;
}
break;
case MONO_TABLE_METHODSPEC:
- if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod")) {
+ if (!strcmp (iltoken->member->vtable->klass->name, "MonoGenericMethod")) {
MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
g_assert (m->signature->generic_param_count);
continue;
if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
MonoMethod *m = ((MonoReflectionMethod*)ctor)->method;
- idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, m));
+ idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
}
}
token = mono_metadata_token_from_dor (
mono_image_typedef_or_ref (assembly, tb->type));
} else if (strcmp (klass->name, "MonoCMethod") == 0 ||
- strcmp (klass->name, "MonoMethod") == 0) {
+ strcmp (klass->name, "MonoMethod") == 0 ||
+ strcmp (klass->name, "MonoGenericMethod") == 0 ||
+ strcmp (klass->name, "MonoGenericCMethod") == 0) {
MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
- if (m->method->signature->is_inflated) {
+ if (m->method->is_inflated) {
if (create_methodspec)
token = mono_image_get_methodspec_token (assembly, m->method);
else
mono_image_init (&image->image);
image->token_fixups = mono_g_hash_table_new (NULL, NULL);
- image->method_to_table_idx = mono_g_hash_table_new (NULL, NULL);
- image->field_to_table_idx = mono_g_hash_table_new (NULL, NULL);
- image->method_aux_hash = mono_g_hash_table_new (NULL, NULL);
+ image->method_to_table_idx = g_hash_table_new (NULL, NULL);
+ image->field_to_table_idx = g_hash_table_new (NULL, NULL);
+ image->method_aux_hash = g_hash_table_new (NULL, NULL);
image->handleref = g_hash_table_new (NULL, NULL);
image->tokens = mono_g_hash_table_new (NULL, NULL);
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->blob_cache = 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);
#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)
MonoReflectionMethodBuilder *methodb = (MonoReflectionMethodBuilder*)assemblyb->entry_point;
table_idx = methodb->table_idx;
} else {
- table_idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, assemblyb->entry_point->method));
+ table_idx = GPOINTER_TO_UINT (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 {
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);
+ g_hash_table_foreach (assembly->blob_cache, (GHFunc)g_free, NULL);
+ g_hash_table_destroy (assembly->blob_cache);
}
MonoReflectionModule *
res = (MonoReflectionAssembly *)mono_object_new (domain, System_Reflection_Assembly);
res->assembly = assembly;
- /* FIXME: This is a workaround for 1.1.3 */
- if (!strcmp (assembly->aname.name, "__MetadataTypes"))
- res->corlib_internal = TRUE;
-
CACHE_OBJECT (assembly, res, NULL);
return res;
}
int i;
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_class->generic_type, t2->data.generic_class->generic_type))
+ if (!mono_metadata_type_equal (&t1->data.generic_class->container_class->byval_arg,
+ &t2->data.generic_class->container_class->byval_arg))
return FALSE;
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]))
}
gclass = geninst->data.generic_class;
- gklass = mono_class_from_mono_type (gclass->generic_type);
+ gklass = gclass->container_class;
mono_class_init (gclass->klass);
if (gklass->wastypebuilder && gklass->reflection_info)
res->generic_type = gklass->reflection_info;
else
- res->generic_type = mono_type_get_object (domain, gclass->generic_type);
+ res->generic_type = mono_type_get_object (domain, &gclass->container_class->byval_arg);
return res;
}
MonoClass *klass;
MonoReflectionMethod *ret;
+ if (method->is_inflated) {
+ MonoReflectionGenericMethod *gret;
+
+ refclass = method->klass;
+ CHECK_OBJECT (MonoReflectionMethod *, method, refclass);
+ if ((*method->name == '.') && (!strcmp (method->name, ".ctor") || !strcmp (method->name, ".cctor")))
+ cname = "MonoGenericCMethod";
+ else
+ cname = "MonoGenericMethod";
+ klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", cname);
+
+ gret = (MonoReflectionGenericMethod*)mono_object_new (domain, klass);
+ gret->method.method = method;
+ gret->method.name = mono_string_new (domain, method->name);
+ gret->method.reftype = mono_type_get_object (domain, &refclass->byval_arg);
+ CACHE_OBJECT (method, gret, refclass);
+ return (MonoReflectionMethod *) gret;
+ }
+
if (!refclass)
refclass = method->klass;
mono_class_init (klass);
if (klass->image->dynamic) {
- MonoReflectionMethodAux *aux = mono_g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+ MonoReflectionMethodAux *aux = 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;
} else if (strcmp (klass->name, "MonoCMethod") == 0 ||
strcmp (klass->name, "MonoMethod") == 0) {
MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
- if (m->method->signature->is_inflated) {
+ if (m->method->is_inflated) {
g_assert_not_reached ();
} else if (m->method->signature->generic_param_count) {
g_assert_not_reached ();
MonoReflectionMethodAux *aux;
if (method->klass->image->dynamic) {
- aux = mono_g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+ aux = g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
if (!aux || !aux->param_cattr)
return NULL;
return aux->param_cattr [param];
method_index = find_method_index (method);
ca = &image->tables [MONO_TABLE_METHOD];
- if (method->klass->generic_class || method->klass->generic_container ||
- method->signature->generic_param_count) {
+ if (method->klass->generic_class || method->signature->generic_param_count) {
/* FIXME FIXME FIXME */
return NULL;
}
} else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) {
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
cinfo = mono_custom_attrs_from_method (rmethod->method);
+ } else if ((strcmp ("MonoGenericMethod", klass->name) == 0) || (strcmp ("MonoGenericCMethod", klass->name) == 0)) {
+ MonoMethod *method = mono_get_inflated_method (((MonoReflectionMethod*)obj)->method);
+ cinfo = mono_custom_attrs_from_method (method);
} else if (strcmp ("ParameterInfo", klass->name) == 0) {
MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
}
/* it may be a boxed value or a Type */
case MONO_TYPE_OBJECT: {
- MonoClass *klass = mono_object_class (arg);
+ MonoClass *klass;
char *str;
guint32 slen;
+
+ if (arg == NULL) {
+ *p++ = MONO_TYPE_STRING; // It's same hack as MS uses
+ *p++ = 0xFF;
+ break;
+ }
+ klass = mono_object_class (arg);
+
if (mono_object_isinst (arg, mono_defaults.monotype_class)) {
*p++ = 0x50;
goto handle_type;
klass->generic_container->type_params [i] = *gparam->type.type->data.generic_param;
g_assert (klass->generic_container->type_params [i].owner);
}
+
+ klass->generic_container->context.gclass = mono_get_shared_generic_class (klass->generic_container, TRUE);
}
/*
((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);
+ g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
return m;
} else if (!m->klass->dummy &&
}
if (klass->image->dynamic && method_aux)
- mono_g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
+ g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
return m;
}
do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types,
MonoType *parent)
{
- MonoClass *klass, *gklass;
+ MonoClass *klass;
MonoReflectionTypeBuilder *tb = NULL;
MonoGenericClass *gclass, *cached;
+ MonoDynamicGenericClass *dgclass = NULL;
+ gboolean is_dynamic = FALSE;
MonoDomain *domain;
MonoType *geninst;
int icount, i;
domain = mono_object_domain (type);
- gclass = g_new0 (MonoGenericClass, 1);
+ if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
+ tb = (MonoReflectionTypeBuilder *) type;
+
+ icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
+ 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;
+ is_dynamic = TRUE;
+ } else {
+ icount = klass->interface_count;
+ }
+
+ if (is_dynamic) {
+ dgclass = g_new0 (MonoDynamicGenericClass, 1);
+ gclass = &dgclass->generic_class;
+ gclass->is_dynamic = TRUE;
+ } else
+ gclass = g_new0 (MonoGenericClass, 1);
+
gclass->inst = g_new0 (MonoGenericInst, 1);
gclass->inst->type_argc = type_argc;
gclass->inst->is_open = mono_class_is_open_constructed_type (types [i]);
}
- gclass->generic_type = &klass->byval_arg;
+ gclass->container_class = klass;
if (klass->generic_class) {
MonoGenericClass *kgclass = klass->generic_class;
MonoGenericClass *ogclass = gclass;
ogclass->context = g_new0 (MonoGenericContext, 1);
- ogclass->context->container = ogclass->container;
+ ogclass->context->container = ogclass->container_class->generic_container;
ogclass->context->gclass = ogclass;
- gclass = g_new0 (MonoGenericClass, 1);
+ if (is_dynamic) {
+ dgclass = g_new0 (MonoDynamicGenericClass, 1);
+ gclass = &dgclass->generic_class;
+ gclass->is_dynamic = TRUE;
+ } else
+ gclass = g_new0 (MonoGenericClass, 1);
+
gclass->inst = g_new0 (MonoGenericInst, 1);
gclass->inst->type_argc = kgclass->inst->type_argc;
gclass->inst->type_argv [i] = t;
}
- gclass->generic_type = kgclass->generic_type;
+ gclass->container_class = kgclass->container_class;
}
geninst = g_new0 (MonoType, 1);
return geninst;
}
- gklass = mono_class_from_mono_type (gclass->generic_type);
- g_assert ((gclass->container = gklass->generic_container) != NULL);
-
geninst->data.generic_class = gclass;
gclass->parent = parent;
gclass->context = g_new0 (MonoGenericContext, 1);
- gclass->context->container = gclass->container;
+ gclass->context->container = gclass->container_class->generic_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;
- 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;
- gclass->is_dynamic = TRUE;
- } else {
- icount = klass->interface_count;
- }
-
gclass->ifaces = g_new0 (MonoType *, icount);
gclass->count_ifaces = icount;
}
context = g_new0 (MonoGenericContext, 1);
- context->container = gclass->container;
+ context->container = gclass->container_class->generic_container;
context->gclass = gclass;
context->gmethod = gmethod;
if (gclass->initialized)
return;
- dgclass = gclass->dynamic_info = g_new0 (MonoDynamicGenericClass, 1);
+ g_assert (gclass->is_dynamic);
+ dgclass = (MonoDynamicGenericClass *) gclass;
- gklass = mono_class_from_mono_type (gclass->generic_type);
+ gklass = gclass->container_class;
mono_class_init (gklass);
if (gclass->parent)
idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
return mono_declsec_get_flags (assembly->image, idx);
}
+
+
+/*
+ * Fill actions for the specific index (which may either be an encoded class token or
+ * an encoded method token) from the metadata image.
+ * Returns TRUE if some actions requiring code generation are present, FALSE otherwise.
+ */
+static MonoBoolean
+fill_actions_from_index (MonoImage *image, guint32 token, MonoDeclSecurityActions* actions)
+{
+ MonoBoolean result = FALSE;
+ MonoTableInfo *t;
+ guint32 cols [MONO_DECL_SECURITY_SIZE];
+ int index = mono_metadata_declsec_from_index (image, token);
+ int i;
+
+ t = &image->tables [MONO_TABLE_DECLSECURITY];
+ for (i = index; i < t->rows; i++) {
+ mono_metadata_decode_row (t, i, cols, MONO_DECL_SECURITY_SIZE);
+
+ if (cols [MONO_DECL_SECURITY_PARENT] != token)
+ return result;
+
+ /* if present only replace (class) permissions with method permissions */
+ /* if empty accept either class or method permissions */
+ switch (cols [MONO_DECL_SECURITY_ACTION]) {
+ case SECURITY_ACTION_DEMAND:
+ if (!actions->demand.blob) {
+ const char *blob = mono_metadata_blob_heap (image, cols [MONO_DECL_SECURITY_PERMISSIONSET]);
+ actions->demand.blob = (char*) (blob + 2);
+ actions->demand.size = mono_metadata_decode_blob_size (blob, &blob);
+ result = TRUE;
+ }
+ break;
+ case SECURITY_ACTION_NONCASDEMAND:
+ if (!actions->noncasdemand.blob) {
+ const char *blob = mono_metadata_blob_heap (image, cols [MONO_DECL_SECURITY_PERMISSIONSET]);
+ actions->noncasdemand.blob = (char*) (blob + 2);
+ actions->noncasdemand.size = mono_metadata_decode_blob_size (blob, &blob);
+ result = TRUE;
+ }
+ break;
+ case SECURITY_ACTION_DEMANDCHOICE:
+ if (!actions->demandchoice.blob) {
+ const char *blob = mono_metadata_blob_heap (image, cols [MONO_DECL_SECURITY_PERMISSIONSET]);
+ actions->demandchoice.blob = (char*) (blob + 2);
+ actions->demandchoice.size = mono_metadata_decode_blob_size (blob, &blob);
+ result = TRUE;
+ }
+ break;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Collect all actions (that requires to generate code in mini) assigned for
+ * the specified method.
+ * Note: Don't use the content of actions if the function return FALSE.
+ */
+MonoBoolean
+mono_declsec_get_demands (MonoMethod *method, MonoDeclSecurityActions* demands)
+{
+ MonoImage *image = method->klass->image;
+ MonoBoolean result = FALSE;
+ guint32 flags;
+
+ /* quick exit if no declarative security is present in the metadata */
+ if (!image->tables [MONO_TABLE_DECLSECURITY].rows)
+ return FALSE;
+
+ memset (demands, 0, sizeof (MonoDeclSecurityActions));
+
+ /* First we look for method-level attributes */
+ if (method->flags & METHOD_ATTRIBUTE_HAS_SECURITY) {
+ guint32 idx = find_method_index (method);
+ idx <<= MONO_HAS_DECL_SECURITY_BITS;
+ idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
+ result = fill_actions_from_index (image, idx, demands);
+ }
+
+ /* Next we fill holes with class-level attributes */
+ /* Here we use (or create) the class declarative cache to look for demands */
+ flags = mono_declsec_flags_from_class (method->klass);
+ if (flags & (MONO_DECLSEC_FLAG_DEMAND | MONO_DECLSEC_FLAG_NONCAS_DEMAND | MONO_DECLSEC_FLAG_DEMAND_CHOICE)) {
+ guint32 idx = mono_metadata_token_index (method->klass->type_token);
+ idx <<= MONO_HAS_DECL_SECURITY_BITS;
+ idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
+ result |= fill_actions_from_index (image, idx, demands);
+ }
+
+ /* The boolean return value is used as a shortcut in case nothing needs to
+ be generated (e.g. LinkDemand[Choice] and InheritanceDemand[Choice]) */
+ return result;
+}
+
+static MonoBoolean
+get_declsec_action (MonoImage *image, guint32 token, guint32 action, MonoDeclSecurityEntry *entry)
+{
+ guint32 cols [MONO_DECL_SECURITY_SIZE];
+ MonoTableInfo *t;
+ int i;
+
+ int index = mono_metadata_declsec_from_index (image, token);
+ if (index == -1)
+ return FALSE;
+
+ t = &image->tables [MONO_TABLE_DECLSECURITY];
+ for (i = index; i < t->rows; i++) {
+ mono_metadata_decode_row (t, i, cols, MONO_DECL_SECURITY_SIZE);
+
+ /* shortcut - index are ordered */
+ if (token != cols [MONO_DECL_SECURITY_PARENT])
+ return FALSE;
+
+ if (cols [MONO_DECL_SECURITY_ACTION] == action) {
+ const char *metadata = mono_metadata_blob_heap (image, cols [MONO_DECL_SECURITY_PERMISSIONSET]);
+ entry->blob = (char*) (metadata + 2);
+ entry->size = mono_metadata_decode_blob_size (metadata, &metadata);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+MonoBoolean
+mono_declsec_get_method_action (MonoMethod *method, guint32 action, MonoDeclSecurityEntry *entry)
+{
+ if (method->flags & METHOD_ATTRIBUTE_HAS_SECURITY) {
+ guint32 idx = find_method_index (method);
+ idx <<= MONO_HAS_DECL_SECURITY_BITS;
+ idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
+ return get_declsec_action (method->klass->image, idx, action, entry);
+ }
+ return FALSE;
+}
+
+MonoBoolean
+mono_declsec_get_class_action (MonoClass *klass, guint32 action, MonoDeclSecurityEntry *entry)
+{
+ /* use cache */
+ guint32 flags = mono_declsec_flags_from_class (klass);
+ if (declsec_flags_map [action] & flags) {
+ guint32 idx = mono_metadata_token_index (klass->type_token);
+ idx <<= MONO_HAS_DECL_SECURITY_BITS;
+ idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
+ return get_declsec_action (klass->image, idx, action, entry);
+ }
+ return FALSE;
+}
+
+MonoBoolean
+mono_declsec_get_assembly_action (MonoAssembly *assembly, guint32 action, MonoDeclSecurityEntry *entry)
+{
+ guint32 idx = 1; /* there is only one assembly */
+ idx <<= MONO_HAS_DECL_SECURITY_BITS;
+ idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
+
+ return get_declsec_action (assembly->image, idx, action, entry);
+}