Merge pull request #1654 from alexanderkyte/xunit-fixes
[mono.git] / mono / mini / mini-exceptions.c
index e9dcda7f59e3b5262390350d707f18cae7b83a34..fef21b9958159dd295540dd98047413905cc09f8 100644 (file)
@@ -715,7 +715,7 @@ ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info
                        sf->il_offset = location->il_offset;
                } else {
                        SeqPoint sp;
-                       if (find_prev_seq_point_for_native_offset (domain, jinfo_get_method (ji), sf->native_offset, NULL, &sp))
+                       if (mono_find_prev_seq_point_for_native_offset (domain, jinfo_get_method (ji), sf->native_offset, NULL, &sp))
                                sf->il_offset = sp.il_offset;
                        else
                                sf->il_offset = -1;
@@ -874,7 +874,7 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoDomain
                                il_offset = source->il_offset;
                        } else {
                                SeqPoint sp;
-                               if (find_prev_seq_point_for_native_offset (domain, jinfo_get_method (frame.ji), frame.native_offset, NULL, &sp))
+                               if (mono_find_prev_seq_point_for_native_offset (domain, jinfo_get_method (frame.ji), frame.native_offset, NULL, &sp))
                                        il_offset = sp.il_offset;
                                else
                                        il_offset = -1;
@@ -979,121 +979,6 @@ ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
        return TRUE;
 }
 
-typedef struct {
-       guint32 skips;
-       MonoSecurityFrame *frame;
-} MonoFrameSecurityInfo;
-
-static gboolean
-callback_get_first_frame_security_info (StackFrameInfo *frame, MonoContext *ctx, gpointer data)
-{
-       MonoFrameSecurityInfo *si = (MonoFrameSecurityInfo*) data;
-       MonoJitInfo *ji = frame->ji;
-       MonoMethod *method;
-
-       if (!ji)
-               return FALSE;
-
-       /* FIXME: skip all wrappers ?? probably not - case by case testing is required */
-       method = jinfo_get_method (ji);
-       if (method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE ||
-           method->wrapper_type == MONO_WRAPPER_XDOMAIN_INVOKE ||
-           method->wrapper_type == MONO_WRAPPER_XDOMAIN_DISPATCH ||
-           method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK ||
-           method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE) {
-               return FALSE;
-       }
-
-       if (si->skips > 0) {
-               si->skips--;
-               return FALSE;
-       }
-
-       si->frame = mono_declsec_create_frame (frame->domain, ji);
-
-       /* Stop - we only want the first frame (e.g. LinkDemand and InheritanceDemand) */
-       return TRUE;
-}
-
-/**
- * ves_icall_System_Security_SecurityFrame_GetSecurityFrame:
- * @skip: the number of stack frames to skip
- *
- * This function returns a the security informations of a single stack frame 
- * (after the skipped ones). This is required for [NonCas]LinkDemand[Choice]
- * and [NonCas]InheritanceDemand[Choice] as only the caller security is 
- * evaluated.
- */
-MonoSecurityFrame*
-ves_icall_System_Security_SecurityFrame_GetSecurityFrame (gint32 skip)
-{
-       MonoFrameSecurityInfo si;
-
-       si.skips = skip;
-       si.frame = NULL;
-
-       mono_walk_stack (callback_get_first_frame_security_info, MONO_UNWIND_DEFAULT, &si);
-
-       return (si.skips == 0) ? si.frame : NULL;
-}
-
-
-typedef struct {
-       guint32 skips;
-       MonoArray *stack;
-       guint32 count;
-       guint32 maximum;
-} MonoSecurityStack;
-
-static void
-grow_array (MonoSecurityStack *stack)
-{
-       MonoDomain *domain = mono_domain_get ();
-       guint32 newsize = (stack->maximum << 1);
-       MonoArray *newstack = mono_array_new (domain, mono_defaults.runtimesecurityframe_class, newsize);
-       int i;
-       for (i=0; i < stack->maximum; i++) {
-               gpointer frame = mono_array_get (stack->stack, gpointer, i);
-               mono_array_setref (newstack, i, frame);
-       }
-       stack->maximum = newsize;
-       stack->stack = newstack;
-}
-
-static gboolean
-callback_get_stack_frames_security_info (StackFrameInfo *frame, MonoContext *ctx, gpointer data)
-{
-       MonoSecurityStack *ss = (MonoSecurityStack*) data;
-       MonoJitInfo *ji = frame->ji;
-       MonoMethod *method;
-
-       if (!ji)
-               return FALSE;
-
-       /* FIXME: skip all wrappers ?? probably not - case by case testing is required */
-       method = jinfo_get_method (ji);
-       if (method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE ||
-           method->wrapper_type == MONO_WRAPPER_XDOMAIN_INVOKE ||
-           method->wrapper_type == MONO_WRAPPER_XDOMAIN_DISPATCH ||
-           method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK ||
-           method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE) {
-               return FALSE;
-       }
-
-       if (ss->skips > 0) {
-               ss->skips--;
-               return FALSE;
-       }
-
-       if (ss->count == ss->maximum)
-               grow_array (ss);
-
-       mono_array_setref (ss->stack, ss->count++, mono_declsec_create_frame (frame->domain, ji));
-
-       /* continue down the stack */
-       return FALSE;
-}
-
 static MonoArray *
 glist_to_array (GList *list, MonoClass *eclass) 
 {
@@ -1113,33 +998,6 @@ glist_to_array (GList *list, MonoClass *eclass)
        return res;
 }
 
