| 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,
|
|
|