Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (210006 => 210007)
--- trunk/Source/_javascript_Core/ChangeLog 2016-12-20 01:18:57 UTC (rev 210006)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-12-20 01:48:52 UTC (rev 210007)
@@ -1,3 +1,49 @@
+2016-12-19 Mark Lam <mark....@apple.com>
+
+ Rolling out r209974 and r209952. They break some websites in mysterious ways. Step 1: Rollout r209974.
+ https://bugs.webkit.org/show_bug.cgi?id=166049
+
+ Not reviewed.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitEnumeration):
+ (JSC::BytecodeGenerator::emitJumpViaFinallyIfNeeded):
+ (JSC::BytecodeGenerator::emitReturnViaFinallyIfNeeded):
+ (JSC::BytecodeGenerator::emitFinallyCompletion):
+ (JSC::BytecodeGenerator::allocateFinallyRegisters):
+ (JSC::BytecodeGenerator::releaseFinallyRegisters):
+ (JSC::BytecodeGenerator::emitCompareFinallyActionAndJumpIf):
+ (JSC::BytecodeGenerator::allocateCompletionRecordRegisters): Deleted.
+ (JSC::BytecodeGenerator::releaseCompletionRecordRegisters): Deleted.
+ (JSC::BytecodeGenerator::emitJumpIfCompletionType): Deleted.
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::FinallyJump::FinallyJump):
+ (JSC::FinallyContext::registerJump):
+ (JSC::BytecodeGenerator::FinallyRegistersScope::FinallyRegistersScope):
+ (JSC::BytecodeGenerator::FinallyRegistersScope::~FinallyRegistersScope):
+ (JSC::BytecodeGenerator::finallyActionRegister):
+ (JSC::BytecodeGenerator::finallyReturnValueRegister):
+ (JSC::BytecodeGenerator::emitSetFinallyActionToNormalCompletion):
+ (JSC::BytecodeGenerator::emitSetFinallyActionToReturnCompletion):
+ (JSC::BytecodeGenerator::emitSetFinallyActionToJumpID):
+ (JSC::BytecodeGenerator::emitSetFinallyReturnValueRegister):
+ (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNormalCompletion):
+ (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotJump):
+ (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsReturnCompletion):
+ (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotReturnCompletion):
+ (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotThrowCompletion):
+ (JSC::BytecodeGenerator::emitJumpIfCompletionTypeIsThrow):
+ (JSC::BytecodeGenerator::bytecodeOffsetToJumpID):
+ (JSC::bytecodeOffsetToJumpID): Deleted.
+ (JSC::BytecodeGenerator::CompletionRecordScope::CompletionRecordScope): Deleted.
+ (JSC::BytecodeGenerator::CompletionRecordScope::~CompletionRecordScope): Deleted.
+ (JSC::BytecodeGenerator::completionTypeRegister): Deleted.
+ (JSC::BytecodeGenerator::completionValueRegister): Deleted.
+ (JSC::BytecodeGenerator::emitSetCompletionType): Deleted.
+ (JSC::BytecodeGenerator::emitSetCompletionValue): Deleted.
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::TryNode::emitBytecode):
+
2016-12-19 Joseph Pecoraro <pecor...@apple.com>
Web Inspector: Assertion seen in InspectorDebuggerAgent::refAsyncCallData with Inspector open
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (210006 => 210007)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2016-12-20 01:18:57 UTC (rev 210006)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2016-12-20 01:48:52 UTC (rev 210007)
@@ -4126,7 +4126,7 @@
void BytecodeGenerator::emitEnumeration(ThrowableExpressionData* node, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack, ForOfNode* forLoopNode, RegisterID* forLoopSymbolTable)
{
- CompletionRecordScope completionRecordScope(*this);
+ FinallyRegistersScope finallyRegistersScope(*this);
RefPtr<RegisterID> subject = newTemporary();
emitNode(subject.get(), subjectNode);
@@ -4169,19 +4169,11 @@
emitLabel(finallyViaThrowLabel.get());
popTry(tryData, finallyViaThrowLabel.get());
- RefPtr<Label> finallyBodyLabel = newLabel();
- RefPtr<RegisterID> finallyExceptionRegister = newTemporary();
RegisterID* unused = newTemporary();
+ emitCatch(finallyActionRegister(), unused);
+ // Setting the finallyActionRegister to the caught exception here implies CompletionType::Throw.
- emitCatch(completionValueRegister(), unused);
- emitSetCompletionType(CompletionType::Throw);
- emitMove(finallyExceptionRegister.get(), completionValueRegister());
- emitJump(finallyBodyLabel.get());
-
emitLabel(finallyLabel.get());
- emitMoveEmptyValue(finallyExceptionRegister.get());
-
- emitLabel(finallyBodyLabel.get());
restoreScopeRegister();
RefPtr<Label> finallyDone = newLabel();
@@ -4189,6 +4181,9 @@
RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().returnKeyword);
emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), finallyDone.get());
+ RefPtr<RegisterID> originalFinallyActionRegister = newTemporary();
+ emitMove(originalFinallyActionRegister.get(), finallyActionRegister());
+
RefPtr<Label> returnCallTryStart = newLabel();
emitLabel(returnCallTryStart.get());
TryData* returnCallTryData = pushTry(returnCallTryStart.get(), catchLabel.get(), HandlerType::SynthesizedCatch);
@@ -4214,16 +4209,14 @@
RefPtr<RegisterID> exceptionRegister = newTemporary();
RegisterID* unused = newTemporary();
emitCatch(exceptionRegister.get(), unused);
- // Since this is a synthesized catch block and we're guaranteed to never need
- // to resolve any symbols from the scope, we can skip restoring the scope
- // register here.
+ restoreScopeRegister();
RefPtr<Label> throwLabel = newLabel();
- emitJumpIfTrue(emitIsEmpty(newTemporary(), finallyExceptionRegister.get()), throwLabel.get());
- emitMove(exceptionRegister.get(), finallyExceptionRegister.get());
+ emitJumpIfCompletionTypeIsThrow(originalFinallyActionRegister.get(), throwLabel.get());
+ emitMove(originalFinallyActionRegister.get(), exceptionRegister.get());
emitLabel(throwLabel.get());
- emitThrow(exceptionRegister.get());
+ emitThrow(originalFinallyActionRegister.get());
emitLabel(endCatchLabel.get());
}
@@ -4826,11 +4819,11 @@
if (!outermostFinallyContext)
return false; // No finallys to thread through.
- auto jumpID = bytecodeOffsetToJumpID(instructions().size());
+ int jumpID = bytecodeOffsetToJumpID(instructions().size());
int lexicalScopeIndex = labelScopeDepthToLexicalScopeIndex(targetLabelScopeDepth);
outermostFinallyContext->registerJump(jumpID, lexicalScopeIndex, jumpTarget);
- emitSetCompletionType(jumpID);
+ emitSetFinallyActionToJumpID(jumpID);
emitJump(innermostFinallyContext->finallyLabel());
return true; // We'll be jumping to a finally block.
}
@@ -4856,8 +4849,8 @@
if (!innermostFinallyContext)
return false; // No finallys to thread through.
- emitSetCompletionType(CompletionType::Return);
- emitSetCompletionValue(returnRegister);
+ emitSetFinallyActionToReturnCompletion();
+ emitSetFinallyReturnValueRegister(returnRegister);
emitJump(innermostFinallyContext->finallyLabel());
return true; // We'll be jumping to a finally block.
}
@@ -4864,7 +4857,9 @@
void BytecodeGenerator::emitFinallyCompletion(FinallyContext& context, Label* normalCompletionLabel)
{
- emitJumpIfCompletionType(op_stricteq, CompletionType::Normal, normalCompletionLabel);
+ // FIXME: switch the finallyActionRegister to only store int values for all CompletionTypes. This is more optimal for JIT type speculation.
+ // https://bugs.webkit.org/show_bug.cgi?id=165979
+ emitJumpIfFinallyActionIsNormalCompletion(normalCompletionLabel);
if (context.numberOfBreaksOrContinues() || context.handlesReturns()) {
FinallyContext* outerContext = context.outerContext();
@@ -4874,10 +4869,10 @@
for (size_t i = 0; i < numberOfJumps; i++) {
RefPtr<Label> nextLabel = newLabel();
auto& jump = context.jumps(i);
- emitJumpIfCompletionType(op_nstricteq, jump.jumpID, nextLabel.get());
+ emitJumpIfFinallyActionIsNotJump(jump.jumpID, nextLabel.get());
restoreScopeRegister(jump.targetLexicalScopeIndex);
- emitSetCompletionType(CompletionType::Normal);
+ emitSetFinallyActionToNormalCompletion();
emitJump(jump.targetLabel.get());
emitLabel(nextLabel.get());
@@ -4885,7 +4880,7 @@
bool hasBreaksOrContinuesNotCoveredByJumps = context.numberOfBreaksOrContinues() > numberOfJumps;
if (hasBreaksOrContinuesNotCoveredByJumps || context.handlesReturns())
- emitJumpIfCompletionType(op_nstricteq, CompletionType::Throw, outerContext->finallyLabel());
+ emitJumpIfFinallyActionIsNotThrowCompletion(outerContext->finallyLabel());
} else {
// We are the outermost finally.
@@ -4895,10 +4890,10 @@
for (size_t i = 0; i < numberOfJumps; i++) {
RefPtr<Label> nextLabel = newLabel();
auto& jump = context.jumps(i);
- emitJumpIfCompletionType(op_nstricteq, jump.jumpID, nextLabel.get());
+ emitJumpIfFinallyActionIsNotJump(jump.jumpID, nextLabel.get());
restoreScopeRegister(jump.targetLexicalScopeIndex);
- emitSetCompletionType(CompletionType::Normal);
+ emitSetFinallyActionToNormalCompletion();
emitJump(jump.targetLabel.get());
emitLabel(nextLabel.get());
@@ -4906,46 +4901,46 @@
if (context.handlesReturns()) {
RefPtr<Label> notReturnLabel = newLabel();
- emitJumpIfCompletionType(op_nstricteq, CompletionType::Return, notReturnLabel.get());
+ emitJumpIfFinallyActionIsNotReturnCompletion(notReturnLabel.get());
emitWillLeaveCallFrameDebugHook();
- emitReturn(completionValueRegister(), ReturnFrom::Finally);
+ emitReturn(finallyReturnValueRegister(), ReturnFrom::Finally);
emitLabel(notReturnLabel.get());
}
}
}
- emitThrow(completionValueRegister());
+ emitThrow(finallyActionRegister());
}
-bool BytecodeGenerator::allocateCompletionRecordRegisters()
+bool BytecodeGenerator::allocateFinallyRegisters()
{
- if (m_completionTypeRegister)
+ if (m_finallyActionRegister)
return false;
- ASSERT(!m_completionValueRegister);
- m_completionTypeRegister = newTemporary();
- m_completionValueRegister = newTemporary();
+ ASSERT(!m_finallyReturnValueRegister);
+ m_finallyActionRegister = newTemporary();
+ m_finallyReturnValueRegister = newTemporary();
- emitSetCompletionType(CompletionType::Normal);
- emitMoveEmptyValue(m_completionValueRegister.get());
+ emitSetFinallyActionToNormalCompletion();
+ emitMoveEmptyValue(m_finallyReturnValueRegister.get());
return true;
}
-void BytecodeGenerator::releaseCompletionRecordRegisters()
+void BytecodeGenerator::releaseFinallyRegisters()
{
- ASSERT(m_completionTypeRegister && m_completionValueRegister);
- m_completionTypeRegister = nullptr;
- m_completionValueRegister = nullptr;
+ ASSERT(m_finallyActionRegister && m_finallyReturnValueRegister);
+ m_finallyActionRegister = nullptr;
+ m_finallyReturnValueRegister = nullptr;
}
-void BytecodeGenerator::emitJumpIfCompletionType(OpcodeID compareOpcode, CompletionType type, Label* jumpTarget)
+void BytecodeGenerator::emitCompareFinallyActionAndJumpIf(OpcodeID compareOpcode, int value, Label* jumpTarget)
{
RefPtr<RegisterID> tempRegister = newTemporary();
- RegisterID* valueConstant = addConstantValue(JSValue(static_cast<int>(type)));
+ RegisterID* valueConstant = addConstantValue(JSValue(value));
OperandTypes operandTypes = OperandTypes(ResultType::numberTypeIsInt32(), ResultType::unknownType());
- auto equivalenceResult = emitBinaryOp(compareOpcode, tempRegister.get(), valueConstant, completionTypeRegister(), operandTypes);
+ auto equivalenceResult = emitBinaryOp(compareOpcode, tempRegister.get(), valueConstant, finallyActionRegister(), operandTypes);
emitJumpIfTrue(equivalenceResult, jumpTarget);
}
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (210006 => 210007)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2016-12-20 01:18:57 UTC (rev 210006)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2016-12-20 01:48:52 UTC (rev 210007)
@@ -80,41 +80,15 @@
unsigned m_padding;
};
- // https://tc39.github.io/ecma262/#sec-completion-record-specification-type
- //
- // For the Break and Continue cases, instead of using the Break and Continue enum values
- // below, we use the unique jumpID of the break and continue statement as the encoding
- // for the CompletionType value. emitFinallyCompletion() uses this jumpID value later
- // to determine the appropriate jump target to jump to after executing the relevant finally
- // blocks. The jumpID is computed as:
- // jumpID = bytecodeOffset (of the break/continue node) + CompletionType::NumberOfTypes.
- // Hence, there won't be any collision between jumpIDs and CompletionType enums.
- enum class CompletionType : int {
- Normal,
- Break,
- Continue,
- Return,
- Throw,
-
- NumberOfTypes
- };
-
- inline CompletionType bytecodeOffsetToJumpID(unsigned offset)
- {
- int jumpIDAsInt = offset + static_cast<int>(CompletionType::NumberOfTypes);
- ASSERT(jumpIDAsInt >= static_cast<int>(CompletionType::NumberOfTypes));
- return static_cast<CompletionType>(jumpIDAsInt);
- }
-
struct FinallyJump {
- FinallyJump(CompletionType jumpID, int targetLexicalScopeIndex, Label* targetLabel)
+ FinallyJump(int jumpID, int targetLexicalScopeIndex, Label* targetLabel)
: jumpID(jumpID)
, targetLexicalScopeIndex(targetLexicalScopeIndex)
, targetLabel(targetLabel)
{ }
- CompletionType jumpID;
- int targetLexicalScopeIndex;
+ int jumpID { 0 };
+ int targetLexicalScopeIndex { 0 };
RefPtr<Label> targetLabel;
};
@@ -142,7 +116,7 @@
bool handlesReturns() const { return m_handlesReturns; }
void setHandlesReturns() { m_handlesReturns = true; }
- void registerJump(CompletionType jumpID, int lexicalScopeIndex, Label* targetLabel)
+ void registerJump(int jumpID, int lexicalScopeIndex, Label* targetLabel)
{
if (!m_jumps)
m_jumps = std::make_unique<Vector<FinallyJump>>();
@@ -801,18 +775,18 @@
void emitDebugHook(ExpressionNode*);
void emitWillLeaveCallFrameDebugHook();
- class CompletionRecordScope {
+ class FinallyRegistersScope {
public:
- CompletionRecordScope(BytecodeGenerator& generator, bool needCompletionRecordRegisters = true)
+ FinallyRegistersScope(BytecodeGenerator& generator, bool needFinallyRegisters = true)
: m_generator(generator)
{
- if (needCompletionRecordRegisters && m_generator.allocateCompletionRecordRegisters())
+ if (needFinallyRegisters && m_generator.allocateFinallyRegisters())
m_needToReleaseOnDestruction = true;
}
- ~CompletionRecordScope()
+ ~FinallyRegistersScope()
{
if (m_needToReleaseOnDestruction)
- m_generator.releaseCompletionRecordRegisters();
+ m_generator.releaseFinallyRegisters();
}
private:
@@ -820,36 +794,79 @@
bool m_needToReleaseOnDestruction { false };
};
- RegisterID* completionTypeRegister() const
+ RegisterID* finallyActionRegister() const
{
- ASSERT(m_completionTypeRegister);
- return m_completionTypeRegister.get();
+ ASSERT(m_finallyActionRegister);
+ return m_finallyActionRegister.get();
}
- RegisterID* completionValueRegister() const
+ RegisterID* finallyReturnValueRegister() const
{
- ASSERT(m_completionValueRegister);
- return m_completionValueRegister.get();
+ ASSERT(m_finallyReturnValueRegister);
+ return m_finallyReturnValueRegister.get();
}
- void emitSetCompletionType(CompletionType type)
+ void emitSetFinallyActionToNormalCompletion()
{
- emitLoad(completionTypeRegister(), JSValue(static_cast<int>(type)));
+ emitMoveEmptyValue(m_finallyActionRegister.get());
}
- void emitSetCompletionValue(RegisterID* reg)
+ void emitSetFinallyActionToReturnCompletion()
{
- emitMove(completionValueRegister(), reg);
+ emitLoad(finallyActionRegister(), JSValue(static_cast<int>(CompletionType::Return)));
}
+ void emitSetFinallyActionToJumpID(int jumpID)
+ {
+ emitLoad(finallyActionRegister(), JSValue(jumpID));
+ }
+ void emitSetFinallyReturnValueRegister(RegisterID* reg)
+ {
+ emitMove(finallyReturnValueRegister(), reg);
+ }
- void emitJumpIfCompletionType(OpcodeID compareOpcode, CompletionType, Label* jumpTarget);
+ void emitJumpIfFinallyActionIsNormalCompletion(Label* jumpTarget)
+ {
+ emitJumpIfTrue(emitIsEmpty(newTemporary(), finallyActionRegister()), jumpTarget);
+ }
+ void emitJumpIfFinallyActionIsNotJump(int jumpID, Label* jumpTarget)
+ {
+ emitCompareFinallyActionAndJumpIf(op_nstricteq, jumpID, jumpTarget);
+ }
+
+ void emitJumpIfFinallyActionIsReturnCompletion(Label* jumpTarget)
+ {
+ emitCompareFinallyActionAndJumpIf(op_stricteq, static_cast<int>(CompletionType::Return), jumpTarget);
+ }
+ void emitJumpIfFinallyActionIsNotReturnCompletion(Label* jumpTarget)
+ {
+ emitCompareFinallyActionAndJumpIf(op_nstricteq, static_cast<int>(CompletionType::Return), jumpTarget);
+ }
+
+ void emitJumpIfFinallyActionIsNotThrowCompletion(Label* jumpTarget)
+ {
+ emitJumpIfTrue(emitIsNumber(newTemporary(), finallyActionRegister()), jumpTarget);
+ }
+ void emitJumpIfCompletionTypeIsThrow(RegisterID* reg, Label* jumpTarget)
+ {
+ emitJumpIfFalse(emitIsNumber(newTemporary(), reg), jumpTarget);
+ }
+
bool emitJumpViaFinallyIfNeeded(int targetLabelScopeDepth, Label* jumpTarget);
bool emitReturnViaFinallyIfNeeded(RegisterID* returnRegister);
void emitFinallyCompletion(FinallyContext&, Label* normalCompletionLabel);
private:
- bool allocateCompletionRecordRegisters();
- void releaseCompletionRecordRegisters();
+ void emitCompareFinallyActionAndJumpIf(OpcodeID compareOpcode, int value, Label* jumpTarget);
+ int bytecodeOffsetToJumpID(unsigned offset)
+ {
+ int jumpID = offset + static_cast<int>(CompletionType::NumberOfTypes);
+ ASSERT(jumpID >= static_cast<int>(CompletionType::NumberOfTypes));
+ return jumpID;
+ }
+
+ bool allocateFinallyRegisters();
+ void releaseFinallyRegisters();
+
public:
FinallyContext* pushFinallyControlFlowScope(Label* finallyLabel);
FinallyContext popFinallyControlFlowScope();
@@ -1083,9 +1100,33 @@
RegisterID* m_arrowFunctionContextLexicalEnvironmentRegister { nullptr };
RegisterID* m_promiseCapabilityRegister { nullptr };
- RefPtr<RegisterID> m_completionTypeRegister;
- RefPtr<RegisterID> m_completionValueRegister;
+ // The spec at https://tc39.github.io/ecma262/#sec-completion-record-specification-type says
+ // that there are 5 types of completions. Conceptually, we'll set m_finallyActionRegister
+ // to one of these completion types. However, to optimize our implementation, we'll encode
+ // these type info as follows:
+ //
+ // CompletionType::Normal - m_finallyActionRegister is empty.
+ // CompletionType::Break - m_finallyActionRegister is an int JSValue jumpID.
+ // CompletionType::Continue - m_finallyActionRegister is an int JSValue jumpID.
+ // CompletionType::Return - m_finallyActionRegister is the Return enum as an int JSValue.
+ // CompletionType::Throw - m_finallyActionRegister is the Exception object to rethrow.
+ //
+ // Hence, of the 5 completion types, only the CompletionType::Return enum value is used in
+ // our implementation. The rest are just provided for completeness.
+ enum class CompletionType : int {
+ Normal,
+ Break,
+ Continue,
+ Return,
+ Throw,
+
+ NumberOfTypes
+ };
+
+ RefPtr<RegisterID> m_finallyActionRegister;
+ RefPtr<RegisterID> m_finallyReturnValueRegister;
+
FinallyContext* m_currentFinallyContext { nullptr };
SegmentedVector<RegisterID*, 16> m_localRegistersForCalleeSaveRegisters;
@@ -1102,7 +1143,7 @@
void pushLocalControlFlowScope();
void popLocalControlFlowScope();
- // FIXME: Restore overflow checking with UnsafeVectorOverflow once SegmentVector supports it.
+ // FIXME: Restore overflow checking with UnsafeVectorOverflow once SegmentVector supports it.
// https://bugs.webkit.org/show_bug.cgi?id=165980
SegmentedVector<ControlFlowScope, 16> m_controlFlowScopeStack;
Vector<SwitchInfo> m_switchContextStack;
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (210006 => 210007)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2016-12-20 01:18:57 UTC (rev 210006)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2016-12-20 01:48:52 UTC (rev 210007)
@@ -3287,7 +3287,7 @@
// optimizer knows they may be jumped to from anywhere.
ASSERT(m_catchBlock || m_finallyBlock);
- BytecodeGenerator::CompletionRecordScope completionRecordScope(generator, m_finallyBlock);
+ BytecodeGenerator::FinallyRegistersScope finallyRegistersScope(generator, m_finallyBlock);
RefPtr<Label> catchLabel;
RefPtr<Label> catchEndLabel;
@@ -3316,6 +3316,7 @@
generator.emitNode(dst, m_tryBlock);
+ // The finallyActionRegister is an empty value by default, which implies CompletionType::Normal.
if (m_finallyBlock)
generator.emitJump(finallyLabel.get());
else
@@ -3350,7 +3351,7 @@
generator.emitPopCatchScope(m_lexicalVariables);
if (m_finallyBlock) {
- generator.emitSetCompletionType(CompletionType::Normal);
+ generator.emitSetFinallyActionToNormalCompletion();
generator.emitJump(finallyLabel.get());
generator.popTry(tryData, finallyViaThrowLabel.get());
}
@@ -3365,8 +3366,8 @@
// Entry to the finally block for CompletionType::Throw.
generator.emitLabel(finallyViaThrowLabel.get());
RegisterID* unused = generator.newTemporary();
- generator.emitCatch(generator.completionValueRegister(), unused);
- generator.emitSetCompletionType(CompletionType::Throw);
+ generator.emitCatch(generator.finallyActionRegister(), unused);
+ // Setting the finallyActionRegister to the caught exception here implies CompletionType::Throw.
// Entry to the finally block for CompletionTypes other than Throw.
generator.emitLabel(finallyLabel.get());