-/**
- * ves_icall_System_Security_SecurityFrame_GetSecurityStack:
- * @skip: the number of stack frames to skip
- *
- * This function returns an managed array of containing the security
- * informations for each frame (after the skipped ones). This is used for
- * [NonCas]Demand[Choice] where the complete evaluation of the stack is 
- * required.
- */
-MonoArray*
-ves_icall_System_Security_SecurityFrame_GetSecurityStack (gint32 skip)
-{
-       MonoSecurityStack ss;
-
-#if    defined(__ia64__) || defined(__s390__) || defined(__s390x__)
-       skip--;
-#endif
-
-       ss.skips = skip;
-       ss.count = 0;
-       ss.maximum = MONO_CAS_INITIAL_STACK_SIZE;
-       ss.stack = mono_array_new (mono_domain_get (), mono_defaults.runtimesecurityframe_class, ss.maximum);
-       mono_walk_stack (callback_get_stack_frames_security_info, MONO_UNWIND_DEFAULT, &ss);
-       /* g_warning ("STACK RESULT: %d out of %d", ss.count, ss.maximum); */
-       return ss.stack;
-}
-
 static MonoClass*
 get_exception_catch_class (MonoJitExceptionInfo *ei, MonoJitInfo *ji, MonoContext *ctx)
 {
@@ -1169,14 +1027,14 @@ get_exception_catch_class (MonoJitExceptionInfo *ei, MonoJitInfo *ji, MonoContex
 }
 
 /*
- * mini_jit_info_table_find:
+ * mini_jit_info_table_find_ext:
  *
  *   Same as mono_jit_info_table_find, but search all the domains of the current thread
  * if ADDR is not found in DOMAIN. The domain where the method was found is stored into
  * OUT_DOMAIN if it is not NULL.
  */
 MonoJitInfo*
-mini_jit_info_table_find (MonoDomain *domain, char *addr, MonoDomain **out_domain)
+mini_jit_info_table_find_ext (MonoDomain *domain, char *addr, gboolean allow_trampolines, MonoDomain **out_domain)
 {
        MonoJitInfo *ji;
        MonoInternalThread *t = mono_thread_internal_current ();
@@ -1185,7 +1043,7 @@ mini_jit_info_table_find (MonoDomain *domain, char *addr, MonoDomain **out_domai
        if (out_domain)
                *out_domain = NULL;
 
-       ji = mono_jit_info_table_find (domain, addr);
+       ji = mono_jit_info_table_find_internal (domain, addr, TRUE, allow_trampolines);
        if (ji) {
                if (out_domain)
                        *out_domain = domain;
@@ -1194,7 +1052,7 @@ mini_jit_info_table_find (MonoDomain *domain, char *addr, MonoDomain **out_domai
 
        /* maybe it is shared code, so we also search in the root domain */
        if (domain != mono_get_root_domain ()) {
-               ji = mono_jit_info_table_find (mono_get_root_domain (), addr);
+               ji = mono_jit_info_table_find_internal (mono_get_root_domain (), addr, TRUE, allow_trampolines);
                if (ji) {
                        if (out_domain)
                                *out_domain = mono_get_root_domain ();
@@ -1208,7 +1066,7 @@ mini_jit_info_table_find (MonoDomain *domain, char *addr, MonoDomain **out_domai
        refs = (t->appdomain_refs) ? *(gpointer *) t->appdomain_refs : NULL;
        for (; refs && *refs; refs++) {
                if (*refs != domain && *refs != mono_get_root_domain ()) {
-                       ji = mono_jit_info_table_find ((MonoDomain*) *refs, addr);
+                       ji = mono_jit_info_table_find_internal ((MonoDomain*) *refs, addr, TRUE, allow_trampolines);
                        if (ji) {
                                if (out_domain)
                                        *out_domain = (MonoDomain*) *refs;
@@ -1220,6 +1078,12 @@ mini_jit_info_table_find (MonoDomain *domain, char *addr, MonoDomain **out_domai
        return NULL;
 }
 
+MonoJitInfo*
+mini_jit_info_table_find (MonoDomain *domain, char *addr, MonoDomain **out_domain)
+{
+       return mini_jit_info_table_find_ext (domain, addr, FALSE, out_domain);
+}
+
 /*
  * wrap_non_exception_throws:
  *
@@ -1483,20 +1347,17 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, gpointer obj, gint3
                                        if (is_user_frame)
                                                setup_managed_stacktrace_information ();
 
-                                       if (ji->from_llvm) {
 #ifdef MONO_CONTEXT_SET_LLVM_EXC_REG
+                                       if (ji->from_llvm)
                                                MONO_CONTEXT_SET_LLVM_EXC_REG (ctx, ex_obj);
-#else
-                                               g_assert_not_reached ();
-#endif
-                                       } else {
-#ifdef MONO_ARCH_HAVE_OP_GET_EX_OBJ
-                                               MONO_CONTEXT_SET_LLVM_EXC_REG (ctx, ex_obj);
-#else
-                                               /* store the exception object in bp + ei->exvar_offset */
+                                       else
+                                               /* Can't pass the ex object in a register yet to filter clauses, because call_filter () might not support it */
                                                *((gpointer *)(gpointer)((char *)MONO_CONTEXT_GET_BP (ctx) + ei->exvar_offset)) = ex_obj;
+#else
+                                       g_assert (!ji->from_llvm);
+                                       /* store the exception object in bp + ei->exvar_offset */
+                                       *((gpointer *)(gpointer)((char *)MONO_CONTEXT_GET_BP (ctx) + ei->exvar_offset)) = ex_obj;
 #endif
-                                       }
 
 #ifdef MONO_CONTEXT_SET_LLVM_EH_SELECTOR_REG
                                        /*
@@ -1792,20 +1653,13 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume,
                                        ex_obj = obj;
 
                                if (((ei->flags == MONO_EXCEPTION_CLAUSE_NONE) || (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER))) {
-                                       if (ji->from_llvm) {
 #ifdef MONO_CONTEXT_SET_LLVM_EXC_REG
-                                               MONO_CONTEXT_SET_LLVM_EXC_REG (ctx, ex_obj);
+                                       MONO_CONTEXT_SET_LLVM_EXC_REG (ctx, ex_obj);
 #else
-                                               g_assert_not_reached ();
+                                       g_assert (!ji->from_llvm);
+                                       /* store the exception object in bp + ei->exvar_offset */
+                                       *((gpointer *)(gpointer)((char *)MONO_CONTEXT_GET_BP (ctx) + ei->exvar_offset)) = ex_obj;
 #endif
-                                       } else {
-#ifdef MONO_ARCH_HAVE_OP_GET_EX_OBJ
-                                               MONO_CONTEXT_SET_LLVM_EXC_REG (ctx, ex_obj);
-#else
-                                               /* store the exception object in bp + ei->exvar_offset */
-                                               *((gpointer *)(gpointer)((char *)MONO_CONTEXT_GET_BP (ctx) + ei->exvar_offset)) = ex_obj;
-#endif
-                                       }
                                }
 
 #ifdef MONO_CONTEXT_SET_LLVM_EH_SELECTOR_REG