ICALL_EXPORT MonoObject *
ves_icall_System_Array_GetValueImpl (MonoArray *arr, guint32 pos)
{
+ MonoError error;
MonoClass *ac;
gint32 esize;
gpointer *ea;
+ MonoObject *result = NULL;
ac = (MonoClass *)arr->obj.vtable->klass;
esize = mono_array_element_size (ac);
ea = (gpointer*)((char*)arr->vector + (pos * esize));
- if (ac->element_class->valuetype)
- return mono_value_box (arr->obj.vtable->domain, ac->element_class, ea);
- else
- return (MonoObject *)*ea;
+ if (ac->element_class->valuetype) {
+ result = mono_value_box_checked (arr->obj.vtable->domain, ac->element_class, ea, &error);
+ mono_error_set_pending_exception (&error);
+ } else
+ result = (MonoObject *)*ea;
+ return result;
}
ICALL_EXPORT MonoObject *
ICALL_EXPORT MonoObject *
ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
{
+ MonoError error;
MonoDomain *domain = mono_object_domain (method);
MonoMethod *m = method->method;
MonoMethodSignature *sig = mono_method_signature (m);
MonoClassField* field = mono_class_get_field_from_name (k, str);
if (field) {
MonoClass *field_klass = mono_class_from_mono_type (field->type);
- if (field_klass->valuetype)
- result = mono_value_box (domain, field_klass, (char *)this_arg + field->offset);
- else
+ if (field_klass->valuetype) {
+ result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
+ mono_error_set_pending_exception (&error);
+ /* fallthru to cleanup */
+ } else
result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
out_args = mono_array_new (domain, mono_defaults.object_class, 1);
ICALL_EXPORT MonoObject*
mono_TypedReference_ToObject (MonoTypedRef* tref)
{
+ MonoError error;
+ MonoObject *result = NULL;
if (MONO_TYPE_IS_REFERENCE (tref->type)) {
MonoObject** objp = (MonoObject **)tref->value;
return *objp;
}
- return mono_value_box (mono_domain_get (), tref->klass, tref->value);
+ result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
}
ICALL_EXPORT MonoTypedRef
if (use_aot_wrappers) {
wrapper = mono_marshal_get_native_func_wrapper_aot (klass);
- this_obj = mono_value_box (mono_domain_get (), mono_defaults.int_class, &ftn);
+ this_obj = mono_value_box_checked (mono_domain_get (), mono_defaults.int_class, &ftn, &error);
+ if (!is_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
} else {
memset (&piinfo, 0, sizeof (piinfo));
parse_unmanaged_function_pointer_attr (klass, &piinfo);
void
mono_nullable_init (guint8 *buf, MonoObject *value, MonoClass *klass);
+MonoObject *
+mono_value_box_checked (MonoDomain *domain, MonoClass *klass, void* val, MonoError *error);
+
MonoObject*
-mono_nullable_box (guint8 *buf, MonoClass *klass);
+mono_nullable_box (guint8 *buf, MonoClass *klass, MonoError *error);
#ifdef MONO_SMALL_CONFIG
#define MONO_IMT_SIZE 9
klass = mono_class_from_mono_type (type);
if (mono_class_is_nullable (klass))
- return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass);
+ return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass, error);
o = mono_object_new_checked (domain, klass, error);
return_val_if_nok (error, NULL);
* mono_nullable_box:
* @buf: The buffer representing the data to be boxed
* @klass: the type to box it as.
+ * @error: set on oerr
*
* Creates a boxed vtype or NULL from the Nullable structure pointed to by
- * @buf.
+ * @buf. On failure returns NULL and sets @error
*/
MonoObject*
-mono_nullable_box (guint8 *buf, MonoClass *klass)
+mono_nullable_box (guint8 *buf, MonoClass *klass, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoError error;
-
+ mono_error_init (error);
MonoClass *param_class = klass->cast_class;
mono_class_setup_fields_locking (klass);
g_assert (mono_class_from_mono_type (klass->fields [1].type) == mono_defaults.boolean_class);
if (*(guint8*)(buf + klass->fields [1].offset - sizeof (MonoObject))) {
- MonoObject *o = mono_object_new_checked (mono_domain_get (), param_class, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoObject *o = mono_object_new_checked (mono_domain_get (), param_class, error);
+ return_val_if_nok (error, NULL);
if (param_class->has_references)
mono_gc_wbarrier_value_copy (mono_object_unbox (o), buf + klass->fields [0].offset - sizeof (MonoObject), 1, param_class);
else
* boxed object in the arg array with the copy.
*/
MonoObject *orig = mono_array_get (params, MonoObject*, i);
- MonoObject *copy = mono_value_box (mono_domain_get (), orig->vtable->klass, mono_object_unbox (orig));
+ MonoObject *copy = mono_value_box_checked (mono_domain_get (), orig->vtable->klass, mono_object_unbox (orig), &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
mono_array_setref (params, i, copy);
}
if (!params)
return NULL;
- else
- return mono_value_box (mono_domain_get (), method->klass->cast_class, pa [0]);
+ else {
+ MonoObject *result = mono_value_box_checked (mono_domain_get (), method->klass->cast_class, pa [0], &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return result;
+ }
}
if (!obj) {
else
o = obj;
} else if (method->klass->valuetype) {
- obj = mono_value_box (mono_domain_get (), method->klass, obj);
+ obj = mono_value_box_checked (mono_domain_get (), method->klass, obj, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
if (exc) {
nullable = mono_object_new_checked (mono_domain_get (), method->klass, &error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
- mono_nullable_init ((guint8 *)mono_object_unbox (nullable), mono_value_box (mono_domain_get (), method->klass->cast_class, obj), method->klass);
+ MonoObject *boxed = mono_value_box_checked (mono_domain_get (), method->klass->cast_class, obj, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_nullable_init ((guint8 *)mono_object_unbox (nullable), boxed, method->klass);
obj = mono_object_unbox (nullable);
}
MonoObject *
mono_value_box (MonoDomain *domain, MonoClass *klass, gpointer value)
{
- MONO_REQ_GC_UNSAFE_MODE;
-
MonoError error;
+ MonoObject *result = mono_value_box_checked (domain, klass, value, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+/**
+ * mono_value_box_checked:
+ * @domain: the domain of the new object
+ * @class: the class of the value
+ * @value: a pointer to the unboxed data
+ * @error: set on error
+ *
+ * Returns: A newly created object which contains @value. On failure
+ * returns NULL and sets @error.
+ */
+MonoObject *
+mono_value_box_checked (MonoDomain *domain, MonoClass *klass, gpointer value, MonoError *error)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
MonoObject *res;
int size;
MonoVTable *vtable;
+ mono_error_init (error);
+
g_assert (klass->valuetype);
if (mono_class_is_nullable (klass))
- return mono_nullable_box ((guint8 *)value, klass);
+ return mono_nullable_box ((guint8 *)value, klass, error);
vtable = mono_class_vtable (domain, klass);
if (!vtable)
return NULL;
size = mono_class_instance_size (klass);
- res = mono_object_new_alloc_specific_checked (vtable, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ res = mono_object_new_alloc_specific_checked (vtable, error);
+ return_val_if_nok (error, NULL);
size = size - sizeof (MonoObject);
#endif
#endif
if (klass->has_finalize) {
- mono_object_register_finalizer (res, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_object_register_finalizer (res, error);
+ return_val_if_nok (error, NULL);
}
return res;
}
klass = mono_class_from_mono_type (sig->params [i]);
- if (klass->valuetype)
- arg = mono_value_box (domain, klass, vpos);
- else
+ if (klass->valuetype) {
+ arg = mono_value_box_checked (domain, klass, vpos, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ } else
arg = *((MonoObject **)vpos);
mono_array_setref (msg->args, i, arg);
mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
- if (field_class->valuetype)
- arg = mono_value_box (domain, field_class, val);
- else
+ if (field_class->valuetype) {
+ arg = mono_value_box_checked (domain, field_class, val, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ } else
arg = *((MonoObject **)val);
MONO_API MonoString *
mono_object_to_string (MonoObject *obj, MonoObject **exc);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoObject *
mono_value_box (MonoDomain *domain, MonoClass *klass, void* val);
static gboolean is_sre_method_on_tb_inst (MonoClass *klass);
static gboolean is_sre_ctor_on_tb_inst (MonoClass *klass);
+static gboolean type_is_reference (MonoType *type);
+
static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error);
return NULL;
}
+static MonoObject*
+load_cattr_value_boxed (MonoDomain *domain, MonoImage *image, MonoType *t, const char* p, const char** end, MonoError *error)
+{
+ mono_error_init (error);
+
+ gboolean is_ref = type_is_reference (t);
+
+ void *val = load_cattr_value (image, t, p, end, error);
+ if (!is_ok (error)) {
+ if (is_ref)
+ g_free (val);
+ return NULL;
+ }
+
+ if (is_ref)
+ return (MonoObject*)val;
+
+ MonoObject *boxed = mono_value_box_checked (domain, mono_class_from_mono_type (t), val, error);
+ g_free (val);
+ return boxed;
+}
+
static MonoObject*
create_cattr_typed_arg (MonoType *t, MonoObject *val, MonoError *error)
{
p += 2;
for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
MonoObject *obj;
- void *val;
- val = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p, error);
- if (!mono_error_ok (error)) {
- if (!type_is_reference (mono_method_signature (method)->params [i]))
- g_free (val);
- return;
- }
-
- obj = (MonoObject *)(type_is_reference (mono_method_signature (method)->params [i]) ?
- val : mono_value_box (domain, mono_class_from_mono_type (mono_method_signature (method)->params [i]), val));
+ obj = load_cattr_value_boxed (domain, image, mono_method_signature (method)->params [i], p, &p, error);
+ return_if_nok (error);
mono_array_setref (typedargs, i, obj);
-
- if (!type_is_reference (mono_method_signature (method)->params [i]))
- g_free (val);
}
named = p;
if (named_type == 0x53) {
MonoObject *obj;
MonoClassField *field = mono_class_get_field_from_name (attrklass, name);
- void *val;
if (!field) {
g_free (name);
arginfo [j].type = field->type;
arginfo [j].field = field;
- val = load_cattr_value (image, field->type, named, &named, error);
- if (!mono_error_ok (error)) {
- if (!type_is_reference (field->type))
- g_free (val);
+ obj = load_cattr_value_boxed (domain, image, field->type, named, &named, error);
+ if (!is_ok (error)) {
g_free (name);
return;
}
-
- obj = (MonoObject *)(type_is_reference (field->type) ? val : mono_value_box (domain, mono_class_from_mono_type (field->type), val));
mono_array_setref (namedargs, j, obj);
- if (!type_is_reference (field->type))
- g_free (val);
+
} else if (named_type == 0x54) {
MonoObject *obj;
MonoType *prop_type;
MonoProperty *prop = mono_class_get_property_from_name (attrklass, name);
- void *val;
if (!prop || !prop->set) {
g_free (name);
arginfo [j].type = prop_type;
arginfo [j].prop = prop;
- val = load_cattr_value (image, prop_type, named, &named, error);
- if (!mono_error_ok (error)) {
- if (!type_is_reference (prop_type))
- g_free (val);
+ obj = load_cattr_value_boxed (domain, image, prop_type, named, &named, error);
+ if (!is_ok (error)) {
g_free (name);
return;
}
-
- obj = (MonoObject *)(type_is_reference (prop_type) ? val : mono_value_box (domain, mono_class_from_mono_type (prop_type), val));
mono_array_setref (namedargs, j, obj);
- if (!type_is_reference (prop_type))
- g_free (val);
}
g_free (name);
}
mparams[i] = *((gpointer *)params [i]);
} else {
/* runtime_invoke expects a boxed instance */
- if (mono_class_is_nullable (mono_class_from_mono_type (sig->params [i])))
- mparams[i] = mono_nullable_box ((guint8 *)params [i], klass);
- else
+ if (mono_class_is_nullable (mono_class_from_mono_type (sig->params [i]))) {
+ mparams[i] = mono_nullable_box ((guint8 *)params [i], klass, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ } else
mparams[i] = params [i];
}
} else {
case MONO_TYPE_U8:
case MONO_TYPE_R4:
case MONO_TYPE_R8: {
- return mono_value_box (domain, mono_object_class (val), ((char*)val) + sizeof(MonoObject));
+ MonoObject *res = mono_value_box_checked (domain, mono_object_class (val), ((char*)val) + sizeof(MonoObject), &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return res;
+
}
case MONO_TYPE_STRING: {
MonoString *str = (MonoString *) val;
static MonoObject*
int_to_object (MonoDomain *domain, int val)
{
- return mono_value_box (domain, mono_get_int32_class (), &val);
+ MonoError error;
+ MonoObject *result = mono_value_box_checked (domain, mono_get_int32_class (), &val, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return result;
}
void
} else if (type == VALUE_TYPE_ID_NULL) {
*(MonoObject**)addr = NULL;
} else if (type == MONO_TYPE_VALUETYPE) {
+ MonoError error;
guint8 *buf2;
gboolean is_enum;
MonoClass *klass;
g_free (vtype_buf);
return err;
}
- *(MonoObject**)addr = mono_value_box (d, klass, vtype_buf);
+ *(MonoObject**)addr = mono_value_box_checked (d, klass, vtype_buf, &error);
+ mono_error_cleanup (&error);
g_free (vtype_buf);
} else {
char *name = mono_type_full_name (t);
static ErrorCode
decode_value (MonoType *t, MonoDomain *domain, guint8 *addr, guint8 *buf, guint8 **endbuf, guint8 *limit)
{
+ MonoError error;
ErrorCode err;
int type = decode_byte (buf, &buf, limit);
g_free (nullable_buf);
return err;
}
- mono_nullable_init (addr, mono_value_box (domain, mono_class_from_mono_type (targ), nullable_buf), mono_class_from_mono_type (t));
+ MonoObject *boxed = mono_value_box_checked (domain, mono_class_from_mono_type (targ), nullable_buf, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error);
+ return ERR_INVALID_OBJECT;
+ }
+ mono_nullable_init (addr, boxed, mono_class_from_mono_type (t));
g_free (nullable_buf);
*endbuf = buf;
return ERR_NONE;
/*
* Calling a non-vtype method with a vtype receiver, has to box.
*/
- *this_arg = mono_value_box (mono_domain_get (), klass, mp);
+ *this_arg = mono_value_box_checked (mono_domain_get (), klass, mp, error);
else if (klass->valuetype)
/*
* Calling a vtype method with a vtype receiver
mono_error_set_exception_instance (error, (MonoException*) *exc);
if (sig->ret->type != MONO_TYPE_VOID && info->ret_box_class)
- return mono_value_box (domain, info->ret_box_class, retval);
+ return mono_value_box_checked (domain, info->ret_box_class, retval, error);
else
return *(MonoObject**)retval;
}
mono_arch_finish_dyn_call (info->dyn_call_info, buf);
if (info->ret_box_class)
- return mono_value_box (domain, info->ret_box_class, retval);
+ return mono_value_box_checked (domain, info->ret_box_class, retval, error);
else
return *(MonoObject**)retval;
}