#include "mono/metadata/metadata-internals.h"
#include <mono/metadata/assembly.h>
#include <mono/metadata/exception.h>
+ #include <mono/metadata/exception-internals.h>
#include <mono/metadata/threads.h>
#include <mono/metadata/threadpool-ms.h>
#include <mono/metadata/socket-io.h>
* Changes which are already detected at runtime, like the addition
* of icalls, do not require an increment.
*/
-#define MONO_CORLIB_VERSION 148
+#define MONO_CORLIB_VERSION 149
typedef struct
{
* Create an instance early since we can't do it when there is no memory.
*/
arg = mono_string_new (domain, "Out of memory");
- domain->out_of_memory_ex = mono_exception_from_name_two_strings (mono_defaults.corlib, "System", "OutOfMemoryException", arg, NULL);
+ domain->out_of_memory_ex = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "OutOfMemoryException", arg, NULL, &error);
+ mono_error_assert_ok (&error);
/*
* These two are needed because the signal handlers might be executing on
* an alternate stack, and Boehm GC can't handle that.
*/
arg = mono_string_new (domain, "A null value was found where an object instance was required");
- domain->null_reference_ex = mono_exception_from_name_two_strings (mono_defaults.corlib, "System", "NullReferenceException", arg, NULL);
+ domain->null_reference_ex = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "NullReferenceException", arg, NULL, &error);
+ mono_error_assert_ok (&error);
arg = mono_string_new (domain, "The requested operation caused a stack overflow.");
- domain->stack_overflow_ex = mono_exception_from_name_two_strings (mono_defaults.corlib, "System", "StackOverflowException", arg, NULL);
+ domain->stack_overflow_ex = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "StackOverflowException", arg, NULL, &error);
+ mono_error_assert_ok (&error);
/*The ephemeron tombstone i*/
domain->ephemeron_tombstone = mono_object_new_checked (domain, mono_defaults.object_class, &error);
#include <mono/utils/mono-memory-model.h>
#include <mono/utils/checked-build.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
#include "cominterop.h"
static void
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_start_invoke (method);
- MONO_ENTER_GC_UNSAFE;
-
result = callbacks.runtime_invoke (method, obj, params, exc, error);
- MONO_EXIT_GC_UNSAFE;
-
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_end_invoke (method);
}
} else {
MonoObject *result = mono_runtime_try_invoke_array (method, obj, params, NULL, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_raise_exception (&error); /* OK to throw, external only without a good alternative */
return result;
}
}
return interned;
}
+/*
+ * mono_ldstr_utf8:
+ *
+ * Same as mono_ldstr, but return a NULL terminated utf8 string instead
+ * of an object.
+ */
+char*
+mono_ldstr_utf8 (MonoImage *image, guint32 idx, MonoError *error)
+{
+ const char *str;
+ size_t len2;
+ long written = 0;
+ char *as;
+ GError *gerror = NULL;
+
+ mono_error_init (error);
+
+ if (!mono_verifier_verify_string_signature (image, idx, NULL))
+ return NULL; /*FIXME we should probably be raising an exception here*/
+ str = mono_metadata_user_string (image, idx);
+
+ len2 = mono_metadata_decode_blob_size (str, &str);
+ len2 >>= 1;
+
+ as = g_utf16_to_utf8 ((guint16*)str, len2, NULL, &written, &gerror);
+ if (gerror) {
+ mono_error_set_argument (error, "string", "%s", gerror->message);
+ g_error_free (gerror);
+ return NULL;
+ }
+ /* g_utf16_to_utf8 may not be able to complete the convertion (e.g. NULL values were found, #335488) */
+ if (len2 > written) {
+ /* allocate the total length and copy the part of the string that has been converted */
+ char *as2 = (char *)g_malloc0 (len2);
+ memcpy (as2, as, written);
+ g_free (as);
+ as = as2;
+ }
+
+ return as;
+}
+
/**
* mono_string_to_utf8:
* @s: a System.String
#include "jit-icalls.h"
#include <mono/utils/mono-error-internals.h>
+ #include <mono/metadata/exception-internals.h>
#include <mono/metadata/threads-types.h>
#include <mono/metadata/reflection-internals.h>
MonoException *
mono_create_corlib_exception_1 (guint32 token, MonoString *arg)
{
- return mono_exception_from_token_two_strings (mono_defaults.corlib, token, arg, NULL);
+ MonoError error;
+ MonoException *ret = mono_exception_from_token_two_strings_checked (
+ mono_defaults.corlib, token, arg, NULL, &error);
+ mono_error_set_pending_exception (&error);
+ return ret;
}
MonoException *
mono_create_corlib_exception_2 (guint32 token, MonoString *arg1, MonoString *arg2)
{
- return mono_exception_from_token_two_strings (mono_defaults.corlib, token, arg1, arg2);
+ MonoError error;
+ MonoException *ret = mono_exception_from_token_two_strings_checked (
+ mono_defaults.corlib, token, arg1, arg2, &error);
+ mono_error_set_pending_exception (&error);
+ return ret;
}
MonoObject*
* out parameter.
*/
static gpointer
-resolve_iface_call (MonoObject *this_obj, int imt_slot, MonoMethod *imt_method, gpointer *out_arg, gboolean caller_gsharedvt)
+resolve_iface_call (MonoObject *this_obj, int imt_slot, MonoMethod *imt_method, gpointer *out_arg, gboolean caller_gsharedvt, MonoError *error)
{
- MonoError error;
MonoVTable *vt;
gpointer *imt, *vtable_slot;
MonoMethod *impl_method, *generic_virtual = NULL, *variant_iface = NULL;
gpointer addr, compiled_method, aot_addr;
gboolean need_rgctx_tramp = FALSE, need_unbox_tramp = FALSE;
+ mono_error_init (error);
if (!this_obj)
/* The caller will handle it */
return NULL;
vt = this_obj->vtable;
imt = (gpointer*)vt - MONO_IMT_SIZE;
- vtable_slot = mini_resolve_imt_method (vt, imt + imt_slot, imt_method, &impl_method, &aot_addr, &need_rgctx_tramp, &variant_iface);
+ vtable_slot = mini_resolve_imt_method (vt, imt + imt_slot, imt_method, &impl_method, &aot_addr, &need_rgctx_tramp, &variant_iface, error);
+ return_val_if_nok (error, NULL);
// FIXME: This can throw exceptions
- addr = compiled_method = mono_compile_method_checked (impl_method, &error);
- mono_error_assert_ok (&error);
+ addr = compiled_method = mono_compile_method_checked (impl_method, error);
+ mono_error_assert_ok (error);
g_assert (addr);
if (imt_method->is_inflated && ((MonoMethodInflated*)imt_method)->context.method_inst)
gpointer
mono_resolve_iface_call_gsharedvt (MonoObject *this_obj, int imt_slot, MonoMethod *imt_method, gpointer *out_arg)
{
- return resolve_iface_call (this_obj, imt_slot, imt_method, out_arg, TRUE);
+ MonoError error;
+ gpointer res = resolve_iface_call (this_obj, imt_slot, imt_method, out_arg, TRUE, &error);
+ if (!is_ok (&error)) {
+ MonoException *ex = mono_error_convert_to_exception (&error);
+ mono_llvm_throw_exception ((MonoObject*)ex);
+ }
+ return res;
}
static gboolean
* out parameter.
*/
static gpointer
-resolve_vcall (MonoVTable *vt, int slot, MonoMethod *imt_method, gpointer *out_arg, gboolean gsharedvt)
+resolve_vcall (MonoVTable *vt, int slot, MonoMethod *imt_method, gpointer *out_arg, gboolean gsharedvt, MonoError *error)
{
- MonoError error;
MonoMethod *m, *generic_virtual = NULL;
gpointer addr, compiled_method;
gboolean need_unbox_tramp = FALSE;
+ mono_error_init (error);
/* Same as in common_call_trampoline () */
/* Avoid loading metadata or creating a generic vtable if possible */
- addr = mono_aot_get_method_from_vt_slot (mono_domain_get (), vt, slot, &error);
- mono_error_raise_exception (&error); // FIXME: Don't raise here
+ addr = mono_aot_get_method_from_vt_slot (mono_domain_get (), vt, slot, error);
+ return_val_if_nok (error, NULL);
if (addr && !vt->klass->valuetype)
return mono_create_ftnptr (mono_domain_get (), addr);
g_assert (generic_virtual->is_inflated);
context.method_inst = ((MonoMethodInflated*)generic_virtual)->context.method_inst;
- m = mono_class_inflate_generic_method_checked (declaring, &context, &error);
- mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ m = mono_class_inflate_generic_method_checked (declaring, &context, error);
+ mono_error_assert_ok (error); /* FIXME don't swallow the error */
}
if (generic_virtual) {
}
// FIXME: This can throw exceptions
- addr = compiled_method = mono_compile_method_checked (m, &error);
- mono_error_assert_ok (&error);
+ addr = compiled_method = mono_compile_method_checked (m, error);
+ mono_error_assert_ok (error);
g_assert (addr);
addr = mini_add_method_wrappers_llvmonly (m, addr, gsharedvt, need_unbox_tramp, out_arg);
{
g_assert (this_obj);
- return resolve_vcall (this_obj->vtable, slot, imt_method, out_arg, TRUE);
+ MonoError error;
+ gpointer result = resolve_vcall (this_obj->vtable, slot, imt_method, out_arg, TRUE, &error);
+ if (!is_ok (&error)) {
+ MonoException *ex = mono_error_convert_to_exception (&error);
+ mono_llvm_throw_exception ((MonoObject*)ex);
+ }
+ return result;
}
/*
imt = (gpointer*)vt - MONO_IMT_SIZE;
- mini_resolve_imt_method (vt, imt + imt_slot, generic_virtual, &m, &aot_addr, &need_rgctx_tramp, &variant_iface);
+ mini_resolve_imt_method (vt, imt + imt_slot, generic_virtual, &m, &aot_addr, &need_rgctx_tramp, &variant_iface, &error);
+ if (!is_ok (&error)) {
+ MonoException *ex = mono_error_convert_to_exception (&error);
+ mono_llvm_throw_exception ((MonoObject*)ex);
+ }
if (vt->klass->valuetype)
need_unbox_tramp = TRUE;
gpointer
mono_init_vtable_slot (MonoVTable *vtable, int slot)
{
+ MonoError error;
gpointer arg = NULL;
gpointer addr;
gpointer *ftnptr;
- addr = resolve_vcall (vtable, slot, NULL, &arg, FALSE);
+ addr = resolve_vcall (vtable, slot, NULL, &arg, FALSE, &error);
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
ftnptr = mono_domain_alloc0 (vtable->domain, 2 * sizeof (gpointer));
ftnptr [0] = addr;
ftnptr [1] = arg;