-/*
- * custom-attrs.c: Custom attributes.
+/**
+ * \file
+ * Custom attributes.
*
* Author:
* Paolo Molaro (lupus@ximian.com)
#include "mono/metadata/gc-internals.h"
#include "mono/metadata/mono-endian.h"
#include "mono/metadata/object-internals.h"
-#include "mono/metadata/reflection-cache.h"
#include "mono/metadata/custom-attrs-internals.h"
#include "mono/metadata/sre-internals.h"
#include "mono/metadata/reflection-internals.h"
static gboolean type_is_reference (MonoType *type);
-static GENERATE_GET_CLASS_WITH_CACHE (custom_attribute_typed_argument, System.Reflection, CustomAttributeTypedArgument);
-static GENERATE_GET_CLASS_WITH_CACHE (custom_attribute_named_argument, System.Reflection, CustomAttributeNamedArgument);
+static GENERATE_GET_CLASS_WITH_CACHE (custom_attribute_typed_argument, "System.Reflection", "CustomAttributeTypedArgument");
+static GENERATE_GET_CLASS_WITH_CACHE (custom_attribute_named_argument, "System.Reflection", "CustomAttributeNamedArgument");
+
+static MonoCustomAttrInfo*
+mono_custom_attrs_from_builders_handle (MonoImage *alloc_img, MonoImage *image, MonoArrayHandle cattrs);
+
+static gboolean
+bcheck_blob (const char *ptr, int bump, const char *endp, MonoError *error);
+
+static gboolean
+decode_blob_value_checked (const char *ptr, const char *endp, guint32 *size_out, const char **retp, MonoError *error);
/*
* LOCKING: Acquires the loader lock.
/* FIXME: Need to do more checks */
if (cattr->ctor->method && (cattr->ctor->method->klass->image != image)) {
- int visibility = cattr->ctor->method->klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+ int visibility = mono_class_get_flags (cattr->ctor->method->klass) & TYPE_ATTRIBUTE_VISIBILITY_MASK;
if ((visibility != TYPE_ATTRIBUTE_PUBLIC) && (visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC))
return FALSE;
find_field_index (MonoClass *klass, MonoClassField *field) {
int i;
- for (i = 0; i < klass->field.count; ++i) {
+ int fcount = mono_class_get_field_count (klass);
+ for (i = 0; i < fcount; ++i) {
if (field == &klass->fields [i])
- return klass->field.first + 1 + i;
+ return mono_class_get_first_field_idx (klass) + 1 + i;
}
return 0;
}
* Find the property index in the metadata Property table.
*/
static guint32
-find_property_index (MonoClass *klass, MonoProperty *property) {
+find_property_index (MonoClass *klass, MonoProperty *property)
+{
int i;
+ MonoClassPropertyInfo *info = mono_class_get_property_info (klass);
- for (i = 0; i < klass->ext->property.count; ++i) {
- if (property == &klass->ext->properties [i])
- return klass->ext->property.first + 1 + i;
+ for (i = 0; i < info->count; ++i) {
+ if (property == &info->properties [i])
+ return info->first + 1 + i;
}
return 0;
}
* Find the event index in the metadata Event table.
*/
static guint32
-find_event_index (MonoClass *klass, MonoEvent *event) {
+find_event_index (MonoClass *klass, MonoEvent *event)
+{
int i;
+ MonoClassEventInfo *info = mono_class_get_event_info (klass);
- for (i = 0; i < klass->ext->event.count; ++i) {
- if (event == &klass->ext->events [i])
- return klass->ext->event.first + 1 + i;
+ for (i = 0; i < info->count; ++i) {
+ if (event == &info->events [i])
+ return info->first + 1 + i;
}
return 0;
}
}
static MonoClass*
-load_cattr_enum_type (MonoImage *image, const char *p, const char **end, MonoError *error)
+load_cattr_enum_type (MonoImage *image, const char *p, const char *boundp, const char **end, MonoError *error)
{
char *n;
MonoType *t;
- int slen = mono_metadata_decode_value (p, &p);
+ guint32 slen;
+ error_init (error);
- mono_error_init (error);
+ if (!decode_blob_value_checked (p, boundp, &slen, &p, error))
+ return NULL;
+ if (boundp && slen > 0 && !bcheck_blob (p, slen - 1, boundp, error))
+ return NULL;
n = (char *)g_memdup (p, slen + 1);
n [slen] = 0;
t = cattr_type_from_name (n, image, TRUE, error);
}
static void*
-load_cattr_value (MonoImage *image, MonoType *t, const char *p, const char **end, MonoError *error)
+load_cattr_value (MonoImage *image, MonoType *t, const char *p, const char *boundp, const char **end, MonoError *error)
{
- int slen, type = t->type;
+ int type = t->type;
+ guint32 slen;
MonoClass *tklass = t->data.klass;
- mono_error_init (error);
+ g_assert (boundp);
+ error_init (error);
handle_enum:
switch (type) {
case MONO_TYPE_I1:
case MONO_TYPE_BOOLEAN: {
MonoBoolean *bval = (MonoBoolean *)g_malloc (sizeof (MonoBoolean));
+ if (!bcheck_blob (p, 0, boundp, error))
+ return NULL;
*bval = *p;
*end = p + 1;
return bval;
case MONO_TYPE_U2:
case MONO_TYPE_I2: {
guint16 *val = (guint16 *)g_malloc (sizeof (guint16));
+ if (!bcheck_blob (p, 1, boundp, error))
+ return NULL;
*val = read16 (p);
*end = p + 2;
return val;
case MONO_TYPE_U4:
case MONO_TYPE_I4: {
guint32 *val = (guint32 *)g_malloc (sizeof (guint32));
+ if (!bcheck_blob (p, 3, boundp, error))
+ return NULL;
*val = read32 (p);
*end = p + 4;
return val;
case MONO_TYPE_U8:
case MONO_TYPE_I8: {
guint64 *val = (guint64 *)g_malloc (sizeof (guint64));
+ if (!bcheck_blob (p, 7, boundp, error))
+ return NULL;
*val = read64 (p);
*end = p + 8;
return val;
}
case MONO_TYPE_R8: {
double *val = (double *)g_malloc (sizeof (double));
+ if (!bcheck_blob (p, 7, boundp, error))
+ return NULL;
readr8 (p, val);
*end = p + 8;
return val;
if (mono_is_corlib_image (k->image) && strcmp (k->name_space, "System") == 0 && strcmp (k->name, "DateTime") == 0){
guint64 *val = (guint64 *)g_malloc (sizeof (guint64));
+ if (!bcheck_blob (p, 7, boundp, error))
+ return NULL;
*val = read64 (p);
*end = p + 8;
return val;
break;
case MONO_TYPE_STRING:
+ if (!bcheck_blob (p, 0, boundp, error))
+ return NULL;
if (*p == (char)0xFF) {
*end = p + 1;
return NULL;
}
- slen = mono_metadata_decode_value (p, &p);
+ if (!decode_blob_value_checked (p, boundp, &slen, &p, error))
+ return NULL;
+ if (slen > 0 && !bcheck_blob (p, slen - 1, boundp, error))
+ return NULL;
*end = p + slen;
return mono_string_new_len_checked (mono_domain_get (), p, slen, error);
case MONO_TYPE_CLASS: {
MonoReflectionType *rt;
char *n;
MonoType *t;
+ if (!bcheck_blob (p, 0, boundp, error))
+ return NULL;
if (*p == (char)0xFF) {
*end = p + 1;
return NULL;
}
handle_type:
- slen = mono_metadata_decode_value (p, &p);
+ if (!decode_blob_value_checked (p, boundp, &slen, &p, error))
+ return NULL;
+ if (slen > 0 && !bcheck_blob (p, slen - 1, boundp, error))
+ return NULL;
n = (char *)g_memdup (p, slen + 1);
n [slen] = 0;
t = cattr_type_from_name (n, image, FALSE, error);
return rt;
}
case MONO_TYPE_OBJECT: {
+ if (!bcheck_blob (p, 0, boundp, error))
+ return NULL;
char subt = *p++;
MonoObject *obj;
MonoClass *subc = NULL;
goto handle_enum;
} else if (subt == 0x1D) {
MonoType simple_type = {{0}};
+ if (!bcheck_blob (p, 0, boundp, error))
+ return NULL;
int etype = *p;
p ++;
if (etype == 0x50) {
tklass = mono_defaults.systemtype_class;
} else if (etype == 0x55) {
- tklass = load_cattr_enum_type (image, p, &p, error);
- if (!mono_error_ok (error))
+ tklass = load_cattr_enum_type (image, p, boundp, &p, error);
+ if (!is_ok (error))
return NULL;
} else {
if (etype == 0x51)
} else if (subt == 0x55) {
char *n;
MonoType *t;
- slen = mono_metadata_decode_value (p, &p);
+ if (!decode_blob_value_checked (p, boundp, &slen, &p, error))
+ return NULL;
+ if (slen > 0 && !bcheck_blob (p, slen - 1, boundp, error))
+ return NULL;
n = (char *)g_memdup (p, slen + 1);
n [slen] = 0;
t = cattr_type_from_name (n, image, FALSE, error);
} else {
g_error ("Unknown type 0x%02x for object type encoding in custom attr", subt);
}
- val = load_cattr_value (image, &subc->byval_arg, p, end, error);
+ val = load_cattr_value (image, &subc->byval_arg, p, boundp, end, error);
obj = NULL;
- if (mono_error_ok (error)) {
+ if (is_ok (error)) {
obj = mono_object_new_checked (mono_domain_get (), subc, error);
g_assert (!subc->has_references);
- if (mono_error_ok (error))
+ if (is_ok (error))
mono_gc_memmove_atomic ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL));
}
case MONO_TYPE_SZARRAY: {
MonoArray *arr;
guint32 i, alen, basetype;
+ if (!bcheck_blob (p, 3, boundp, error))
+ return NULL;
alen = read32 (p);
p += 4;
if (alen == 0xffffffff) {
case MONO_TYPE_I1:
case MONO_TYPE_BOOLEAN:
for (i = 0; i < alen; i++) {
+ if (!bcheck_blob (p, 0, boundp, error))
+ return NULL;
MonoBoolean val = *p++;
mono_array_set (arr, MonoBoolean, i, val);
}
case MONO_TYPE_U2:
case MONO_TYPE_I2:
for (i = 0; i < alen; i++) {
+ if (!bcheck_blob (p, 1, boundp, error))
+ return NULL;
guint16 val = read16 (p);
mono_array_set (arr, guint16, i, val);
p += 2;
case MONO_TYPE_U4:
case MONO_TYPE_I4:
for (i = 0; i < alen; i++) {
+ if (!bcheck_blob (p, 3, boundp, error))
+ return NULL;
guint32 val = read32 (p);
mono_array_set (arr, guint32, i, val);
p += 4;
break;
case MONO_TYPE_R8:
for (i = 0; i < alen; i++) {
+ if (!bcheck_blob (p, 7, boundp, error))
+ return NULL;
double val;
readr8 (p, &val);
mono_array_set (arr, double, i, val);
case MONO_TYPE_U8:
case MONO_TYPE_I8:
for (i = 0; i < alen; i++) {
+ if (!bcheck_blob (p, 7, boundp, error))
+ return NULL;
guint64 val = read64 (p);
mono_array_set (arr, guint64, i, val);
p += 8;
case MONO_TYPE_STRING:
case MONO_TYPE_SZARRAY:
for (i = 0; i < alen; i++) {
- MonoObject *item = (MonoObject *)load_cattr_value (image, &tklass->byval_arg, p, &p, error);
- if (!mono_error_ok (error))
+ MonoObject *item = (MonoObject *)load_cattr_value (image, &tklass->byval_arg, p, boundp, &p, error);
+ if (!is_ok (error))
return NULL;
mono_array_setref (arr, i, item);
}
}
static MonoObject*
-load_cattr_value_boxed (MonoDomain *domain, MonoImage *image, MonoType *t, const char* p, const char** end, MonoError *error)
+load_cattr_value_boxed (MonoDomain *domain, MonoImage *image, MonoType *t, const char* p, const char *boundp, const char** end, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
gboolean is_ref = type_is_reference (t);
- void *val = load_cattr_value (image, t, p, end, error);
+ void *val = load_cattr_value (image, t, p, boundp, end, error);
if (!is_ok (error)) {
if (is_ref)
g_free (val);
MonoObject *retval;
void *params [2], *unboxed;
- mono_error_init (error);
+ error_init (error);
if (!ctor)
ctor = mono_class_get_method_from_name (mono_class_get_custom_attribute_typed_argument_class (), ".ctor", 2);
MonoObject *retval;
void *unboxed, *params [2];
- mono_error_init (error);
+ error_init (error);
if (!ctor)
ctor = mono_class_get_method_from_name (mono_class_get_custom_attribute_named_argument_class (), ".ctor", 2);
}
+static MonoCustomAttrInfo*
+mono_custom_attrs_from_builders_handle (MonoImage *alloc_img, MonoImage *image, MonoArrayHandle cattrs)
+{
+ return mono_custom_attrs_from_builders (alloc_img, image, MONO_HANDLE_RAW (cattrs)); /* FIXME use coop handles for mono_custom_attrs_from_builders */
+}
+
MonoCustomAttrInfo*
mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArray *cattrs)
{
return ainfo;
}
+static void
+set_custom_attr_fmt_error (MonoError *error)
+{
+ error_init (error);
+ mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
+}
+
+/**
+ * bcheck_blob:
+ * \param ptr a pointer into a blob
+ * \param bump how far we plan on reading past \p ptr.
+ * \param endp upper bound for \p ptr - one past the last valid value for \p ptr.
+ * \param error set on error
+ *
+ * Check that ptr+bump is below endp. Returns TRUE on success, or FALSE on
+ * failure and sets \p error.
+ */
+static gboolean
+bcheck_blob (const char *ptr, int bump, const char *endp, MonoError *error)
+{
+ error_init (error);
+ if (ADDP_IS_GREATER_OR_OVF (ptr, bump, endp - 1)) {
+ set_custom_attr_fmt_error (error);
+ return FALSE;
+ } else
+ return TRUE;
+}
+
+/**
+ * decode_blob_size_checked:
+ * \param ptr a pointer into a blob
+ * \param endp upper bound for \p ptr - one pas the last valid value for \p ptr
+ * \param size_out on success set to the decoded size
+ * \param retp on success set to the next byte after the encoded size
+ * \param error set on error
+ *
+ * Decode an encoded size value which takes 1, 2, or 4 bytes and set \p
+ * size_out to the decoded size and \p retp to the next byte after the encoded
+ * size. Returns TRUE on success, or FALASE on failure and sets \p error.
+ */
+static gboolean
+decode_blob_size_checked (const char *ptr, const char *endp, guint32 *size_out, const char **retp, MonoError *error)
+{
+ error_init (error);
+ if (endp && !bcheck_blob (ptr, 0, endp, error))
+ goto leave;
+ if ((*ptr & 0x80) != 0) {
+ if ((*ptr & 0x40) == 0 && !bcheck_blob (ptr, 1, endp, error))
+ goto leave;
+ else if (!bcheck_blob (ptr, 3, endp, error))
+ goto leave;
+ }
+ *size_out = mono_metadata_decode_blob_size (ptr, retp);
+leave:
+ return is_ok (error);
+}
+
+/**
+ * decode_blob_value_checked:
+ * \param ptr a pointer into a blob
+ * \param endp upper bound for \p ptr - one pas the last valid value for \p ptr
+ * \param value_out on success set to the decoded value
+ * \param retp on success set to the next byte after the encoded size
+ * \param error set on error
+ *
+ * Decode an encoded uint32 value which takes 1, 2, or 4 bytes and set \p
+ * value_out to the decoded value and \p retp to the next byte after the
+ * encoded value. Returns TRUE on success, or FALASE on failure and sets \p
+ * error.
+ */
+static gboolean
+decode_blob_value_checked (const char *ptr, const char *endp, guint32 *value_out, const char **retp, MonoError *error)
+{
+ /* This similar to decode_blob_size_checked, above but delegates to
+ * mono_metadata_decode_value which is semantically different. */
+ error_init (error);
+ if (!bcheck_blob (ptr, 0, endp, error))
+ goto leave;
+ if ((*ptr & 0x80) != 0) {
+ if ((*ptr & 0x40) == 0 && !bcheck_blob (ptr, 1, endp, error))
+ goto leave;
+ else if (!bcheck_blob (ptr, 3, endp, error))
+ goto leave;
+ }
+ *value_out = mono_metadata_decode_value (ptr, retp);
+leave:
+ return is_ok (error);
+}
static MonoObject*
create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoError *error)
{
const char *p = (const char*)data;
+ const char *data_end = (const char*)data + len;
const char *named;
guint32 i, j, num_named;
MonoObject *attr;
void **params = NULL;
MonoMethodSignature *sig;
- mono_error_init (error);
+ error_init (error);
mono_class_init (method->klass);
if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL)) {
- mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
+ set_custom_attr_fmt_error (error);
return NULL;
}
/* skip prolog */
p += 2;
for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
- params [i] = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p, error);
- if (!mono_error_ok (error))
+ params [i] = load_cattr_value (image, mono_method_signature (method)->params [i], p, data_end, &p, error);
+ if (!is_ok (error))
goto fail;
}
goto fail;
}
- num_named = read16 (named);
- named += 2;
+ if (named + 1 < data_end) {
+ num_named = read16 (named);
+ named += 2;
+ } else {
+ /* CoreCLR allows p == data + len */
+ if (named == data_end)
+ num_named = 0;
+ else {
+ set_custom_attr_fmt_error (error);
+ goto fail;
+ }
+ }
for (j = 0; j < num_named; j++) {
- gint name_len;
+ guint32 name_len;
char *name, named_type, data_type;
+ if (!bcheck_blob (named, 1, data_end, error))
+ goto fail;
named_type = *named++;
data_type = *named++; /* type of data */
- if (data_type == MONO_TYPE_SZARRAY)
+ if (data_type == MONO_TYPE_SZARRAY) {
+ if (!bcheck_blob (named, 0, data_end, error))
+ goto fail;
data_type = *named++;
+ }
if (data_type == MONO_TYPE_ENUM) {
- gint type_len;
+ guint32 type_len;
char *type_name;
- type_len = mono_metadata_decode_blob_size (named, &named);
+ if (!decode_blob_size_checked (named, data_end, &type_len, &named, error))
+ goto fail;
+ if (type_len > 0 && !bcheck_blob (named, type_len - 1, data_end, error))
+ goto fail;
type_name = (char *)g_malloc (type_len + 1);
memcpy (type_name, named, type_len);
type_name [type_len] = 0;
/* FIXME: lookup the type and check type consistency */
g_free (type_name);
}
- name_len = mono_metadata_decode_blob_size (named, &named);
+ if (!decode_blob_size_checked (named, data_end, &name_len, &named, error))
+ goto fail;
+ if (name_len > 0 && !bcheck_blob (named, name_len - 1, data_end, error))
+ goto fail;
name = (char *)g_malloc (name_len + 1);
memcpy (name, named, name_len);
name [name_len] = 0;
goto fail;
}
- val = load_cattr_value (image, field->type, named, &named, error);
- if (!mono_error_ok (error)) {
+ val = load_cattr_value (image, field->type, named, data_end, &named, error);
+ if (!is_ok (error)) {
g_free (name);
if (!type_is_reference (field->type))
g_free (val);
prop_type = prop->get? mono_method_signature (prop->get)->ret :
mono_method_signature (prop->set)->params [mono_method_signature (prop->set)->param_count - 1];
- pparams [0] = load_cattr_value (image, prop_type, named, &named, error);
- if (!mono_error_ok (error)) {
+ pparams [0] = load_cattr_value (image, prop_type, named, data_end, &named, error);
+ if (!is_ok (error)) {
g_free (name);
if (!type_is_reference (prop_type))
g_free (pparams [0]);
MonoClass *attrklass;
MonoDomain *domain;
const char *p = (const char*)data;
+ const char *data_end = p + len;
const char *named;
guint32 i, j, num_named;
CattrNamedArg *arginfo = NULL;
*named_args = NULL;
*named_arg_info = NULL;
- mono_error_init (error);
+ error_init (error);
if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL)) {
mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
if (len < 2 || read16 (p) != 0x0001) /* Prolog */
return;
+ /* skip prolog */
+ p += 2;
+ /* Parse each argument corresponding to the signature's parameters from
+ * the blob and store in typedargs.
+ */
typedargs = mono_array_new_checked (domain, mono_get_object_class (), mono_method_signature (method)->param_count, error);
return_if_nok (error);
- /* skip prolog */
- p += 2;
for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
MonoObject *obj;
- obj = load_cattr_value_boxed (domain, image, mono_method_signature (method)->params [i], p, &p, error);
+ obj = load_cattr_value_boxed (domain, image, mono_method_signature (method)->params [i], p, data_end, &p, error);
return_if_nok (error);
mono_array_setref (typedargs, i, obj);
}
named = p;
+
+ /* Parse mandatory count of named arguments (could be zero) */
+ if (!bcheck_blob (named, 1, data_end, error))
+ return;
num_named = read16 (named);
namedargs = mono_array_new_checked (domain, mono_get_object_class (), num_named, error);
return_if_nok (error);
arginfo = g_new0 (CattrNamedArg, num_named);
*named_arg_info = arginfo;
+ /* Parse each named arg, and add to arginfo. Each named argument could
+ * be a field name or a property name followed by a value. */
for (j = 0; j < num_named; j++) {
- gint name_len;
+ guint32 name_len;
char *name, named_type, data_type;
- named_type = *named++;
+ if (!bcheck_blob (named, 1, data_end, error))
+ return;
+ named_type = *named++; /* field or property? */
data_type = *named++; /* type of data */
- if (data_type == MONO_TYPE_SZARRAY)
+ if (data_type == MONO_TYPE_SZARRAY) {
+ if (!bcheck_blob (named, 0, data_end, error))
+ return;
data_type = *named++;
+ }
if (data_type == MONO_TYPE_ENUM) {
- gint type_len;
+ guint32 type_len;
char *type_name;
- type_len = mono_metadata_decode_blob_size (named, &named);
+ if (!decode_blob_size_checked (named, data_end, &type_len, &named, error))
+ return;
if (ADDP_IS_GREATER_OR_OVF ((const guchar*)named, type_len, data + len))
goto fail;
/* FIXME: lookup the type and check type consistency */
g_free (type_name);
}
- name_len = mono_metadata_decode_blob_size (named, &named);
+ /* named argument name: length, then name */
+ if (!decode_blob_size_checked(named, data_end, &name_len, &named, error))
+ return;
if (ADDP_IS_GREATER_OR_OVF ((const guchar*)named, name_len, data + len))
goto fail;
name = (char *)g_malloc (name_len + 1);
name [name_len] = 0;
named += name_len;
if (named_type == 0x53) {
+ /* Named arg is a field. */
MonoObject *obj;
MonoClassField *field = mono_class_get_field_from_name (attrklass, name);
arginfo [j].type = field->type;
arginfo [j].field = field;
- obj = load_cattr_value_boxed (domain, image, field->type, named, &named, error);
+ obj = load_cattr_value_boxed (domain, image, field->type, named, data_end, &named, error);
if (!is_ok (error)) {
g_free (name);
return;
mono_array_setref (namedargs, j, obj);
} else if (named_type == 0x54) {
+ /* Named arg is a property */
MonoObject *obj;
MonoType *prop_type;
MonoProperty *prop = mono_class_get_property_from_name (attrklass, name);
arginfo [j].type = prop_type;
arginfo [j].prop = prop;
- obj = load_cattr_value_boxed (domain, image, prop_type, named, &named, error);
+ obj = load_cattr_value_boxed (domain, image, prop_type, named, data_end, &named, error);
if (!is_ok (error)) {
g_free (name);
return;
CattrNamedArg *arginfo = NULL;
int i;
- mono_error_init (error);
+ error_init (error);
*ctor_args = NULL;
*named_args = NULL;
mono_error_set_pending_exception (&error);
}
-static MonoObject*
-create_custom_attr_data (MonoImage *image, MonoCustomAttrEntry *cattr, MonoError *error)
+static MonoObjectHandle
+create_custom_attr_data_handle (MonoImage *image, MonoCustomAttrEntry *cattr, MonoError *error)
{
static MonoMethod *ctor;
MonoDomain *domain;
- MonoObject *attr;
void *params [4];
- mono_error_init (error);
+ error_init (error);
g_assert (image->assembly);
ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 4);
domain = mono_domain_get ();
- attr = mono_object_new_checked (domain, mono_defaults.customattribute_data_class, error);
- return_val_if_nok (error, NULL);
- params [0] = mono_method_get_object_checked (domain, cattr->ctor, NULL, error);
- return_val_if_nok (error, NULL);
- params [1] = mono_assembly_get_object_checked (domain, image->assembly, error);
- return_val_if_nok (error, NULL);
+
+ MonoObjectHandle attr = MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (domain, mono_defaults.customattribute_data_class, error));
+ if (!is_ok (error))
+ goto fail;
+
+ MonoReflectionMethod *ctor_obj = mono_method_get_object_checked (domain, cattr->ctor, NULL, error);
+ if (!is_ok (error))
+ goto fail;
+ MonoReflectionAssemblyHandle assm = mono_assembly_get_object_handle (domain, image->assembly, error);
+ if (!is_ok (error))
+ goto fail;
+ params [0] = ctor_obj;
+ params [1] = MONO_HANDLE_RAW (assm);
params [2] = (gpointer)&cattr->data;
params [3] = &cattr->data_size;
- mono_runtime_invoke_checked (ctor, attr, params, error);
- return_val_if_nok (error, NULL);
+ mono_runtime_invoke_checked (ctor, MONO_HANDLE_RAW (attr), params, error);
return attr;
+fail:
+ return MONO_HANDLE_NEW (MonoObject, NULL);
+}
+
+static MonoObject *
+create_custom_attr_data (MonoImage *image, MonoCustomAttrEntry *cattr, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER ();
+ MonoObjectHandle obj = create_custom_attr_data_handle (image, cattr, error);
+ HANDLE_FUNCTION_RETURN_OBJ (obj);
}
static MonoArray*
MonoObject *attr;
int i, n;
- mono_error_init (error);
+ error_init (error);
for (i = 0; i < cinfo->num_attrs; ++i) {
MonoCustomAttrEntry *centry = &cinfo->attrs[i];
return result;
}
+/**
+ * mono_custom_attrs_construct:
+ */
MonoArray*
mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
{
MonoObject *attr;
int i;
- mono_error_init (error);
+ error_init (error);
result = mono_array_new_checked (mono_domain_get (), mono_defaults.customattribute_data_class, cinfo->num_attrs, error);
return_val_if_nok (error, NULL);
for (i = 0; i < cinfo->num_attrs; ++i) {
}
/**
* mono_custom_attrs_from_index_checked:
- *
- * Returns: NULL if no attributes are found. On error returns NULL and sets @error.
+ * \returns NULL if no attributes are found. On error returns NULL and sets \p error.
*/
MonoCustomAttrInfo*
mono_custom_attrs_from_index_checked (MonoImage *image, guint32 idx, gboolean ignore_missing, MonoError *error)
const char *data;
MonoCustomAttrEntry* attr;
- mono_error_init (error);
+ error_init (error);
ca = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x due to: %s", image->name, mtoken, mono_error_get_message (error));
if (ignore_missing) {
mono_error_cleanup (error);
- mono_error_init (error);
+ error_init (error);
} else {
g_list_free (list);
g_free (ainfo);
return ainfo;
}
+/**
+ * mono_custom_attrs_from_method:
+ */
MonoCustomAttrInfo*
mono_custom_attrs_from_method (MonoMethod *method)
{
{
guint32 idx;
- mono_error_init (error);
+ error_init (error);
/*
* An instantiated method has the same cattrs as the generic method definition.
return mono_custom_attrs_from_index_checked (method->klass->image, idx, FALSE, error);
}
+/**
+ * mono_custom_attrs_from_class:
+ */
MonoCustomAttrInfo*
mono_custom_attrs_from_class (MonoClass *klass)
{
{
guint32 idx;
- mono_error_init (error);
+ error_init (error);
- if (klass->generic_class)
- klass = klass->generic_class->container_class;
+ if (mono_class_is_ginst (klass))
+ klass = mono_class_get_generic_class (klass)->container_class;
if (image_is_dynamic (klass->image))
return lookup_custom_attr (klass->image, klass);
return mono_custom_attrs_from_index_checked (klass->image, idx, FALSE, error);
}
+/**
+ * mono_custom_attrs_from_assembly:
+ */
MonoCustomAttrInfo*
mono_custom_attrs_from_assembly (MonoAssembly *assembly)
{
{
guint32 idx;
- mono_error_init (error);
+ error_init (error);
if (image_is_dynamic (assembly->image))
return lookup_custom_attr (assembly->image, assembly);
mono_custom_attrs_from_module (MonoImage *image, MonoError *error)
{
guint32 idx;
+
+ error_init (error);
if (image_is_dynamic (image))
return lookup_custom_attr (image, image);
return mono_custom_attrs_from_index_checked (image, idx, FALSE, error);
}
+/**
+ * mono_custom_attrs_from_property:
+ */
MonoCustomAttrInfo*
mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property)
{
mono_custom_attrs_from_property_checked (MonoClass *klass, MonoProperty *property, MonoError *error)
{
guint32 idx;
+
+ error_init (error);
if (image_is_dynamic (klass->image)) {
property = mono_metadata_get_corresponding_property_from_generic_type_definition (property);
return mono_custom_attrs_from_index_checked (klass->image, idx, FALSE, error);
}
+/**
+ * mono_custom_attrs_from_event:
+ */
MonoCustomAttrInfo*
mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event)
{
mono_custom_attrs_from_event_checked (MonoClass *klass, MonoEvent *event, MonoError *error)
{
guint32 idx;
+
+ error_init (error);
if (image_is_dynamic (klass->image)) {
event = mono_metadata_get_corresponding_event_from_generic_type_definition (event);
return mono_custom_attrs_from_index_checked (klass->image, idx, FALSE, error);
}
+/**
+ * mono_custom_attrs_from_field:
+ */
MonoCustomAttrInfo*
mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field)
{
mono_custom_attrs_from_field_checked (MonoClass *klass, MonoClassField *field, MonoError *error)
{
guint32 idx;
- mono_error_init (error);
+ error_init (error);
if (image_is_dynamic (klass->image)) {
field = mono_metadata_get_corresponding_field_from_generic_type_definition (field);
/**
* mono_custom_attrs_from_param:
- * @method: handle to the method that we want to retrieve custom parameter information from
- * @param: parameter number, where zero represent the return value, and one is the first parameter in the method
+ * \param method handle to the method that we want to retrieve custom parameter information from
+ * \param param parameter number, where zero represent the return value, and one is the first parameter in the method
*
* The result must be released with mono_custom_attrs_free().
*
- * Returns: the custom attribute object for the specified parameter, or NULL if there are none.
+ * \returns the custom attribute object for the specified parameter, or NULL if there are none.
*/
MonoCustomAttrInfo*
mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
/**
* mono_custom_attrs_from_param_checked:
- * @method: handle to the method that we want to retrieve custom parameter information from
- * @param: parameter number, where zero represent the return value, and one is the first parameter in the method
- * @error: set on error
+ * \param method handle to the method that we want to retrieve custom parameter information from
+ * \param param parameter number, where zero represent the return value, and one is the first parameter in the method
+ * \param error set on error
*
* The result must be released with mono_custom_attrs_free().
*
- * Returns: the custom attribute object for the specified parameter, or NULL if there are none. On failure returns NULL and sets @error.
+ * \returns the custom attribute object for the specified parameter, or NULL if there are none. On failure returns NULL and sets \p error.
*/
MonoCustomAttrInfo*
mono_custom_attrs_from_param_checked (MonoMethod *method, guint32 param, MonoError *error)
MonoImage *image;
MonoReflectionMethodAux *aux;
- mono_error_init (error);
+ error_init (error);
/*
* An instantiated method has the same cattrs as the generic method definition.
return mono_custom_attrs_from_index_checked (image, idx, FALSE, error);
}
+/**
+ * mono_custom_attrs_has_attr:
+ */
gboolean
mono_custom_attrs_has_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
{
return FALSE;
}
+/**
+ * mono_custom_attrs_get_attr:
+ */
MonoObject*
mono_custom_attrs_get_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
{
g_assert (attr_klass != NULL);
- mono_error_init (error);
+ error_init (error);
for (i = 0; i < ainfo->num_attrs; ++i) {
centry = &ainfo->attrs[i];
return create_custom_attr (ainfo->image, centry->ctor, centry->data, centry->data_size, error);
}
-/*
+/**
* mono_reflection_get_custom_attrs_info:
- * @obj: a reflection object handle
+ * \param obj a reflection object handle
*
- * Return the custom attribute info for attributes defined for the
- * reflection handle @obj. The objects.
+ * \returns the custom attribute info for attributes defined for the
+ * reflection handle \p obj. The objects.
*
* FIXME this function leaks like a sieve for SRE objects.
*/
MonoCustomAttrInfo*
-mono_reflection_get_custom_attrs_info (MonoObject *obj)
+mono_reflection_get_custom_attrs_info (MonoObject *obj_raw)
{
+ HANDLE_FUNCTION_ENTER ();
MonoError error;
+ MONO_HANDLE_DCL (MonoObject, obj);
MonoCustomAttrInfo *result = mono_reflection_get_custom_attrs_info_checked (obj, &error);
mono_error_assert_ok (&error);
- return result;
+ HANDLE_FUNCTION_RETURN_VAL (result);
}
/**
* mono_reflection_get_custom_attrs_info_checked:
- * @obj: a reflection object handle
- * @error: set on error
- *
- * Return the custom attribute info for attributes defined for the
- * reflection handle @obj. The objects.
+ * \param obj a reflection object handle
+ * \param error set on error
*
- * On failure returns NULL and sets @error.
+ * \returns the custom attribute info for attributes defined for the
+ * reflection handle \p obj. The objects. On failure returns NULL and sets \p error.
*
* FIXME this function leaks like a sieve for SRE objects.
*/
MonoCustomAttrInfo*
-mono_reflection_get_custom_attrs_info_checked (MonoObject *obj, MonoError *error)
+mono_reflection_get_custom_attrs_info_checked (MonoObjectHandle obj, MonoError *error)
{
+ HANDLE_FUNCTION_ENTER ();
MonoClass *klass;
MonoCustomAttrInfo *cinfo = NULL;
- mono_error_init (error);
+ error_init (error);
- klass = obj->vtable->klass;
+ klass = mono_handle_class (obj);
if (klass == mono_defaults.runtimetype_class) {
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
- return_val_if_nok (error, NULL);
+ MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST(MonoReflectionType, obj), error);
+ if (!is_ok (error))
+ goto leave;
klass = mono_class_from_mono_type (type);
/*We cannot mono_class_init the class from which we'll load the custom attributes since this must work with broken types.*/
cinfo = mono_custom_attrs_from_class_checked (klass, error);
- return_val_if_nok (error, NULL);
+ if (!is_ok (error))
+ goto leave;
} else if (strcmp ("Assembly", klass->name) == 0 || strcmp ("MonoAssembly", klass->name) == 0) {
- MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
- cinfo = mono_custom_attrs_from_assembly_checked (rassembly->assembly, FALSE, error);
- return_val_if_nok (error, NULL);
+ MonoReflectionAssemblyHandle rassembly = MONO_HANDLE_CAST (MonoReflectionAssembly, obj);
+ cinfo = mono_custom_attrs_from_assembly_checked (MONO_HANDLE_GETVAL (rassembly, assembly), FALSE, error);
+ if (!is_ok (error))
+ goto leave;
} else if (strcmp ("Module", klass->name) == 0 || strcmp ("MonoModule", klass->name) == 0) {
- MonoReflectionModule *module = (MonoReflectionModule*)obj;
- cinfo = mono_custom_attrs_from_module (module->image, error);
- return_val_if_nok (error, NULL);
+ MonoReflectionModuleHandle module = MONO_HANDLE_CAST (MonoReflectionModule, obj);
+ cinfo = mono_custom_attrs_from_module (MONO_HANDLE_GETVAL (module, image), error);
+ if (!is_ok (error))
+ goto leave;
} else if (strcmp ("MonoProperty", klass->name) == 0) {
- MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
- cinfo = mono_custom_attrs_from_property_checked (rprop->property->parent, rprop->property, error);
- return_val_if_nok (error, NULL);
+ MonoReflectionPropertyHandle rprop = MONO_HANDLE_CAST (MonoReflectionProperty, obj);
+ MonoProperty *property = MONO_HANDLE_GETVAL (rprop, property);
+ cinfo = mono_custom_attrs_from_property_checked (property->parent, property, error);
+ if (!is_ok (error))
+ goto leave;
} else if (strcmp ("MonoEvent", klass->name) == 0) {
- MonoReflectionMonoEvent *revent = (MonoReflectionMonoEvent*)obj;
- cinfo = mono_custom_attrs_from_event_checked (revent->event->parent, revent->event, error);
- return_val_if_nok (error, NULL);
+ MonoReflectionMonoEventHandle revent = MONO_HANDLE_CAST (MonoReflectionMonoEvent, obj);
+ MonoEvent *event = MONO_HANDLE_GETVAL (revent, event);
+ cinfo = mono_custom_attrs_from_event_checked (event->parent, event, error);
+ if (!is_ok (error))
+ goto leave;
} else if (strcmp ("MonoField", klass->name) == 0) {
- MonoReflectionField *rfield = (MonoReflectionField*)obj;
- cinfo = mono_custom_attrs_from_field_checked (rfield->field->parent, rfield->field, error);
- return_val_if_nok (error, NULL);
+ MonoReflectionFieldHandle rfield = MONO_HANDLE_CAST (MonoReflectionField, obj);
+ MonoClassField *field = MONO_HANDLE_GETVAL (rfield, field);
+ cinfo = mono_custom_attrs_from_field_checked (field->parent, field, error);
+ if (!is_ok (error))
+ goto leave;
} else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) {
- MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
- cinfo = mono_custom_attrs_from_method_checked (rmethod->method, error);
- return_val_if_nok (error, NULL);
+ MonoReflectionMethodHandle rmethod = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
+ cinfo = mono_custom_attrs_from_method_checked (MONO_HANDLE_GETVAL (rmethod, method), error);
+ if (!is_ok (error))
+ goto leave;
} else if (strcmp ("ParameterInfo", klass->name) == 0 || strcmp ("MonoParameterInfo", klass->name) == 0) {
- MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
- MonoClass *member_class = mono_object_class (param->MemberImpl);
+ MonoReflectionParameterHandle param = MONO_HANDLE_CAST (MonoReflectionParameter, obj);
+ MonoObjectHandle member_impl = MONO_HANDLE_NEW_GET (MonoObject, param, MemberImpl);
+ MonoClass *member_class = mono_handle_class (member_impl);
if (mono_class_is_reflection_method_or_constructor (member_class)) {
- MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
- cinfo = mono_custom_attrs_from_param_checked (rmethod->method, param->PositionImpl + 1, error);
- return_val_if_nok (error, NULL);
+ MonoReflectionMethodHandle rmethod = MONO_HANDLE_CAST (MonoReflectionMethod, member_impl);
+ cinfo = mono_custom_attrs_from_param_checked (MONO_HANDLE_GETVAL (rmethod, method), MONO_HANDLE_GETVAL (param, PositionImpl) + 1, error);
+ if (!is_ok (error))
+ goto leave;
} else if (mono_is_sr_mono_property (member_class)) {
- MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
+ MonoReflectionPropertyHandle prop = MONO_HANDLE_CAST (MonoReflectionProperty, member_impl);
+ MonoProperty *property = MONO_HANDLE_GETVAL (prop, property);
MonoMethod *method;
- if (!(method = prop->property->get))
- method = prop->property->set;
+ if (!(method = property->get))
+ method = property->set;
g_assert (method);
- cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
- return_val_if_nok (error, NULL);
+ cinfo = mono_custom_attrs_from_param_checked (method, MONO_HANDLE_GETVAL (param, PositionImpl) + 1, error);
+ if (!is_ok (error))
+ goto leave;
}
#ifndef DISABLE_REFLECTION_EMIT
else if (mono_is_sre_method_on_tb_inst (member_class)) {/*XXX This is a workaround for Compiler Context*/
"Custom attributes on a ParamInfo with member %s are not supported",
type_name);
g_free (type_name);
- return NULL;
+ goto leave;
}
} else if (strcmp ("AssemblyBuilder", klass->name) == 0) {
- MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)obj;
- cinfo = mono_custom_attrs_from_builders (NULL, assemblyb->assembly.assembly->image, assemblyb->cattrs);
+ MonoReflectionAssemblyBuilderHandle assemblyb = MONO_HANDLE_CAST (MonoReflectionAssemblyBuilder, obj);
+ MonoReflectionAssemblyHandle assembly = MONO_HANDLE_CAST (MonoReflectionAssembly, assemblyb);
+ MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, assemblyb, cattrs);
+ MonoImage * image = MONO_HANDLE_GETVAL (assembly, assembly)->image;
+ g_assert (image);
+ cinfo = mono_custom_attrs_from_builders_handle (NULL, image, cattrs);
} else if (strcmp ("TypeBuilder", klass->name) == 0) {
- MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
- cinfo = mono_custom_attrs_from_builders (NULL, &tb->module->dynamic_image->image, tb->cattrs);
+ MonoReflectionTypeBuilderHandle tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, obj);
+ MonoReflectionModuleBuilderHandle module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, tb, module);
+ MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (module, dynamic_image);
+ MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, tb, cattrs);
+ cinfo = mono_custom_attrs_from_builders_handle (NULL, &dynamic_image->image, cattrs);
} else if (strcmp ("ModuleBuilder", klass->name) == 0) {
- MonoReflectionModuleBuilder *mb = (MonoReflectionModuleBuilder*)obj;
- cinfo = mono_custom_attrs_from_builders (NULL, &mb->dynamic_image->image, mb->cattrs);
+ MonoReflectionModuleBuilderHandle mb = MONO_HANDLE_CAST (MonoReflectionModuleBuilder, obj);
+ MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
+ MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, mb, cattrs);
+ cinfo = mono_custom_attrs_from_builders_handle (NULL, &dynamic_image->image, cattrs);
} else if (strcmp ("ConstructorBuilder", klass->name) == 0) {
- MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
- cinfo = mono_custom_attrs_from_builders (NULL, cb->mhandle->klass->image, cb->cattrs);
+ MonoReflectionCtorBuilderHandle cb = MONO_HANDLE_CAST (MonoReflectionCtorBuilder, obj);
+ MonoMethod *mhandle = MONO_HANDLE_GETVAL (cb, mhandle);
+ MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, cb, cattrs);
+ cinfo = mono_custom_attrs_from_builders_handle (NULL, mhandle->klass->image, cattrs);
} else if (strcmp ("MethodBuilder", klass->name) == 0) {
- MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
- cinfo = mono_custom_attrs_from_builders (NULL, mb->mhandle->klass->image, mb->cattrs);
+ MonoReflectionMethodBuilderHandle mb = MONO_HANDLE_CAST (MonoReflectionMethodBuilder, obj);
+ MonoMethod *mhandle = MONO_HANDLE_GETVAL (mb, mhandle);
+ MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, mb, cattrs);
+ cinfo = mono_custom_attrs_from_builders_handle (NULL, mhandle->klass->image, cattrs);
} else if (strcmp ("FieldBuilder", klass->name) == 0) {
- MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
- cinfo = mono_custom_attrs_from_builders (NULL, &((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image->image, fb->cattrs);
+ MonoReflectionFieldBuilderHandle fb = MONO_HANDLE_CAST (MonoReflectionFieldBuilder, obj);
+ MonoReflectionTypeBuilderHandle tb = MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder, fb, typeb);
+ MonoReflectionModuleBuilderHandle mb = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, tb, module);
+ MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
+ MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, fb, cattrs);
+ cinfo = mono_custom_attrs_from_builders_handle (NULL, &dynamic_image->image, cattrs);
} else if (strcmp ("MonoGenericClass", klass->name) == 0) {
- MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)obj;
- cinfo = mono_reflection_get_custom_attrs_info_checked ((MonoObject*)gclass->generic_type, error);
- return_val_if_nok (error, NULL);
+ MonoReflectionGenericClassHandle gclass = MONO_HANDLE_CAST (MonoReflectionGenericClass, obj);
+ MonoReflectionTypeHandle generic_type = MONO_HANDLE_NEW_GET (MonoReflectionType, gclass, generic_type);
+ cinfo = mono_reflection_get_custom_attrs_info_checked (MONO_HANDLE_CAST (MonoObject, generic_type), error);
+ if (!is_ok (error))
+ goto leave;
} else { /* handle other types here... */
g_error ("get custom attrs not yet supported for %s", klass->name);
}
- return cinfo;
+leave:
+ HANDLE_FUNCTION_RETURN_VAL (cinfo);
}
-/*
+/**
* mono_reflection_get_custom_attrs_by_type:
- * @obj: a reflection object handle
- *
- * Return an array with all the custom attributes defined of the
- * reflection handle @obj. If @attr_klass is non-NULL, only custom attributes
+ * \param obj a reflection object handle
+ * \returns an array with all the custom attributes defined of the
+ * reflection handle \p obj. If \p attr_klass is non-NULL, only custom attributes
* of that type are returned. The objects are fully build. Return NULL if a loading error
* occurs.
*/
MonoArray*
-mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass, MonoError *error)
+mono_reflection_get_custom_attrs_by_type (MonoObject *obj_raw, MonoClass *attr_klass, MonoError *error)
{
- MonoArray *result;
+ HANDLE_FUNCTION_ENTER ();
+ MONO_HANDLE_DCL (MonoObject, obj);
+ MonoArrayHandle result = mono_reflection_get_custom_attrs_by_type_handle (obj, attr_klass, error);
+ HANDLE_FUNCTION_RETURN_OBJ (result);
+}
+
+MonoArrayHandle
+mono_reflection_get_custom_attrs_by_type_handle (MonoObjectHandle obj, MonoClass *attr_klass, MonoError *error)
+{
+ MonoArrayHandle result = MONO_HANDLE_NEW (MonoArray, NULL);
MonoCustomAttrInfo *cinfo;
- mono_error_init (error);
+ error_init (error);
cinfo = mono_reflection_get_custom_attrs_info_checked (obj, error);
- return_val_if_nok (error, NULL);
+ if (!is_ok (error))
+ goto leave;
if (cinfo) {
- result = mono_custom_attrs_construct_by_type (cinfo, attr_klass, error);
+ MONO_HANDLE_ASSIGN (result, MONO_HANDLE_NEW (MonoArray, mono_custom_attrs_construct_by_type (cinfo, attr_klass, error))); /* FIXME use coop handles for mono_custom_attrs_construct_by_type */
if (!cinfo->cached)
mono_custom_attrs_free (cinfo);
if (!result)
- return NULL;
+ goto leave;
} else {
- result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, 0, error);
+ MONO_HANDLE_ASSIGN (result, mono_array_new_handle (mono_domain_get (), mono_defaults.attribute_class, 0, error));
}
+leave:
return result;
}
-/*
+/**
* mono_reflection_get_custom_attrs:
- * @obj: a reflection object handle
- *
- * Return an array with all the custom attributes defined of the
- * reflection handle @obj. The objects are fully build. Return NULL if a loading error
+ * \param obj a reflection object handle
+ * \return an array with all the custom attributes defined of the
+ * reflection handle \p obj. The objects are fully build. Return NULL if a loading error
* occurs.
*/
MonoArray*
-mono_reflection_get_custom_attrs (MonoObject *obj)
+mono_reflection_get_custom_attrs (MonoObject *obj_raw)
{
+ HANDLE_FUNCTION_ENTER ();
MonoError error;
-
- return mono_reflection_get_custom_attrs_by_type (obj, NULL, &error);
+ MONO_HANDLE_DCL (MonoObject, obj);
+ MonoArrayHandle result = mono_reflection_get_custom_attrs_by_type_handle (obj, NULL, &error);
+ mono_error_cleanup (&error);
+ HANDLE_FUNCTION_RETURN_OBJ (result);
}
-/*
+/**
* mono_reflection_get_custom_attrs_data:
- * @obj: a reflection obj handle
- *
- * Returns an array of System.Reflection.CustomAttributeData,
+ * \param obj a reflection obj handle
+ * \returns an array of \c System.Reflection.CustomAttributeData,
* which include information about attributes reflected on
* types loaded using the Reflection Only methods
*/
MonoArray*
-mono_reflection_get_custom_attrs_data (MonoObject *obj)
+mono_reflection_get_custom_attrs_data (MonoObject *obj_raw)
{
+ HANDLE_FUNCTION_ENTER ();
MonoError error;
- MonoArray* result;
- result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
+ MONO_HANDLE_DCL (MonoObject, obj);
+ MonoArrayHandle result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
mono_error_cleanup (&error);
- return result;
+ HANDLE_FUNCTION_RETURN_OBJ (result);
}
/*
* which include information about attributes reflected on
* types loaded using the Reflection Only methods
*/
-MonoArray*
-mono_reflection_get_custom_attrs_data_checked (MonoObject *obj, MonoError *error)
+MonoArrayHandle
+mono_reflection_get_custom_attrs_data_checked (MonoObjectHandle obj, MonoError *error)
{
- MonoArray *result;
+ MonoArrayHandle result = MONO_HANDLE_NEW (MonoArray, NULL);
MonoCustomAttrInfo *cinfo;
- mono_error_init (error);
+ error_init (error);
cinfo = mono_reflection_get_custom_attrs_info_checked (obj, error);
- return_val_if_nok (error, NULL);
+ if (!is_ok (error))
+ goto leave;
if (cinfo) {
- result = mono_custom_attrs_data_construct (cinfo, error);
+ MONO_HANDLE_ASSIGN (result, MONO_HANDLE_NEW (MonoArray, mono_custom_attrs_data_construct (cinfo, error))); /* FIXME use coop handles in mono_custom_attrs_data_construct */
if (!cinfo->cached)
mono_custom_attrs_free (cinfo);
- return_val_if_nok (error, NULL);
+ if (!is_ok (error))
+ goto leave;
} else
- result = mono_array_new_checked (mono_domain_get (), mono_defaults.customattribute_data_class, 0, error);
+ MONO_HANDLE_ASSIGN (result, mono_array_new_handle (mono_domain_get (), mono_defaults.customattribute_data_class, 0, error));
+leave:
return result;
}
/**
* mono_assembly_metadata_foreach_custom_attr:
- * @assembly: the assembly to iterate over
- * @func: the function to call for each custom attribute
- * @user_data: passed to @func
- *
- * Calls @func for each custom attribute type on the given assembly until @func returns TRUE.
+ * \param assembly the assembly to iterate over
+ * \param func the function to call for each custom attribute
+ * \param user_data passed to \p func
+ * Calls \p func for each custom attribute type on the given assembly until \p func returns TRUE.
* Everything is done using low-level metadata APIs, so it is safe to use during assembly loading.
- *
*/
void
mono_assembly_metadata_foreach_custom_attr (MonoAssembly *assembly, MonoAssemblyMetadataCustomAttrIterFunc func, gpointer user_data)
*/
image = assembly->image;
+ /* Dynamic images would need to go through the AssemblyBuilder's
+ * CustomAttributeBuilder array. Going through the tables below
+ * definitely won't work. */
g_assert (!image_is_dynamic (image));
idx = 1; /* there is only one assembly */
idx <<= MONO_CUSTOM_ATTR_BITS;