#include "jit-icalls.h"
#include <mono/utils/mono-error-internals.h>
+#include <mono/metadata/threads-types.h>
#ifdef ENABLE_LLVM
#include "mini-llvm-cpp.h"
MonoArray *
mono_array_new_va (MonoMethod *cm, ...)
{
+ MonoError error;
+ MonoArray *arr;
MonoDomain *domain = mono_domain_get ();
va_list ap;
uintptr_t *lengths;
}
va_end(ap);
- return mono_array_new_full (domain, cm->klass, lengths, lower_bounds);
+ arr = mono_array_new_full_checked (domain, cm->klass, lengths, lower_bounds, &error);
+
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+
+ return arr;
}
/* Specialized version of mono_array_new_va () which avoids varargs */
MonoArray *
mono_array_new_1 (MonoMethod *cm, guint32 length)
{
+ MonoError error;
+ MonoArray *arr;
MonoDomain *domain = mono_domain_get ();
uintptr_t lengths [1];
intptr_t *lower_bounds;
lower_bounds = NULL;
}
- return mono_array_new_full (domain, cm->klass, lengths, lower_bounds);
+ arr = mono_array_new_full_checked (domain, cm->klass, lengths, lower_bounds, &error);
+
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+
+ return arr;
}
MonoArray *
mono_array_new_2 (MonoMethod *cm, guint32 length1, guint32 length2)
{
+ MonoError error;
+ MonoArray *arr;
MonoDomain *domain = mono_domain_get ();
uintptr_t lengths [2];
intptr_t *lower_bounds;
lower_bounds = NULL;
}
- return mono_array_new_full (domain, cm->klass, lengths, lower_bounds);
+ arr = mono_array_new_full_checked (domain, cm->klass, lengths, lower_bounds, &error);
+
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+
+ return arr;
}
MonoArray *
mono_array_new_3 (MonoMethod *cm, guint32 length1, guint32 length2, guint32 length3)
{
+ MonoError error;
+ MonoArray *arr;
MonoDomain *domain = mono_domain_get ();
uintptr_t lengths [3];
intptr_t *lower_bounds;
lower_bounds = NULL;
}
- return mono_array_new_full (domain, cm->klass, lengths, lower_bounds);
+ arr = mono_array_new_full_checked (domain, cm->klass, lengths, lower_bounds, &error);
+
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+
+ return arr;
}
MonoArray *
mono_array_new_4 (MonoMethod *cm, guint32 length1, guint32 length2, guint32 length3, guint32 length4)
{
+ MonoError error;
+ MonoArray *arr;
MonoDomain *domain = mono_domain_get ();
uintptr_t lengths [4];
intptr_t *lower_bounds;
lower_bounds = NULL;
}
- return mono_array_new_full (domain, cm->klass, lengths, lower_bounds);
+ arr = mono_array_new_full_checked (domain, cm->klass, lengths, lower_bounds, &error);
+
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+
+ return arr;
}
gpointer
return NULL;
}
- return mono_object_new (mono_domain_get (), klass);
+ MonoObject *obj = mono_object_new_checked (mono_domain_get (), klass, &error);
+ if (!mono_error_ok (&error))
+ mono_error_set_pending_exception (&error);
+ return obj;
}
/*
}
static MonoMethod*
-constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gpointer *this_arg)
+constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gpointer *this_arg, MonoError *error)
{
MonoMethod *m;
int vt_slot, iface_offset;
+ mono_error_init (error);
+
if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
MonoObject *this_obj;
MonoObject*
mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gboolean deref_arg, gpointer *args)
{
+ MonoError error;
MonoMethod *m;
gpointer this_arg;
gpointer new_args [16];
- m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg);
+ m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+
if (!m)
return NULL;
if (args && deref_arg) {
gpointer
mono_fill_class_rgctx (MonoVTable *vtable, int index)
{
- return mono_class_fill_runtime_generic_context (vtable, index);
+ MonoError error;
+ gpointer res;
+
+ res = mono_class_fill_runtime_generic_context (vtable, index, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
gpointer
mono_fill_method_rgctx (MonoMethodRuntimeGenericContext *mrgctx, int index)
{
- return mono_method_fill_runtime_generic_context (mrgctx, index);
+ MonoError error;
+ gpointer res;
+
+ res = mono_method_fill_runtime_generic_context (mrgctx, index, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
/*
jit_tls->calling_image = image;
}
+
+static gboolean
+get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
+{
+ MonoMethod **dest = (MonoMethod **)data;
+
+ /* skip unmanaged frames */
+ if (!managed)
+ return FALSE;
+
+ if (!(*dest)) {
+ if (!strcmp (m->klass->name_space, "System.Reflection"))
+ return FALSE;
+ *dest = m;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
+{
+ MonoMethod **dest = (MonoMethod **)data;
+
+ /* skip unmanaged frames */
+ if (!managed)
+ return FALSE;
+
+ if (m->wrapper_type != MONO_WRAPPER_NONE)
+ return FALSE;
+
+ if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
+ return FALSE;
+
+ if (m == *dest) {
+ *dest = NULL;
+ return FALSE;
+ }
+ if (!(*dest)) {
+ *dest = m;
+ return TRUE;
+ }
+ return FALSE;
+}
+
MonoObject*
mono_llvmonly_get_calling_assembly (void)
{
MonoJitTlsData *jit_tls = NULL;
+ MonoMethod *m;
+ MonoMethod *dest;
+ MonoAssembly *assembly;
- jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
- g_assert (jit_tls);
- if (!jit_tls->calling_image)
- mono_raise_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
+ dest = NULL;
+ mono_stack_walk_no_il (get_executing, &dest);
+ m = dest;
+ mono_stack_walk_no_il (get_caller_no_reflection, &dest);
+
+ if (!dest) {
+ /* Fall back to TLS */
+ jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
+ g_assert (jit_tls);
+ if (!jit_tls->calling_image) {
+ mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
+ return NULL;
+ }
+ assembly = jit_tls->calling_image->assembly;
+ } else {
+ assembly = dest->klass->image->assembly;
+ }
return (MonoObject*)mono_assembly_get_object (mono_domain_get (), jit_tls->calling_image->assembly);
}
+
+/*
+ * mono_interruption_checkpoint_from_trampoline:
+ *
+ * Check whenever the thread has a pending exception, and throw it
+ * if needed.
+ * Architectures should move away from calling this function and
+ * instead call mono_thread_force_interruption_checkpoint_noraise (),
+ * rewrind to the parent frame, and throw the exception normally.
+ */
+void
+mono_interruption_checkpoint_from_trampoline (void)
+{
+ MonoException *ex;
+
+ ex = mono_thread_force_interruption_checkpoint_noraise ();
+ if (ex)
+ mono_raise_exception (ex);
+}