|
@@ -6777,9 +6777,9 @@ void EmitIteratorTopLevelFinally(
|
|
|
Js::RegSlot yieldOffsetLocation,
|
|
Js::RegSlot yieldOffsetLocation,
|
|
|
ByteCodeGenerator* byteCodeGenerator,
|
|
ByteCodeGenerator* byteCodeGenerator,
|
|
|
FuncInfo* funcInfo,
|
|
FuncInfo* funcInfo,
|
|
|
|
|
+ bool hasYield,
|
|
|
bool isAsync)
|
|
bool isAsync)
|
|
|
{
|
|
{
|
|
|
- bool isCoroutine = funcInfo->byteCodeFunction->IsCoroutine();
|
|
|
|
|
|
|
|
|
|
Js::ByteCodeLabel afterFinallyBlockLabel = byteCodeGenerator->Writer()->DefineLabel();
|
|
Js::ByteCodeLabel afterFinallyBlockLabel = byteCodeGenerator->Writer()->DefineLabel();
|
|
|
byteCodeGenerator->Writer()->Empty(Js::OpCode::Leave);
|
|
byteCodeGenerator->Writer()->Empty(Js::OpCode::Leave);
|
|
@@ -6805,8 +6805,9 @@ void EmitIteratorTopLevelFinally(
|
|
|
byteCodeGenerator->Writer()->MarkLabel(skipCallCloseLabel);
|
|
byteCodeGenerator->Writer()->MarkLabel(skipCallCloseLabel);
|
|
|
|
|
|
|
|
byteCodeGenerator->PopJumpCleanup();
|
|
byteCodeGenerator->PopJumpCleanup();
|
|
|
- if (isCoroutine)
|
|
|
|
|
|
|
+ if (hasYield)
|
|
|
{
|
|
{
|
|
|
|
|
+ Assert(funcInfo->byteCodeFunction->IsCoroutine());
|
|
|
funcInfo->ReleaseTmpRegister(yieldOffsetLocation);
|
|
funcInfo->ReleaseTmpRegister(yieldOffsetLocation);
|
|
|
funcInfo->ReleaseTmpRegister(yieldExceptionLocation);
|
|
funcInfo->ReleaseTmpRegister(yieldExceptionLocation);
|
|
|
}
|
|
}
|
|
@@ -6826,6 +6827,7 @@ void EmitIteratorCatchAndFinally(
|
|
|
Js::RegSlot yieldOffsetLocation,
|
|
Js::RegSlot yieldOffsetLocation,
|
|
|
ByteCodeGenerator* byteCodeGenerator,
|
|
ByteCodeGenerator* byteCodeGenerator,
|
|
|
FuncInfo* funcInfo,
|
|
FuncInfo* funcInfo,
|
|
|
|
|
+ bool hasYield,
|
|
|
bool isAsync = false)
|
|
bool isAsync = false)
|
|
|
{
|
|
{
|
|
|
byteCodeGenerator->PopJumpCleanup();
|
|
byteCodeGenerator->PopJumpCleanup();
|
|
@@ -6849,6 +6851,7 @@ void EmitIteratorCatchAndFinally(
|
|
|
yieldOffsetLocation,
|
|
yieldOffsetLocation,
|
|
|
byteCodeGenerator,
|
|
byteCodeGenerator,
|
|
|
funcInfo,
|
|
funcInfo,
|
|
|
|
|
+ hasYield,
|
|
|
isAsync);
|
|
isAsync);
|
|
|
|
|
|
|
|
funcInfo->ReleaseTmpRegister(shouldCallReturnFunctionLocationFinally);
|
|
funcInfo->ReleaseTmpRegister(shouldCallReturnFunctionLocationFinally);
|
|
@@ -6901,10 +6904,11 @@ void EmitDestructuredArray(
|
|
|
|
|
|
|
|
Js::RegSlot regException = Js::Constants::NoRegister;
|
|
Js::RegSlot regException = Js::Constants::NoRegister;
|
|
|
Js::RegSlot regOffset = Js::Constants::NoRegister;
|
|
Js::RegSlot regOffset = Js::Constants::NoRegister;
|
|
|
- bool isCoroutine = funcInfo->byteCodeFunction->IsCoroutine();
|
|
|
|
|
|
|
+ bool hasYield = byteCodeGenerator->GetHasYield(lhs);
|
|
|
|
|
|
|
|
- if (isCoroutine)
|
|
|
|
|
|
|
+ if (hasYield)
|
|
|
{
|
|
{
|
|
|
|
|
+ Assert(funcInfo->byteCodeFunction->IsCoroutine());
|
|
|
regException = funcInfo->AcquireTmpRegister();
|
|
regException = funcInfo->AcquireTmpRegister();
|
|
|
regOffset = funcInfo->AcquireTmpRegister();
|
|
regOffset = funcInfo->AcquireTmpRegister();
|
|
|
}
|
|
}
|
|
@@ -6914,7 +6918,7 @@ void EmitDestructuredArray(
|
|
|
Js::ByteCodeLabel catchLabel = byteCodeGenerator->Writer()->DefineLabel();
|
|
Js::ByteCodeLabel catchLabel = byteCodeGenerator->Writer()->DefineLabel();
|
|
|
byteCodeGenerator->Writer()->RecordCrossFrameEntryExitRecord(true);
|
|
byteCodeGenerator->Writer()->RecordCrossFrameEntryExitRecord(true);
|
|
|
|
|
|
|
|
- if (isCoroutine)
|
|
|
|
|
|
|
+ if (hasYield)
|
|
|
{
|
|
{
|
|
|
byteCodeGenerator->Writer()->BrReg2(Js::OpCode::TryFinallyWithYield, finallyLabel, regException, regOffset);
|
|
byteCodeGenerator->Writer()->BrReg2(Js::OpCode::TryFinallyWithYield, finallyLabel, regException, regOffset);
|
|
|
byteCodeGenerator->PushJumpCleanupForTry(
|
|
byteCodeGenerator->PushJumpCleanupForTry(
|
|
@@ -6950,7 +6954,8 @@ void EmitDestructuredArray(
|
|
|
regException,
|
|
regException,
|
|
|
regOffset,
|
|
regOffset,
|
|
|
byteCodeGenerator,
|
|
byteCodeGenerator,
|
|
|
- funcInfo);
|
|
|
|
|
|
|
+ funcInfo,
|
|
|
|
|
+ hasYield);
|
|
|
|
|
|
|
|
funcInfo->ReleaseTmpRegister(nextMethodReg);
|
|
funcInfo->ReleaseTmpRegister(nextMethodReg);
|
|
|
funcInfo->ReleaseTmpRegister(iteratorLocation);
|
|
funcInfo->ReleaseTmpRegister(iteratorLocation);
|
|
@@ -9836,6 +9841,7 @@ void EmitForInOrForOf(ParseNodeForInOrForOf *loopNode, ByteCodeGenerator *byteCo
|
|
|
{
|
|
{
|
|
|
bool isForIn = (loopNode->nop == knopForIn);
|
|
bool isForIn = (loopNode->nop == knopForIn);
|
|
|
bool isForAwaitOf = (loopNode->nop == knopForAwaitOf);
|
|
bool isForAwaitOf = (loopNode->nop == knopForAwaitOf);
|
|
|
|
|
+ bool hasYield = isForAwaitOf || byteCodeGenerator->GetHasYield(loopNode);
|
|
|
Assert(isForAwaitOf || isForIn || loopNode->nop == knopForOf);
|
|
Assert(isForAwaitOf || isForIn || loopNode->nop == knopForOf);
|
|
|
|
|
|
|
|
BeginEmitBlock(loopNode->pnodeBlock, byteCodeGenerator, funcInfo);
|
|
BeginEmitBlock(loopNode->pnodeBlock, byteCodeGenerator, funcInfo);
|
|
@@ -9899,10 +9905,9 @@ void EmitForInOrForOf(ParseNodeForInOrForOf *loopNode, ByteCodeGenerator *byteCo
|
|
|
Js::RegSlot shouldCallReturnFunctionLocation = loopNode->shouldCallReturnFunctionLocation;
|
|
Js::RegSlot shouldCallReturnFunctionLocation = loopNode->shouldCallReturnFunctionLocation;
|
|
|
Js::RegSlot shouldCallReturnFunctionLocationFinally = loopNode->shouldCallReturnFunctionLocationFinally;
|
|
Js::RegSlot shouldCallReturnFunctionLocationFinally = loopNode->shouldCallReturnFunctionLocationFinally;
|
|
|
|
|
|
|
|
- bool isCoroutine = funcInfo->byteCodeFunction->IsCoroutine();
|
|
|
|
|
-
|
|
|
|
|
- if (isCoroutine)
|
|
|
|
|
|
|
+ if (hasYield)
|
|
|
{
|
|
{
|
|
|
|
|
+ Assert(funcInfo->byteCodeFunction->IsCoroutine());
|
|
|
regException = funcInfo->AcquireTmpRegister();
|
|
regException = funcInfo->AcquireTmpRegister();
|
|
|
regOffset = funcInfo->AcquireTmpRegister();
|
|
regOffset = funcInfo->AcquireTmpRegister();
|
|
|
}
|
|
}
|
|
@@ -9946,7 +9951,7 @@ void EmitForInOrForOf(ParseNodeForInOrForOf *loopNode, ByteCodeGenerator *byteCo
|
|
|
byteCodeGenerator->Writer()->Reg1(Js::OpCode::LdFalse, shouldCallReturnFunctionLocation);
|
|
byteCodeGenerator->Writer()->Reg1(Js::OpCode::LdFalse, shouldCallReturnFunctionLocation);
|
|
|
byteCodeGenerator->Writer()->Reg1(Js::OpCode::LdFalse, shouldCallReturnFunctionLocationFinally);
|
|
byteCodeGenerator->Writer()->Reg1(Js::OpCode::LdFalse, shouldCallReturnFunctionLocationFinally);
|
|
|
|
|
|
|
|
- if (isCoroutine)
|
|
|
|
|
|
|
+ if (hasYield)
|
|
|
{
|
|
{
|
|
|
byteCodeGenerator->Writer()->BrReg2(Js::OpCode::TryFinallyWithYield, finallyLabel, regException, regOffset);
|
|
byteCodeGenerator->Writer()->BrReg2(Js::OpCode::TryFinallyWithYield, finallyLabel, regException, regOffset);
|
|
|
byteCodeGenerator->PushJumpCleanupForTry(
|
|
byteCodeGenerator->PushJumpCleanupForTry(
|
|
@@ -10027,6 +10032,7 @@ void EmitForInOrForOf(ParseNodeForInOrForOf *loopNode, ByteCodeGenerator *byteCo
|
|
|
regOffset,
|
|
regOffset,
|
|
|
byteCodeGenerator,
|
|
byteCodeGenerator,
|
|
|
funcInfo,
|
|
funcInfo,
|
|
|
|
|
+ hasYield,
|
|
|
isForAwaitOf);
|
|
isForAwaitOf);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -12545,11 +12551,11 @@ void Emit(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator, FuncInfo* func
|
|
|
|
|
|
|
|
finallyLabel = byteCodeGenerator->Writer()->DefineLabel();
|
|
finallyLabel = byteCodeGenerator->Writer()->DefineLabel();
|
|
|
byteCodeGenerator->Writer()->RecordCrossFrameEntryExitRecord(true);
|
|
byteCodeGenerator->Writer()->RecordCrossFrameEntryExitRecord(true);
|
|
|
|
|
+ bool hasYield = byteCodeGenerator->GetHasYield(pnodeTryFinally);
|
|
|
|
|
|
|
|
- // [CONSIDER][aneeshd] Ideally the TryFinallyWithYield opcode needs to be used only if there is a yield expression.
|
|
|
|
|
- // For now, if the function is generator we are using the TryFinallyWithYield.
|
|
|
|
|
- if (funcInfo->byteCodeFunction->IsCoroutine())
|
|
|
|
|
|
|
+ if (hasYield)
|
|
|
{
|
|
{
|
|
|
|
|
+ Assert(funcInfo->byteCodeFunction->IsCoroutine());
|
|
|
regException = funcInfo->AcquireTmpRegister();
|
|
regException = funcInfo->AcquireTmpRegister();
|
|
|
regOffset = funcInfo->AcquireTmpRegister();
|
|
regOffset = funcInfo->AcquireTmpRegister();
|
|
|
byteCodeGenerator->Writer()->BrReg2(Js::OpCode::TryFinallyWithYield, finallyLabel, regException, regOffset);
|
|
byteCodeGenerator->Writer()->BrReg2(Js::OpCode::TryFinallyWithYield, finallyLabel, regException, regOffset);
|
|
@@ -12593,7 +12599,7 @@ void Emit(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator, FuncInfo* func
|
|
|
Emit(pnodeFinally->pnodeBody, byteCodeGenerator, funcInfo, fReturnValue);
|
|
Emit(pnodeFinally->pnodeBody, byteCodeGenerator, funcInfo, fReturnValue);
|
|
|
funcInfo->ReleaseLoc(pnodeFinally->pnodeBody);
|
|
funcInfo->ReleaseLoc(pnodeFinally->pnodeBody);
|
|
|
|
|
|
|
|
- if (funcInfo->byteCodeFunction->IsCoroutine())
|
|
|
|
|
|
|
+ if (hasYield)
|
|
|
{
|
|
{
|
|
|
funcInfo->ReleaseTmpRegister(regOffset);
|
|
funcInfo->ReleaseTmpRegister(regOffset);
|
|
|
funcInfo->ReleaseTmpRegister(regException);
|
|
funcInfo->ReleaseTmpRegister(regException);
|