From 9c6d733449a04be3f042ed01fc9bc49fda8494bf Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Fri, 30 Nov 2018 11:22:11 +0200 Subject: [PATCH] [interp] Fix rethrow (#11844) * [interp] Remove some useless code * [interp] Remove useless variable When unwinding, we get the last interp frame that was executing from the LMF marker. * [interp] Rethrow from the actual ip Before we would rethrow from ip - 1 which could be part of another clause, screwing up EH. * [interp] Enable all bcl disabled tests --- .../ExpressionTest_Coalesce.cs | 1 - .../Test/System.Linq/EnumerableAsQueryableTest.cs | 1 - .../Test/System.Linq/ParallelEnumerableTests.cs | 1 - .../System/Test/System.Net/HttpListenerTest.cs | 3 - .../SerializationTest.cs | 1 - mono/mini/interp/interp-internals.h | 3 - mono/mini/interp/interp.c | 68 ++++------------------ 7 files changed, 10 insertions(+), 68 deletions(-) diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Coalesce.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Coalesce.cs index 452b7c58d6e..2ab978d5187 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Coalesce.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Coalesce.cs @@ -133,7 +133,6 @@ namespace MonoTests.System.Linq.Expressions [Test] [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=349822 - [Category ("NotWorkingRuntimeInterpreter")] public void CoalesceUserDefinedConversion () { var s = Expression.Parameter (typeof (string), "s"); diff --git a/mcs/class/System.Core/Test/System.Linq/EnumerableAsQueryableTest.cs b/mcs/class/System.Core/Test/System.Linq/EnumerableAsQueryableTest.cs index 9b24f2a9fd6..aee3bff9ee3 100644 --- a/mcs/class/System.Core/Test/System.Linq/EnumerableAsQueryableTest.cs +++ b/mcs/class/System.Core/Test/System.Linq/EnumerableAsQueryableTest.cs @@ -239,7 +239,6 @@ namespace MonoTests.System.Linq { } [Test] - [Category ("NotWorkingRuntimeInterpreter")] public void SelectMany () { int [] arr1 = _array.SelectMany ((n) => new int [] { n, n, n }).ToArray (); diff --git a/mcs/class/System.Core/Test/System.Linq/ParallelEnumerableTests.cs b/mcs/class/System.Core/Test/System.Linq/ParallelEnumerableTests.cs index e3dab3c50d3..5d76629eda8 100644 --- a/mcs/class/System.Core/Test/System.Linq/ParallelEnumerableTests.cs +++ b/mcs/class/System.Core/Test/System.Linq/ParallelEnumerableTests.cs @@ -364,7 +364,6 @@ namespace MonoTests.System.Linq } [Test] - [Category ("NotWorkingRuntimeInterpreter")] public void SelectManyOrderedTest () { IEnumerable initial = Enumerable.Range (1, 50); diff --git a/mcs/class/System/Test/System.Net/HttpListenerTest.cs b/mcs/class/System/Test/System.Net/HttpListenerTest.cs index cc4f207d805..2683fc6166d 100644 --- a/mcs/class/System/Test/System.Net/HttpListenerTest.cs +++ b/mcs/class/System/Test/System.Net/HttpListenerTest.cs @@ -197,7 +197,6 @@ namespace MonoTests.System.Net { #else [ExpectedException (typeof (HttpListenerException))] #endif - [Category ("NotWorkingRuntimeInterpreter")] public void TwoListeners_SameURL () { HttpListener listener1 = NetworkHelpers.CreateAndStartHttpListener ("http://127.0.0.1:", out var port, "/hola/"); @@ -210,7 +209,6 @@ namespace MonoTests.System.Net { #else [ExpectedException (typeof (HttpListenerException))] #endif - [Category ("NotWorkingRuntimeInterpreter")] public void MultipleSlashes () { // this one throws on Start(), not when adding it. @@ -223,7 +221,6 @@ namespace MonoTests.System.Net { #else [ExpectedException (typeof (HttpListenerException))] #endif - [Category ("NotWorkingRuntimeInterpreter")] public void PercentSign () { HttpListener listener = NetworkHelpers.CreateAndStartHttpListener ("http://127.0.0.1:", out var port, "/hola%3E/"); diff --git a/mcs/class/corlib/Test/System.Runtime.Serialization/SerializationTest.cs b/mcs/class/corlib/Test/System.Runtime.Serialization/SerializationTest.cs index aa677741266..189b8ab0fc2 100644 --- a/mcs/class/corlib/Test/System.Runtime.Serialization/SerializationTest.cs +++ b/mcs/class/corlib/Test/System.Runtime.Serialization/SerializationTest.cs @@ -30,7 +30,6 @@ namespace MonoTests.System.Runtime.Serialization #if FEATURE_REMOTING [Test] - [Category ("NotWorkingRuntimeInterpreter")] public void TestSerialization () { MethodTester mt = new MethodTester(); diff --git a/mono/mini/interp/interp-internals.h b/mono/mini/interp/interp-internals.h index 938908c8bde..72cce08f1e2 100644 --- a/mono/mini/interp/interp-internals.h +++ b/mono/mini/interp/interp-internals.h @@ -139,12 +139,9 @@ struct _InterpFrame { unsigned char invoke_trap; const unsigned short *ip; MonoException *ex; - MonoExceptionClause *ex_handler; - MonoDomain *domain; }; typedef struct { - InterpFrame *current_frame; /* Resume state for resuming execution in mixed mode */ gboolean has_resume_state; /* Frame to resume execution at */ diff --git a/mono/mini/interp/interp.c b/mono/mini/interp/interp.c index e6856540a27..7628442e428 100644 --- a/mono/mini/interp/interp.c +++ b/mono/mini/interp/interp.c @@ -1210,8 +1210,7 @@ ves_pinvoke_method (InterpFrame *frame, MonoMethodSignature *sig, MonoFuncV addr g_print ("ICALL: mono_interp_to_native_trampoline = %p, addr = %p\n", mono_interp_to_native_trampoline, addr); #endif - context->current_frame = frame; - INTERP_PUSH_LMF_WITH_CTX (context->current_frame, ext, &&exit_pinvoke); + INTERP_PUSH_LMF_WITH_CTX (frame, ext, &&exit_pinvoke); #ifdef MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP mono_interp_to_native_trampoline (addr, &ccontext); #else @@ -1608,7 +1607,7 @@ get_trace_ips (MonoDomain *domain, InterpFrame *top) static MonoObject* interp_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError *error) { - InterpFrame frame, *old_frame; + InterpFrame frame; ThreadContext *context = get_context (); MonoMethodSignature *sig = mono_method_signature_internal (method); MonoClass *klass = mono_class_from_mono_type_internal (sig->ret); @@ -1621,8 +1620,6 @@ interp_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject frame.ex = NULL; - old_frame = context->current_frame; - MonoDomain *domain = mono_domain_get (); if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) @@ -1649,8 +1646,6 @@ interp_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject interp_exec_method (&frame, context); - context->current_frame = old_frame; - if (frame.ex) { if (exc) { *exc = (MonoObject*) frame.ex; @@ -1677,7 +1672,6 @@ interp_entry (InterpEntryData *data) InterpFrame frame; InterpMethod *rmethod = data->rmethod; ThreadContext *context; - InterpFrame *old_frame; stackval result; stackval *args; MonoMethod *method; @@ -1699,7 +1693,6 @@ interp_entry (InterpEntryData *data) //printf ("%s\n", mono_method_full_name (method, 1)); frame.ex = NULL; - old_frame = context->current_frame; args = g_newa (stackval, sig->param_count + (sig->hasthis ? 1 : 0)); if (sig->hasthis) @@ -1750,7 +1743,6 @@ interp_entry (InterpEntryData *data) } interp_exec_method (&frame, context); - context->current_frame = old_frame; if (rmethod->needs_thread_attach) mono_threads_detach_coop (orig_domain, &attach_cookie); @@ -1784,10 +1776,10 @@ interp_entry (InterpEntryData *data) /* MONO_NO_OPTIMIATION is needed due to usage of INTERP_PUSH_LMF_WITH_CTX. */ static MONO_NO_OPTIMIZATION MONO_NEVER_INLINE stackval * -do_icall (ThreadContext *context, MonoMethodSignature *sig, int op, stackval *sp, gpointer ptr) +do_icall (InterpFrame *frame, MonoMethodSignature *sig, int op, stackval *sp, gpointer ptr) { MonoLMFExt ext; - INTERP_PUSH_LMF_WITH_CTX (context->current_frame, ext, &&exit_icall); + INTERP_PUSH_LMF_WITH_CTX (frame, ext, &&exit_icall); switch (op) { case MINT_ICALL_V_V: { @@ -2377,7 +2369,6 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype { InterpFrame frame; ThreadContext *context; - InterpFrame *old_frame; stackval result; stackval *args; MonoMethod *method; @@ -2396,7 +2387,6 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype sig = mono_method_signature_internal (method); frame.ex = NULL; - old_frame = context->current_frame; args = (stackval*)alloca (sizeof (stackval) * (sig->param_count + (sig->hasthis ? 1 : 0))); @@ -2415,7 +2405,6 @@ interp_entry_from_trampoline (gpointer ccontext_untyped, gpointer rmethod_untype mono_arch_get_native_call_context_args (ccontext, &frame, sig); interp_exec_method (&frame, context); - context->current_frame = old_frame; if (rmethod->needs_thread_attach) mono_threads_detach_coop (orig_domain, &attach_cookie); @@ -2633,11 +2622,7 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st frame->ex = NULL; - frame->ex_handler = NULL; frame->ip = NULL; - frame->domain = mono_domain_get (); - context->current_frame = frame; - debug_enter (frame, &tracing); rtm = frame->imethod; @@ -2888,8 +2873,6 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st interp_exec_method (&child_frame, context); - context->current_frame = frame; - if (context->has_resume_state) { if (frame == context->handler_frame) SET_RESUME_STATE (context); @@ -2914,7 +2897,7 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st sp--; frame->ip = ip; - sp = do_icall (context, csignature, opcode, sp, target_ip); + sp = do_icall (frame, csignature, opcode, sp, target_ip); EXCEPTION_CHECKPOINT; if (context->has_resume_state) { if (frame == context->handler_frame) @@ -2969,7 +2952,6 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st } else { ves_pinvoke_method (&child_frame, csignature, (MonoFuncV) code, FALSE, context); } - context->current_frame = frame; if (context->has_resume_state) { if (frame == context->handler_frame) @@ -3029,8 +3011,6 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st interp_exec_method (&child_frame, context); - context->current_frame = frame; - if (context->has_resume_state) { if (frame == context->handler_frame) SET_RESUME_STATE (context); @@ -4075,8 +4055,6 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st interp_exec_method (&child_frame, context); - context->current_frame = frame; - if (context->has_resume_state) { if (frame == context->handler_frame) SET_RESUME_STATE (context); @@ -4159,8 +4137,6 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st interp_exec_method (&child_frame, context); - context->current_frame = frame; - if (context->has_resume_state) { if (frame == context->handler_frame) SET_RESUME_STATE (context); @@ -4265,7 +4241,6 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st MINT_IN_BREAK; MINT_IN_CASE(MINT_THROW) --sp; - frame->ex_handler = NULL; if (!sp->data.p) sp->data.p = mono_get_exception_null_reference (); @@ -5270,11 +5245,6 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st } frame->ip = ip; - if (frame->ex_handler != NULL && MONO_OFFSET_IN_HANDLER(frame->ex_handler, frame->ip - rtm->code)) { - frame->ex_handler = NULL; - frame->ex = NULL; - } - if (frame->imethod->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE) { stackval tmp_sp; @@ -5285,9 +5255,7 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st * to check the abort threshold. For this to work we use child_frame as a * dummy frame that is stored in the lmf and serves as the transition frame */ - context->current_frame = &child_frame; - do_icall (context, NULL, MINT_ICALL_V_P, &tmp_sp, (gpointer)mono_thread_get_undeniable_exception); - context->current_frame = frame; + do_icall (&child_frame, NULL, MINT_ICALL_V_P, &tmp_sp, (gpointer)mono_thread_get_undeniable_exception); MonoException *abort_exc = (MonoException*)tmp_sp.data.p; if (abort_exc) @@ -5317,7 +5285,7 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st MINT_IN_CASE(MINT_ICALL_PPPPPP_V) MINT_IN_CASE(MINT_ICALL_PPPPPP_P) frame->ip = ip; - sp = do_icall (context, NULL, *ip, sp, rtm->data_items [*(guint16 *)(ip + 1)]); + sp = do_icall (frame, NULL, *ip, sp, rtm->data_items [*(guint16 *)(ip + 1)]); EXCEPTION_CHECKPOINT; if (context->has_resume_state) { if (frame == context->handler_frame) @@ -5803,19 +5771,8 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st MINT_IN_BREAK; #endif MINT_IN_CASE(MINT_RETHROW) { - /* - * need to clarify what this should actually do: - * start the search from the last found handler in - * this method or continue in the caller or what. - * Also, do we need to run finally/fault handlers after a retrow? - * Well, this implementation will follow the usual search - * for an handler, considering the current ip as throw spot. - * We need to NULL frame->ex_handler for the later code to - * actually run the new found handler. - */ int exvar_offset = *(guint16*)(ip + 1); - frame->ex_handler = NULL; - THROW_EX_GENERAL (*(MonoException**)(frame->locals + exvar_offset), ip - 1, TRUE); + THROW_EX_GENERAL (*(MonoException**)(frame->locals + exvar_offset), ip, TRUE); MINT_IN_BREAK; } MINT_IN_CASE(MINT_MONO_RETHROW) { @@ -5828,7 +5785,6 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st */ --sp; - frame->ex_handler = NULL; if (!sp->data.p) sp->data.p = mono_get_exception_null_reference (); @@ -5899,12 +5855,8 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st if (endfinally_ip != NULL) finally_ips = g_slist_prepend(finally_ips, (void *)endfinally_ip); - for (i = 0; i < rtm->num_clauses; ++i) - if (frame->ex_handler == &rtm->clauses [i]) - break; - while (i > 0) { - --i; + for (i = rtm->num_clauses - 1; i >= 0; i--) { clause = &rtm->clauses [i]; if (MONO_OFFSET_IN_CLAUSE (clause, ip_offset) && (endfinally_ip == NULL || !(MONO_OFFSET_IN_CLAUSE (clause, endfinally_ip - rtm->code)))) { if (clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY) { @@ -6104,7 +6056,7 @@ interp_frame_iter_next (MonoInterpStackIter *iter, StackFrameInfo *frame) return FALSE; MonoMethod *method = iframe->imethod->method; - frame->domain = iframe->domain; + frame->domain = iframe->imethod->domain; frame->interp_frame = iframe; frame->method = method; frame->actual_method = method; -- 2.11.4.GIT