Diff
Modified: trunk/JSTests/ChangeLog (279446 => 279447)
--- trunk/JSTests/ChangeLog 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/JSTests/ChangeLog 2021-07-01 02:03:55 UTC (rev 279447)
@@ -1,3 +1,11 @@
+2021-06-29 Yusuke Suzuki <[email protected]>
+
+ [JSC] Private names should be handled by usedVariables mechanism
+ https://bugs.webkit.org/show_bug.cgi?id=227476
+ rdar://76049469
+
+ Reviewed by Saam Barati.
+
2021-06-30 Mikhail R. Gadelha <[email protected]>
Unskip interpreter-wasm.js on ARM and MIPS
Modified: trunk/JSTests/stress/undeclared-private-field-in-eval.js (279446 => 279447)
--- trunk/JSTests/stress/undeclared-private-field-in-eval.js 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/JSTests/stress/undeclared-private-field-in-eval.js 2021-07-01 02:03:55 UTC (rev 279447)
@@ -13,7 +13,7 @@
assert(!!error);
assert(error instanceof SyntaxError);
- assert(error.message === "Cannot reference undeclared private names");
+ assert(error.message.startsWith("Cannot reference undeclared private names"));
}
class C {
Modified: trunk/Source/_javascript_Core/ChangeLog (279446 => 279447)
--- trunk/Source/_javascript_Core/ChangeLog 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-07-01 02:03:55 UTC (rev 279447)
@@ -1,3 +1,122 @@
+2021-06-30 Yusuke Suzuki <[email protected]>
+
+ [JSC] Private names should be handled by usedVariables mechanism
+ https://bugs.webkit.org/show_bug.cgi?id=227476
+ rdar://76049469
+
+ Reviewed by Saam Barati.
+
+ Private name handling in the current parser has many problems.
+
+ 1. The parser backtracks when it sees destructuring assignment, arrow function etc. In that case, the discarded code
+ must not have any effect on the outside of that code. However, private name handling is annotating "used" of the
+ upper scopes, which is wrong.
+ 2. In class _expression_, private name lookup intentionally skips the class-scope when parsing class heritage. But this
+ is not correct since CodeBlock will perform lookup on the normal scope chain and this will look into the class-scope
+ inconsistently. This means that we could encounter different private name at runtime. (it is tested in the added test).
+ 3. We skip inner function parsing when it is parsed previously. At that case, we must preserve private name annotation,
+ but restored function information does not preserve that.
+
+ This patch changes how private name is handled.
+
+ 1. We were anyway defining #XXX variables which holds private symbols. So we track "use" information by the mechanism used
+ for usual variables. We remove Used / Declared bits from PrivateNameEntry since they are not necessary at runtime, and
+ these information is handled / tracked in Parser's Scope. For backtracking, we already have a mechanism to roll-back
+ m_usedVariables, so using variable mechanism automatically fixes the problem.
+ 2. We define class-head-scope separately from class-scope. class-heritage _expression_ can see class name, but it cannot use
+ private names. Previously, our implementation attempted to achieve that by hacky way: skipping this class-scope for private
+ names only while parsing class-heritage. But this was wrong since it does not consider CodeBlock's linking phase as described
+ in the problem (2). Instead, we just define class-head-scope which holds class constructor name.
+ 3. We clean up popScopeInternal to populate lexical-variables and function-stack. Previously, we are stealing them before popping
+ the scope when necessary, but this is a hack and a bit wrong since scope's popping operation needs to access these information
+ in some cases. Instead, popScopeInternal populates them after popping the scope.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::pushClassHeadLexicalScope):
+ (JSC::BytecodeGenerator::popClassHeadLexicalScope):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ClassExprNode::emitBytecode):
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::createClassExpr):
+ (JSC::ASTBuilder::createBlockStatement):
+ (JSC::ASTBuilder::createForLoop):
+ (JSC::ASTBuilder::createForInLoop):
+ (JSC::ASTBuilder::createForOfLoop):
+ (JSC::ASTBuilder::createTryStatement):
+ (JSC::ASTBuilder::createSwitchStatement):
+ * parser/NodeConstructors.h:
+ (JSC::ForNode::ForNode):
+ (JSC::TryNode::TryNode):
+ (JSC::ClassExprNode::ClassExprNode):
+ (JSC::SwitchNode::SwitchNode):
+ (JSC::BlockNode::BlockNode):
+ (JSC::EnumerationNode::EnumerationNode):
+ (JSC::ForInNode::ForInNode):
+ (JSC::ForOfNode::ForOfNode):
+ * parser/Nodes.cpp:
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::ProgramNode::ProgramNode):
+ (JSC::ModuleProgramNode::ModuleProgramNode):
+ (JSC::EvalNode::EvalNode):
+ (JSC::FunctionNode::FunctionNode):
+ (JSC::VariableEnvironmentNode::VariableEnvironmentNode):
+ * parser/Nodes.h:
+ (JSC::VariableEnvironmentNode::VariableEnvironmentNode): Deleted.
+ * parser/Parser.cpp:
+ (JSC::isPrivateFieldName):
+ (JSC::Parser<LexerType>::parseInner):
+ (JSC::Parser<LexerType>::parseForStatement):
+ (JSC::Parser<LexerType>::parseSwitchStatement):
+ (JSC::Parser<LexerType>::parseTryStatement):
+ (JSC::Parser<LexerType>::parseBlockStatement):
+ (JSC::Parser<LexerType>::parseFunctionDeclarationStatement):
+ (JSC::Parser<LexerType>::parseFunctionInfo):
+ (JSC::Parser<LexerType>::parseClass):
+ (JSC::Parser<LexerType>::parseBinaryExpression):
+ (JSC::Parser<LexerType>::parseMemberExpression):
+ (JSC::Parser<LexerType>::usePrivateName): Deleted.
+ * parser/Parser.h:
+ (JSC::Scope::finalizeLexicalEnvironment):
+ (JSC::Scope::takeLexicalEnvironment):
+ (JSC::Scope::takeDeclaredVariables):
+ (JSC::Scope::takeFunctionDeclarations):
+ (JSC::Scope::forEachUsedVariable):
+ (JSC::Scope::usePrivateName):
+ (JSC::Scope::currentUsedVariablesSize):
+ (JSC::Parser::popScopeInternal):
+ (JSC::Parser::popScope):
+ (JSC::Parser<LexerType>::parse):
+ (JSC::Scope::copyUndeclaredPrivateNamesTo): Deleted.
+ (JSC::Scope::hasUsedButUndeclaredPrivateNames const): Deleted.
+ (JSC::Parser::privateNameScope): Deleted.
+ (JSC::Parser::copyUndeclaredPrivateNamesToOuterScope): Deleted.
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::createClassExpr):
+ (JSC::SyntaxChecker::createBlockStatement):
+ (JSC::SyntaxChecker::createForLoop):
+ (JSC::SyntaxChecker::createForInLoop):
+ (JSC::SyntaxChecker::createForOfLoop):
+ (JSC::SyntaxChecker::createTryStatement):
+ (JSC::SyntaxChecker::createSwitchStatement):
+ * parser/VariableEnvironment.cpp:
+ (JSC::VariableEnvironmentEntry::dump const):
+ (JSC::VariableEnvironment::declarePrivateField):
+ (JSC::VariableEnvironment::declarePrivateAccessor):
+ (JSC::VariableEnvironment::declarePrivateMethod):
+ (JSC::VariableEnvironment::dump const):
+ * parser/VariableEnvironment.h:
+ (JSC::VariableEnvironment::declarePrivateField):
+ (JSC::VariableEnvironment::privateNameEnvironment):
+ (JSC::VariableEnvironment::addPrivateNamesFrom):
+ (JSC::PrivateNameEntry::isUsed const): Deleted.
+ (JSC::PrivateNameEntry::isDeclared const): Deleted.
+ (JSC::PrivateNameEntry::setIsUsed): Deleted.
+ (JSC::PrivateNameEntry::setIsDeclared): Deleted.
+ (JSC::VariableEnvironment::usePrivateName): Deleted.
+ (JSC::VariableEnvironment::copyPrivateNamesTo const): Deleted.
+ (JSC::VariableEnvironment::copyUndeclaredPrivateNamesTo const): Deleted.
+
2021-06-30 Mark Lam <[email protected]>
ARM64: Disable selection of BFI instruction variants by default.
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (279446 => 279447)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2021-07-01 02:03:55 UTC (rev 279447)
@@ -1992,6 +1992,16 @@
*constantSymbolTableResult = constantSymbolTableResultTemp;
}
+void BytecodeGenerator::pushClassHeadLexicalScope(VariableEnvironment& environment)
+{
+ pushLexicalScopeInternal(environment, TDZCheckOptimization::Optimize, NestedScopeType::IsNested, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block);
+}
+
+void BytecodeGenerator::popClassHeadLexicalScope(VariableEnvironment& environment)
+{
+ popLexicalScopeInternal(environment);
+}
+
void BytecodeGenerator::pushLexicalScopeInternal(VariableEnvironment& environment, TDZCheckOptimization tdzCheckOptimization, NestedScopeType nestedScopeType,
RegisterID** constantSymbolTableResult, TDZRequirement tdzRequirement, ScopeType scopeType, ScopeRegisterType scopeRegisterType)
{
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (279446 => 279447)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2021-07-01 02:03:55 UTC (rev 279447)
@@ -986,6 +986,9 @@
void emitOutOfLineCatchHandler(RegisterID* thrownValueRegister, RegisterID* completionTypeRegister, TryData*);
void emitOutOfLineFinallyHandler(RegisterID* exceptionRegister, RegisterID* completionTypeRegister, TryData*);
+ void pushClassHeadLexicalScope(VariableEnvironment&);
+ void popClassHeadLexicalScope(VariableEnvironment&);
+
private:
static constexpr int CurrentLexicalScopeIndex = -2;
static constexpr int OutermostLexicalScopeIndex = -1;
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (279446 => 279447)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2021-07-01 02:03:55 UTC (rev 279447)
@@ -5189,6 +5189,16 @@
{
StrictModeScope strictModeScope(generator);
+ if (!m_name.isNull())
+ generator.pushClassHeadLexicalScope(m_classHeadEnvironment);
+
+ // Class heritage must be evaluated outside of private fields access.
+ RefPtr<RegisterID> superclass;
+ if (m_classHeritage) {
+ superclass = generator.newTemporary();
+ generator.emitNode(superclass.get(), m_classHeritage);
+ }
+
if (m_needsLexicalScope)
generator.pushLexicalScope(this, BytecodeGenerator::ScopeType::ClassScope, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested);
@@ -5200,12 +5210,6 @@
if (shouldEmitPrivateBrand)
generator.emitCreatePrivateBrand(m_position, m_position, m_position);
- RefPtr<RegisterID> superclass;
- if (m_classHeritage) {
- superclass = generator.newTemporary();
- generator.emitNode(superclass.get(), m_classHeritage);
- }
-
RefPtr<RegisterID> constructor = generator.tempDestination(dst);
bool needsHomeObject = false;
@@ -5272,7 +5276,7 @@
}
}
- if (m_needsLexicalScope && !m_name.isNull()) {
+ if (!m_name.isNull()) {
Variable classNameVar = generator.variable(m_name);
RELEASE_ASSERT(classNameVar.isResolved());
RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, classNameVar);
@@ -5293,11 +5297,14 @@
generator.emitCall(generator.newTemporary(), staticFieldInitializer.get(), NoExpectedFunction, args, position(), position(), position(), DebuggableCall::No);
}
+ if (hasPrivateNames)
+ generator.popPrivateAccessNames();
+
if (m_needsLexicalScope)
generator.popLexicalScope(this);
- if (hasPrivateNames)
- generator.popPrivateAccessNames();
+ if (!m_name.isNull())
+ generator.popClassHeadLexicalScope(m_classHeadEnvironment);
return generator.move(generator.finalDestination(dst, constructor.get()), constructor.get());
}
Modified: trunk/Source/_javascript_Core/parser/ASTBuilder.h (279446 => 279447)
--- trunk/Source/_javascript_Core/parser/ASTBuilder.h 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/parser/ASTBuilder.h 2021-07-01 02:03:55 UTC (rev 279447)
@@ -415,11 +415,11 @@
return new (m_parserArena) DefineFieldNode(location, ident, initializer, type);
}
- ClassExprNode* createClassExpr(const JSTokenLocation& location, const ParserClassInfo<ASTBuilder>& classInfo, VariableEnvironment& classEnvironment, ExpressionNode* constructor,
+ ClassExprNode* createClassExpr(const JSTokenLocation& location, const ParserClassInfo<ASTBuilder>& classInfo, VariableEnvironment&& classHeadEnvironment, VariableEnvironment&& classEnvironment, ExpressionNode* constructor,
ExpressionNode* parentClass, PropertyListNode* classElements, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
{
SourceCode source = m_sourceCode->subExpression(classInfo.startOffset, classInfo.endOffset, classInfo.startLine, classInfo.startColumn);
- ClassExprNode* node = new (m_parserArena) ClassExprNode(location, *classInfo.className, source, classEnvironment, constructor, parentClass, classElements);
+ ClassExprNode* node = new (m_parserArena) ClassExprNode(location, *classInfo.className, source, WTFMove(classHeadEnvironment), WTFMove(classEnvironment), constructor, parentClass, classElements);
setExceptionLocation(node, start, divot, end);
return node;
}
@@ -587,9 +587,9 @@
return decl;
}
- StatementNode* createBlockStatement(const JSTokenLocation& location, JSC::SourceElements* elements, int startLine, int endLine, VariableEnvironment& lexicalVariables, DeclarationStacks::FunctionStack&& functionStack)
+ StatementNode* createBlockStatement(const JSTokenLocation& location, JSC::SourceElements* elements, int startLine, int endLine, VariableEnvironment&& lexicalVariables, DeclarationStacks::FunctionStack&& functionStack)
{
- BlockNode* block = new (m_parserArena) BlockNode(location, elements, lexicalVariables, WTFMove(functionStack));
+ BlockNode* block = new (m_parserArena) BlockNode(location, elements, WTFMove(lexicalVariables), WTFMove(functionStack));
block->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return block;
}
@@ -608,39 +608,39 @@
return result;
}
- StatementNode* createForLoop(const JSTokenLocation& location, ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, int start, int end, VariableEnvironment& lexicalVariables)
+ StatementNode* createForLoop(const JSTokenLocation& location, ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, int start, int end, VariableEnvironment&& lexicalVariables)
{
- ForNode* result = new (m_parserArena) ForNode(location, initializer, condition, iter, statements, lexicalVariables);
+ ForNode* result = new (m_parserArena) ForNode(location, initializer, condition, iter, statements, WTFMove(lexicalVariables));
result->setLoc(start, end, location.startOffset, location.lineStartOffset);
return result;
}
- StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation&, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables)
+ StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation&, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment&& lexicalVariables)
{
- ForInNode* result = new (m_parserArena) ForInNode(location, lhs, iter, statements, lexicalVariables);
+ ForInNode* result = new (m_parserArena) ForInNode(location, lhs, iter, statements, WTFMove(lexicalVariables));
result->setLoc(start, end, location.startOffset, location.lineStartOffset);
setExceptionLocation(result, eStart, eDivot, eEnd);
return result;
}
- StatementNode* createForInLoop(const JSTokenLocation& location, DestructuringPatternNode* pattern, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation& declLocation, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables)
+ StatementNode* createForInLoop(const JSTokenLocation& location, DestructuringPatternNode* pattern, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation& declLocation, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment&& lexicalVariables)
{
auto lexpr = new (m_parserArena) DestructuringAssignmentNode(declLocation, pattern, nullptr);
- return createForInLoop(location, lexpr, iter, statements, declLocation, eStart, eDivot, eEnd, start, end, lexicalVariables);
+ return createForInLoop(location, lexpr, iter, statements, declLocation, eStart, eDivot, eEnd, start, end, WTFMove(lexicalVariables));
}
- StatementNode* createForOfLoop(bool isForAwait, const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation&, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables)
+ StatementNode* createForOfLoop(bool isForAwait, const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation&, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment&& lexicalVariables)
{
- ForOfNode* result = new (m_parserArena) ForOfNode(isForAwait, location, lhs, iter, statements, lexicalVariables);
+ ForOfNode* result = new (m_parserArena) ForOfNode(isForAwait, location, lhs, iter, statements, WTFMove(lexicalVariables));
result->setLoc(start, end, location.startOffset, location.lineStartOffset);
setExceptionLocation(result, eStart, eDivot, eEnd);
return result;
}
- StatementNode* createForOfLoop(bool isForAwait, const JSTokenLocation& location, DestructuringPatternNode* pattern, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation& declLocation, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment& lexicalVariables)
+ StatementNode* createForOfLoop(bool isForAwait, const JSTokenLocation& location, DestructuringPatternNode* pattern, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation& declLocation, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment&& lexicalVariables)
{
auto lexpr = new (m_parserArena) DestructuringAssignmentNode(declLocation, pattern, nullptr);
- return createForOfLoop(isForAwait, location, lexpr, iter, statements, declLocation, eStart, eDivot, eEnd, start, end, lexicalVariables);
+ return createForOfLoop(isForAwait, location, lexpr, iter, statements, declLocation, eStart, eDivot, eEnd, start, end, WTFMove(lexicalVariables));
}
bool isBindingNode(const DestructuringPattern& pattern)
@@ -732,17 +732,17 @@
return result;
}
- StatementNode* createTryStatement(const JSTokenLocation& location, StatementNode* tryBlock, DestructuringPatternNode* catchPattern, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine, VariableEnvironment& catchEnvironment)
+ StatementNode* createTryStatement(const JSTokenLocation& location, StatementNode* tryBlock, DestructuringPatternNode* catchPattern, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine, VariableEnvironment&& catchEnvironment)
{
- TryNode* result = new (m_parserArena) TryNode(location, tryBlock, catchPattern, catchBlock, catchEnvironment, finallyBlock);
+ TryNode* result = new (m_parserArena) TryNode(location, tryBlock, catchPattern, catchBlock, WTFMove(catchEnvironment), finallyBlock);
result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
- StatementNode* createSwitchStatement(const JSTokenLocation& location, ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine, VariableEnvironment& lexicalVariables, DeclarationStacks::FunctionStack&& functionStack)
+ StatementNode* createSwitchStatement(const JSTokenLocation& location, ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine, VariableEnvironment&& lexicalVariables, DeclarationStacks::FunctionStack&& functionStack)
{
CaseBlockNode* cases = new (m_parserArena) CaseBlockNode(firstClauses, defaultClause, secondClauses);
- SwitchNode* result = new (m_parserArena) SwitchNode(location, expr, cases, lexicalVariables, WTFMove(functionStack));
+ SwitchNode* result = new (m_parserArena) SwitchNode(location, expr, cases, WTFMove(lexicalVariables), WTFMove(functionStack));
result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
Modified: trunk/Source/_javascript_Core/parser/NodeConstructors.h (279446 => 279447)
--- trunk/Source/_javascript_Core/parser/NodeConstructors.h 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/parser/NodeConstructors.h 2021-07-01 02:03:55 UTC (rev 279447)
@@ -941,9 +941,9 @@
{
}
- inline ForNode::ForNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, VariableEnvironment& lexicalVariables)
+ inline ForNode::ForNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, VariableEnvironment&& lexicalVariables)
: StatementNode(location)
- , VariableEnvironmentNode(lexicalVariables)
+ , VariableEnvironmentNode(WTFMove(lexicalVariables))
, m_expr1(expr1)
, m_expr2(expr2)
, m_expr3(expr3)
@@ -995,9 +995,9 @@
m_expr->setIsOnlyChildOfStatement();
}
- inline TryNode::TryNode(const JSTokenLocation& location, StatementNode* tryBlock, DestructuringPatternNode* catchPattern, StatementNode* catchBlock, VariableEnvironment& catchEnvironment, StatementNode* finallyBlock)
+ inline TryNode::TryNode(const JSTokenLocation& location, StatementNode* tryBlock, DestructuringPatternNode* catchPattern, StatementNode* catchBlock, VariableEnvironment&& catchEnvironment, StatementNode* finallyBlock)
: StatementNode(location)
- , VariableEnvironmentNode(catchEnvironment)
+ , VariableEnvironmentNode(WTFMove(catchEnvironment))
, m_tryBlock(tryBlock)
, m_catchPattern(catchPattern)
, m_catchBlock(catchBlock)
@@ -1071,9 +1071,10 @@
{
}
- inline ClassExprNode::ClassExprNode(const JSTokenLocation& location, const Identifier& name, const SourceCode& classSource, VariableEnvironment& classEnvironment, ExpressionNode* constructorExpression, ExpressionNode* classHeritage, PropertyListNode* classElements)
+ inline ClassExprNode::ClassExprNode(const JSTokenLocation& location, const Identifier& name, const SourceCode& classSource, VariableEnvironment&& classHeadEnvironment, VariableEnvironment&& classEnvironment, ExpressionNode* constructorExpression, ExpressionNode* classHeritage, PropertyListNode* classElements)
: ExpressionNode(location)
- , VariableEnvironmentNode(classEnvironment)
+ , VariableEnvironmentNode(WTFMove(classEnvironment))
+ , m_classHeadEnvironment(WTFMove(classHeadEnvironment))
, m_classSource(classSource)
, m_name(name)
, m_ecmaName(&name)
@@ -1080,7 +1081,7 @@
, m_constructorExpression(constructorExpression)
, m_classHeritage(classHeritage)
, m_classElements(classElements)
- , m_needsLexicalScope(!name.isNull() || PropertyListNode::shouldCreateLexicalScopeForClass(classElements))
+ , m_needsLexicalScope(PropertyListNode::shouldCreateLexicalScopeForClass(classElements))
{
}
@@ -1108,24 +1109,24 @@
{
}
- inline SwitchNode::SwitchNode(const JSTokenLocation& location, ExpressionNode* expr, CaseBlockNode* block, VariableEnvironment& lexicalVariables, FunctionStack&& functionStack)
+ inline SwitchNode::SwitchNode(const JSTokenLocation& location, ExpressionNode* expr, CaseBlockNode* block, VariableEnvironment&& lexicalVariables, FunctionStack&& functionStack)
: StatementNode(location)
- , VariableEnvironmentNode(lexicalVariables, WTFMove(functionStack))
+ , VariableEnvironmentNode(WTFMove(lexicalVariables), WTFMove(functionStack))
, m_expr(expr)
, m_block(block)
{
}
- inline BlockNode::BlockNode(const JSTokenLocation& location, SourceElements* statements, VariableEnvironment& lexicalVariables, FunctionStack&& functionStack)
+ inline BlockNode::BlockNode(const JSTokenLocation& location, SourceElements* statements, VariableEnvironment&& lexicalVariables, FunctionStack&& functionStack)
: StatementNode(location)
- , VariableEnvironmentNode(lexicalVariables, WTFMove(functionStack))
+ , VariableEnvironmentNode(WTFMove(lexicalVariables), WTFMove(functionStack))
, m_statements(statements)
{
}
- inline EnumerationNode::EnumerationNode(const JSTokenLocation& location, ExpressionNode* lexpr, ExpressionNode* expr, StatementNode* statement, VariableEnvironment& lexicalVariables)
+ inline EnumerationNode::EnumerationNode(const JSTokenLocation& location, ExpressionNode* lexpr, ExpressionNode* expr, StatementNode* statement, VariableEnvironment&& lexicalVariables)
: StatementNode(location)
- , VariableEnvironmentNode(lexicalVariables)
+ , VariableEnvironmentNode(WTFMove(lexicalVariables))
, m_lexpr(lexpr)
, m_expr(expr)
, m_statement(statement)
@@ -1133,13 +1134,13 @@
ASSERT(lexpr);
}
- inline ForInNode::ForInNode(const JSTokenLocation& location, ExpressionNode* lexpr, ExpressionNode* expr, StatementNode* statement, VariableEnvironment& lexicalVariables)
- : EnumerationNode(location, lexpr, expr, statement, lexicalVariables)
+ inline ForInNode::ForInNode(const JSTokenLocation& location, ExpressionNode* lexpr, ExpressionNode* expr, StatementNode* statement, VariableEnvironment&& lexicalVariables)
+ : EnumerationNode(location, lexpr, expr, statement, WTFMove(lexicalVariables))
{
}
- inline ForOfNode::ForOfNode(bool isForAwait, const JSTokenLocation& location, ExpressionNode* lexpr, ExpressionNode* expr, StatementNode* statement, VariableEnvironment& lexicalVariables)
- : EnumerationNode(location, lexpr, expr, statement, lexicalVariables)
+ inline ForOfNode::ForOfNode(bool isForAwait, const JSTokenLocation& location, ExpressionNode* lexpr, ExpressionNode* expr, StatementNode* statement, VariableEnvironment&& lexicalVariables)
+ : EnumerationNode(location, lexpr, expr, statement, WTFMove(lexicalVariables))
, m_isForAwait(isForAwait)
{
}
Modified: trunk/Source/_javascript_Core/parser/Nodes.cpp (279446 => 279447)
--- trunk/Source/_javascript_Core/parser/Nodes.cpp 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/parser/Nodes.cpp 2021-07-01 02:03:55 UTC (rev 279447)
@@ -131,10 +131,10 @@
{
}
-ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants)
+ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants)
: StatementNode(endLocation)
, ParserArenaRoot(parserArena)
- , VariableEnvironmentNode(lexicalVariables, WTFMove(funcStack))
+ , VariableEnvironmentNode(WTFMove(lexicalVariables), WTFMove(funcStack))
, m_startLineNumber(startLocation.line)
, m_startStartOffset(startLocation.startOffset)
, m_startLineStartOffset(startLocation.lineStartOffset)
@@ -142,11 +142,11 @@
, m_lexicalScopeFeatures(lexicalScopeFeatures)
, m_innerArrowFunctionCodeFeatures(innerArrowFunctionCodeFeatures)
, m_source(source)
+ , m_varDeclarations(WTFMove(varEnvironment))
, m_sloppyModeHoistedFunctions(WTFMove(sloppyModeHoistedFunctions))
, m_numConstants(numConstants)
, m_statements(children)
{
- m_varDeclarations.swap(varEnvironment);
}
StatementNode* ScopeNode::singleStatement() const
@@ -166,8 +166,8 @@
// ------------------------------ ProgramNode -----------------------------
-ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
- : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
+ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
+ : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
, m_startColumn(startColumn)
, m_endColumn(endColumn)
{
@@ -175,8 +175,8 @@
// ------------------------------ ModuleProgramNode -----------------------------
-ModuleProgramNode::ModuleProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&& moduleScopeData)
- : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
+ModuleProgramNode::ModuleProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&& moduleScopeData)
+ : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
, m_startColumn(startColumn)
, m_endColumn(endColumn)
, m_usesAwait(features & AwaitFeature)
@@ -186,8 +186,8 @@
// ------------------------------ EvalNode -----------------------------
-EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
- : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
+EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
+ : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
, m_endColumn(endColumn)
{
}
@@ -306,8 +306,8 @@
// ------------------------------ FunctionNode -----------------------------
-FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters* parameters, const SourceCode& sourceCode, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
- : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
+FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters* parameters, const SourceCode& sourceCode, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
+ : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
, m_parameters(parameters)
, m_startColumn(startColumn)
, m_endColumn(endColumn)
@@ -360,15 +360,15 @@
return false;
}
-VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment& lexicalVariables)
+VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment&& lexicalVariables)
+ : m_lexicalVariables(WTFMove(lexicalVariables))
{
- m_lexicalVariables.swap(lexicalVariables);
}
-VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment& lexicalVariables, FunctionStack&& functionStack)
+VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment&& lexicalVariables, FunctionStack&& functionStack)
+ : m_lexicalVariables(WTFMove(lexicalVariables))
+ , m_functionStack(WTFMove(functionStack))
{
- m_lexicalVariables.swap(lexicalVariables);
- m_functionStack = WTFMove(functionStack);
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/parser/Nodes.h (279446 => 279447)
--- trunk/Source/_javascript_Core/parser/Nodes.h 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/parser/Nodes.h 2021-07-01 02:03:55 UTC (rev 279447)
@@ -273,13 +273,10 @@
public:
typedef DeclarationStacks::FunctionStack FunctionStack;
- VariableEnvironmentNode()
- {
- }
+ VariableEnvironmentNode() = default;
+ VariableEnvironmentNode(VariableEnvironment&& lexicalDeclaredVariables);
+ VariableEnvironmentNode(VariableEnvironment&& lexicalDeclaredVariables, FunctionStack&&);
- VariableEnvironmentNode(VariableEnvironment& lexicalDeclaredVariables);
- VariableEnvironmentNode(VariableEnvironment& lexicalDeclaredVariables, FunctionStack&&);
-
VariableEnvironment& lexicalVariables() { return m_lexicalVariables; }
FunctionStack& functionStack() { return m_functionStack; }
@@ -1624,7 +1621,7 @@
class BlockNode final : public StatementNode, public VariableEnvironmentNode {
JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(BlockNode);
public:
- BlockNode(const JSTokenLocation&, SourceElements*, VariableEnvironment&, FunctionStack&&);
+ BlockNode(const JSTokenLocation&, SourceElements*, VariableEnvironment&&, FunctionStack&&);
StatementNode* singleStatement() const;
StatementNode* lastStatement() const;
@@ -1746,7 +1743,7 @@
class ForNode final : public StatementNode, public VariableEnvironmentNode {
JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ForNode);
public:
- ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*, VariableEnvironment&);
+ ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*, VariableEnvironment&&);
private:
void emitBytecode(BytecodeGenerator&, RegisterID* = nullptr) final;
@@ -1762,7 +1759,7 @@
class EnumerationNode : public StatementNode, public ThrowableExpressionData, public VariableEnvironmentNode {
JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(EnumerationNode);
public:
- EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&);
+ EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&&);
ExpressionNode* lexpr() const { return m_lexpr; }
ExpressionNode* expr() const { return m_expr; }
@@ -1776,7 +1773,7 @@
class ForInNode final : public EnumerationNode {
JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ForInNode);
public:
- ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&);
+ ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&&);
private:
RegisterID* tryGetBoundLocal(BytecodeGenerator&);
@@ -1788,7 +1785,7 @@
class ForOfNode final : public EnumerationNode {
JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ForOfNode);
public:
- ForOfNode(bool, const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&);
+ ForOfNode(bool, const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&&);
bool isForOfNode() const final { return true; }
bool isForAwait() const { return m_isForAwait; }
@@ -1878,7 +1875,7 @@
class TryNode final : public StatementNode, public VariableEnvironmentNode {
JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(TryNode);
public:
- TryNode(const JSTokenLocation&, StatementNode* tryBlock, DestructuringPatternNode* catchPattern, StatementNode* catchBlock, VariableEnvironment& catchEnvironment, StatementNode* finallyBlock);
+ TryNode(const JSTokenLocation&, StatementNode* tryBlock, DestructuringPatternNode* catchPattern, StatementNode* catchBlock, VariableEnvironment&& catchEnvironment, StatementNode* finallyBlock);
private:
void emitBytecode(BytecodeGenerator&, RegisterID* = nullptr) final;
@@ -1898,7 +1895,7 @@
using ParserArenaRoot::operator new;
ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, LexicalScopeFeatures);
- ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, CodeFeatures, LexicalScopeFeatures, InnerArrowFunctionCodeFeatures, int numConstants);
+ ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VariableEnvironment&&, FunctionStack&&, VariableEnvironment&&, UniquedStringImplPtrSet&&, CodeFeatures, LexicalScopeFeatures, InnerArrowFunctionCodeFeatures, int numConstants);
const SourceCode& source() const { return m_source; }
intptr_t sourceID() const { return m_source.providerID(); }
@@ -1974,7 +1971,7 @@
class ProgramNode final : public ScopeNode {
public:
- ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, LexicalScopeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
+ ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&&, FunctionStack&&, VariableEnvironment&&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, LexicalScopeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
unsigned startColumn() const { return m_startColumn; }
unsigned endColumn() const { return m_endColumn; }
@@ -1989,7 +1986,7 @@
class EvalNode final : public ScopeNode {
public:
- EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, LexicalScopeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
+ EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&&, FunctionStack&&, VariableEnvironment&&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, LexicalScopeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
ALWAYS_INLINE unsigned startColumn() const { return 0; }
unsigned endColumn() const { return m_endColumn; }
@@ -2004,7 +2001,7 @@
class ModuleProgramNode final : public ScopeNode {
public:
- ModuleProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, LexicalScopeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
+ ModuleProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&&, FunctionStack&&, VariableEnvironment&&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, LexicalScopeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
unsigned startColumn() const { return m_startColumn; }
unsigned endColumn() const { return m_endColumn; }
@@ -2262,7 +2259,7 @@
class FunctionNode final : public ScopeNode {
public:
- FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, LexicalScopeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
+ FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&&, FunctionStack&&, VariableEnvironment&&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, LexicalScopeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
FunctionParameters* parameters() const { return m_parameters; }
@@ -2378,7 +2375,7 @@
JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ClassExprNode);
public:
ClassExprNode(const JSTokenLocation&, const Identifier&, const SourceCode& classSource,
- VariableEnvironment& classEnvironment, ExpressionNode* constructorExpresssion,
+ VariableEnvironment&& classHeadEnvironment, VariableEnvironment&& classEnvironment, ExpressionNode* constructorExpresssion,
ExpressionNode* parentClass, PropertyListNode* classElements);
const Identifier& name() { return m_name; }
@@ -2393,6 +2390,7 @@
bool isClassExprNode() const final { return true; }
+ VariableEnvironment m_classHeadEnvironment;
SourceCode m_classSource;
const Identifier& m_name;
const Identifier* m_ecmaName;
@@ -2675,7 +2673,7 @@
class SwitchNode final : public StatementNode, public VariableEnvironmentNode {
JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(SwitchNode);
public:
- SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*, VariableEnvironment&, FunctionStack&&);
+ SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*, VariableEnvironment&&, FunctionStack&&);
private:
void emitBytecode(BytecodeGenerator&, RegisterID* = nullptr) final;
Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (279446 => 279447)
--- trunk/Source/_javascript_Core/parser/Parser.cpp 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp 2021-07-01 02:03:55 UTC (rev 279447)
@@ -214,6 +214,11 @@
out.print(*m_data.cooked);
}
+static ALWAYS_INLINE bool isPrivateFieldName(UniquedStringImpl* uid)
+{
+ return uid->length() && uid->at(0) == '#';
+}
+
template <typename LexerType>
Expected<typename Parser<LexerType>::ParseInnerResult, String> Parser<LexerType>::parseInner(const Identifier& calleeName, ParsingContext parsingContext, std::optional<int> functionConstructorParametersEndPosition, const FixedVector<JSTextPosition>* classFieldLocations, const PrivateNameEnvironment* parentScopePrivateNames)
{
@@ -291,8 +296,21 @@
if (!sourceElements || !validEnding)
return makeUnexpected(hasError() ? m_errorMessage : "Parser error"_s);
- if (hasPrivateNames && scope->hasUsedButUndeclaredPrivateNames())
- return makeUnexpected("Cannot reference undeclared private names");
+ if (Options::usePrivateClassFields() && !m_lexer->isReparsingFunction() && m_seenPrivateNameUseInNonReparsingFunctionMode) {
+ String errorMessage;
+ scope->forEachUsedVariable([&] (UniquedStringImpl* impl) {
+ if (!isPrivateFieldName(impl))
+ return IterationStatus::Continue;
+ if (parentScopePrivateNames && parentScopePrivateNames->contains(impl))
+ return IterationStatus::Continue;
+ if (scope->lexicalVariables().contains(impl))
+ return IterationStatus::Continue;
+ errorMessage = makeString("Cannot reference undeclared private names: \"", String(impl), "\"");
+ return IterationStatus::Done;
+ });
+ if (!errorMessage.isNull())
+ return makeUnexpected(errorMessage);
+ }
IdentifierSet capturedVariables;
UniquedStringImplPtrSet sloppyModeHoistedFunctions;
@@ -302,6 +320,7 @@
VariableEnvironment& varDeclarations = scope->declaredVariables();
for (auto& entry : capturedVariables)
varDeclarations.markVariableAsCaptured(entry);
+ scope->finalizeLexicalEnvironment();
if (isGeneratorWrapperParseMode(parseMode) || isAsyncFunctionOrAsyncGeneratorWrapperParseMode(parseMode)) {
if (scope->usedVariablesContains(m_vm.propertyNames->arguments.impl()))
@@ -311,7 +330,7 @@
CodeFeatures features = context.features();
if (scope->shadowsArguments())
features |= ShadowsArgumentsFeature;
- if (m_seenTaggedTemplate)
+ if (m_seenTaggedTemplateInNonReparsingFunctionMode)
features |= NoEvalCacheFeature;
if (scope->hasNonSimpleParameterList())
features |= NonSimpleParameterListFeature;
@@ -331,7 +350,7 @@
}
#endif // ASSERT_ENABLED
- return ParseInnerResult { parameters, sourceElements, scope->takeFunctionDeclarations(), WTFMove(varDeclarations), WTFMove(sloppyModeHoistedFunctions), features, context.numConstants() };
+ return ParseInnerResult { parameters, sourceElements, scope->takeFunctionDeclarations(), scope->takeDeclaredVariables(), scope->takeLexicalEnvironment(), WTFMove(sloppyModeHoistedFunctions), features, context.numConstants() };
}
template <typename LexerType>
@@ -1384,23 +1403,16 @@
bool isConstDeclaration = match(CONSTTOKEN);
bool forLoopConstDoesNotHaveInitializer = false;
- VariableEnvironment dummySet;
- VariableEnvironment* lexicalVariables = nullptr;
AutoCleanupLexicalScope lexicalScope;
- auto gatherLexicalVariablesIfNecessary = [&] {
+ auto popLexicalScopeIfNecessary = [&]() -> VariableEnvironment {
if (isLetDeclaration || isConstDeclaration) {
- ScopeRef scope = lexicalScope.scope();
- lexicalVariables = &scope->finalizeLexicalEnvironment();
- } else
- lexicalVariables = &dummySet;
+ auto [lexicalVariables, functionDeclarations] = popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
+ return lexicalVariables;
+ }
+ return { };
};
- auto popLexicalScopeIfNecessary = [&] {
- if (isLetDeclaration || isConstDeclaration)
- popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
- };
-
if (isVarDeclaration || isLetDeclaration || isConstDeclaration) {
/*
for (var/let/const IDENT in/of _expression_) statement
@@ -1477,19 +1489,13 @@
TreeStatement statement = parseStatement(context, unused);
endLoop();
failIfFalse(statement, "Expected statement as body of for-", isOfEnumeration ? "of" : "in", " statement");
- gatherLexicalVariablesIfNecessary();
- TreeStatement result;
+ VariableEnvironment lexicalVariables = popLexicalScopeIfNecessary();
if (isOfEnumeration)
- result = context.createForOfLoop(isAwaitFor, location, forInTarget, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables);
- else {
- ASSERT(!isAwaitFor);
- if (isVarDeclaration && forInInitializer)
- result = context.createForInLoop(location, decls, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables);
- else
- result = context.createForInLoop(location, forInTarget, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables);
- }
- popLexicalScopeIfNecessary();
- return result;
+ return context.createForOfLoop(isAwaitFor, location, forInTarget, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, WTFMove(lexicalVariables));
+ ASSERT(!isAwaitFor);
+ if (isVarDeclaration && forInInitializer)
+ return context.createForInLoop(location, decls, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, WTFMove(lexicalVariables));
+ return context.createForInLoop(location, forInTarget, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, WTFMove(lexicalVariables));
}
if (!match(SEMICOLON)) {
@@ -1542,10 +1548,8 @@
TreeStatement statement = parseStatement(context, unused);
endLoop();
failIfFalse(statement, "Expected a statement as the body of a for loop");
- gatherLexicalVariablesIfNecessary();
- TreeStatement result = context.createForLoop(location, decls, condition, increment, statement, startLine, endLine, *lexicalVariables);
- popLexicalScopeIfNecessary();
- return result;
+ VariableEnvironment lexicalVariables = popLexicalScopeIfNecessary();
+ return context.createForLoop(location, decls, condition, increment, statement, startLine, endLine, WTFMove(lexicalVariables));
}
// For-in and For-of loop
@@ -1579,30 +1583,22 @@
TreeStatement statement = parseStatement(context, unused);
endLoop();
failIfFalse(statement, "Expected a statement as the body of a for-", isOfEnumeration ? "of" : "in", "loop");
- gatherLexicalVariablesIfNecessary();
- TreeStatement result;
if (pattern) {
ASSERT(!decls);
+ VariableEnvironment lexicalVariables = popLexicalScopeIfNecessary();
if (isOfEnumeration)
- result = context.createForOfLoop(isAwaitFor, location, pattern, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
- else {
- ASSERT(!isAwaitFor);
- result = context.createForInLoop(location, pattern, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
- }
-
- popLexicalScopeIfNecessary();
- return result;
+ return context.createForOfLoop(isAwaitFor, location, pattern, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, WTFMove(lexicalVariables));
+ ASSERT(!isAwaitFor);
+ return context.createForInLoop(location, pattern, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, WTFMove(lexicalVariables));
}
semanticFailIfFalse(isSimpleAssignmentTarget(context, decls), "Left side of assignment is not a reference");
+
+ VariableEnvironment lexicalVariables = popLexicalScopeIfNecessary();
if (isOfEnumeration)
- result = context.createForOfLoop(isAwaitFor, location, decls, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
- else {
- ASSERT(!isAwaitFor);
- result = context.createForInLoop(location, decls, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
- }
- popLexicalScopeIfNecessary();
- return result;
+ return context.createForOfLoop(isAwaitFor, location, decls, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, WTFMove(lexicalVariables));
+ ASSERT(!isAwaitFor);
+ return context.createForInLoop(location, decls, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, WTFMove(lexicalVariables));
}
template <typename LexerType>
@@ -1751,9 +1747,8 @@
endSwitch();
handleProductionOrFail(CLOSEBRACE, "}", "end", "body of a 'switch'");
- TreeStatement result = context.createSwitchStatement(location, expr, firstClauses, defaultClause, secondClauses, startLine, endLine, lexicalScope->finalizeLexicalEnvironment(), lexicalScope->takeFunctionDeclarations());
- popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
- return result;
+ auto [lexicalEnvironment, functionDeclarations] = popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
+ return context.createSwitchStatement(location, expr, firstClauses, defaultClause, secondClauses, startLine, endLine, WTFMove(lexicalEnvironment), WTFMove(functionDeclarations));
}
template <typename LexerType>
@@ -1820,6 +1815,7 @@
failIfFalse(tryBlock, "Cannot parse the body of try block");
int lastLine = m_lastTokenEndPosition.line;
VariableEnvironment catchEnvironment;
+ DeclarationStacks::FunctionStack functionStack;
if (match(CATCH)) {
next();
@@ -1849,9 +1845,9 @@
constexpr bool isCatchBlock = true;
catchBlock = parseBlockStatement(context, isCatchBlock);
failIfFalse(catchBlock, "Unable to parse 'catch' block");
- catchEnvironment = catchScope->finalizeLexicalEnvironment();
+ std::tie(catchEnvironment, functionStack) = popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo);
+ ASSERT(functionStack.isEmpty());
RELEASE_ASSERT(!ident || (catchEnvironment.size() == 1 && catchEnvironment.contains(ident->impl())));
- popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo);
}
}
@@ -1862,7 +1858,7 @@
failIfFalse(finallyBlock, "Cannot parse finally body");
}
failIfFalse(catchBlock || finallyBlock, "Try statements must have at least a catch or finally block");
- return context.createTryStatement(location, tryBlock, catchPattern, catchBlock, finallyBlock, firstLine, lastLine, catchEnvironment);
+ return context.createTryStatement(location, tryBlock, catchPattern, catchBlock, finallyBlock, firstLine, lastLine, WTFMove(catchEnvironment));
}
template <typename LexerType>
@@ -1899,17 +1895,17 @@
JSTokenLocation location(tokenLocation());
int startOffset = m_token.m_data.offset;
int start = tokenLine();
- VariableEnvironment emptyEnvironment;
- DeclarationStacks::FunctionStack emptyFunctionStack;
+ VariableEnvironment lexicalEnvironment;
+ DeclarationStacks::FunctionStack functionStack;
next();
if (match(CLOSEBRACE)) {
int endOffset = m_token.m_data.offset;
next();
- TreeStatement result = context.createBlockStatement(location, 0, start, m_lastTokenEndPosition.line, shouldPushLexicalScope ? currentScope()->finalizeLexicalEnvironment() : emptyEnvironment, shouldPushLexicalScope ? currentScope()->takeFunctionDeclarations() : WTFMove(emptyFunctionStack));
+ if (shouldPushLexicalScope)
+ std::tie(lexicalEnvironment, functionStack) = popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
+ TreeStatement result = context.createBlockStatement(location, 0, start, m_lastTokenEndPosition.line, WTFMove(lexicalEnvironment), WTFMove(functionStack));
context.setStartOffset(result, startOffset);
context.setEndOffset(result, endOffset);
- if (shouldPushLexicalScope)
- popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
return result;
}
TreeSourceElements subtree = parseSourceElements(context, DontCheckForStrictMode);
@@ -1917,12 +1913,11 @@
matchOrFail(CLOSEBRACE, "Expected a closing '}' at the end of a block statement");
int endOffset = m_token.m_data.offset;
next();
- TreeStatement result = context.createBlockStatement(location, subtree, start, m_lastTokenEndPosition.line, shouldPushLexicalScope ? currentScope()->finalizeLexicalEnvironment() : emptyEnvironment, shouldPushLexicalScope ? currentScope()->takeFunctionDeclarations() : WTFMove(emptyFunctionStack));
+ if (shouldPushLexicalScope)
+ std::tie(lexicalEnvironment, functionStack) = popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
+ TreeStatement result = context.createBlockStatement(location, subtree, start, m_lastTokenEndPosition.line, WTFMove(lexicalEnvironment), WTFMove(functionStack));
context.setStartOffset(result, startOffset);
context.setEndOffset(result, endOffset);
- if (shouldPushLexicalScope)
- popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
-
return result;
}
@@ -2095,9 +2090,8 @@
failIfFalse(function, "Expected valid function statement after 'function' keyword");
TreeSourceElements sourceElements = context.createSourceElements();
context.appendStatement(sourceElements, function);
- TreeStatement result = context.createBlockStatement(location, sourceElements, start, m_lastTokenEndPosition.line, currentScope()->finalizeLexicalEnvironment(), currentScope()->takeFunctionDeclarations());
- popScope(blockScope, TreeBuilder::NeedsFreeVariableInfo);
- return result;
+ auto [lexicalEnvironment, functionDeclarations] = popScope(blockScope, TreeBuilder::NeedsFreeVariableInfo);
+ return context.createBlockStatement(location, sourceElements, start, m_lastTokenEndPosition.line, WTFMove(lexicalEnvironment), WTFMove(functionDeclarations));
}
template <typename LexerType>
@@ -2606,6 +2600,7 @@
if (TreeBuilder::NeedsFreeVariableInfo)
parentScope->addClosedVariableCandidateUnconditionally(impl);
}
+ return IterationStatus::Continue;
});
auto performParsingFunctionBody = [&] {
@@ -2890,14 +2885,25 @@
info.startColumn = tokenColumn();
info.startOffset = location.startOffset;
- AutoPopScopeRef classScope(this, pushScope());
- classScope->setIsLexicalScope();
- classScope->preventVarDeclarations();
- classScope->setStrictMode();
- bool declaresPrivateMethod = false;
- bool declaresPrivateAccessor = false;
- bool declaresStaticPrivateMethod = false;
- bool declaresStaticPrivateAccessor = false;
+ // We have a subtle problem here. Class heritage evaluation should find class declaration's constructor name, but should not find private name evaluation.
+ // For example,
+ //
+ // class A extends (
+ // class {
+ // constructor() {
+ // print(A); // This is OK.
+ // print(A.#test); // This is SyntaxError.
+ // }
+ // }) {
+ // static #test = 42;
+ // }
+ //
+ // We need to create two scopes here since private name lookup will traverse scope at linking time in CodeBlock.
+ // This classHeadScope is similar to functionScope in FunctionExpression with name.
+ AutoPopScopeRef classHeadScope(this, pushScope());
+ classHeadScope->setIsLexicalScope();
+ classHeadScope->preventVarDeclarations();
+ classHeadScope->setStrictMode();
next();
ASSERT_WITH_MESSAGE(requirements != FunctionNameRequirements::Unnamed, "Currently, there is no caller that uses FunctionNameRequirements::Unnamed for class syntax.");
@@ -2905,7 +2911,7 @@
if (match(IDENT) || isAllowedIdentifierAwait(m_token)) {
info.className = m_token.m_data.ident;
next();
- failIfTrue(classScope->declareLexicalVariable(info.className, true) & DeclarationResult::InvalidStrictMode, "'", info.className->impl(), "' is not a valid class name");
+ failIfTrue(classHeadScope->declareLexicalVariable(info.className, true) & DeclarationResult::InvalidStrictMode, "'", info.className->impl(), "' is not a valid class name");
} else if (requirements == FunctionNameRequirements::Named) {
if (match(OPENBRACE))
semanticFail("Class statements must have a name");
@@ -2921,12 +2927,22 @@
parentClass = parseMemberExpression(context);
failIfFalse(parentClass, "Cannot parse the parent class name");
}
- classScope->setIsClassScope();
const ConstructorKind constructorKind = parentClass ? ConstructorKind::Extends : ConstructorKind::Base;
JSTextPosition classHeadEnd = lastTokenEndPosition();
consumeOrFail(OPENBRACE, "Expected opening '{' at the start of a class body");
+ AutoPopScopeRef classScope(this, pushScope());
+ classScope->setIsLexicalScope();
+ classScope->preventVarDeclarations();
+ classScope->setStrictMode();
+ classScope->setIsClassScope();
+
+ bool declaresPrivateMethod = false;
+ bool declaresPrivateAccessor = false;
+ bool declaresStaticPrivateMethod = false;
+ bool declaresStaticPrivateAccessor = false;
+
TreeExpression constructor = 0;
TreePropertyList classElements = 0;
TreePropertyList classElementsTail = 0;
@@ -3168,14 +3184,11 @@
classElements->setHasPrivateAccessors(declaresPrivateAccessor || declaresStaticPrivateAccessor);
}
- if (Options::usePrivateClassFields()) {
- // Fail if there are no parent private name scopes and any used-but-undeclared private names.
- semanticFailIfFalse(copyUndeclaredPrivateNamesToOuterScope(), "Cannot reference undeclared private names");
- }
-
- auto classExpression = context.createClassExpr(location, info, classScope->finalizeLexicalEnvironment(), constructor, parentClass, classElements, start, divot, classHeadEnd);
- popScope(classScope, TreeBuilder::NeedsFreeVariableInfo);
- return classExpression;
+ auto [lexicalEnvironment, functionDeclarations] = popScope(classScope, TreeBuilder::NeedsFreeVariableInfo);
+ auto [classHeadEnvironment, classHeadFunctionDeclarations] = popScope(classHeadScope, TreeBuilder::NeedsFreeVariableInfo);
+ ASSERT(functionDeclarations.isEmpty());
+ ASSERT(classHeadFunctionDeclarations.isEmpty());
+ return context.createClassExpr(location, info, WTFMove(classHeadEnvironment), WTFMove(lexicalEnvironment), constructor, parentClass, classElements, start, divot, classHeadEnd);
}
template <typename LexerType>
@@ -4237,8 +4250,8 @@
if (Options::usePrivateIn() && match(PRIVATENAME)) {
const Identifier* ident = m_token.m_data.ident;
ASSERT(ident);
- semanticFailIfFalse(usePrivateName(ident), "Cannot reference private names outside of class");
- currentScope()->useVariable(ident, false);
+ currentScope()->usePrivateName(*ident);
+ m_seenPrivateNameUseInNonReparsingFunctionMode = true;
next();
semanticFailIfTrue(m_token.m_type != INTOKEN, "Bare private name can only be used as the left-hand side of an `in` _expression_");
current = context.createPrivateIdentifierNode(location, *ident);
@@ -5048,22 +5061,6 @@
}
template <typename LexerType>
-bool Parser<LexerType>::usePrivateName(const Identifier* ident)
-{
- if (m_lexer->isReparsingFunction())
- return true;
-
- if (auto maybeCurrent = findPrivateNameScope()) {
- ScopeRef current = maybeCurrent.value();
- if (!current->hasPrivateName(*ident))
- current->usePrivateName(*ident);
- return true;
- }
-
- return false;
-}
-
-template <typename LexerType>
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpression(TreeBuilder& context)
{
TreeExpression base = 0;
@@ -5272,9 +5269,9 @@
failIfTrue(baseIsSuper, "Cannot access private names from super");
if (UNLIKELY(currentScope()->evalContextType() == EvalContextType::InstanceFieldEvalContext))
semanticFailIfFalse(currentScope()->hasPrivateName(*ident), "Cannot reference undeclared private field '", ident->impl(), "'");
- semanticFailIfFalse(usePrivateName(ident), "Cannot reference private names outside of class");
+ currentScope()->usePrivateName(*ident);
+ m_seenPrivateNameUseInNonReparsingFunctionMode = true;
m_parserState.lastPrivateName = ident;
- currentScope()->useVariable(ident, false);
type = DotType::PrivateMember;
m_token.m_type = IDENT;
}
@@ -5294,7 +5291,7 @@
failIfFalse(templateLiteral, "Cannot parse template literal");
base = context.createTaggedTemplate(startLocation, base, templateLiteral, expressionStart, expressionEnd, lastTokenEndPosition());
m_parserState.nonLHSCount = nonLHSCount;
- m_seenTaggedTemplate = true;
+ m_seenTaggedTemplateInNonReparsingFunctionMode = true;
break;
}
default:
Modified: trunk/Source/_javascript_Core/parser/Parser.h (279446 => 279447)
--- trunk/Source/_javascript_Core/parser/Parser.h 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/parser/Parser.h 2021-07-01 02:03:55 UTC (rev 279447)
@@ -23,6 +23,7 @@
#pragma once
#include "ExecutableInfo.h"
+#include "IterationStatus.h"
#include "Lexer.h"
#include "ModuleScopeData.h"
#include "Nodes.h"
@@ -319,16 +320,17 @@
const HashSet<UniquedStringImpl*>& closedVariableCandidates() const { return m_closedVariableCandidates; }
VariableEnvironment& declaredVariables() { return m_declaredVariables; }
VariableEnvironment& lexicalVariables() { return m_lexicalVariables; }
- VariableEnvironment& finalizeLexicalEnvironment()
- {
+ void finalizeLexicalEnvironment()
+ {
if (m_usesEval || m_needsFullActivation)
m_lexicalVariables.markAllVariablesAsCaptured();
else
computeLexicallyCapturedVariablesAndPurgeCandidates();
-
- return m_lexicalVariables;
}
+ VariableEnvironment takeLexicalEnvironment() { return WTFMove(m_lexicalVariables); }
+ VariableEnvironment takeDeclaredVariables() { return WTFMove(m_declaredVariables); }
+
void computeLexicallyCapturedVariablesAndPurgeCandidates()
{
// Because variables may be defined at any time in the range of a lexical scope, we must
@@ -421,7 +423,7 @@
ASSERT(node);
m_functionDeclarations.append(node);
}
- DeclarationStacks::FunctionStack&& takeFunctionDeclarations() { return WTFMove(m_functionDeclarations); }
+ DeclarationStacks::FunctionStack takeFunctionDeclarations() { return WTFMove(m_functionDeclarations); }
DeclarationResultMask declareLexicalVariable(const Identifier* ident, bool isConstant, DeclarationImportType importType = DeclarationImportType::NotImported)
@@ -480,28 +482,6 @@
return m_lexicalVariables.hasPrivateName(ident);
}
- void copyUndeclaredPrivateNamesTo(Scope& other)
- {
- m_lexicalVariables.copyUndeclaredPrivateNamesTo(other.m_lexicalVariables);
- }
-
- bool hasUsedButUndeclaredPrivateNames() const
- {
- if (m_lexicalVariables.privateNamesSize() > 0) {
- for (auto entry : m_lexicalVariables.privateNames()) {
- if (entry.value.isUsed() && !entry.value.isDeclared())
- return true;
- }
- }
- return false;
- }
-
- void usePrivateName(const Identifier& ident)
- {
- ASSERT(m_allowsLexicalDeclarations);
- m_lexicalVariables.usePrivateName(ident);
- }
-
DeclarationResultMask declarePrivateMethod(const Identifier& ident, ClassElementTag tag)
{
ASSERT(m_allowsLexicalDeclarations);
@@ -611,8 +591,10 @@
void forEachUsedVariable(const Func& func)
{
for (const UniquedStringImplPtrSet& set : m_usedVariables) {
- for (UniquedStringImpl* impl : set)
- func(impl);
+ for (UniquedStringImpl* impl : set) {
+ if (func(impl) == IterationStatus::Done)
+ return;
+ }
}
}
void useVariable(const Identifier* ident, bool isEval)
@@ -624,10 +606,14 @@
m_usesEval |= isEval;
m_usedVariables.last().add(impl);
}
+ void usePrivateName(const Identifier& ident)
+ {
+ ASSERT(m_allowsLexicalDeclarations);
+ useVariable(&ident, false);
+ }
void pushUsedVariableSet() { m_usedVariables.append(UniquedStringImplPtrSet()); }
size_t currentUsedVariablesSize() { return m_usedVariables.size(); }
-
void revertToPreviousUsedVariables(size_t size) { m_usedVariables.resize(size); }
void setNeedsFullActivation() { m_needsFullActivation = true; }
@@ -1280,31 +1266,6 @@
return std::nullopt;
}
- ScopeRef privateNameScope()
- {
- ASSERT(m_scopeStack.size());
- unsigned i = m_scopeStack.size() - 1;
- while (i && !m_scopeStack[i].isPrivateNameScope())
- i--;
-
- ASSERT(m_scopeStack[i].isPrivateNameScope());
- return ScopeRef(&m_scopeStack, i);
- }
-
- bool copyUndeclaredPrivateNamesToOuterScope()
- {
- ScopeRef current = privateNameScope();
- unsigned i = current.index() - 1;
- while (i && !m_scopeStack[i].isPrivateNameScope())
- i--;
-
- if (!i)
- return !current->hasUsedButUndeclaredPrivateNames();
-
- current->copyUndeclaredPrivateNamesTo(m_scopeStack[i]);
- return true;
- }
-
ScopeRef closestParentOrdinaryFunctionNonLexicalScope()
{
unsigned i = m_scopeStack.size() - 1;
@@ -1342,40 +1303,46 @@
return currentScope();
}
- void popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
+ std::tuple<VariableEnvironment, DeclarationStacks::FunctionStack> popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
{
EXCEPTION_ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
ASSERT(m_scopeStack.size() > 1);
- m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
+ Scope& lastScope = m_scopeStack.last();
+
+ // Finalize lexical variables.
+ lastScope.finalizeLexicalEnvironment();
+ m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&lastScope, shouldTrackClosedVariables);
- if (m_scopeStack.last().isArrowFunction())
- m_scopeStack.last().setInnerArrowFunctionUsesEvalAndUseArgumentsIfNeeded();
+ if (lastScope.isArrowFunction())
+ lastScope.setInnerArrowFunctionUsesEvalAndUseArgumentsIfNeeded();
- if (!(m_scopeStack.last().isFunctionBoundary() && !m_scopeStack.last().isArrowFunctionBoundary()))
- m_scopeStack[m_scopeStack.size() - 2].mergeInnerArrowFunctionFeatures(m_scopeStack.last().innerArrowFunctionFeatures());
+ if (!(lastScope.isFunctionBoundary() && !lastScope.isArrowFunctionBoundary()))
+ m_scopeStack[m_scopeStack.size() - 2].mergeInnerArrowFunctionFeatures(lastScope.innerArrowFunctionFeatures());
- if (!m_scopeStack.last().isFunctionBoundary() && m_scopeStack.last().needsFullActivation())
+ if (!lastScope.isFunctionBoundary() && lastScope.needsFullActivation())
m_scopeStack[m_scopeStack.size() - 2].setNeedsFullActivation();
+ std::tuple result { lastScope.takeLexicalEnvironment(), lastScope.takeFunctionDeclarations() };
m_scopeStack.removeLast();
+ return result;
}
- ALWAYS_INLINE void popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
+ ALWAYS_INLINE std::tuple<VariableEnvironment, DeclarationStacks::FunctionStack> popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
{
- popScopeInternal(scope, shouldTrackClosedVariables);
+ return popScopeInternal(scope, shouldTrackClosedVariables);
}
- ALWAYS_INLINE void popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
+ ALWAYS_INLINE std::tuple<VariableEnvironment, DeclarationStacks::FunctionStack> popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
{
scope.setPopped();
- popScopeInternal(scope, shouldTrackClosedVariables);
+ return popScopeInternal(scope, shouldTrackClosedVariables);
}
- ALWAYS_INLINE void popScope(AutoCleanupLexicalScope& cleanupScope, bool shouldTrackClosedVariables)
+ ALWAYS_INLINE std::tuple<VariableEnvironment, DeclarationStacks::FunctionStack> popScope(AutoCleanupLexicalScope& cleanupScope, bool shouldTrackClosedVariables)
{
RELEASE_ASSERT(cleanupScope.isValid());
ScopeRef& scope = cleanupScope.scope();
cleanupScope.setPopped();
- popScopeInternal(scope, shouldTrackClosedVariables);
+ return popScopeInternal(scope, shouldTrackClosedVariables);
}
NEVER_INLINE DeclarationResultMask declareHoistedVariable(const Identifier* ident)
@@ -1509,6 +1476,7 @@
SourceElements* sourceElements;
DeclarationStacks::FunctionStack functionDeclarations;
VariableEnvironment varDeclarations;
+ VariableEnvironment lexicalVariables;
UniquedStringImplPtrSet sloppyModeHoistedFunctions;
CodeFeatures features;
int numConstants;
@@ -1839,8 +1807,6 @@
template <class TreeBuilder> ALWAYS_INLINE bool isSimpleAssignmentTarget(TreeBuilder&, TreeExpression);
- ALWAYS_INLINE bool usePrivateName(const Identifier*);
-
ALWAYS_INLINE int isBinaryOperator(JSTokenType);
bool allowAutomaticSemicolon();
@@ -2123,8 +2089,9 @@
RefPtr<ModuleScopeData> m_moduleScopeData;
DebuggerParseData* m_debuggerParseData;
CallOrApplyDepthScope* m_callOrApplyDepthScope { nullptr };
- bool m_seenTaggedTemplate { false };
bool m_isInsideOrdinaryFunction;
+ bool m_seenTaggedTemplateInNonReparsingFunctionMode { false };
+ bool m_seenPrivateNameUseInNonReparsingFunctionMode { false };
};
@@ -2172,9 +2139,9 @@
startColumn,
endColumn,
parseResult.value().sourceElements,
- parseResult.value().varDeclarations,
+ WTFMove(parseResult.value().varDeclarations),
WTFMove(parseResult.value().functionDeclarations),
- currentScope()->finalizeLexicalEnvironment(),
+ WTFMove(parseResult.value().lexicalVariables),
WTFMove(parseResult.value().sloppyModeHoistedFunctions),
parseResult.value().parameters,
*m_source,
Modified: trunk/Source/_javascript_Core/parser/SyntaxChecker.h (279446 => 279447)
--- trunk/Source/_javascript_Core/parser/SyntaxChecker.h 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/parser/SyntaxChecker.h 2021-07-01 02:03:55 UTC (rev 279447)
@@ -192,7 +192,7 @@
ExpressionType createYield(const JSTokenLocation&) { return YieldExpr; }
ExpressionType createYield(const JSTokenLocation&, ExpressionType, bool, int, int, int) { return YieldExpr; }
ExpressionType createAwait(const JSTokenLocation&, ExpressionType, int, int, int) { return AwaitExpr; }
- ClassExpression createClassExpr(const JSTokenLocation&, const ParserClassInfo<SyntaxChecker>&, VariableEnvironment&, ExpressionType, ExpressionType, PropertyList, int, int, int) { return ClassExpr; }
+ ClassExpression createClassExpr(const JSTokenLocation&, const ParserClassInfo<SyntaxChecker>&, VariableEnvironment&&, VariableEnvironment&&, ExpressionType, ExpressionType, PropertyList, int, int, int) { return ClassExpr; }
ExpressionType createFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
ExpressionType createGeneratorFunctionBody(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&, const Identifier&) { return FunctionExpr; }
ExpressionType createAsyncFunctionBody(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
@@ -251,13 +251,13 @@
int createDefineField(const JSTokenLocation&, const Identifier*, int, DefineFieldNode::Type) { return 0; }
int createClassDeclStatement(const JSTokenLocation&, ClassExpression,
const JSTextPosition&, const JSTextPosition&, int, int) { return StatementResult; }
- int createBlockStatement(const JSTokenLocation&, int, int, int, VariableEnvironment&, DeclarationStacks::FunctionStack&&) { return StatementResult; }
+ int createBlockStatement(const JSTokenLocation&, int, int, int, VariableEnvironment&&, DeclarationStacks::FunctionStack&&) { return StatementResult; }
int createExprStatement(const JSTokenLocation&, int, int, int) { return StatementResult; }
int createIfStatement(const JSTokenLocation&, int, int, int, int) { return StatementResult; }
int createIfStatement(const JSTokenLocation&, int, int, int, int, int) { return StatementResult; }
- int createForLoop(const JSTokenLocation&, int, int, int, int, int, int, VariableEnvironment&) { return StatementResult; }
- int createForInLoop(const JSTokenLocation&, int, int, int, const JSTokenLocation&, int, int, int, int, int, VariableEnvironment&) { return StatementResult; }
- int createForOfLoop(bool, const JSTokenLocation&, int, int, int, const JSTokenLocation&, int, int, int, int, int, VariableEnvironment&) { return StatementResult; }
+ int createForLoop(const JSTokenLocation&, int, int, int, int, int, int, VariableEnvironment&&) { return StatementResult; }
+ int createForInLoop(const JSTokenLocation&, int, int, int, const JSTokenLocation&, int, int, int, int, int, VariableEnvironment&&) { return StatementResult; }
+ int createForOfLoop(bool, const JSTokenLocation&, int, int, int, const JSTokenLocation&, int, int, int, int, int, VariableEnvironment&&) { return StatementResult; }
int createEmptyStatement(const JSTokenLocation&) { return StatementResult; }
int createDeclarationStatement(const JSTokenLocation&, int, int, int) { return StatementResult; }
int createReturnStatement(const JSTokenLocation&, int, int, int) { return StatementResult; }
@@ -265,8 +265,8 @@
int createBreakStatement(const JSTokenLocation&, const Identifier*, int, int) { return StatementResult; }
int createContinueStatement(const JSTokenLocation&, int, int) { return StatementResult; }
int createContinueStatement(const JSTokenLocation&, const Identifier*, int, int) { return StatementResult; }
- int createTryStatement(const JSTokenLocation&, int, int, int, int, int, int, VariableEnvironment&) { return StatementResult; }
- int createSwitchStatement(const JSTokenLocation&, int, int, int, int, int, int, VariableEnvironment&, DeclarationStacks::FunctionStack&&) { return StatementResult; }
+ int createTryStatement(const JSTokenLocation&, int, int, int, int, int, int, VariableEnvironment&&) { return StatementResult; }
+ int createSwitchStatement(const JSTokenLocation&, int, int, int, int, int, int, VariableEnvironment&&, DeclarationStacks::FunctionStack&&) { return StatementResult; }
int createWhileStatement(const JSTokenLocation&, int, int, int, int) { return StatementResult; }
int createWithStatement(const JSTokenLocation&, int, int, int, int, int, int) { return StatementResult; }
int createDoWhileStatement(const JSTokenLocation&, int, int, int, int) { return StatementResult; }
Modified: trunk/Source/_javascript_Core/parser/VariableEnvironment.cpp (279446 => 279447)
--- trunk/Source/_javascript_Core/parser/VariableEnvironment.cpp 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/parser/VariableEnvironment.cpp 2021-07-01 02:03:55 UTC (rev 279447)
@@ -25,10 +25,17 @@
#include "config.h"
#include "VariableEnvironment.h"
+#include <wtf/CommaPrinter.h>
+#include <wtf/HexNumber.h>
#include <wtf/text/UniquedStringImpl.h>
namespace JSC {
+void VariableEnvironmentEntry::dump(PrintStream& out) const
+{
+ out.print(hex(m_bits));
+}
+
VariableEnvironment& VariableEnvironment::operator=(const VariableEnvironment& other)
{
VariableEnvironment env(other);
@@ -104,6 +111,16 @@
findResult->value.setIsExported();
}
+VariableEnvironment::Map::AddResult VariableEnvironment::declarePrivateField(const RefPtr<UniquedStringImpl>& identifier)
+{
+ getOrAddPrivateName(identifier.get());
+ auto entry = VariableEnvironmentEntry();
+ entry.setIsPrivateField();
+ entry.setIsConst();
+ entry.setIsCaptured();
+ return m_map.add(identifier, entry);
+}
+
VariableEnvironment::PrivateDeclarationResult VariableEnvironment::declarePrivateAccessor(const RefPtr<UniquedStringImpl>& identifier, PrivateNameEntry accessorTraits)
{
if (!m_rareData)
@@ -112,7 +129,7 @@
auto findResult = m_rareData->m_privateNames.find(identifier);
if (findResult == m_rareData->m_privateNames.end()) {
- PrivateNameEntry meta(PrivateNameEntry::Traits::IsDeclared | accessorTraits.bits());
+ PrivateNameEntry meta(accessorTraits.bits());
auto entry = VariableEnvironmentEntry();
if (accessorTraits.isSetter())
@@ -130,43 +147,25 @@
}
PrivateNameEntry currentEntry = findResult->value;
- if (currentEntry.isDeclared()) {
- if ((accessorTraits.isSetter() && !currentEntry.isGetter())
- || (accessorTraits.isGetter() && !currentEntry.isSetter()))
- return PrivateDeclarationResult::DuplicatedName;
+ if ((accessorTraits.isSetter() && !currentEntry.isGetter())
+ || (accessorTraits.isGetter() && !currentEntry.isSetter()))
+ return PrivateDeclarationResult::DuplicatedName;
- if (accessorTraits.isStatic() != currentEntry.isStatic())
- return PrivateDeclarationResult::InvalidStaticNonStatic;
+ if (accessorTraits.isStatic() != currentEntry.isStatic())
+ return PrivateDeclarationResult::InvalidStaticNonStatic;
- PrivateNameEntry meta(currentEntry.bits() | accessorTraits.bits());
- m_rareData->m_privateNames.set(identifier, meta);
+ PrivateNameEntry meta(currentEntry.bits() | accessorTraits.bits());
+ m_rareData->m_privateNames.set(identifier, meta);
- auto entryIterator = m_map.find(identifier);
- ASSERT(entryIterator != m_map.end());
- if (accessorTraits.isSetter())
- entryIterator->value.setIsPrivateSetter();
- else {
- ASSERT(accessorTraits.isGetter());
- entryIterator->value.setIsPrivateGetter();
- }
-
- return PrivateDeclarationResult::Success;
- }
-
- // it was previously used, mark it as declared.
- auto entry = VariableEnvironmentEntry();
+ auto entryIterator = m_map.find(identifier);
+ ASSERT(entryIterator != m_map.end());
if (accessorTraits.isSetter())
- entry.setIsPrivateSetter();
+ entryIterator->value.setIsPrivateSetter();
else {
ASSERT(accessorTraits.isGetter());
- entry.setIsPrivateGetter();
+ entryIterator->value.setIsPrivateGetter();
}
- entry.setIsConst();
- entry.setIsCaptured();
- m_map.add(identifier, entry);
- PrivateNameEntry newEntry(currentEntry.bits() | PrivateNameEntry::Traits::IsDeclared | accessorTraits.bits());
- m_rareData->m_privateNames.set(identifier, newEntry);
return PrivateDeclarationResult::Success;
}
@@ -188,7 +187,7 @@
auto findResult = m_rareData->m_privateNames.find(identifier);
if (findResult == m_rareData->m_privateNames.end()) {
- PrivateNameEntry meta(PrivateNameEntry::Traits::IsDeclared | PrivateNameEntry::Traits::IsMethod | addionalTraits);
+ PrivateNameEntry meta(PrivateNameEntry::Traits::IsMethod | addionalTraits);
auto entry = VariableEnvironmentEntry();
entry.setIsPrivateMethod();
@@ -200,19 +199,14 @@
return addResult.isNewEntry;
}
- if (findResult->value.isDeclared())
- return false; // Error: declaring a duplicate private name.
+ return false; // Error: declaring a duplicate private name.
+}
- auto entry = VariableEnvironmentEntry();
- entry.setIsPrivateMethod();
- entry.setIsConst();
- entry.setIsCaptured();
- m_map.add(identifier, entry);
-
- // it was previously used, mark it as declared.
- PrivateNameEntry meta(PrivateNameEntry::Traits::IsDeclared | PrivateNameEntry::Traits::IsUsed | PrivateNameEntry::Traits::IsMethod | addionalTraits);
- auto addResult = m_rareData->m_privateNames.set(identifier, meta);
- return !addResult.isNewEntry;
+void VariableEnvironment::dump(PrintStream& out) const
+{
+ CommaPrinter comma(", ");
+ for (auto& pair : m_map)
+ out.print(comma, pair.key, " => ", pair.value);
}
void CompactTDZEnvironment::sortCompact(Compact& compact)
Modified: trunk/Source/_javascript_Core/parser/VariableEnvironment.h (279446 => 279447)
--- trunk/Source/_javascript_Core/parser/VariableEnvironment.h 2021-07-01 00:48:51 UTC (rev 279446)
+++ trunk/Source/_javascript_Core/parser/VariableEnvironment.h 2021-07-01 02:03:55 UTC (rev 279447)
@@ -74,6 +74,8 @@
return m_bits == other.m_bits;
}
+ void dump(PrintStream&) const;
+
private:
enum Traits : uint16_t {
IsCaptured = 1 << 0,
@@ -107,8 +109,6 @@
public:
PrivateNameEntry(uint16_t traits = 0) { m_bits = traits; }
- ALWAYS_INLINE bool isUsed() const { return m_bits & IsUsed; }
- ALWAYS_INLINE bool isDeclared() const { return m_bits & IsDeclared; }
ALWAYS_INLINE bool isMethod() const { return m_bits & IsMethod; }
ALWAYS_INLINE bool isSetter() const { return m_bits & IsSetter; }
ALWAYS_INLINE bool isGetter() const { return m_bits & IsGetter; }
@@ -117,9 +117,6 @@
bool isPrivateMethodOrAccessor() const { return isMethod() || isSetter() || isGetter(); }
- ALWAYS_INLINE void setIsUsed() { m_bits |= IsUsed; }
- ALWAYS_INLINE void setIsDeclared() { m_bits |= IsDeclared; }
-
uint16_t bits() const { return m_bits; }
bool operator==(const PrivateNameEntry& other) const
@@ -129,12 +126,10 @@
enum Traits : uint16_t {
None = 0,
- IsUsed = 1 << 0,
- IsDeclared = 1 << 1,
- IsMethod = 1 << 2,
- IsGetter = 1 << 3,
- IsSetter = 1 << 4,
- IsStatic = 1 << 5,
+ IsMethod = 1 << 0,
+ IsGetter = 1 << 1,
+ IsSetter = 1 << 2,
+ IsStatic = 1 << 3,
};
private:
@@ -206,7 +201,6 @@
using PrivateNamesRange = WTF::IteratorRange<PrivateNameEnvironment::iterator>;
ALWAYS_INLINE Map::AddResult declarePrivateField(const Identifier& identifier) { return declarePrivateField(identifier.impl()); }
- ALWAYS_INLINE void usePrivateName(const Identifier& identifier) { usePrivateName(identifier.impl()); }
bool declarePrivateMethod(const Identifier& identifier) { return declarePrivateMethod(identifier.impl()); }
bool declarePrivateMethod(const RefPtr<UniquedStringImpl>& identifier, PrivateNameEntry::Traits addionalTraits = PrivateNameEntry::Traits::None);
@@ -232,23 +226,7 @@
PrivateDeclarationResult declareStaticPrivateGetter(const Identifier& identifier) { return declarePrivateGetter(identifier.impl(), PrivateNameEntry::Traits::IsStatic); }
PrivateDeclarationResult declarePrivateGetter(const RefPtr<UniquedStringImpl>& identifier, PrivateNameEntry::Traits modifierTraits = PrivateNameEntry::Traits::None);
- Map::AddResult declarePrivateField(const RefPtr<UniquedStringImpl>& identifier)
- {
- auto& meta = getOrAddPrivateName(identifier.get());
- meta.setIsDeclared();
- auto entry = VariableEnvironmentEntry();
- entry.setIsPrivateField();
- entry.setIsConst();
- entry.setIsCaptured();
- return m_map.add(identifier, entry);
- }
- void usePrivateName(const RefPtr<UniquedStringImpl>& identifier)
- {
- auto& meta = getOrAddPrivateName(identifier.get());
- meta.setIsUsed();
- if (meta.isDeclared())
- find(identifier)->value.setIsCaptured();
- }
+ Map::AddResult declarePrivateField(const RefPtr<UniquedStringImpl>&);
ALWAYS_INLINE PrivateNamesRange privateNames() const
{
@@ -264,6 +242,13 @@
return m_rareData->m_privateNames.size();
}
+ ALWAYS_INLINE PrivateNameEnvironment* privateNameEnvironment()
+ {
+ if (!m_rareData)
+ return nullptr;
+ return &m_rareData->m_privateNames;
+ }
+
ALWAYS_INLINE const PrivateNameEnvironment* privateNameEnvironment() const
{
if (!m_rareData)
@@ -304,20 +289,6 @@
return m_rareData->m_privateNames.contains(identifier.impl());
}
- ALWAYS_INLINE void copyPrivateNamesTo(VariableEnvironment& other) const
- {
- if (!m_rareData)
- return;
- if (!other.m_rareData)
- other.m_rareData = WTF::makeUnique<VariableEnvironment::RareData>();
- if (privateNamesSize() > 0) {
- for (auto entry : privateNames()) {
- if (!(entry.value.isUsed() && entry.value.isDeclared()))
- other.m_rareData->m_privateNames.add(entry.key, entry.value);
- }
- }
- }
-
ALWAYS_INLINE void addPrivateNamesFrom(const PrivateNameEnvironment* privateNameEnvironment)
{
if (!privateNameEnvironment)
@@ -326,24 +297,10 @@
if (!m_rareData)
m_rareData = makeUnique<VariableEnvironment::RareData>();
- for (auto entry : *privateNameEnvironment) {
- ASSERT(entry.value.isDeclared());
+ for (auto entry : *privateNameEnvironment)
m_rareData->m_privateNames.add(entry.key, entry.value);
- }
}
- ALWAYS_INLINE void copyUndeclaredPrivateNamesTo(VariableEnvironment& outer) const {
- // Used by the Parser to transfer recorded uses of PrivateNames from an
- // inner PrivateNameEnvironment into an outer one, in case a PNE is used
- // earlier in the source code than it is defined.
- if (privateNamesSize() > 0) {
- for (auto entry : privateNames()) {
- if (entry.value.isUsed() && !entry.value.isDeclared())
- outer.getOrAddPrivateName(entry.key.get()).setIsUsed();
- }
- }
- }
-
struct RareData {
WTF_MAKE_STRUCT_FAST_ALLOCATED;
@@ -357,6 +314,8 @@
PrivateNameEnvironment m_privateNames;
};
+ void dump(PrintStream&) const;
+
private:
friend class CachedVariableEnvironment;