#include "mono/metadata/mono-debug-debugger.h"
#include <mono/metadata/gc-internals.h>
#include <mono/metadata/verify-internals.h>
+#include <mono/metadata/reflection-internals.h>
#include <mono/utils/strenc.h>
#include <mono/utils/mono-counters.h>
#include <mono/utils/mono-error-internals.h>
always_build_imt_thunks = value;
}
-static MonoCompileFunc default_mono_compile_method = NULL;
-
-/**
- * mono_install_compile_method:
- * @func: function to install
- *
- * This is a VM internal routine
- */
-void
-mono_install_compile_method (MonoCompileFunc func)
-{
- default_mono_compile_method = func;
-}
-
/**
* mono_compile_method:
* @method: The method to compile.
gpointer
mono_compile_method (MonoMethod *method)
{
+ gpointer res;
+ MonoError error;
+
MONO_REQ_GC_NEUTRAL_MODE
- if (!default_mono_compile_method) {
+ if (!callbacks.compile_method) {
g_error ("compile method called on uninitialized runtime");
return NULL;
}
- return default_mono_compile_method (method);
+ res = callbacks.compile_method (method, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
+ return res;
}
gpointer
#endif
MonoString*
-mono_string_alloc (int length)
+ves_icall_string_alloc (int length)
{
- MONO_REQ_GC_UNSAFE_MODE;
- return mono_string_new_size (mono_domain_get (), length);
+ MonoError error;
+ MonoString *str = mono_string_new_size_checked (mono_domain_get (), length, &error);
+ mono_error_raise_exception (&error);
+
+ return str;
}
void
if (!gcj_inited) {
mono_loader_lock ();
- mono_register_jit_icall (mono_object_new_fast, "mono_object_new_fast", mono_create_icall_signature ("object ptr"), FALSE);
- mono_register_jit_icall (mono_string_alloc, "mono_string_alloc", mono_create_icall_signature ("object int"), FALSE);
+ mono_register_jit_icall (ves_icall_object_new_fast, "ves_icall_object_new_fast", mono_create_icall_signature ("object ptr"), FALSE);
+ mono_register_jit_icall (ves_icall_string_alloc, "ves_icall_string_alloc", mono_create_icall_signature ("object int"), FALSE);
gcj_inited = TRUE;
mono_loader_unlock ();
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoVTable *vt;
MonoClassRuntimeInfo *runtime_info, *old_info;
MonoClassField *field;
/* Special case System.MonoType to avoid infinite recursion */
if (klass != mono_defaults.monotype_class) {
/*FIXME check for OOM*/
- vt->type = mono_type_get_object (domain, &klass->byval_arg);
+ vt->type = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
if (mono_object_get_class ((MonoObject *)vt->type) != mono_defaults.monotype_class)
/* This is unregistered in
unregister_vtable_reflection_type() in
if (klass == mono_defaults.monotype_class) {
/*FIXME check for OOM*/
- vt->type = mono_type_get_object (domain, &klass->byval_arg);
+ vt->type = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
if (mono_object_get_class ((MonoObject *)vt->type) != mono_defaults.monotype_class)
/* This is unregistered in
unregister_vtable_reflection_type() in
}
static MonoObject*
-dummy_mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
+do_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
{
- g_error ("runtime invoke called on uninitialized runtime");
- return NULL;
-}
+ MonoObject *result = NULL;
+ MonoError error;
+
+ g_assert (callbacks.runtime_invoke);
+ result = callbacks.runtime_invoke (method, obj, params, &error, exc);
+ if (!mono_error_ok (&error)) {
+ if (exc) {
+ *exc = (MonoObject*)mono_error_convert_to_exception (&error);
+ return NULL;
+ } else {
+ mono_error_raise_exception (&error);
+ }
+ }
-static MonoInvokeFunc default_mono_runtime_invoke = dummy_mono_runtime_invoke;
+ return result;
+}
/**
* mono_runtime_invoke:
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_start_invoke (method);
- result = default_mono_runtime_invoke (method, obj, params, exc);
+ MONO_PREPARE_RESET_BLOCKING;
+
+ result = do_runtime_invoke (method, obj, params, exc);
+
+ MONO_FINISH_RESET_BLOCKING;
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_end_invoke (method);
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoObject *o;
MonoClass *klass;
MonoVTable *vtable = NULL;
gboolean is_ref = FALSE;
gboolean is_literal = FALSE;
gboolean is_ptr = FALSE;
- MonoError error;
MonoType *type = mono_field_get_type_checked (field, &error);
if (!mono_error_ok (&error))
/* MONO_TYPE_PTR is passed by value to runtime_invoke () */
args [0] = ptr ? *ptr : NULL;
- args [1] = mono_type_get_object (mono_domain_get (), type);
+ args [1] = mono_type_get_object_checked (mono_domain_get (), type, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return mono_runtime_invoke (m, NULL, args, NULL);
}
if (mono_class_is_nullable (klass))
return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass);
- o = mono_object_new (domain, klass);
+ o = mono_object_new_checked (domain, klass, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
v = ((gchar *) o) + sizeof (MonoObject);
if (is_literal) {
{
MONO_REQ_GC_UNSAFE_MODE;
- default_mono_runtime_invoke (prop->set, obj, params, exc);
+ do_runtime_invoke (prop->set, obj, params, exc);
}
/**
{
MONO_REQ_GC_UNSAFE_MODE;
- return default_mono_runtime_invoke (prop->get, obj, params, exc);
+ return do_runtime_invoke (prop->get, obj, params, exc);
}
/*
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError 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 (mono_domain_get (), param_class);
+ MonoObject *o = mono_object_new_checked (mono_domain_get (), param_class, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
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
static MonoMethod *get_proxy_method;
+ MonoError error;
MonoDomain *domain = mono_domain_get ();
MonoRealProxy *real_proxy;
MonoReflectionType *reflection_type;
g_assert (mono_class_is_marshalbyref (obj->vtable->klass));
- real_proxy = (MonoRealProxy*) mono_object_new (domain, mono_defaults.real_proxy_class);
- reflection_type = mono_type_get_object (domain, &obj->vtable->klass->byval_arg);
+ real_proxy = (MonoRealProxy*) mono_object_new_checked (domain, mono_defaults.real_proxy_class, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ reflection_type = mono_type_get_object_checked (domain, &obj->vtable->klass->byval_arg, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
MONO_OBJECT_SETREF (real_proxy, class_to_proxy, reflection_type);
MONO_OBJECT_SETREF (real_proxy, unwrapped_server, obj);
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoClass *klass;
gpointer args [2];
MonoMethod *method = NULL;
args [0] = exc;
args [1] = &is_terminating;
- obj = mono_object_new (mono_domain_get (), klass);
+ obj = mono_object_new_checked (mono_domain_get (), klass, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
mono_runtime_invoke (method, obj, args, NULL);
return obj;
str = g_strconcat (assembly->image->name, ".config", NULL);
MONO_OBJECT_SETREF (domain->setup, configuration_file, mono_string_new (domain, str));
g_free (str);
- mono_set_private_bin_path_from_config (domain);
+ mono_domain_set_options_from_config (domain);
}
}
return rval;
}
-/**
- * mono_install_runtime_invoke:
- * @func: Function to install
- *
- * This is a VM internal routine
- */
-void
-mono_install_runtime_invoke (MonoInvokeFunc func)
-{
- default_mono_runtime_invoke = func ? func: dummy_mono_runtime_invoke;
-}
-
-
/**
* mono_runtime_invoke_array:
* @method: method to invoke
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoMethodSignature *sig = mono_method_signature (method);
gpointer *pa = NULL;
MonoObject *res;
has_byref_nullables = TRUE;
} else {
/* MS seems to create the objects if a null is passed in */
- if (!mono_array_get (params, MonoObject*, i))
- mono_array_setref (params, i, mono_object_new (mono_domain_get (), mono_class_from_mono_type (sig->params [i])));
+ if (!mono_array_get (params, MonoObject*, i)) {
+ MonoObject *o = mono_object_new_checked (mono_domain_get (), mono_class_from_mono_type (sig->params [i]), &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_array_setref (params, i, o);
+ }
if (t->byref) {
/*
}
if (!obj) {
- obj = mono_object_new (mono_domain_get (), method->klass);
- g_assert (obj); /*maybe we should raise a TLE instead?*/
+ obj = mono_object_new_checked (mono_domain_get (), method->klass, &error);
+ g_assert (obj && mono_error_ok (&error)); /*maybe we should raise a TLE instead?*/ /* FIXME don't swallow error */
#ifndef DISABLE_REMOTING
if (mono_object_class(obj) == mono_defaults.transparent_proxy_class) {
method = mono_marshal_get_remoting_invoke (method->slot == -1 ? method : method->klass->vtable [method->slot]);
MonoObject *nullable;
/* Convert the unboxed vtype into a Nullable structure */
- nullable = mono_object_new (mono_domain_get (), method->klass);
+ 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);
obj = mono_object_unbox (nullable);
g_assert (res->vtable->klass == mono_defaults.int_class);
box_args [0] = ((MonoIntPtr*)res)->m_value;
- box_args [1] = mono_type_get_object (mono_domain_get (), sig->ret);
+ box_args [1] = mono_type_get_object_checked (mono_domain_get (), sig->ret, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
res = mono_runtime_invoke (box_method, NULL, box_args, &box_exc);
g_assert (!box_exc);
}
}
}
-static void
-arith_overflow (void)
-{
- MONO_REQ_GC_UNSAFE_MODE;
-
- mono_raise_exception (mono_get_exception_overflow ());
-}
-
/**
* mono_object_new:
* @klass: the class of the object that we want to create
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
+
+ MonoObject * result = mono_object_new_checked (domain, klass, &error);
+
+ mono_error_raise_exception (&error);
+ return result;
+}
+
+MonoObject *
+ves_icall_object_new (MonoDomain *domain, MonoClass *klass)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
+ MonoError error;
+
+ MonoObject * result = mono_object_new_checked (domain, klass, &error);
+
+ mono_error_raise_exception (&error);
+ return result;
+}
+
+/**
+ * mono_object_new_checked:
+ * @klass: the class of the object that we want to create
+ * @error: set on error
+ *
+ * Returns: a newly created object whose definition is
+ * looked up using @klass. This will not invoke any constructors,
+ * so the consumer of this routine has to invoke any constructors on
+ * its own to initialize the object.
+ *
+ * It returns NULL on failure and sets @error.
+ */
+MonoObject *
+mono_object_new_checked (MonoDomain *domain, MonoClass *klass, MonoError *error)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vtable;
vtable = mono_class_vtable (domain, klass);
- if (!vtable)
- return NULL;
- return mono_object_new_specific (vtable);
+ g_assert (vtable); /* FIXME don't swallow the error */
+
+ MonoObject *o = mono_object_new_specific_checked (vtable, error);
+ return o;
}
/**
* For SGEN, these objects will only be freed at appdomain unload.
*/
MonoObject *
-mono_object_new_pinned (MonoDomain *domain, MonoClass *klass)
+mono_object_new_pinned (MonoDomain *domain, MonoClass *klass, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
MonoVTable *vtable;
+ mono_error_init (error);
+
vtable = mono_class_vtable (domain, klass);
- if (!vtable)
- return NULL;
+ g_assert (vtable); /* FIXME don't swallow the error */
-#ifdef HAVE_SGEN_GC
- return (MonoObject *)mono_gc_alloc_pinned_obj (vtable, mono_class_instance_size (klass));
-#else
- return mono_object_new_specific (vtable);
-#endif
+ MonoObject *o = (MonoObject *)mono_gc_alloc_pinned_obj (vtable, mono_class_instance_size (klass));
+
+ if (G_UNLIKELY (!o))
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", mono_class_instance_size (klass));
+ else if (G_UNLIKELY (vtable->klass->has_finalize))
+ mono_object_register_finalizer (o);
+
+ return o;
}
/**
*/
MonoObject *
mono_object_new_specific (MonoVTable *vtable)
+{
+ MonoError error;
+ MonoObject *o = mono_object_new_specific_checked (vtable, &error);
+ mono_error_raise_exception (&error);
+
+ return o;
+}
+
+MonoObject *
+mono_object_new_specific_checked (MonoVTable *vtable, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
MonoObject *o;
+ mono_error_init (error);
+
/* check for is_com_object for COM Interop */
if (mono_vtable_is_remote (vtable) || mono_class_is_com_object (vtable->klass))
{
mono_class_init (klass);
im = mono_class_get_method_from_name (klass, "CreateProxyForType", 1);
- if (!im)
- mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
+ if (!im) {
+ mono_error_set_generic_error (error, "System", "NotSupportedException", "Linked away.");
+ return NULL;
+ }
vtable->domain->create_proxy_for_type_method = im;
}
- pa [0] = mono_type_get_object (mono_domain_get (), &vtable->klass->byval_arg);
+ pa [0] = mono_type_get_object_checked (mono_domain_get (), &vtable->klass->byval_arg, error);
+ if (!mono_error_ok (error))
+ return NULL;
o = mono_runtime_invoke (im, NULL, pa, NULL);
if (o != NULL) return o;
}
- return mono_object_new_alloc_specific (vtable);
+ return mono_object_new_alloc_specific_checked (vtable, error);
+}
+
+MonoObject *
+ves_icall_object_new_specific (MonoVTable *vtable)
+{
+ MonoError error;
+ MonoObject *o = mono_object_new_specific_checked (vtable, &error);
+ mono_error_raise_exception (&error);
+
+ return o;
}
MonoObject *
mono_object_new_alloc_specific (MonoVTable *vtable)
+{
+ MonoError error;
+ MonoObject *o = mono_object_new_alloc_specific_checked (vtable, &error);
+ mono_error_raise_exception (&error);
+
+ return o;
+}
+
+MonoObject *
+mono_object_new_alloc_specific_checked (MonoVTable *vtable, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoObject *o = (MonoObject *)mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
+ MonoObject *o;
+
+ mono_error_init (error);
+
+ o = (MonoObject *)mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
- if (G_UNLIKELY (vtable->klass->has_finalize))
+ if (G_UNLIKELY (!o))
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", vtable->klass->instance_size);
+ else if (G_UNLIKELY (vtable->klass->has_finalize))
mono_object_register_finalizer (o);
return o;
MonoObject*
mono_object_new_fast (MonoVTable *vtable)
+{
+ MonoError error;
+ MonoObject *o = mono_object_new_fast_checked (vtable, &error);
+ mono_error_raise_exception (&error);
+
+ return o;
+}
+
+MonoObject*
+mono_object_new_fast_checked (MonoVTable *vtable, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- return (MonoObject *)mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
+ MonoObject *o;
+
+ mono_error_init (error);
+
+ o = mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
+
+ if (G_UNLIKELY (!o))
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", vtable->klass->instance_size);
+
+ return o;
+}
+
+MonoObject *
+ves_icall_object_new_fast (MonoVTable *vtable)
+{
+ MonoError error;
+ MonoObject *o = mono_object_new_fast_checked (vtable, &error);
+ mono_error_raise_exception (&error);
+
+ return o;
+}
+
+MonoObject*
+mono_object_new_mature (MonoVTable *vtable, MonoError *error)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
+ MonoObject *o;
+
+ mono_error_init (error);
+
+ o = mono_gc_alloc_mature (vtable, vtable->klass->instance_size);
+
+ if (G_UNLIKELY (!o))
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", vtable->klass->instance_size);
+ else if (G_UNLIKELY (vtable->klass->has_finalize))
+ mono_object_register_finalizer (o);
+
+ return o;
}
/**
*pass_size_in_words = FALSE;
if (mono_class_has_finalizer (vtable->klass) || mono_class_is_marshalbyref (vtable->klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
- return mono_object_new_specific;
+ return ves_icall_object_new_specific;
if (vtable->gc_descr != MONO_GC_DESCRIPTOR_NULL) {
- return mono_object_new_fast;
+ return ves_icall_object_new_fast;
/*
- * FIXME: This is actually slower than mono_object_new_fast, because
+ * FIXME: This is actually slower than ves_icall_object_new_fast, because
* of the overhead of parameter passing.
*/
/*
*/
}
- return mono_object_new_specific;
+ return ves_icall_object_new_specific;
}
/**
MONO_REQ_GC_UNSAFE_MODE;
MonoError error;
+ MonoObject *result;
MonoClass *klass;
klass = mono_class_get_checked (image, token, &error);
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+
+ result = mono_object_new_checked (domain, klass, &error);
- return mono_object_new (domain, klass);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return result;
+
}
*/
MonoObject *
mono_object_clone (MonoObject *obj)
+{
+ MonoError error;
+ MonoObject *o = mono_object_clone_checked (obj, &error);
+ mono_error_raise_exception (&error);
+
+ return o;
+}
+
+MonoObject *
+mono_object_clone_checked (MonoObject *obj, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
MonoObject *o;
- int size = obj->vtable->klass->instance_size;
+ int size;
+
+ mono_error_init (error);
+
+ size = obj->vtable->klass->instance_size;
if (obj->vtable->klass->rank)
return (MonoObject*)mono_array_clone ((MonoArray*)obj);
o = (MonoObject *)mono_gc_alloc_obj (obj->vtable, size);
+ if (G_UNLIKELY (!o)) {
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", size);
+ return NULL;
+ }
+
/* If the object doesn't contain references this will do a simple memmove. */
mono_gc_wbarrier_object_copy (o, obj);
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoArray *o;
uintptr_t size, i;
uintptr_t *sizes;
if (array->bounds == NULL) {
size = mono_array_length (array);
- o = mono_array_new_full (domain, klass, &size, NULL);
+ o = mono_array_new_full_checked (domain, klass, &size, NULL, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
size *= mono_array_element_size (klass);
#ifdef HAVE_SGEN_GC
size *= array->bounds [i].length;
sizes [i + klass->rank] = array->bounds [i].lower_bound;
}
- o = mono_array_new_full (domain, klass, sizes, (intptr_t*)sizes + klass->rank);
+ o = mono_array_new_full_checked (domain, klass, sizes, (intptr_t*)sizes + klass->rank, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
#ifdef HAVE_SGEN_GC
if (klass->element_class->valuetype) {
if (klass->element_class->has_references)
*/
MonoArray*
mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds)
+{
+ MonoError error;
+ MonoArray *array = mono_array_new_full_checked (domain, array_class, lengths, lower_bounds, &error);
+ mono_error_raise_exception (&error);
+
+ return array;
+}
+
+MonoArray*
+mono_array_new_full_checked (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
MonoVTable *vtable;
int i;
+ mono_error_init (error);
+
if (!array_class->inited)
mono_class_init (array_class);
/* A single dimensional array with a 0 lower bound is the same as an szarray */
if (array_class->rank == 1 && ((array_class->byval_arg.type == MONO_TYPE_SZARRAY) || (lower_bounds && lower_bounds [0] == 0))) {
len = lengths [0];
- if (len > MONO_ARRAY_MAX_INDEX)//MONO_ARRAY_MAX_INDEX
- arith_overflow ();
+ if (len > MONO_ARRAY_MAX_INDEX) {
+ mono_error_set_generic_error (error, "System", "OverflowException", "");
+ return NULL;
+ }
bounds_size = 0;
} else {
bounds_size = sizeof (MonoArrayBounds) * array_class->rank;
for (i = 0; i < array_class->rank; ++i) {
- if (lengths [i] > MONO_ARRAY_MAX_INDEX) //MONO_ARRAY_MAX_INDEX
- arith_overflow ();
- if (CHECK_MUL_OVERFLOW_UN (len, lengths [i]))
- mono_gc_out_of_memory (MONO_ARRAY_MAX_SIZE);
+ if (lengths [i] > MONO_ARRAY_MAX_INDEX) {
+ mono_error_set_generic_error (error, "System", "OverflowException", "");
+ return NULL;
+ }
+ if (CHECK_MUL_OVERFLOW_UN (len, lengths [i])) {
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", MONO_ARRAY_MAX_SIZE);
+ return NULL;
+ }
len *= lengths [i];
}
}
- if (!mono_array_calc_byte_len (array_class, len, &byte_len))
- mono_gc_out_of_memory (MONO_ARRAY_MAX_SIZE);
+ if (!mono_array_calc_byte_len (array_class, len, &byte_len)) {
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", MONO_ARRAY_MAX_SIZE);
+ return NULL;
+ }
if (bounds_size) {
/* align */
- if (CHECK_ADD_OVERFLOW_UN (byte_len, 3))
- mono_gc_out_of_memory (MONO_ARRAY_MAX_SIZE);
+ if (CHECK_ADD_OVERFLOW_UN (byte_len, 3)) {
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", MONO_ARRAY_MAX_SIZE);
+ return NULL;
+ }
byte_len = (byte_len + 3) & ~3;
- if (CHECK_ADD_OVERFLOW_UN (byte_len, bounds_size))
- mono_gc_out_of_memory (MONO_ARRAY_MAX_SIZE);
+ if (CHECK_ADD_OVERFLOW_UN (byte_len, bounds_size)) {
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", MONO_ARRAY_MAX_SIZE);
+ return NULL;
+ }
byte_len += bounds_size;
}
/*
o = (MonoObject *)mono_gc_alloc_array (vtable, byte_len, len, bounds_size);
else
o = (MonoObject *)mono_gc_alloc_vector (vtable, byte_len, len);
+
+ if (G_UNLIKELY (!o)) {
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", byte_len);
+ return NULL;
+ }
+
array = (MonoArray*)o;
bounds = array->bounds;
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoClass *ac;
+ MonoArray *arr;
ac = mono_array_class_get (eclass, 1);
g_assert (ac);
- return mono_array_new_specific (mono_class_vtable_full (domain, ac, TRUE), n);
+ arr = mono_array_new_specific_checked (mono_class_vtable_full (domain, ac, TRUE), n, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ return arr;
}
/**
*/
MonoArray *
mono_array_new_specific (MonoVTable *vtable, uintptr_t n)
+{
+ MonoError error;
+ MonoArray *arr = mono_array_new_specific_checked (vtable, n, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ return arr;
+}
+
+MonoArray*
+mono_array_new_specific_checked (MonoVTable *vtable, uintptr_t n, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
MonoObject *o;
- MonoArray *ao;
uintptr_t byte_len;
+ mono_error_init (error);
+
if (G_UNLIKELY (n > MONO_ARRAY_MAX_INDEX)) {
- arith_overflow ();
+ mono_error_set_generic_error (error, "System", "OverflowException", "");
return NULL;
}
if (!mono_array_calc_byte_len (vtable->klass, n, &byte_len)) {
- mono_gc_out_of_memory (MONO_ARRAY_MAX_SIZE);
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", MONO_ARRAY_MAX_SIZE);
return NULL;
}
o = (MonoObject *)mono_gc_alloc_vector (vtable, byte_len, n);
- ao = (MonoArray*)o;
- return ao;
+ if (G_UNLIKELY (!o)) {
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", byte_len);
+ return NULL;
+ }
+
+ return (MonoArray*)o;
+}
+
+MonoArray*
+ves_icall_array_new_specific (MonoVTable *vtable, uintptr_t n)
+{
+ MonoError error;
+ MonoArray *arr = mono_array_new_specific_checked (vtable, n, &error);
+ mono_error_raise_exception (&error);
+
+ return arr;
}
/**
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
+ MonoString *res = NULL;
+ res = mono_string_new_utf16_checked (domain, text, len, &error);
+ mono_error_raise_exception (&error);
+
+ return res;
+}
+
+/**
+ * mono_string_new_utf16_checked:
+ * @text: a pointer to an utf16 string
+ * @len: the length of the string
+ * @error: written on error.
+ *
+ * Returns: A newly created string object which contains @text.
+ * On error, returns NULL and sets @error.
+ */
+MonoString *
+mono_string_new_utf16_checked (MonoDomain *domain, const guint16 *text, gint32 len, MonoError *error)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString *s;
- s = mono_string_new_size (domain, len);
- g_assert (s != NULL);
-
- memcpy (mono_string_chars (s), text, len * 2);
+ mono_error_init (error);
+
+ s = mono_string_new_size_checked (domain, len, error);
+ if (s != NULL)
+ memcpy (mono_string_chars (s), text, len * 2);
return s;
}
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoString *s;
mono_unichar2 *utf16_output = NULL;
gint32 utf16_len = 0;
- GError *error = NULL;
+ GError *gerror = NULL;
glong items_written;
- utf16_output = g_ucs4_to_utf16 (text, len, NULL, &items_written, &error);
+ utf16_output = g_ucs4_to_utf16 (text, len, NULL, &items_written, &gerror);
- if (error)
- g_error_free (error);
+ if (gerror)
+ g_error_free (gerror);
while (utf16_output [utf16_len]) utf16_len++;
- s = mono_string_new_size (domain, utf16_len);
- g_assert (s != NULL);
+ s = mono_string_new_size_checked (domain, utf16_len, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
memcpy (mono_string_chars (s), utf16_output, utf16_len * 2);
*/
MonoString *
mono_string_new_size (MonoDomain *domain, gint32 len)
+{
+ MonoError error;
+ MonoString *str = mono_string_new_size_checked (domain, len, &error);
+ mono_error_raise_exception (&error);
+
+ return str;
+}
+
+MonoString *
+mono_string_new_size_checked (MonoDomain *domain, gint32 len, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
MonoVTable *vtable;
size_t size;
+ mono_error_init (error);
+
/* check for overflow */
- if (len < 0 || len > ((SIZE_MAX - G_STRUCT_OFFSET (MonoString, chars) - 8) / 2))
- mono_gc_out_of_memory (-1);
+ if (len < 0 || len > ((SIZE_MAX - G_STRUCT_OFFSET (MonoString, chars) - 8) / 2)) {
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", -1);
+ return NULL;
+ }
size = (G_STRUCT_OFFSET (MonoString, chars) + (((size_t)len + 1) * 2));
g_assert (size > 0);
s = (MonoString *)mono_gc_alloc_string (vtable, size, len);
+ if (G_UNLIKELY (!s)) {
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", size);
+ return NULL;
+ }
+
return s;
}
{
MONO_REQ_GC_UNSAFE_MODE;
- GError *error = NULL;
+ MonoError error;
+ GError *eg_error = NULL;
MonoString *o = NULL;
guint16 *ut;
glong items_written;
- ut = eg_utf8_to_utf16_with_nuls (text, length, NULL, &items_written, &error);
+ mono_error_init (&error);
- if (!error)
- o = mono_string_new_utf16 (domain, ut, items_written);
+ ut = eg_utf8_to_utf16_with_nuls (text, length, NULL, &items_written, &eg_error);
+
+ if (!eg_error)
+ o = mono_string_new_utf16_checked (domain, ut, items_written, &error);
else
- g_error_free (error);
+ g_error_free (eg_error);
g_free (ut);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return o;
}
* @text: a pointer to an utf8 string
*
* Returns: A newly created string object which contains @text.
+ *
+ * This function asserts if it cannot allocate a new string.
+ *
+ * @deprecated Use mono_string_new_checked in new code.
*/
MonoString*
mono_string_new (MonoDomain *domain, const char *text)
+{
+ MonoError error;
+ MonoString *res = NULL;
+ res = mono_string_new_checked (domain, text, &error);
+ mono_error_assert_ok (&error);
+ return res;
+}
+
+/**
+ * mono_string_new_checked:
+ * @text: a pointer to an utf8 string
+ * @merror: set on error
+ *
+ * Returns: A newly created string object which contains @text.
+ * On error returns NULL and sets @merror.
+ */
+MonoString*
+mono_string_new_checked (MonoDomain *domain, const char *text, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- GError *error = NULL;
+ GError *eg_error = NULL;
MonoString *o = NULL;
guint16 *ut;
glong items_written;
int l;
+ mono_error_init (error);
+
l = strlen (text);
- ut = g_utf8_to_utf16 (text, l, NULL, &items_written, &error);
+ ut = g_utf8_to_utf16 (text, l, NULL, &items_written, &eg_error);
- if (!error)
- o = mono_string_new_utf16 (domain, ut, items_written);
+ if (!eg_error)
+ o = mono_string_new_utf16_checked (domain, ut, items_written, error);
else
- g_error_free (error);
+ g_error_free (eg_error);
g_free (ut);
+ mono_error_raise_exception (error);
+
/*FIXME g_utf8_get_char, g_utf8_next_char and g_utf8_validate are not part of eglib.*/
#if 0
gunichar2 *str;
int len;
MonoString *o = NULL;
- if (!g_utf8_validate (text, -1, &end))
- return NULL;
+ if (!g_utf8_validate (text, -1, &end)) {
+ mono_error_set_argument (error, "text", "Not a valid utf8 string");
+ goto leave;
+ }
len = g_utf8_strlen (text, -1);
- o = mono_string_new_size (domain, len);
+ o = mono_string_new_size_checked (domain, len, error);
+ if (!o)
+ goto leave;
str = mono_string_chars (o);
while (text < end) {
*str++ = g_utf8_get_char (text);
text = g_utf8_next_char (text);
}
+
+leave:
#endif
return o;
}
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoObject *res;
int size;
MonoVTable *vtable;
if (!vtable)
return NULL;
size = mono_class_instance_size (klass);
- res = mono_object_new_alloc_specific (vtable);
+ res = mono_object_new_alloc_specific_checked (vtable, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
size = size - sizeof (MonoObject);
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoVTable *vt;
if (!obj)
im = mono_object_get_virtual_method (rp, im);
g_assert (im);
- pa [0] = mono_type_get_object (domain, &klass->byval_arg);
+ pa [0] = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
pa [1] = obj;
res = mono_runtime_invoke (im, rp, pa, NULL);
info->res = (MonoString *)mono_g_hash_table_lookup (domain->ldstr_table, info->ins);
}
-#ifdef HAVE_SGEN_GC
-
static MonoString*
-mono_string_get_pinned (MonoString *str)
+mono_string_get_pinned (MonoString *str, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
+ mono_error_init (error);
+
+ /* We only need to make a pinned version of a string if this is a moving GC */
+ if (!mono_gc_is_moving ())
+ return str;
int size;
MonoString *news;
size = sizeof (MonoString) + 2 * (mono_string_length (str) + 1);
if (news) {
memcpy (mono_string_chars (news), mono_string_chars (str), mono_string_length (str) * 2);
news->length = mono_string_length (str);
+ } else {
+ mono_error_set_out_of_memory (error, "Could not allocate %i bytes", size);
}
return news;
}
-#else
-#define mono_string_get_pinned(str) (str)
-#endif
-
static MonoString*
mono_string_is_interned_lookup (MonoString *str, int insert)
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoGHashTable *ldstr_table;
MonoString *s, *res;
MonoDomain *domain;
if (insert) {
/* Allocate outside the lock */
ldstr_unlock ();
- s = mono_string_get_pinned (str);
+ s = mono_string_get_pinned (str, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
if (s) {
ldstr_lock ();
res = (MonoString *)mono_g_hash_table_lookup (ldstr_table, str);
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
const char *str = sig;
MonoString *o, *interned;
size_t len2;
len2 = mono_metadata_decode_blob_size (str, &str);
len2 >>= 1;
- o = mono_string_new_utf16 (domain, (guint16*)str, len2);
+ o = mono_string_new_utf16_checked (domain, (guint16*)str, len2, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
{
int i;
if (interned)
return interned; /* o will get garbage collected */
- o = mono_string_get_pinned (o);
+ o = mono_string_get_pinned (o, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
if (o) {
ldstr_lock ();
interned = (MonoString *)mono_g_hash_table_lookup (domain->ldstr_table, o);
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
+ MonoString *res = NULL;
MonoDomain *domain = mono_domain_get ();
int len = 0;
while (data [len]) len++;
- return mono_string_new_utf16 (domain, data, len);
+ res = mono_string_new_utf16_checked (domain, data, len, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return res;
}
/**
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoWaitHandle *res;
gpointer params [1];
static MonoMethod *handle_set;
- res = (MonoWaitHandle *)mono_object_new (domain, mono_defaults.manualresetevent_class);
+ res = (MonoWaitHandle *)mono_object_new_checked (domain, mono_defaults.manualresetevent_class, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
/* Even though this method is virtual, it's safe to invoke directly, since the object type matches. */
if (!handle_set)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoAsyncResult *res = (MonoAsyncResult *)mono_object_new (domain, mono_defaults.asyncresult_class);
+ MonoError error;
+ MonoAsyncResult *res = (MonoAsyncResult *)mono_object_new_checked (domain, mono_defaults.asyncresult_class, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
MonoObject *context = mono_runtime_capture_context (domain);
/* we must capture the execution context from the original thread */
if (context) {
static MonoClass *object_array_klass;
static MonoClass *byte_array_klass;
static MonoClass *string_array_klass;
+ MonoError error;
MonoMethodSignature *sig = mono_method_signature (method->method);
MonoString *name;
+ MonoArray *arr;
int i, j;
char **names;
guint8 arg_type;
MONO_OBJECT_SETREF (this_obj, method, method);
- MONO_OBJECT_SETREF (this_obj, args, mono_array_new_specific (mono_class_vtable (domain, object_array_klass), sig->param_count));
- MONO_OBJECT_SETREF (this_obj, arg_types, mono_array_new_specific (mono_class_vtable (domain, byte_array_klass), sig->param_count));
+ arr = mono_array_new_specific_checked (mono_class_vtable (domain, object_array_klass), sig->param_count, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ MONO_OBJECT_SETREF (this_obj, args, arr);
+
+ arr = mono_array_new_specific_checked (mono_class_vtable (domain, byte_array_klass), sig->param_count, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ MONO_OBJECT_SETREF (this_obj, arg_types, arr);
+
this_obj->async_result = NULL;
this_obj->call_type = CallType_Sync;
names = g_new (char *, sig->param_count);
mono_method_get_param_names (method->method, (const char **) names);
- MONO_OBJECT_SETREF (this_obj, names, mono_array_new_specific (mono_class_vtable (domain, string_array_klass), sig->param_count));
+
+ arr = mono_array_new_specific_checked (mono_class_vtable (domain, string_array_klass), sig->param_count, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ MONO_OBJECT_SETREF (this_obj, names, arr);
for (i = 0; i < sig->param_count; i++) {
name = mono_string_new (domain, names [i]);
MONO_REQ_GC_UNSAFE_MODE;
static MonoClass *object_array_klass;
+ MonoError error;
MonoDomain *domain;
MonoMethod *method;
MonoMethodSignature *sig;
MonoObject *ret;
+ MonoArray *arr;
int i, j, outarg_count = 0;
#ifndef DISABLE_REMOTING
object_array_klass = klass;
}
- mono_gc_wbarrier_generic_store (out_args, (MonoObject*) mono_array_new_specific (mono_class_vtable (domain, object_array_klass), outarg_count));
+ arr = mono_array_new_specific_checked (mono_class_vtable (domain, object_array_klass), outarg_count, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ mono_gc_wbarrier_generic_store (out_args, (MonoObject*) arr);
*exc = NULL;
ret = mono_runtime_invoke_array (method, method->klass->valuetype? mono_object_unbox (target): target, msg->args, exc);
}
delegate->invoke_impl = arch_create_delegate_trampoline (delegate->object.vtable->domain, delegate->object.vtable->klass);
+ if (callbacks.init_delegate)
+ callbacks.init_delegate (delegate);
}
/**
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
+
MonoDomain *domain = mono_domain_get ();
MonoMethodSignature *sig = mono_method_signature (method);
MonoMethodMessage *msg;
int i, count;
- msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
-
+ msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
if (invoke) {
- mono_message_init (domain, msg, mono_method_get_object (domain, invoke, NULL), NULL);
+ MonoReflectionMethod *rm = mono_method_get_object_checked (domain, invoke, NULL, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_message_init (domain, msg, rm, NULL);
count = sig->param_count - 2;
} else {
- mono_message_init (domain, msg, mono_method_get_object (domain, method, NULL), NULL);
+ MonoReflectionMethod *rm = mono_method_get_object_checked (domain, method, NULL, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_message_init (domain, msg, rm, NULL);
count = sig->param_count;
}
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
+
static MonoMethod *getter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
field_class = mono_class_from_mono_type (field->type);
- msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
+ msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
out_args = mono_array_new (domain, mono_defaults.object_class, 1);
- mono_message_init (domain, msg, mono_method_get_object (domain, getter, NULL), out_args);
+ MonoReflectionMethod *rm = mono_method_get_object_checked (domain, getter, NULL, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_message_init (domain, msg, rm, out_args);
full_name = mono_type_get_full_name (klass);
mono_array_setref (msg->args, 0, mono_string_new (domain, full_name));
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
+
static MonoMethod *getter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
gpointer val;
if (field_class->valuetype) {
- res = mono_object_new (domain, field_class);
+ res = mono_object_new_checked (domain, field_class, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
val = ((gchar *) res) + sizeof (MonoObject);
} else {
val = &res;
mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
- msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
+ msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
out_args = mono_array_new (domain, mono_defaults.object_class, 1);
- mono_message_init (domain, msg, mono_method_get_object (domain, getter, NULL), out_args);
+ MonoReflectionMethod *rm = mono_method_get_object_checked (domain, getter, NULL, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_message_init (domain, msg, rm, out_args);
full_name = mono_type_get_full_name (klass);
mono_array_setref (msg->args, 0, mono_string_new (domain, full_name));
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
+
static MonoMethod *setter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
arg = *((MonoObject **)val);
- msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
- mono_message_init (domain, msg, mono_method_get_object (domain, setter, NULL), NULL);
+ msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_message_init (domain, msg, rm, NULL);
full_name = mono_type_get_full_name (klass);
mono_array_setref (msg->args, 0, mono_string_new (domain, full_name));
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
+
static MonoMethod *setter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
- msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
- mono_message_init (domain, msg, mono_method_get_object (domain, setter, NULL), NULL);
+ msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_message_init (domain, msg, rm, NULL);
full_name = mono_type_get_full_name (klass);
mono_array_setref (msg->args, 0, mono_string_new (domain, full_name));