Index: src/parsing/parser-base.h |
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h |
index 92377acc7aa303382437f4d6e4c3b6f10dc4debc..4a40ce85d903e526da52c5e4c369246f56df8744 100644 |
--- a/src/parsing/parser-base.h |
+++ b/src/parsing/parser-base.h |
@@ -201,10 +201,10 @@ class ParserBase : public Traits { |
v8::Extension* extension, AstValueFactory* ast_value_factory, |
ParserRecorder* log, typename Traits::Type::Parser this_object) |
: Traits(this_object), |
- scope_(NULL), |
- function_state_(NULL), |
+ scope_state_(nullptr), |
+ function_state_(nullptr), |
extension_(extension), |
- fni_(NULL), |
+ fni_(nullptr), |
ast_value_factory_(ast_value_factory), |
log_(log), |
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
@@ -272,21 +272,34 @@ class ParserBase : public Traits { |
class ObjectLiteralCheckerBase; |
// --------------------------------------------------------------------------- |
- // FunctionState and BlockState together implement the parser's scope stack. |
- // The parser's current scope is in scope_. BlockState and FunctionState |
- // constructors push on the scope stack and the destructors pop. They are also |
- // used to hold the parser's per-function and per-block state. |
- class BlockState BASE_EMBEDDED { |
+ // ScopeState and its subclasses implement the parser's scope stack. |
+ // ScopeState keeps track of the current scope, and the outer ScopeState. The |
+ // parser's scope_state_ points to the top ScopeState. ScopeState's |
+ // constructor push on the scope stack and the destructors pop. BlockState and |
+ // FunctionState are used to hold additional per-block and per-function state. |
+ class ScopeState BASE_EMBEDDED { |
public: |
- BlockState(Scope** scope_stack, Scope* scope) |
- : scope_stack_(scope_stack), outer_scope_(*scope_stack) { |
- *scope_stack_ = scope; |
+ V8_INLINE Scope* scope() const { return scope_; } |
+ |
+ protected: |
+ ScopeState(ScopeState** scope_stack, Scope* scope) |
+ : scope_stack_(scope_stack), outer_scope_(*scope_stack), scope_(scope) { |
+ *scope_stack = this; |
} |
- ~BlockState() { *scope_stack_ = outer_scope_; } |
+ ~ScopeState() { *scope_stack_ = outer_scope_; } |
+ |
+ Zone* zone() const { return scope_->zone(); } |
private: |
- Scope** scope_stack_; |
- Scope* outer_scope_; |
+ ScopeState** scope_stack_; |
+ ScopeState* outer_scope_; |
+ Scope* scope_; |
+ }; |
+ |
+ class BlockState final : public ScopeState { |
+ public: |
+ BlockState(ScopeState** scope_stack, Scope* scope) |
+ : ScopeState(scope_stack, scope) {} |
}; |
struct DestructuringAssignment { |
@@ -356,10 +369,10 @@ class ParserBase : public Traits { |
kInsideForInOfBody, |
}; |
- class FunctionState BASE_EMBEDDED { |
+ class FunctionState final : public ScopeState { |
public: |
- FunctionState(FunctionState** function_state_stack, Scope** scope_stack, |
- Scope* scope, FunctionKind kind, |
+ FunctionState(FunctionState** function_state_stack, |
+ ScopeState** scope_stack, Scope* scope, FunctionKind kind, |
typename Traits::Type::Factory* factory); |
~FunctionState(); |
@@ -458,13 +471,11 @@ class ParserBase : public Traits { |
private: |
void AddDestructuringAssignment(DestructuringAssignment pair) { |
- destructuring_assignments_to_rewrite_.Add(pair, (*scope_stack_)->zone()); |
+ destructuring_assignments_to_rewrite_.Add(pair, this->zone()); |
} |
- V8_INLINE Scope* scope() { return *scope_stack_; } |
- |
void AddNonPatternForRewriting(ExpressionT expr, bool* ok) { |
- non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone()); |
+ non_patterns_to_rewrite_.Add(expr, this->zone()); |
if (non_patterns_to_rewrite_.length() >= |
std::numeric_limits<uint16_t>::max()) |
*ok = false; |
@@ -495,8 +506,6 @@ class ParserBase : public Traits { |
FunctionState** function_state_stack_; |
FunctionState* outer_function_state_; |
- Scope** scope_stack_; |
- Scope* outer_scope_; |
ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_; |
TailCallExpressionList tail_call_expressions_; |
@@ -815,7 +824,7 @@ class ParserBase : public Traits { |
return function_state_->factory(); |
} |
- LanguageMode language_mode() { return scope_->language_mode(); } |
+ LanguageMode language_mode() { return scope()->language_mode(); } |
bool is_generator() const { return function_state_->is_generator(); } |
bool is_async_function() const { |
return function_state_->is_async_function(); |
@@ -1191,7 +1200,10 @@ class ParserBase : public Traits { |
bool has_seen_constructor_; |
}; |
- Scope* scope_; // Scope stack. |
+ ModuleDescriptor* module() const { return scope()->module(); } |
+ Scope* scope() const { return scope_state_->scope(); } |
+ |
+ ScopeState* scope_state_; // Scope stack. |
FunctionState* function_state_; // Function state stack. |
v8::Extension* extension_; |
FuncNameInferrer* fni_; |
@@ -1221,9 +1233,10 @@ class ParserBase : public Traits { |
template <class Traits> |
ParserBase<Traits>::FunctionState::FunctionState( |
- FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, |
- FunctionKind kind, typename Traits::Type::Factory* factory) |
- : next_materialized_literal_index_(0), |
+ FunctionState** function_state_stack, ScopeState** scope_stack, |
+ Scope* scope, FunctionKind kind, typename Traits::Type::Factory* factory) |
+ : ScopeState(scope_stack, scope), |
+ next_materialized_literal_index_(0), |
expected_property_count_(0), |
this_location_(Scanner::Location::invalid()), |
return_location_(Scanner::Location::invalid()), |
@@ -1232,8 +1245,6 @@ ParserBase<Traits>::FunctionState::FunctionState( |
generator_object_variable_(NULL), |
function_state_stack_(function_state_stack), |
outer_function_state_(*function_state_stack), |
- scope_stack_(scope_stack), |
- outer_scope_(*scope_stack), |
destructuring_assignments_to_rewrite_(16, scope->zone()), |
tail_call_expressions_(scope->zone()), |
return_expr_context_(ReturnExprContext::kInsideValidBlock), |
@@ -1242,7 +1253,6 @@ ParserBase<Traits>::FunctionState::FunctionState( |
factory_(factory), |
next_function_is_parenthesized_(false), |
this_function_is_parenthesized_(false) { |
- *scope_stack_ = scope; |
*function_state_stack = this; |
if (outer_function_state_) { |
this_function_is_parenthesized_ = |
@@ -1254,7 +1264,6 @@ ParserBase<Traits>::FunctionState::FunctionState( |
template <class Traits> |
ParserBase<Traits>::FunctionState::~FunctionState() { |
- *scope_stack_ = outer_scope_; |
*function_state_stack_ = outer_function_state_; |
} |
@@ -1370,7 +1379,7 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
} |
} |
if (this->IsArguments(name)) { |
- scope_->RecordArgumentsUsage(); |
+ scope()->RecordArgumentsUsage(); |
classifier->RecordStrictModeFormalParameterError( |
scanner()->location(), MessageTemplate::kStrictEvalArguments); |
if (is_strict(language_mode())) { |
@@ -1438,7 +1447,7 @@ ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( |
} |
IdentifierT name = this->GetSymbol(scanner()); |
- if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
+ if (this->IsArguments(name)) scope()->RecordArgumentsUsage(); |
return name; |
} |
@@ -1458,7 +1467,7 @@ ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
} |
IdentifierT name = this->GetSymbol(scanner()); |
- if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
+ if (this->IsArguments(name)) scope()->RecordArgumentsUsage(); |
return name; |
} |
@@ -1516,7 +1525,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
case Token::THIS: { |
BindingPatternUnexpectedToken(classifier); |
Consume(Token::THIS); |
- return this->ThisExpression(scope_, factory(), beg_pos); |
+ return this->ThisExpression(scope(), factory(), beg_pos); |
} |
case Token::NULL_LITERAL: |
@@ -1549,7 +1558,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
// Using eval or arguments in this context is OK even in strict mode. |
IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
return this->ExpressionFromIdentifier( |
- name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
+ name, beg_pos, scanner()->location().end_pos, scope(), factory()); |
} |
case Token::STRING: { |
@@ -1975,7 +1984,7 @@ ParserBase<Traits>::ParsePropertyDefinition( |
} |
} |
ExpressionT lhs = this->ExpressionFromIdentifier( |
- *name, next_beg_pos, next_end_pos, scope_, factory()); |
+ *name, next_beg_pos, next_end_pos, scope(), factory()); |
CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); |
if (peek() == Token::ASSIGN) { |
@@ -2282,7 +2291,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
IdentifierT name = |
ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); |
expression = this->ExpressionFromIdentifier( |
- name, position(), scanner()->location().end_pos, scope_, factory()); |
+ name, position(), scanner()->location().end_pos, scope(), factory()); |
} |
if (peek() == Token::ARROW) { |
@@ -2298,13 +2307,13 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); |
Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
- Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE, |
+ Scope* scope = this->NewScope(this->scope(), FUNCTION_SCOPE, |
is_async ? FunctionKind::kAsyncArrowFunction |
: FunctionKind::kArrowFunction); |
// Because the arrow's parameters were parsed in the outer scope, any |
// usage flags that might have been triggered there need to be copied |
// to the arrow scope. |
- scope_->PropagateUsageFlagsToScope(scope); |
+ this->scope()->PropagateUsageFlagsToScope(scope); |
FormalParametersT parameters(scope); |
if (!arrow_formals_classifier.is_simple_parameter_list()) { |
scope->SetHasNonSimpleParameters(); |
@@ -2726,7 +2735,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, |
MessageTemplate::kAwaitBindingIdentifier); |
return this->ExpressionFromIdentifier( |
- name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
+ name, beg_pos, scanner()->location().end_pos, scope(), factory()); |
} |
default: |
break; |
@@ -2871,7 +2880,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression( |
// no explicit receiver. |
// These calls are marked as potentially direct eval calls. Whether |
// they are actually direct calls to eval is determined at run time. |
- this->CheckPossibleEvalCall(result, scope_); |
+ this->CheckPossibleEvalCall(result, scope()); |
bool is_super_call = result->IsSuperCallReference(); |
if (spread_pos.IsValid()) { |
@@ -2884,7 +2893,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression( |
// Explicit calls to the super constructor using super() perform an |
// implicit binding assignment to the 'this' variable. |
if (is_super_call) { |
- ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); |
+ ExpressionT this_expr = this->ThisExpression(scope(), factory(), pos); |
result = |
factory()->NewAssignment(Token::INIT, this_expr, result, pos); |
} |
@@ -3022,7 +3031,7 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, |
return this->EmptyExpression(); |
} |
- return this->FunctionSentExpression(scope_, factory(), pos); |
+ return this->FunctionSentExpression(scope(), factory(), pos); |
} |
bool is_generator = Check(Token::MUL); |
@@ -3065,13 +3074,13 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new, |
Expect(Token::SUPER, CHECK_OK); |
int pos = position(); |
- Scope* scope = scope_->ReceiverScope(); |
+ Scope* scope = this->scope()->ReceiverScope(); |
FunctionKind kind = scope->function_kind(); |
if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
IsClassConstructor(kind)) { |
if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
scope->RecordSuperPropertyUsage(); |
- return this->NewSuperPropertyReference(scope_, factory(), pos); |
+ return this->NewSuperPropertyReference(this->scope(), factory(), pos); |
} |
// new super() is never allowed. |
// super() is only allowed in derived constructor |
@@ -3079,7 +3088,7 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new, |
// TODO(rossberg): This might not be the correct FunctionState for the |
// method here. |
function_state_->set_super_location(scanner()->location()); |
- return this->NewSuperCallReference(scope_, factory(), pos); |
+ return this->NewSuperCallReference(this->scope(), factory(), pos); |
} |
} |
@@ -3108,14 +3117,14 @@ ParserBase<Traits>::ParseNewTargetExpression(bool* ok) { |
int pos = position(); |
ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK); |
- if (!scope_->ReceiverScope()->is_function_scope()) { |
+ if (!scope()->ReceiverScope()->is_function_scope()) { |
ReportMessageAt(scanner()->location(), |
MessageTemplate::kUnexpectedNewTarget); |
*ok = false; |
return this->EmptyExpression(); |
} |
- return this->NewTargetExpression(scope_, factory(), pos); |
+ return this->NewTargetExpression(scope(), factory(), pos); |
} |
template <class Traits> |
@@ -3357,7 +3366,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( |
FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; |
{ |
typename Traits::Type::Factory function_factory(ast_value_factory()); |
- FunctionState function_state(&function_state_, &scope_, |
+ FunctionState function_state(&function_state_, &scope_state_, |
formal_parameters.scope, arrow_kind, |
&function_factory); |
@@ -3372,7 +3381,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( |
// Multiple statement body |
Consume(Token::LBRACE); |
bool is_lazily_parsed = |
- (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); |
+ (mode() == PARSE_LAZILY && scope()->AllowsLazyParsing()); |
if (is_lazily_parsed) { |
body = this->NewStatementList(0, zone()); |
this->SkipLazyFunctionBody(&materialized_literal_count, |