|
|
@@ -1709,10 +1709,14 @@ namespace Js
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+#if !defined(_M_ARM64)
|
|
|
Var InterpreterStackFrame::StaticInterpreterThunk(RecyclableObject* function, CallInfo callInfo, ...)
|
|
|
{
|
|
|
return InterpreterThunk((JavascriptCallStackLayout*)&function);
|
|
|
}
|
|
|
+#else
|
|
|
+ // Language\arm64\arm64_Thunks.asm
|
|
|
+#endif
|
|
|
#pragma optimize("", on)
|
|
|
|
|
|
Var InterpreterStackFrame::InterpreterThunk(JavascriptCallStackLayout* layout)
|
|
|
@@ -1965,7 +1969,7 @@ namespace Js
|
|
|
TTD::TTDExceptionFramePopper exceptionFramePopper;
|
|
|
if(SHOULD_DO_TTD_STACK_STMT_OP(functionScriptContext))
|
|
|
{
|
|
|
- bool isInFinally = ((newInstance->m_flags & Js::InterpreterStackFrameFlags_WithinFinallyBlock) == Js::InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
+ bool isInFinally = newInstance->TestFlags(Js::InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
|
|
|
threadContext->TTDExecutionInfo->PushCallEvent(function, args.Info.Count, args.Values, isInFinally);
|
|
|
exceptionFramePopper.PushInfo(threadContext->TTDExecutionInfo, function);
|
|
|
@@ -2868,7 +2872,6 @@ namespace Js
|
|
|
#else
|
|
|
InterpreterStackFrame * newInstance = newInstance = setup.InitializeAllocation(allocation, funcObj->GetFunctionBody()->GetHasImplicitArgIns(), doProfile, nullptr, stackAddr);
|
|
|
#endif
|
|
|
-
|
|
|
newInstance->m_reader.Create(funcObj->GetFunctionBody());
|
|
|
// now that we have set up the new frame, let's interpret it!
|
|
|
funcObj->GetFunctionBody()->BeginExecution();
|
|
|
@@ -3285,11 +3288,11 @@ namespace Js
|
|
|
} autoRestore(this);
|
|
|
#endif
|
|
|
|
|
|
- if (this->ehBailoutData && !(m_flags & InterpreterStackFrameFlags_FromInlineeCodeInEHBailOut))
|
|
|
+ if (this->ehBailoutData && !this->TestFlags(InterpreterStackFrameFlags_FromBailOutInInlinee))
|
|
|
{
|
|
|
- if ((m_flags & Js::InterpreterStackFrameFlags_FromBailOut) && !(m_flags & InterpreterStackFrameFlags_ProcessingBailOutFromEHCode))
|
|
|
+ if (this->TestFlags(Js::InterpreterStackFrameFlags_FromBailOut) && !this->TestFlags(InterpreterStackFrameFlags_ProcessingBailOutFromEHCode))
|
|
|
{
|
|
|
- m_flags |= Js::InterpreterStackFrameFlags_ProcessingBailOutFromEHCode;
|
|
|
+ this->OrFlags(Js::InterpreterStackFrameFlags_ProcessingBailOutFromEHCode);
|
|
|
EHBailoutData * topLevelEHBailoutData = this->ehBailoutData;
|
|
|
while (topLevelEHBailoutData->parent->nestingDepth != -1)
|
|
|
{
|
|
|
@@ -3297,7 +3300,7 @@ namespace Js
|
|
|
topLevelEHBailoutData = topLevelEHBailoutData->parent;
|
|
|
}
|
|
|
ProcessTryHandlerBailout(topLevelEHBailoutData, this->ehBailoutData->nestingDepth);
|
|
|
- m_flags &= ~Js::InterpreterStackFrameFlags_ProcessingBailOutFromEHCode;
|
|
|
+ this->ClearFlags(Js::InterpreterStackFrameFlags_ProcessingBailOutFromEHCode);
|
|
|
this->ehBailoutData = nullptr;
|
|
|
}
|
|
|
}
|
|
|
@@ -3364,7 +3367,7 @@ namespace Js
|
|
|
#if ENABLE_PROFILE_INFO
|
|
|
FunctionBody *const functionBody = GetFunctionBody();
|
|
|
const ExecutionMode interpreterExecutionMode =
|
|
|
- functionBody->GetInterpreterExecutionMode(!!(GetFlags() & InterpreterStackFrameFlags_FromBailOut));
|
|
|
+ functionBody->GetInterpreterExecutionMode(TestFlags(InterpreterStackFrameFlags_FromBailOut));
|
|
|
if(interpreterExecutionMode == ExecutionMode::ProfilingInterpreter)
|
|
|
{
|
|
|
#if ENABLE_TTD
|
|
|
@@ -5021,9 +5024,9 @@ namespace Js
|
|
|
GetReg(playout->Element),
|
|
|
m_functionBody,
|
|
|
playout->profileId,
|
|
|
- (m_flags & InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall) != 0));
|
|
|
+ this->TestFlags(InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall)));
|
|
|
|
|
|
- m_flags &= ~InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall);
|
|
|
|
|
|
threadContext->CheckAndResetImplicitCallAccessorFlag();
|
|
|
threadContext->AddImplicitCallFlags(savedImplicitCallFlags);
|
|
|
@@ -5058,7 +5061,7 @@ namespace Js
|
|
|
element = JavascriptOperators::OP_GetElementI(instance, GetReg(playout->Element), GetScriptContext());
|
|
|
}
|
|
|
|
|
|
- m_flags &= ~InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall);
|
|
|
|
|
|
threadContext->CheckAndResetImplicitCallAccessorFlag();
|
|
|
threadContext->AddImplicitCallFlags(savedImplicitCallFlags);
|
|
|
@@ -5098,7 +5101,7 @@ namespace Js
|
|
|
JavascriptOperators::OP_SetElementI(instance, varIndex, value, GetScriptContext(), flags);
|
|
|
}
|
|
|
|
|
|
- m_flags &= ~InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall);
|
|
|
|
|
|
threadContext->CheckAndResetImplicitCallAccessorFlag();
|
|
|
threadContext->AddImplicitCallFlags(savedImplicitCallFlags);
|
|
|
@@ -5121,9 +5124,9 @@ namespace Js
|
|
|
m_functionBody,
|
|
|
playout->profileId,
|
|
|
flags,
|
|
|
- (m_flags & InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall) != 0);
|
|
|
+ this->TestFlags(InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall));
|
|
|
|
|
|
- m_flags &= ~InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall);
|
|
|
|
|
|
threadContext->CheckAndResetImplicitCallAccessorFlag();
|
|
|
threadContext->AddImplicitCallFlags(savedImplicitCallFlags);
|
|
|
@@ -5861,7 +5864,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
Assert(!this->IsInCatchOrFinallyBlock());
|
|
|
|
|
|
Js::LoopHeader *loopHeader = fn->GetLoopHeader(loopNumber);
|
|
|
- loopHeader->isInTry = (this->m_flags & Js::InterpreterStackFrameFlags_WithinTryBlock);
|
|
|
+ loopHeader->isInTry = this->TestFlags(Js::InterpreterStackFrameFlags_WithinTryBlock);
|
|
|
|
|
|
Js::LoopEntryPointInfo * entryPointInfo = loopHeader->GetCurrentEntryPointInfo();
|
|
|
|
|
|
@@ -6454,7 +6457,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
|
|
|
void InterpreterStackFrame::OP_ChkNewCallFlag()
|
|
|
{
|
|
|
- if (!(this->m_callFlags & CallFlags_New))
|
|
|
+ if (!(this->m_callFlags & CallFlags_New) && !this->TestFlags(InterpreterStackFrameFlags_FromBailOutInInlinee))
|
|
|
{
|
|
|
JavascriptError::ThrowTypeError(scriptContext, JSERR_ClassConstructorCannotBeCalledWithoutNew);
|
|
|
}
|
|
|
@@ -6495,7 +6498,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
{
|
|
|
this->nestedTryDepth++;
|
|
|
// mark the stackFrame as 'in try block'
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinTryBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinTryBlock);
|
|
|
|
|
|
Js::JavascriptExceptionOperators::AutoCatchHandlerExists autoCatchHandlerExists(scriptContext);
|
|
|
|
|
|
@@ -6534,7 +6537,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
if (--this->nestedTryDepth == -1)
|
|
|
{
|
|
|
// unmark the stackFrame as 'in try block'
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinTryBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinTryBlock);
|
|
|
}
|
|
|
|
|
|
// Now that the stack is unwound, let's run the catch block.
|
|
|
@@ -6573,14 +6576,14 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
|
|
|
this->nestedCatchDepth++;
|
|
|
// mark the stackFrame as 'in catch block'
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinCatchBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinCatchBlock);
|
|
|
|
|
|
this->ProcessCatch();
|
|
|
|
|
|
if (--this->nestedCatchDepth == -1)
|
|
|
{
|
|
|
// unmark the stackFrame as 'in catch block'
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinCatchBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinCatchBlock);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -6637,7 +6640,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
{
|
|
|
this->nestedTryDepth++;
|
|
|
// mark the stackFrame as 'in try block'
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinTryBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinTryBlock);
|
|
|
|
|
|
if (tryNestingDepth != 0)
|
|
|
{
|
|
|
@@ -6685,7 +6688,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
{
|
|
|
this->nestedCatchDepth++;
|
|
|
// mark the stackFrame as 'in catch block'
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinCatchBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinCatchBlock);
|
|
|
|
|
|
if (tryNestingDepth != 0)
|
|
|
{
|
|
|
@@ -6696,7 +6699,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
if (--this->nestedCatchDepth == -1)
|
|
|
{
|
|
|
// unmark the stackFrame as 'in catch block'
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinCatchBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinCatchBlock);
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
@@ -6705,7 +6708,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
Assert(ehBailoutData->ht == HandlerType::HT_Finally);
|
|
|
this->nestedFinallyDepth++;
|
|
|
// mark the stackFrame as 'in finally block'
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinFinallyBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
|
|
|
if (tryNestingDepth != 0)
|
|
|
{
|
|
|
@@ -6720,7 +6723,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
if (--this->nestedFinallyDepth == -1)
|
|
|
{
|
|
|
// unmark the stackFrame as 'in finally block'
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinFinallyBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
}
|
|
|
|
|
|
// Finally exited with LeaveNull, We don't throw for early returns
|
|
|
@@ -6739,7 +6742,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
if (--this->nestedTryDepth == -1)
|
|
|
{
|
|
|
// unmark the stackFrame as 'in try block'
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinTryBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinTryBlock);
|
|
|
}
|
|
|
|
|
|
// Now that the stack is unwound, let's run the catch block.
|
|
|
@@ -6779,14 +6782,14 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
|
|
|
this->nestedCatchDepth++;
|
|
|
// mark the stackFrame as 'in catch block'
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinCatchBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinCatchBlock);
|
|
|
|
|
|
this->ProcessCatch();
|
|
|
|
|
|
if (--this->nestedCatchDepth == -1)
|
|
|
{
|
|
|
// unmark the stackFrame as 'in catch block'
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinCatchBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinCatchBlock);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
@@ -6800,7 +6803,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
|
|
|
this->nestedFinallyDepth++;
|
|
|
// mark the stackFrame as 'in finally block'
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinFinallyBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
|
|
|
LayoutSize layoutSize;
|
|
|
OpCode finallyOp = m_reader.ReadOp(layoutSize);
|
|
|
@@ -6820,7 +6823,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
if (--this->nestedFinallyDepth == -1)
|
|
|
{
|
|
|
// unmark the stackFrame as 'in finally block'
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinFinallyBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
}
|
|
|
if (finallyEndOffset == 0)
|
|
|
{
|
|
|
@@ -6840,7 +6843,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
this->nestedFinallyDepth++;
|
|
|
|
|
|
// mark the stackFrame as 'in finally block'
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinFinallyBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
|
|
|
LayoutSize layoutSize;
|
|
|
OpCode finallyOp = m_reader.ReadOp(layoutSize);
|
|
|
@@ -6860,7 +6863,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
if (--this->nestedFinallyDepth == -1)
|
|
|
{
|
|
|
// unmark the stackFrame as 'in finally block'
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinFinallyBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
}
|
|
|
if (finallyEndOffset == 0)
|
|
|
{
|
|
|
@@ -6872,7 +6875,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
|
|
|
void InterpreterStackFrame::TrySetRetOffset()
|
|
|
{
|
|
|
- Assert(this->m_flags & Js::InterpreterStackFrameFlags_WithinTryBlock);
|
|
|
+ Assert(this->TestFlags(Js::InterpreterStackFrameFlags_WithinTryBlock));
|
|
|
// It may happen that a JITted loop body returned the offset of RET. If the loop body was
|
|
|
// called from a try, the interpreter "Process()" should also just return.
|
|
|
if (this->retOffset != 0)
|
|
|
@@ -6883,8 +6886,8 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
|
|
|
bool InterpreterStackFrame::IsInCatchOrFinallyBlock()
|
|
|
{
|
|
|
- return (this->m_flags & Js::InterpreterStackFrameFlags_WithinCatchBlock) ||
|
|
|
- (this->m_flags & Js::InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
+ return this->TestFlags(Js::InterpreterStackFrameFlags_WithinCatchBlock) ||
|
|
|
+ this->TestFlags(Js::InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
}
|
|
|
|
|
|
void InterpreterStackFrame::OP_BeginBodyScope()
|
|
|
@@ -6911,7 +6914,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
|
|
|
void InterpreterStackFrame::OP_ResumeCatch()
|
|
|
{
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinCatchBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinCatchBlock);
|
|
|
|
|
|
#ifdef ENABLE_SCRIPT_DEBUGGING
|
|
|
if (this->IsInDebugMode())
|
|
|
@@ -6924,7 +6927,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
this->Process();
|
|
|
}
|
|
|
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinCatchBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinCatchBlock);
|
|
|
}
|
|
|
|
|
|
/// ---------------------------------------------------------------------------------------------------
|
|
|
@@ -6945,7 +6948,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
|
|
|
this->nestedTryDepth++;
|
|
|
// mark the stackFrame as 'in try block'
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinTryBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinTryBlock);
|
|
|
|
|
|
if (shouldCacheSP)
|
|
|
{
|
|
|
@@ -6988,7 +6991,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
if (--this->nestedTryDepth == -1)
|
|
|
{
|
|
|
// unmark the stackFrame as 'in try block'
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinTryBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinTryBlock);
|
|
|
}
|
|
|
|
|
|
shouldCacheSP = !skipFinallyBlock;
|
|
|
@@ -7032,7 +7035,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
|
|
|
RestoreSp();
|
|
|
// mark the stackFrame as 'in finally block'
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinFinallyBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
|
|
|
LayoutSize layoutSize;
|
|
|
OpCode finallyOp = m_reader.ReadOp(layoutSize);
|
|
|
@@ -7052,7 +7055,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
if (--this->nestedFinallyDepth == -1)
|
|
|
{
|
|
|
// unmark the stackFrame as 'in finally block'
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinFinallyBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
}
|
|
|
|
|
|
bool endOfFinallyBlock = newOffset == 0;
|
|
|
@@ -7087,7 +7090,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
|
|
|
void InterpreterStackFrame::OP_ResumeFinally(const byte* ip, Js::JumpOffset jumpOffset, RegSlot exceptionRegSlot, RegSlot offsetRegSlot)
|
|
|
{
|
|
|
- this->m_flags |= InterpreterStackFrameFlags_WithinFinallyBlock;
|
|
|
+ this->OrFlags(InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
|
|
|
int newOffset = 0;
|
|
|
#ifdef ENABLE_SCRIPT_DEBUGGING
|
|
|
@@ -7101,7 +7104,7 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
|
|
|
newOffset = ::Math::PointerCastToIntegral<int>(this->Process());
|
|
|
}
|
|
|
|
|
|
- this->m_flags &= ~InterpreterStackFrameFlags_WithinFinallyBlock;
|
|
|
+ this->ClearFlags(InterpreterStackFrameFlags_WithinFinallyBlock);
|
|
|
|
|
|
bool endOfFinallyBlock = newOffset == 0;
|
|
|
if (endOfFinallyBlock)
|