|
|
@@ -190,19 +190,23 @@ namespace Js
|
|
|
{
|
|
|
void *tryContinuation = nullptr;
|
|
|
JavascriptExceptionObject *exception = nullptr;
|
|
|
+ void *tryHandlerAddrOfReturnAddr = nullptr;
|
|
|
|
|
|
Js::JavascriptExceptionOperators::HasBailedOutPtrStack hasBailedOutPtrStack(scriptContext, (bool*)((char*)frame + hasBailedOutOffset));
|
|
|
PROBE_STACK(scriptContext, Constants::MinStackJitEHBailout + spillSize + argsSize);
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
- tryContinuation = amd64_CallWithFakeFrame(tryAddr, frame, spillSize, argsSize);
|
|
|
- }
|
|
|
- catch (const Js::JavascriptException& err)
|
|
|
{
|
|
|
- exception = err.GetAndClear();
|
|
|
+ void * addrOfReturnAddr = (void*)((char*)frame + sizeof(char*));
|
|
|
+ Js::JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack tryHandlerAddrOfReturnAddrStack(scriptContext, addrOfReturnAddr);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ tryContinuation = amd64_CallWithFakeFrame(tryAddr, frame, spillSize, argsSize);
|
|
|
+ }
|
|
|
+ catch (const Js::JavascriptException& err)
|
|
|
+ {
|
|
|
+ exception = err.GetAndClear();
|
|
|
+ tryHandlerAddrOfReturnAddr = scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr();
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
if (exception)
|
|
|
{
|
|
|
// Clone static exception object early in case finally block overwrites it
|
|
|
@@ -212,19 +216,9 @@ namespace Js
|
|
|
if (exception)
|
|
|
{
|
|
|
#if ENABLE_NATIVE_CODEGEN
|
|
|
- if (scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr() != nullptr)
|
|
|
- {
|
|
|
- if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
|
|
|
- {
|
|
|
- WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr());
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
+ if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
|
|
|
{
|
|
|
- if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
|
|
|
- {
|
|
|
- WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, frame);
|
|
|
- }
|
|
|
+ WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryHandlerAddrOfReturnAddr);
|
|
|
}
|
|
|
#endif
|
|
|
bool hasBailedOut = *(bool*)((char*)frame + hasBailedOutOffset); // stack offsets are negative
|
|
|
@@ -251,21 +245,31 @@ namespace Js
|
|
|
void *tryContinuation = nullptr;
|
|
|
void *finallyContinuation = nullptr;
|
|
|
JavascriptExceptionObject *exception = nullptr;
|
|
|
+ void *tryHandlerAddrOfReturnAddr = nullptr;
|
|
|
|
|
|
PROBE_STACK(scriptContext, Constants::MinStackJitEHBailout + spillSize + argsSize);
|
|
|
- try
|
|
|
- {
|
|
|
- tryContinuation = amd64_CallWithFakeFrame(tryAddr, frame, spillSize, argsSize);
|
|
|
- }
|
|
|
- catch (const Js::JavascriptException& err)
|
|
|
{
|
|
|
- exception = err.GetAndClear();
|
|
|
+ void * addrOfReturnAddr = (void*)((char*)frame + sizeof(char*));
|
|
|
+ Js::JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack tryHandlerAddrOfReturnAddrStack(scriptContext, addrOfReturnAddr);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ tryContinuation = amd64_CallWithFakeFrame(tryAddr, frame, spillSize, argsSize);
|
|
|
+ }
|
|
|
+ catch (const Js::JavascriptException& err)
|
|
|
+ {
|
|
|
+ exception = err.GetAndClear();
|
|
|
+ tryHandlerAddrOfReturnAddr = scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr();
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
if (exception)
|
|
|
{
|
|
|
// Clone static exception object early in case finally block overwrites it
|
|
|
exception = exception->CloneIfStaticExceptionObject(scriptContext);
|
|
|
+
|
|
|
+ if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
|
|
|
+ {
|
|
|
+ WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryHandlerAddrOfReturnAddr);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
finallyContinuation = amd64_CallWithFakeFrame(finallyAddr, frame, spillSize, argsSize);
|
|
|
@@ -276,6 +280,10 @@ namespace Js
|
|
|
|
|
|
if (exception)
|
|
|
{
|
|
|
+ if (scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr() != nullptr)
|
|
|
+ {
|
|
|
+ WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr, scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr());
|
|
|
+ }
|
|
|
JavascriptExceptionOperators::DoThrow(exception, scriptContext);
|
|
|
}
|
|
|
|
|
|
@@ -365,44 +373,40 @@ namespace Js
|
|
|
int hasBailedOutOffset,
|
|
|
ScriptContext *scriptContext)
|
|
|
{
|
|
|
- void *tryContinuation = nullptr;
|
|
|
- JavascriptExceptionObject *exception = nullptr;
|
|
|
+ void *tryContinuation = nullptr;
|
|
|
+ JavascriptExceptionObject *exception = nullptr;
|
|
|
+ void *tryHandlerAddrOfReturnAddr = nullptr;
|
|
|
+
|
|
|
Js::JavascriptExceptionOperators::HasBailedOutPtrStack hasBailedOutPtrStack(scriptContext, (bool*)((char*)localsPtr + hasBailedOutOffset));
|
|
|
|
|
|
PROBE_STACK(scriptContext, Constants::MinStackJitEHBailout + argsSize);
|
|
|
- try
|
|
|
{
|
|
|
+ void * addrOfReturnAddr = (void*)((char*)framePtr + sizeof(char*));
|
|
|
+ Js::JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack tryHandlerAddrOfReturnAddrStack(scriptContext, addrOfReturnAddr);
|
|
|
+ try
|
|
|
+ {
|
|
|
#if defined(_M_ARM)
|
|
|
tryContinuation = arm_CallEhFrame(tryAddr, framePtr, localsPtr, argsSize);
|
|
|
#elif defined(_M_ARM64)
|
|
|
tryContinuation = arm64_CallEhFrame(tryAddr, framePtr, localsPtr, argsSize);
|
|
|
#endif
|
|
|
- }
|
|
|
- catch (const Js::JavascriptException& err)
|
|
|
- {
|
|
|
- exception = err.GetAndClear();
|
|
|
- }
|
|
|
-
|
|
|
- if (exception)
|
|
|
- {
|
|
|
-#if ENABLE_NATIVE_CODEGEN
|
|
|
- if (scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr() != nullptr)
|
|
|
- {
|
|
|
- if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
|
|
|
- {
|
|
|
- WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr());
|
|
|
- }
|
|
|
}
|
|
|
- else
|
|
|
+ catch (const Js::JavascriptException& err)
|
|
|
{
|
|
|
- if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
|
|
|
- {
|
|
|
- WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, framePtr);
|
|
|
- }
|
|
|
+ exception = err.GetAndClear();
|
|
|
+ tryHandlerAddrOfReturnAddr = scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr();
|
|
|
}
|
|
|
-#endif
|
|
|
+ }
|
|
|
+ if (exception)
|
|
|
+ {
|
|
|
// Clone static exception object early in case finally block overwrites it
|
|
|
exception = exception->CloneIfStaticExceptionObject(scriptContext);
|
|
|
+
|
|
|
+ if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
|
|
|
+ {
|
|
|
+ WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryHandlerAddrOfReturnAddr);
|
|
|
+ }
|
|
|
+
|
|
|
bool hasBailedOut = *(bool*)((char*)localsPtr + hasBailedOutOffset); // stack offsets are sp relative
|
|
|
if (hasBailedOut)
|
|
|
{
|
|
|
@@ -437,26 +441,36 @@ namespace Js
|
|
|
void *tryContinuation = nullptr;
|
|
|
void *finallyContinuation = nullptr;
|
|
|
JavascriptExceptionObject *exception = nullptr;
|
|
|
+ void *tryHandlerAddrOfReturnAddr = nullptr;
|
|
|
|
|
|
PROBE_STACK(scriptContext, Constants::MinStackJitEHBailout + argsSize);
|
|
|
-
|
|
|
- try
|
|
|
{
|
|
|
+ void * addrOfReturnAddr = (void*)((char*)framePtr + sizeof(char*));
|
|
|
+ Js::JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack tryHandlerAddrOfReturnAddrStack(scriptContext, addrOfReturnAddr);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
#if defined(_M_ARM)
|
|
|
- tryContinuation = arm_CallEhFrame(tryAddr, framePtr, localsPtr, argsSize);
|
|
|
+ tryContinuation = arm_CallEhFrame(tryAddr, framePtr, localsPtr, argsSize);
|
|
|
#elif defined(_M_ARM64)
|
|
|
- tryContinuation = arm64_CallEhFrame(tryAddr, framePtr, localsPtr, argsSize);
|
|
|
+ tryContinuation = arm64_CallEhFrame(tryAddr, framePtr, localsPtr, argsSize);
|
|
|
#endif
|
|
|
+ }
|
|
|
+ catch (const Js::JavascriptException& err)
|
|
|
+ {
|
|
|
+ exception = err.GetAndClear();
|
|
|
+ tryHandlerAddrOfReturnAddr = scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr();
|
|
|
+ }
|
|
|
}
|
|
|
- catch (const Js::JavascriptException& err)
|
|
|
- {
|
|
|
- exception = err.GetAndClear();
|
|
|
- }
|
|
|
-
|
|
|
if (exception)
|
|
|
{
|
|
|
// Clone static exception object early in case finally block overwrites it
|
|
|
exception = exception->CloneIfStaticExceptionObject(scriptContext);
|
|
|
+
|
|
|
+ if (exception->GetExceptionContext() && exception->GetExceptionContext()->ThrowingFunction())
|
|
|
+ {
|
|
|
+ WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryHandlerAddrOfReturnAddr);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#if defined(_M_ARM)
|
|
|
@@ -472,6 +486,10 @@ namespace Js
|
|
|
|
|
|
if (exception)
|
|
|
{
|
|
|
+ if (scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr() != nullptr)
|
|
|
+ {
|
|
|
+ WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr, scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr());
|
|
|
+ }
|
|
|
JavascriptExceptionOperators::DoThrow(exception, scriptContext);
|
|
|
}
|
|
|
|
|
|
@@ -647,21 +665,24 @@ namespace Js
|
|
|
{
|
|
|
Js::JavascriptExceptionObject* pExceptionObject = NULL;
|
|
|
void* continuationAddr = NULL;
|
|
|
+ void* tryHandlerAddrOfReturnAddr = nullptr;
|
|
|
|
|
|
Js::JavascriptExceptionOperators::HasBailedOutPtrStack hasBailedOutPtrStack(scriptContext, (bool*)((char*)framePtr + hasBailedOutOffset));
|
|
|
PROBE_STACK(scriptContext, Constants::MinStackJitEHBailout);
|
|
|
-
|
|
|
- try
|
|
|
{
|
|
|
- // Bug in compiler optimizer: try-catch can be optimized away if the try block contains __asm calls into function
|
|
|
- // that may throw. The current workaround is to add the following dummy throw to prevent this optimization.
|
|
|
- // It seems like compiler got smart and still optimizes if the exception is not JavascriptExceptionObject (see catch handler below).
|
|
|
- // In order to circumvent that we are throwing OutOfMemory.
|
|
|
- if (!tryAddr)
|
|
|
+ void * addrOfReturnAddr = (void*)((char*)framePtr + sizeof(char*));
|
|
|
+ Js::JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack tryHandlerAddrOfReturnAddrStack(scriptContext, addrOfReturnAddr);
|
|
|
+ try
|
|
|
{
|
|
|
- Assert(false);
|
|
|
- ThrowOutOfMemory(scriptContext);
|
|
|
- }
|
|
|
+ // Bug in compiler optimizer: try-catch can be optimized away if the try block contains __asm calls into function
|
|
|
+ // that may throw. The current workaround is to add the following dummy throw to prevent this optimization.
|
|
|
+ // It seems like compiler got smart and still optimizes if the exception is not JavascriptExceptionObject (see catch handler below).
|
|
|
+ // In order to circumvent that we are throwing OutOfMemory.
|
|
|
+ if (!tryAddr)
|
|
|
+ {
|
|
|
+ Assert(false);
|
|
|
+ ThrowOutOfMemory(scriptContext);
|
|
|
+ }
|
|
|
|
|
|
#ifdef _M_IX86
|
|
|
void *savedEsp;
|
|
|
@@ -711,28 +732,19 @@ namespace Js
|
|
|
#else
|
|
|
AssertMsg(FALSE, "Unsupported native try-finally handler");
|
|
|
#endif
|
|
|
+ }
|
|
|
+ catch (const Js::JavascriptException& err)
|
|
|
+ {
|
|
|
+ pExceptionObject = err.GetAndClear();
|
|
|
+ tryHandlerAddrOfReturnAddr = scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr();
|
|
|
+ }
|
|
|
}
|
|
|
- catch(const Js::JavascriptException& err)
|
|
|
- {
|
|
|
- pExceptionObject = err.GetAndClear();
|
|
|
- }
|
|
|
-
|
|
|
if (pExceptionObject)
|
|
|
{
|
|
|
#if ENABLE_NATIVE_CODEGEN
|
|
|
- if (scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr() != nullptr)
|
|
|
- {
|
|
|
- if (pExceptionObject->GetExceptionContext() && pExceptionObject->GetExceptionContext()->ThrowingFunction())
|
|
|
- {
|
|
|
- WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr());
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
+ if (pExceptionObject->GetExceptionContext() && pExceptionObject->GetExceptionContext()->ThrowingFunction())
|
|
|
{
|
|
|
- if (pExceptionObject->GetExceptionContext() && pExceptionObject->GetExceptionContext()->ThrowingFunction())
|
|
|
- {
|
|
|
- WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, framePtr);
|
|
|
- }
|
|
|
+ WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryHandlerAddrOfReturnAddr);
|
|
|
}
|
|
|
#endif
|
|
|
// Clone static exception object early in case finally block overwrites it
|
|
|
@@ -817,79 +829,91 @@ namespace Js
|
|
|
{
|
|
|
Js::JavascriptExceptionObject* pExceptionObject = NULL;
|
|
|
void* continuationAddr = NULL;
|
|
|
+ void * tryHandlerAddrOfReturnAddr = nullptr;
|
|
|
|
|
|
PROBE_STACK(scriptContext, Constants::MinStackJitEHBailout);
|
|
|
-
|
|
|
- try
|
|
|
{
|
|
|
- // Bug in compiler optimizer: try-catch can be optimized away if the try block contains __asm calls into function
|
|
|
- // that may throw. The current workaround is to add the following dummy throw to prevent this optimization.
|
|
|
- // It seems like compiler got smart and still optimizes if the exception is not JavascriptExceptionObject (see catch handler below).
|
|
|
- // In order to circumvent that we are throwing OutOfMemory.
|
|
|
- if (!tryAddr)
|
|
|
+ void * addrOfReturnAddr = (void*)((char*)framePtr + sizeof(char*));
|
|
|
+ Js::JavascriptExceptionOperators::TryHandlerAddrOfReturnAddrStack tryHandlerAddrOfReturnAddrStack(scriptContext, addrOfReturnAddr);
|
|
|
+
|
|
|
+ try
|
|
|
{
|
|
|
- Assert(false);
|
|
|
- ThrowOutOfMemory(scriptContext);
|
|
|
- }
|
|
|
+ // Bug in compiler optimizer: try-catch can be optimized away if the try block contains __asm calls into function
|
|
|
+ // that may throw. The current workaround is to add the following dummy throw to prevent this optimization.
|
|
|
+ // It seems like compiler got smart and still optimizes if the exception is not JavascriptExceptionObject (see catch handler below).
|
|
|
+ // In order to circumvent that we are throwing OutOfMemory.
|
|
|
+ if (!tryAddr)
|
|
|
+ {
|
|
|
+ Assert(false);
|
|
|
+ ThrowOutOfMemory(scriptContext);
|
|
|
+ }
|
|
|
|
|
|
#ifdef _M_IX86
|
|
|
- void *savedEsp;
|
|
|
- __asm
|
|
|
- {
|
|
|
- // Save and restore the callee-saved registers around the call.
|
|
|
- // TODO: track register kills by region and generate per-region prologs and epilogs
|
|
|
- push esi
|
|
|
- push edi
|
|
|
- push ebx
|
|
|
+ void *savedEsp;
|
|
|
+ __asm
|
|
|
+ {
|
|
|
+ // Save and restore the callee-saved registers around the call.
|
|
|
+ // TODO: track register kills by region and generate per-region prologs and epilogs
|
|
|
+ push esi
|
|
|
+ push edi
|
|
|
+ push ebx
|
|
|
|
|
|
- // 8-byte align frame to improve floating point perf of our JIT'd code.
|
|
|
- // Save ESP
|
|
|
- mov ecx, esp
|
|
|
- mov savedEsp, ecx
|
|
|
- and esp, -8
|
|
|
+ // 8-byte align frame to improve floating point perf of our JIT'd code.
|
|
|
+ // Save ESP
|
|
|
+ mov ecx, esp
|
|
|
+ mov savedEsp, ecx
|
|
|
+ and esp, -8
|
|
|
|
|
|
- // Set up the call target, save the current frame ptr, and adjust the frame to access
|
|
|
- // locals in native code.
|
|
|
- mov eax, tryAddr
|
|
|
+ // Set up the call target, save the current frame ptr, and adjust the frame to access
|
|
|
+ // locals in native code.
|
|
|
+ mov eax, tryAddr
|
|
|
|
|
|
#if 0 && defined(_CONTROL_FLOW_GUARD)
|
|
|
- // verify that the call target is valid
|
|
|
- mov ebx, eax; save call target
|
|
|
- mov ecx, eax
|
|
|
- call[__guard_check_icall_fptr]
|
|
|
- mov eax, ebx; restore call target
|
|
|
+ // verify that the call target is valid
|
|
|
+ mov ebx, eax; save call target
|
|
|
+ mov ecx, eax
|
|
|
+ call[__guard_check_icall_fptr]
|
|
|
+ mov eax, ebx; restore call target
|
|
|
#endif
|
|
|
|
|
|
- push ebp
|
|
|
- mov ebp, framePtr
|
|
|
- call eax
|
|
|
- pop ebp
|
|
|
+ push ebp
|
|
|
+ mov ebp, framePtr
|
|
|
+ call eax
|
|
|
+ pop ebp
|
|
|
|
|
|
- // The native code gives us the address where execution should continue on exit
|
|
|
- // from the region.
|
|
|
- mov continuationAddr, eax
|
|
|
+ // The native code gives us the address where execution should continue on exit
|
|
|
+ // from the region.
|
|
|
+ mov continuationAddr, eax
|
|
|
|
|
|
- // Restore ESP
|
|
|
- mov ecx, savedEsp
|
|
|
- mov esp, ecx
|
|
|
+ // Restore ESP
|
|
|
+ mov ecx, savedEsp
|
|
|
+ mov esp, ecx
|
|
|
|
|
|
- pop ebx
|
|
|
- pop edi
|
|
|
- pop esi
|
|
|
- }
|
|
|
+ pop ebx
|
|
|
+ pop edi
|
|
|
+ pop esi
|
|
|
+ }
|
|
|
#else
|
|
|
- AssertMsg(FALSE, "Unsupported native try-finally handler");
|
|
|
+ AssertMsg(FALSE, "Unsupported native try-finally handler");
|
|
|
#endif
|
|
|
+ }
|
|
|
+ catch (const Js::JavascriptException& err)
|
|
|
+ {
|
|
|
+ pExceptionObject = err.GetAndClear();
|
|
|
+ tryHandlerAddrOfReturnAddr = scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr();
|
|
|
+ }
|
|
|
}
|
|
|
- catch (const Js::JavascriptException& err)
|
|
|
- {
|
|
|
- pExceptionObject = err.GetAndClear();
|
|
|
- }
|
|
|
-
|
|
|
if (pExceptionObject)
|
|
|
{
|
|
|
// Clone static exception object early in case finally block overwrites it
|
|
|
pExceptionObject = pExceptionObject->CloneIfStaticExceptionObject(scriptContext);
|
|
|
+
|
|
|
+#if ENABLE_NATIVE_CODEGEN
|
|
|
+ if (pExceptionObject->GetExceptionContext() && pExceptionObject->GetExceptionContext()->ThrowingFunction())
|
|
|
+ {
|
|
|
+ WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr /* start stackwalk from the current frame */, tryHandlerAddrOfReturnAddr);
|
|
|
+ }
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
void* newContinuationAddr = NULL;
|
|
|
@@ -952,6 +976,10 @@ namespace Js
|
|
|
|
|
|
if (pExceptionObject)
|
|
|
{
|
|
|
+ if (scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr() != nullptr)
|
|
|
+ {
|
|
|
+ WalkStackForCleaningUpInlineeInfo(scriptContext, nullptr, scriptContext->GetThreadContext()->GetTryHandlerAddrOfReturnAddr());
|
|
|
+ }
|
|
|
JavascriptExceptionOperators::DoThrow(pExceptionObject, scriptContext);
|
|
|
}
|
|
|
|