@@ -72,6 +72,17 @@ namespace Js
72
72
m_threadContext->SetTryCatchFrameAddr (m_prevTryCatchFrameAddr);
73
73
}
74
74
75
+ JavascriptExceptionOperators::PendingFinallyExceptionStack::PendingFinallyExceptionStack (ScriptContext* scriptContext, Js::JavascriptExceptionObject *exceptionObj)
76
+ {
77
+ m_threadContext = scriptContext->GetThreadContext ();
78
+ m_threadContext->SetPendingFinallyException (exceptionObj);
79
+ }
80
+
81
+ JavascriptExceptionOperators::PendingFinallyExceptionStack::~PendingFinallyExceptionStack ()
82
+ {
83
+ m_threadContext->SetPendingFinallyException (nullptr );
84
+ }
85
+
75
86
bool JavascriptExceptionOperators::CrawlStackForWER (Js::ScriptContext& scriptContext)
76
87
{
77
88
return Js::Configuration::Global.flags .WERExceptionSupport && !scriptContext.GetThreadContext ()->HasCatchHandler ();
@@ -199,9 +210,11 @@ namespace Js
199
210
JavascriptExceptionOperators::DoThrow (exception, scriptContext);
200
211
}
201
212
202
- scriptContext->GetThreadContext ()->SetPendingFinallyException (exception);
203
- void *continuation = amd64_CallWithFakeFrame (finallyAddr, frame, spillSize, argsSize, exception);
204
- return continuation;
213
+ {
214
+ Js::JavascriptExceptionOperators::PendingFinallyExceptionStack pendingFinallyExceptionStack (scriptContext, exception);
215
+ void *continuation = amd64_CallWithFakeFrame (finallyAddr, frame, spillSize, argsSize, exception);
216
+ return continuation;
217
+ }
205
218
}
206
219
207
220
scriptContext->GetThreadContext ()->SetHasBailedOutBitPtr (nullptr );
@@ -371,13 +384,15 @@ namespace Js
371
384
JavascriptExceptionOperators::DoThrow (exception, scriptContext);
372
385
}
373
386
374
- scriptContext->GetThreadContext ()->SetPendingFinallyException (exception);
387
+ {
388
+ Js::JavascriptExceptionOperators::PendingFinallyExceptionStack pendingFinallyExceptionStack (scriptContext, exception);
375
389
#if defined(_M_ARM)
376
- void * finallyContinuation = arm_CallEhFrame (finallyAddr, framePtr, localsPtr, argsSize);
390
+ void * finallyContinuation = arm_CallEhFrame (finallyAddr, framePtr, localsPtr, argsSize);
377
391
#elif defined(_M_ARM64)
378
- void * finallyContinuation = arm64_CallEhFrame (finallyAddr, framePtr, localsPtr, argsSize);
392
+ void * finallyContinuation = arm64_CallEhFrame (finallyAddr, framePtr, localsPtr, argsSize);
379
393
#endif
380
- return finallyContinuation;
394
+ return finallyContinuation;
395
+ }
381
396
}
382
397
383
398
scriptContext->GetThreadContext ()->SetHasBailedOutBitPtr (nullptr );
@@ -699,60 +714,68 @@ namespace Js
699
714
JavascriptExceptionOperators::DoThrow (pExceptionObject, scriptContext);
700
715
}
701
716
702
- scriptContext->GetThreadContext ()->SetPendingFinallyException (pExceptionObject);
717
+ {
718
+ Js::JavascriptExceptionOperators::PendingFinallyExceptionStack pendingFinallyExceptionStack (scriptContext, pExceptionObject);
703
719
704
- void * newContinuationAddr = NULL ;
720
+ if (!tryAddr)
721
+ {
722
+ // Bug in compiler optimizer: dtor is not called, it is a compiler bug
723
+ // The compiler thinks the asm cannot throw, so add an explicit throw to generate dtor calls
724
+ Js::Throw::InternalError ();
725
+ }
726
+ void * newContinuationAddr = NULL ;
705
727
#ifdef _M_IX86
706
- void *savedEsp;
728
+ void *savedEsp;
707
729
708
- __asm
709
- {
710
- // Save and restore the callee-saved registers around the call.
711
- // TODO: track register kills by region and generate per-region prologs and epilogs
712
- push esi
713
- push edi
714
- push ebx
730
+ __asm
731
+ {
732
+ // Save and restore the callee-saved registers around the call.
733
+ // TODO: track register kills by region and generate per-region prologs and epilogs
734
+ push esi
735
+ push edi
736
+ push ebx
715
737
716
- // 8-byte align frame to improve floating point perf of our JIT'd code.
717
- // Save ESP
718
- mov ecx, esp
719
- mov savedEsp, ecx
720
- and esp, -8
738
+ // 8-byte align frame to improve floating point perf of our JIT'd code.
739
+ // Save ESP
740
+ mov ecx, esp
741
+ mov savedEsp, ecx
742
+ and esp, -8
721
743
722
- // Set up the call target
723
- mov eax, handlerAddr
744
+ // Set up the call target
745
+ mov eax, handlerAddr
724
746
725
747
#if 0 && defined(_CONTROL_FLOW_GUARD)
726
- // verify that the call target is valid
727
- mov ebx, eax; save call target
728
- mov ecx, eax
729
- call[__guard_check_icall_fptr]
730
- mov eax, ebx; restore call target
748
+ // verify that the call target is valid
749
+ mov ebx, eax; save call target
750
+ mov ecx, eax
751
+ call[__guard_check_icall_fptr]
752
+ mov eax, ebx; restore call target
731
753
#endif
732
754
733
- // save the current frame ptr, and adjust the frame to access
734
- // locals in native code.
735
- push ebp
736
- mov ebp, framePtr
737
- call eax
738
- pop ebp
755
+ // save the current frame ptr, and adjust the frame to access
756
+ // locals in native code.
757
+ push ebp
758
+ mov ebp, framePtr
759
+ call eax
760
+ pop ebp
739
761
740
- // The native code gives us the address where execution should continue on exit
741
- // from the finally, but only if flow leaves the finally before it completes.
742
- mov newContinuationAddr, eax
762
+ // The native code gives us the address where execution should continue on exit
763
+ // from the finally, but only if flow leaves the finally before it completes.
764
+ mov newContinuationAddr, eax
743
765
744
- // Restore ESP
745
- mov ecx, savedEsp
746
- mov esp, ecx
766
+ // Restore ESP
767
+ mov ecx, savedEsp
768
+ mov esp, ecx
747
769
748
- pop ebx
749
- pop edi
750
- pop esi
751
- }
770
+ pop ebx
771
+ pop edi
772
+ pop esi
773
+ }
752
774
#else
753
- AssertMsg (FALSE , " Unsupported native try-finally handler" );
775
+ AssertMsg (FALSE , " Unsupported native try-finally handler" );
754
776
#endif
755
- return newContinuationAddr;
777
+ return newContinuationAddr;
778
+ }
756
779
}
757
780
758
781
scriptContext->GetThreadContext ()->SetHasBailedOutBitPtr (nullptr );
0 commit comments