Implement catch scope using lexical scoping constructs introduced with "let" scoping patch
https://bugs.webkit.org/show_bug.cgi?id=146979
Reviewed by Geoffrey Garen.
Now that BytecodeGenerator has a notion of local scope depth,
we can easily implement a catch scope that doesn't claim that
all variables are dynamically scoped. This means that functions
that use try/catch can have local variable resolution. This also
means that all functions that use try/catch don't have all
their variables marked as being captured.
Catch scopes now behave like a "let" scope (sans the TDZ logic) with a
single variable. Catch scopes are now just JSLexicalEnvironments and the
symbol table backing the catch scope knows that it corresponds to a catch scope.
* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/EvalCodeCache.h:
(JSC::EvalCodeCache::isCacheable):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack):
(JSC::BytecodeGenerator::emitLoadGlobalObject):
(JSC::BytecodeGenerator::pushLexicalScope):
(JSC::BytecodeGenerator::pushLexicalScopeInternal):
(JSC::BytecodeGenerator::popLexicalScope):
(JSC::BytecodeGenerator::popLexicalScopeInternal):
(JSC::BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration):
(JSC::BytecodeGenerator::variable):
(JSC::BytecodeGenerator::resolveType):
(JSC::BytecodeGenerator::emitResolveScope):
(JSC::BytecodeGenerator::emitPopScope):
(JSC::BytecodeGenerator::emitPopWithScope):
(JSC::BytecodeGenerator::emitDebugHook):
(JSC::BytecodeGenerator::popScopedControlFlowContext):
(JSC::BytecodeGenerator::emitPushCatchScope):
(JSC::BytecodeGenerator::emitPopCatchScope):
(JSC::BytecodeGenerator::beginSwitch):
(JSC::BytecodeGenerator::emitPopWithOrCatchScope): Deleted.
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::lastOpcodeID):
* bytecompiler/NodesCodegen.cpp:
(JSC::AssignResolveNode::emitBytecode):
(JSC::WithNode::emitBytecode):
(JSC::TryNode::emitBytecode):
* debugger/DebuggerScope.cpp:
(JSC::DebuggerScope::isCatchScope):
(JSC::DebuggerScope::isFunctionNameScope):
(JSC::DebuggerScope::isFunctionOrEvalScope):
(JSC::DebuggerScope::caughtValue):
* debugger/DebuggerScope.h:
* inspector/ScriptDebugServer.cpp:
(Inspector::ScriptDebugServer::exceptionOrCaughtValue):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_push_name_scope):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_push_name_scope):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createContinueStatement):
(JSC::ASTBuilder::createTryStatement):
* parser/NodeConstructors.h:
(JSC::ThrowNode::ThrowNode):
(JSC::TryNode::TryNode):
(JSC::FunctionParameters::FunctionParameters):
* parser/Nodes.h:
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseTryStatement):
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createBreakStatement):
(JSC::SyntaxChecker::createContinueStatement):
(JSC::SyntaxChecker::createTryStatement):
(JSC::SyntaxChecker::createSwitchStatement):
(JSC::SyntaxChecker::createWhileStatement):
(JSC::SyntaxChecker::createWithStatement):
* runtime/JSCatchScope.cpp:
* runtime/JSCatchScope.h:
(JSC::JSCatchScope::JSCatchScope): Deleted.
(JSC::JSCatchScope::create): Deleted.
(JSC::JSCatchScope::createStructure): Deleted.
* runtime/JSFunctionNameScope.h:
(JSC::JSFunctionNameScope::JSFunctionNameScope):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::withScopeStructure):
(JSC::JSGlobalObject::strictEvalActivationStructure):
(JSC::JSGlobalObject::activationStructure):
(JSC::JSGlobalObject::functionNameScopeStructure):
(JSC::JSGlobalObject::directArgumentsStructure):
(JSC::JSGlobalObject::scopedArgumentsStructure):
(JSC::JSGlobalObject::catchScopeStructure): Deleted.
* runtime/JSNameScope.cpp:
(JSC::JSNameScope::create):
(JSC::JSNameScope::toThis):
* runtime/JSNameScope.h:
* runtime/JSObject.cpp:
(JSC::JSObject::toThis):
(JSC::JSObject::isFunctionNameScopeObject):
(JSC::JSObject::isCatchScopeObject): Deleted.
* runtime/JSObject.h:
* runtime/JSScope.cpp:
(JSC::JSScope::collectVariablesUnderTDZ):
(JSC::JSScope::isLexicalScope):
(JSC::JSScope::isCatchScope):
(JSC::resolveModeName):
* runtime/JSScope.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::SymbolTable):
(JSC::SymbolTable::cloneScopePart):
* runtime/SymbolTable.h:
* tests/stress/const-semantics.js:
(.):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@187515 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index da46b9f..7c4ea62 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -1858,8 +1858,8 @@
generator.emitTDZCheckIfNecessary(var, local, nullptr);
if (var.isReadOnly() && m_assignmentContext != AssignmentContext::ConstDeclarationStatement) {
+ result = generator.emitNode(dst, m_right); // Execute side effects first.
generator.emitReadOnlyExceptionIfNeeded(var);
- result = generator.emitNode(dst, m_right);
} else if (var.isSpecial() || generator.vm()->typeProfiler()) {
RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
generator.emitNode(tempDst.get(), m_right);
@@ -1888,9 +1888,10 @@
dst = 0;
RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
if (var.isReadOnly() && m_assignmentContext != AssignmentContext::ConstDeclarationStatement) {
+ RegisterID* result = generator.emitNode(dst, m_right); // Execute side effects first.
bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
if (threwException)
- return generator.emitNode(dst, m_right);
+ return result;
}
generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
@@ -2683,7 +2684,7 @@
generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
generator.emitPushWithScope(generator.scopeRegister(), scope.get());
generator.emitNode(dst, m_statement);
- generator.emitPopWithOrCatchScope(generator.scopeRegister());
+ generator.emitPopWithScope(generator.scopeRegister());
}
// ------------------------------ CaseClauseNode --------------------------------
@@ -2933,10 +2934,10 @@
tryData = generator.pushTry(here.get());
}
- generator.emitPushCatchScope(generator.scopeRegister(), m_thrownValueIdent, thrownValueRegister.get(), DontDelete);
+ generator.emitPushCatchScope(m_thrownValueIdent, thrownValueRegister.get(), m_catchEnvironment);
generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
generator.emitNode(dst, m_catchBlock);
- generator.emitPopWithOrCatchScope(generator.scopeRegister());
+ generator.emitPopCatchScope(m_catchEnvironment);
generator.emitLabel(catchEndLabel.get());
}