Commit 6c2c17cd authored by nikolaos's avatar nikolaos Committed by Commit bot

[parser] Apply an adaptation of the CRTP

This patch applies an adaptation of the Curiously Recurring Template
Pattern to the parser objects.  The result is roughly:

    // Common denominator, needed to avoid cyclic dependency.
    // Instances of this template will end up with very minimal
    // definitions, ideally containing just typedefs.
    template <typename Impl>
    class ParserBaseTraits;

    // The parser base object, which should just implement pure
    // parser behavior.  The Impl parameter is the actual derived
    // class (according to CRTP), which implements impure parser
    // behavior.
    template <typename Impl>
    class ParserBase : public ParserBaseTraits<Impl> { ... };

    // And then, for each parser variant:
    class Parser;

    template <>
    class ParserBaseTraits<Parser> { ... };

    class Parser : public ParserBase<Parser> { ... };

Using the CRTP, we will ultimately achieve two goals:
(1) clean up the traits objects, but most importantly
(2) clearly separate pure/impure parser implementation and facilitate
experimentation with different parser variants.

R=adamk@chromium.org, marja@chromium.org
BUG=
LOG=N

Review-Url: https://codereview.chromium.org/2267663002
Cr-Commit-Position: refs/heads/master@{#38819}
parent 1776fd09
...@@ -135,9 +135,38 @@ struct FormalParametersBase { ...@@ -135,9 +135,38 @@ struct FormalParametersBase {
// Used in functions where the return type is ExpressionT. // Used in functions where the return type is ExpressionT.
#define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression) #define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression)
// Common base class template shared between parser and pre-parser.
// The Impl parameter is the actual class of the parser/pre-parser,
// following the Curiously Recurring Template Pattern (CRTP).
// The structure of the parser objects is roughly the following:
//
// // Common denominator, needed to avoid cyclic dependency.
// // Instances of this template will end up with very minimal
// // definitions, ideally containing just typedefs.
// template <typename Impl>
// class ParserBaseTraits;
// // The parser base object, which should just implement pure
// // parser behavior. The Impl parameter is the actual derived
// // class (according to CRTP), which implements impure parser
// // behavior.
// template <typename Impl>
// class ParserBase : public ParserBaseTraits<Impl> { ... };
//
// // And then, for each parser variant (e.g., parser, preparser, etc):
// class Parser;
//
// template <>
// class ParserBaseTraits<Parser> { ... };
//
// class Parser : public ParserBase<Parser> { ... };
//
// TODO(nikolaos): Currently the traits objects contain many things
// that will be moved to the implementation objects or to the parser
// base. The following comments will have to change, when this happens.
// Common base class shared between parser and pre-parser. Traits encapsulate // The traits class template encapsulates the differences between
// the differences between Parser and PreParser: // parser/pre-parser implementations. In particular:
// - Return types: For example, Parser functions return Expression* and // - Return types: For example, Parser functions return Expression* and
// PreParser functions return PreParserExpression. // PreParser functions return PreParserExpression.
...@@ -155,33 +184,40 @@ struct FormalParametersBase { ...@@ -155,33 +184,40 @@ struct FormalParametersBase {
// pretenured, and PreParser doesn't care. // pretenured, and PreParser doesn't care.
// The traits are expected to contain the following typedefs: // The traits are expected to contain the following typedefs:
// struct Traits { // template <>
// class ParserBaseTraits<Impl> {
// // In particular... // // In particular...
// struct Type { // struct Type {
// // Used by FunctionState and BlockState.
// typedef Scope;
// typedef GeneratorVariable; // typedef GeneratorVariable;
// typedef AstProperties;
// typedef ExpressionClassifier;
// // Return types for traversing functions. // // Return types for traversing functions.
// typedef Identifier; // typedef Identifier;
// typedef Expression; // typedef Expression;
// typedef YieldExpression;
// typedef FunctionLiteral; // typedef FunctionLiteral;
// typedef ClassLiteral; // typedef ClassLiteral;
// typedef ObjectLiteralProperty;
// typedef Literal; // typedef Literal;
// typedef ObjectLiteralProperty;
// typedef ExpressionList; // typedef ExpressionList;
// typedef PropertyList; // typedef PropertyList;
// typedef FormalParameter; // typedef FormalParameter;
// typedef FormalParameters; // typedef FormalParameters;
// typedef StatementList;
// // For constructing objects returned by the traversing functions. // // For constructing objects returned by the traversing functions.
// typedef Factory; // typedef Factory;
// }; // };
// // ... // // ...
// }; // };
template <typename Traits> template <typename Impl>
class ParserBase : public Traits { class ParserBaseTraits;
template <typename Impl>
class ParserBase : public ParserBaseTraits<Impl> {
public: public:
// Shorten type names defined by Traits. // Shorten type names defined by Traits.
typedef ParserBaseTraits<Impl> Traits;
typedef typename Traits::Type::Expression ExpressionT; typedef typename Traits::Type::Expression ExpressionT;
typedef typename Traits::Type::Identifier IdentifierT; typedef typename Traits::Type::Identifier IdentifierT;
typedef typename Traits::Type::FormalParameter FormalParameterT; typedef typename Traits::Type::FormalParameter FormalParameterT;
...@@ -192,11 +228,14 @@ class ParserBase : public Traits { ...@@ -192,11 +228,14 @@ class ParserBase : public Traits {
typedef typename Traits::Type::StatementList StatementListT; typedef typename Traits::Type::StatementList StatementListT;
typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier; typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier;
// All implementation-specific methods must be called through this.
Impl* impl() { return static_cast<Impl*>(this); }
const Impl* impl() const { return static_cast<const Impl*>(this); }
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
v8::Extension* extension, AstValueFactory* ast_value_factory, v8::Extension* extension, AstValueFactory* ast_value_factory,
ParserRecorder* log, typename Traits::Type::Parser this_object) ParserRecorder* log)
: Traits(this_object), : scope_state_(nullptr),
scope_state_(nullptr),
function_state_(nullptr), function_state_(nullptr),
extension_(extension), extension_(extension),
fni_(nullptr), fni_(nullptr),
...@@ -515,8 +554,7 @@ class ParserBase : public Traits { ...@@ -515,8 +554,7 @@ class ParserBase : public Traits {
// to this function. Filled in by constructor. // to this function. Filled in by constructor.
bool this_function_is_parenthesized_; bool this_function_is_parenthesized_;
friend class ParserTraits; friend class ParserBaseTraits<Impl>;
friend class PreParserTraits;
friend class Checkpoint; friend class Checkpoint;
}; };
...@@ -1275,8 +1313,8 @@ class ParserBase : public Traits { ...@@ -1275,8 +1313,8 @@ class ParserBase : public Traits {
friend class DiscardableZoneScope; friend class DiscardableZoneScope;
}; };
template <class Traits> template <typename Impl>
ParserBase<Traits>::FunctionState::FunctionState( ParserBase<Impl>::FunctionState::FunctionState(
FunctionState** function_state_stack, ScopeState** scope_stack, FunctionState** function_state_stack, ScopeState** scope_stack,
Scope* scope, FunctionKind kind) Scope* scope, FunctionKind kind)
: ScopeState(scope_stack, scope), : ScopeState(scope_stack, scope),
...@@ -1301,14 +1339,13 @@ ParserBase<Traits>::FunctionState::FunctionState( ...@@ -1301,14 +1339,13 @@ ParserBase<Traits>::FunctionState::FunctionState(
} }
} }
template <typename Impl>
template <class Traits> ParserBase<Impl>::FunctionState::~FunctionState() {
ParserBase<Traits>::FunctionState::~FunctionState() {
*function_state_stack_ = outer_function_state_; *function_state_stack_ = outer_function_state_;
} }
template <class Traits> template <typename Impl>
void ParserBase<Traits>::GetUnexpectedTokenMessage( void ParserBase<Impl>::GetUnexpectedTokenMessage(
Token::Value token, MessageTemplate::Template* message, Token::Value token, MessageTemplate::Template* message,
Scanner::Location* location, const char** arg, Scanner::Location* location, const char** arg,
MessageTemplate::Template default_) { MessageTemplate::Template default_) {
...@@ -1366,15 +1403,13 @@ void ParserBase<Traits>::GetUnexpectedTokenMessage( ...@@ -1366,15 +1403,13 @@ void ParserBase<Traits>::GetUnexpectedTokenMessage(
} }
} }
template <typename Impl>
template <class Traits> void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) {
void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
return ReportUnexpectedTokenAt(scanner_->location(), token); return ReportUnexpectedTokenAt(scanner_->location(), token);
} }
template <typename Impl>
template <class Traits> void ParserBase<Impl>::ReportUnexpectedTokenAt(
void ParserBase<Traits>::ReportUnexpectedTokenAt(
Scanner::Location source_location, Token::Value token, Scanner::Location source_location, Token::Value token,
MessageTemplate::Template message) { MessageTemplate::Template message) {
const char* arg; const char* arg;
...@@ -1382,9 +1417,8 @@ void ParserBase<Traits>::ReportUnexpectedTokenAt( ...@@ -1382,9 +1417,8 @@ void ParserBase<Traits>::ReportUnexpectedTokenAt(
Traits::ReportMessageAt(source_location, message, arg); Traits::ReportMessageAt(source_location, message, arg);
} }
template <typename Impl>
template <class Traits> typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
ExpressionClassifier classifier(this); ExpressionClassifier classifier(this);
auto result = auto result =
...@@ -1398,10 +1432,9 @@ typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( ...@@ -1398,10 +1432,9 @@ typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
return result; return result;
} }
template <typename Impl>
template <class Traits> typename ParserBase<Impl>::IdentifierT
typename ParserBase<Traits>::IdentifierT ParserBase<Impl>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
bool* ok) { bool* ok) {
Token::Value next = Next(); Token::Value next = Next();
if (next == Token::IDENTIFIER || next == Token::ASYNC || if (next == Token::IDENTIFIER || next == Token::ASYNC ||
...@@ -1457,9 +1490,9 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, ...@@ -1457,9 +1490,9 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
} }
} }
template <class Traits> template <class Impl>
typename ParserBase<Traits>::IdentifierT typename ParserBase<Impl>::IdentifierT
ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( ParserBase<Impl>::ParseIdentifierOrStrictReservedWord(
FunctionKind function_kind, bool* is_strict_reserved, bool* ok) { FunctionKind function_kind, bool* is_strict_reserved, bool* ok) {
Token::Value next = Next(); Token::Value next = Next();
if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ && if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ &&
...@@ -1479,9 +1512,9 @@ ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( ...@@ -1479,9 +1512,9 @@ ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
return this->GetSymbol(scanner()); return this->GetSymbol(scanner());
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::IdentifierT typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName(
ParserBase<Traits>::ParseIdentifierName(bool* ok) { bool* ok) {
Token::Value next = Next(); Token::Value next = Next();
if (next != Token::IDENTIFIER && next != Token::ASYNC && if (next != Token::IDENTIFIER && next != Token::ASYNC &&
next != Token::ENUM && next != Token::AWAIT && next != Token::LET && next != Token::ENUM && next != Token::AWAIT && next != Token::LET &&
...@@ -1497,8 +1530,8 @@ ParserBase<Traits>::ParseIdentifierName(bool* ok) { ...@@ -1497,8 +1530,8 @@ ParserBase<Traits>::ParseIdentifierName(bool* ok) {
return this->GetSymbol(scanner()); return this->GetSymbol(scanner());
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral(
bool* ok) { bool* ok) {
int pos = peek_position(); int pos = peek_position();
if (!scanner()->ScanRegExpPattern()) { if (!scanner()->ScanRegExpPattern()) {
...@@ -1523,11 +1556,9 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( ...@@ -1523,11 +1556,9 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
} }
template <typename Impl>
template <class Traits> typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
typename ParserBase<Traits>::ExpressionT ExpressionClassifier* classifier, bool* is_async, bool* ok) {
ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
bool* is_async, bool* ok) {
// PrimaryExpression :: // PrimaryExpression ::
// 'this' // 'this'
// 'null' // 'null'
...@@ -1704,9 +1735,8 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -1704,9 +1735,8 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
return this->EmptyExpression(); return this->EmptyExpression();
} }
template <typename Impl>
template <class Traits> typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression(
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
bool accept_IN, bool* ok) { bool accept_IN, bool* ok) {
ExpressionClassifier classifier(this); ExpressionClassifier classifier(this);
ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
...@@ -1714,8 +1744,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( ...@@ -1714,8 +1744,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
return result; return result;
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression(
bool accept_IN, ExpressionClassifier* classifier, bool* ok) { bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
// Expression :: // Expression ::
// AssignmentExpression // AssignmentExpression
...@@ -1779,9 +1809,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( ...@@ -1779,9 +1809,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
return result; return result;
} }
template <typename Impl>
template <class Traits> typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral(
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
ExpressionClassifier* classifier, bool* ok) { ExpressionClassifier* classifier, bool* ok) {
// ArrayLiteral :: // ArrayLiteral ::
// '[' Expression? (',' Expression?)* ']' // '[' Expression? (',' Expression?)* ']'
...@@ -1856,8 +1885,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( ...@@ -1856,8 +1885,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
return result; return result;
} }
template <class Traits> template <class Impl>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name,
ExpressionClassifier* classifier, bool* ok) { ExpressionClassifier* classifier, bool* ok) {
Token::Value token = peek(); Token::Value token = peek();
...@@ -1913,9 +1942,9 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( ...@@ -1913,9 +1942,9 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
: factory()->NewStringLiteral(*name, pos); : factory()->NewStringLiteral(*name, pos);
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ObjectLiteralPropertyT typename ParserBase<Impl>::ObjectLiteralPropertyT
ParserBase<Traits>::ParsePropertyDefinition( ParserBase<Impl>::ParsePropertyDefinition(
ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor, MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor,
ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { ExpressionClassifier* classifier, IdentifierT* name, bool* ok) {
...@@ -2131,9 +2160,8 @@ ParserBase<Traits>::ParsePropertyDefinition( ...@@ -2131,9 +2160,8 @@ ParserBase<Traits>::ParsePropertyDefinition(
return this->EmptyObjectLiteralProperty(); return this->EmptyObjectLiteralProperty();
} }
template <typename Impl>
template <class Traits> typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
ExpressionClassifier* classifier, bool* ok) { ExpressionClassifier* classifier, bool* ok) {
// ObjectLiteral :: // ObjectLiteral ::
// '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
...@@ -2188,9 +2216,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( ...@@ -2188,9 +2216,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
pos); pos);
} }
template <class Traits> template <typename Impl>
typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( typename ParserBase<Impl>::Traits::Type::ExpressionList
Scanner::Location* first_spread_arg_loc, bool maybe_arrow, ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc,
bool maybe_arrow,
ExpressionClassifier* classifier, bool* ok) { ExpressionClassifier* classifier, bool* ok) {
// Arguments :: // Arguments ::
// '(' (AssignmentExpression)*[','] ')' // '(' (AssignmentExpression)*[','] ')'
...@@ -2271,9 +2300,9 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( ...@@ -2271,9 +2300,9 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
} }
// Precedence = 2 // Precedence = 2
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT
ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN,
ExpressionClassifier* classifier, ExpressionClassifier* classifier,
bool* ok) { bool* ok) {
// AssignmentExpression :: // AssignmentExpression ::
...@@ -2289,7 +2318,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, ...@@ -2289,7 +2318,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
} }
FuncNameInferrer::State fni_state(fni_); FuncNameInferrer::State fni_state(fni_);
ParserBase<Traits>::Checkpoint checkpoint(this); Checkpoint checkpoint(this);
ExpressionClassifier arrow_formals_classifier(this, ExpressionClassifier arrow_formals_classifier(this,
classifier->duplicate_finder()); classifier->duplicate_finder());
...@@ -2478,11 +2507,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, ...@@ -2478,11 +2507,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
return result; return result;
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
ParserBase<Traits>::ParseYieldExpression(bool accept_IN, bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
ExpressionClassifier* classifier,
bool* ok) {
// YieldExpression :: // YieldExpression ::
// 'yield' ([no line terminator] '*'? AssignmentExpression)? // 'yield' ([no line terminator] '*'? AssignmentExpression)?
int pos = peek_position(); int pos = peek_position();
...@@ -2531,9 +2558,9 @@ ParserBase<Traits>::ParseYieldExpression(bool accept_IN, ...@@ -2531,9 +2558,9 @@ ParserBase<Traits>::ParseYieldExpression(bool accept_IN,
return yield; return yield;
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT
ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier, ParserBase<Impl>::ParseTailCallExpression(ExpressionClassifier* classifier,
bool* ok) { bool* ok) {
// TailCallExpression:: // TailCallExpression::
// 'continue' MemberExpression Arguments // 'continue' MemberExpression Arguments
...@@ -2594,9 +2621,9 @@ ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier, ...@@ -2594,9 +2621,9 @@ ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier,
} }
// Precedence = 3 // Precedence = 3
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT
ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, ParserBase<Impl>::ParseConditionalExpression(bool accept_IN,
ExpressionClassifier* classifier, ExpressionClassifier* classifier,
bool* ok) { bool* ok) {
// ConditionalExpression :: // ConditionalExpression ::
...@@ -2627,11 +2654,9 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, ...@@ -2627,11 +2654,9 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
// Precedence >= 4 // Precedence >= 4
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, int prec, bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
ExpressionClassifier* classifier,
bool* ok) {
DCHECK(prec >= 4); DCHECK(prec >= 4);
ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
...@@ -2685,11 +2710,9 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, ...@@ -2685,11 +2710,9 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
return x; return x;
} }
template <typename Impl>
template <class Traits> typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
typename ParserBase<Traits>::ExpressionT ExpressionClassifier* classifier, bool* ok) {
ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
bool* ok) {
// UnaryExpression :: // UnaryExpression ::
// PostfixExpression // PostfixExpression
// 'delete' UnaryExpression // 'delete' UnaryExpression
...@@ -2765,11 +2788,9 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, ...@@ -2765,11 +2788,9 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
} }
} }
template <typename Impl>
template <class Traits> typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression(
typename ParserBase<Traits>::ExpressionT ExpressionClassifier* classifier, bool* ok) {
ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
bool* ok) {
// PostfixExpression :: // PostfixExpression ::
// LeftHandSideExpression ('++' | '--')? // LeftHandSideExpression ('++' | '--')?
...@@ -2798,10 +2819,10 @@ ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, ...@@ -2798,10 +2819,10 @@ ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
return expression; return expression;
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT
ParserBase<Traits>::ParseLeftHandSideExpression( ParserBase<Impl>::ParseLeftHandSideExpression(ExpressionClassifier* classifier,
ExpressionClassifier* classifier, bool* ok) { bool* ok) {
// LeftHandSideExpression :: // LeftHandSideExpression ::
// (NewExpression | MemberExpression) ... // (NewExpression | MemberExpression) ...
...@@ -2946,9 +2967,9 @@ ParserBase<Traits>::ParseLeftHandSideExpression( ...@@ -2946,9 +2967,9 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
} }
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT
ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( ParserBase<Impl>::ParseMemberWithNewPrefixesExpression(
ExpressionClassifier* classifier, bool* is_async, bool* ok) { ExpressionClassifier* classifier, bool* is_async, bool* ok) {
// NewExpression :: // NewExpression ::
// ('new')+ MemberExpression // ('new')+ MemberExpression
...@@ -3011,10 +3032,9 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( ...@@ -3011,10 +3032,9 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
return this->ParseMemberExpression(classifier, is_async, ok); return this->ParseMemberExpression(classifier, is_async, ok);
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression(
ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, ExpressionClassifier* classifier, bool* is_async, bool* ok) {
bool* is_async, bool* ok) {
// MemberExpression :: // MemberExpression ::
// (PrimaryExpression | FunctionLiteral | ClassLiteral) // (PrimaryExpression | FunctionLiteral | ClassLiteral)
// ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
...@@ -3080,9 +3100,9 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, ...@@ -3080,9 +3100,9 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
return result; return result;
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression(
ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { bool is_new, bool* ok) {
Expect(Token::SUPER, CHECK_OK); Expect(Token::SUPER, CHECK_OK);
int pos = position(); int pos = position();
...@@ -3108,8 +3128,8 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { ...@@ -3108,8 +3128,8 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
return this->EmptyExpression(); return this->EmptyExpression();
} }
template <class Traits> template <typename Impl>
void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name, void ParserBase<Impl>::ExpectMetaProperty(Vector<const char> property_name,
const char* full_name, int pos, const char* full_name, int pos,
bool* ok) { bool* ok) {
Consume(Token::PERIOD); Consume(Token::PERIOD);
...@@ -3122,9 +3142,9 @@ void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name, ...@@ -3122,9 +3142,9 @@ void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name,
} }
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT
ParserBase<Traits>::ParseNewTargetExpression(bool* ok) { ParserBase<Impl>::ParseNewTargetExpression(bool* ok) {
int pos = position(); int pos = position();
ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK); ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK);
...@@ -3138,9 +3158,9 @@ ParserBase<Traits>::ParseNewTargetExpression(bool* ok) { ...@@ -3138,9 +3158,9 @@ ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
return this->NewTargetExpression(pos); return this->NewTargetExpression(pos);
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT
ParserBase<Traits>::ParseMemberExpressionContinuation( ParserBase<Impl>::ParseMemberExpressionContinuation(
ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
bool* ok) { bool* ok) {
// Parses this part of MemberExpression: // Parses this part of MemberExpression:
...@@ -3214,10 +3234,10 @@ ParserBase<Traits>::ParseMemberExpressionContinuation( ...@@ -3214,10 +3234,10 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
return this->EmptyExpression(); return this->EmptyExpression();
} }
template <typename Impl>
template <class Traits> void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters,
void ParserBase<Traits>::ParseFormalParameter( ExpressionClassifier* classifier,
FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { bool* ok) {
// FormalParameter[Yield,GeneratorParameter] : // FormalParameter[Yield,GeneratorParameter] :
// BindingElement[?Yield, ?GeneratorParameter] // BindingElement[?Yield, ?GeneratorParameter]
bool is_rest = parameters->has_rest; bool is_rest = parameters->has_rest;
...@@ -3250,9 +3270,8 @@ void ParserBase<Traits>::ParseFormalParameter( ...@@ -3250,9 +3270,8 @@ void ParserBase<Traits>::ParseFormalParameter(
scanner()->location().end_pos, is_rest); scanner()->location().end_pos, is_rest);
} }
template <typename Impl>
template <class Traits> void ParserBase<Impl>::ParseFormalParameterList(
void ParserBase<Traits>::ParseFormalParameterList(
FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
// FormalParameters[Yield] : // FormalParameters[Yield] :
// [empty] // [empty]
...@@ -3302,8 +3321,8 @@ void ParserBase<Traits>::ParseFormalParameterList( ...@@ -3302,8 +3321,8 @@ void ParserBase<Traits>::ParseFormalParameterList(
} }
} }
template <class Traits> template <typename Impl>
void ParserBase<Traits>::CheckArityRestrictions(int param_count, void ParserBase<Impl>::CheckArityRestrictions(int param_count,
FunctionKind function_kind, FunctionKind function_kind,
bool has_rest, bool has_rest,
int formals_start_pos, int formals_start_pos,
...@@ -3328,9 +3347,8 @@ void ParserBase<Traits>::CheckArityRestrictions(int param_count, ...@@ -3328,9 +3347,8 @@ void ParserBase<Traits>::CheckArityRestrictions(int param_count,
} }
} }
template <typename Impl>
template <class Traits> bool ParserBase<Impl>::IsNextLetKeyword() {
bool ParserBase<Traits>::IsNextLetKeyword() {
DCHECK(peek() == Token::LET); DCHECK(peek() == Token::LET);
Token::Value next_next = PeekAhead(); Token::Value next_next = PeekAhead();
switch (next_next) { switch (next_next) {
...@@ -3354,8 +3372,8 @@ bool ParserBase<Traits>::IsNextLetKeyword() { ...@@ -3354,8 +3372,8 @@ bool ParserBase<Traits>::IsNextLetKeyword() {
} }
} }
template <class Traits> template <typename Impl>
bool ParserBase<Traits>::IsTrivialExpression() { bool ParserBase<Impl>::IsTrivialExpression() {
Token::Value peek_token = peek(); Token::Value peek_token = peek();
if (peek_token == Token::SMI || peek_token == Token::NUMBER || if (peek_token == Token::SMI || peek_token == Token::NUMBER ||
peek_token == Token::NULL_LITERAL || peek_token == Token::TRUE_LITERAL || peek_token == Token::NULL_LITERAL || peek_token == Token::TRUE_LITERAL ||
...@@ -3372,9 +3390,9 @@ bool ParserBase<Traits>::IsTrivialExpression() { ...@@ -3372,9 +3390,9 @@ bool ParserBase<Traits>::IsTrivialExpression() {
return false; return false;
} }
template <class Traits> template <typename Impl>
typename ParserBase<Traits>::ExpressionT typename ParserBase<Impl>::ExpressionT
ParserBase<Traits>::ParseArrowFunctionLiteral( ParserBase<Impl>::ParseArrowFunctionLiteral(
bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, bool accept_IN, const FormalParametersT& formal_parameters, bool is_async,
const ExpressionClassifier& formals_classifier, bool* ok) { const ExpressionClassifier& formals_classifier, bool* ok) {
if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
...@@ -3491,12 +3509,9 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( ...@@ -3491,12 +3509,9 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
return function_literal; return function_literal;
} }
template <typename Impl>
template <typename Traits> typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
typename ParserBase<Traits>::ExpressionT ExpressionT tag, int start, ExpressionClassifier* classifier, bool* ok) {
ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
ExpressionClassifier* classifier,
bool* ok) {
// A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
// text followed by a substitution expression), finalized by a single // text followed by a substitution expression), finalized by a single
// TEMPLATE_TAIL. // TEMPLATE_TAIL.
...@@ -3588,20 +3603,18 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, ...@@ -3588,20 +3603,18 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
return Traits::CloseTemplateLiteral(&ts, start, tag); return Traits::CloseTemplateLiteral(&ts, start, tag);
} }
template <typename Impl>
template <typename Traits> typename ParserBase<Impl>::ExpressionT
typename ParserBase<Traits>::ExpressionT ParserBase<Impl>::CheckAndRewriteReferenceExpression(
ParserBase<Traits>::CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos, ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, bool* ok) { MessageTemplate::Template message, bool* ok) {
return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
message, kReferenceError, ok); message, kReferenceError, ok);
} }
template <typename Impl>
template <typename Traits> typename ParserBase<Impl>::ExpressionT
typename ParserBase<Traits>::ExpressionT ParserBase<Impl>::CheckAndRewriteReferenceExpression(
ParserBase<Traits>::CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos, ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, ParseErrorType type, bool* ok) { MessageTemplate::Template message, ParseErrorType type, bool* ok) {
if (this->IsIdentifier(expression) && is_strict(language_mode()) && if (this->IsIdentifier(expression) && is_strict(language_mode()) &&
...@@ -3625,15 +3638,13 @@ ParserBase<Traits>::CheckAndRewriteReferenceExpression( ...@@ -3625,15 +3638,13 @@ ParserBase<Traits>::CheckAndRewriteReferenceExpression(
return this->EmptyExpression(); return this->EmptyExpression();
} }
template <typename Impl>
template <typename Traits> bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) {
bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) {
return this->IsAssignableIdentifier(expression) || expression->IsProperty(); return this->IsAssignableIdentifier(expression) || expression->IsProperty();
} }
template <typename Impl>
template <typename Traits> void ParserBase<Impl>::CheckDestructuringElement(
void ParserBase<Traits>::CheckDestructuringElement(
ExpressionT expression, ExpressionClassifier* classifier, int begin, ExpressionT expression, ExpressionClassifier* classifier, int begin,
int end) { int end) {
if (!IsValidPattern(expression) && !expression->IsAssignment() && if (!IsValidPattern(expression) && !expression->IsAssignment() &&
...@@ -3648,8 +3659,8 @@ void ParserBase<Traits>::CheckDestructuringElement( ...@@ -3648,8 +3659,8 @@ void ParserBase<Traits>::CheckDestructuringElement(
#undef CHECK_OK #undef CHECK_OK
#undef CHECK_OK_CUSTOM #undef CHECK_OK_CUSTOM
template <typename Traits> template <typename Impl>
void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty(
Token::Value property, PropertyKind type, MethodKind method_type, Token::Value property, PropertyKind type, MethodKind method_type,
ExpressionClassifier* classifier, bool* ok) { ExpressionClassifier* classifier, bool* ok) {
DCHECK(!IsStaticMethod(method_type)); DCHECK(!IsStaticMethod(method_type));
...@@ -3667,8 +3678,8 @@ void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( ...@@ -3667,8 +3678,8 @@ void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
} }
} }
template <typename Traits> template <typename Impl>
void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( void ParserBase<Impl>::ClassLiteralChecker::CheckProperty(
Token::Value property, PropertyKind type, MethodKind method_type, Token::Value property, PropertyKind type, MethodKind method_type,
ExpressionClassifier* classifier, bool* ok) { ExpressionClassifier* classifier, bool* ok) {
DCHECK(type == kMethodProperty || type == kAccessorProperty); DCHECK(type == kMethodProperty || type == kAccessorProperty);
......
...@@ -297,75 +297,74 @@ class TargetScope BASE_EMBEDDED { ...@@ -297,75 +297,74 @@ class TargetScope BASE_EMBEDDED {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Implementation of Parser // Implementation of Parser
bool ParserTraits::IsEval(const AstRawString* identifier) const { bool ParserBaseTraits<Parser>::IsEval(const AstRawString* identifier) const {
return identifier == parser_->ast_value_factory()->eval_string(); return identifier == delegate()->ast_value_factory()->eval_string();
} }
bool ParserTraits::IsArguments(const AstRawString* identifier) const { bool ParserBaseTraits<Parser>::IsArguments(
return identifier == parser_->ast_value_factory()->arguments_string(); const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->arguments_string();
} }
bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { bool ParserBaseTraits<Parser>::IsEvalOrArguments(
const AstRawString* identifier) const {
return IsEval(identifier) || IsArguments(identifier); return IsEval(identifier) || IsArguments(identifier);
} }
bool ParserTraits::IsUndefined(const AstRawString* identifier) const { bool ParserBaseTraits<Parser>::IsUndefined(
return identifier == parser_->ast_value_factory()->undefined_string(); const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->undefined_string();
} }
bool ParserTraits::IsPrototype(const AstRawString* identifier) const { bool ParserBaseTraits<Parser>::IsPrototype(
return identifier == parser_->ast_value_factory()->prototype_string(); const AstRawString* identifier) const {
return identifier == delegate()->ast_value_factory()->prototype_string();
} }
bool ParserBaseTraits<Parser>::IsConstructor(
bool ParserTraits::IsConstructor(const AstRawString* identifier) const { const AstRawString* identifier) const {
return identifier == parser_->ast_value_factory()->constructor_string(); return identifier == delegate()->ast_value_factory()->constructor_string();
} }
bool ParserBaseTraits<Parser>::IsThisProperty(Expression* expression) {
bool ParserTraits::IsThisProperty(Expression* expression) {
DCHECK(expression != NULL); DCHECK(expression != NULL);
Property* property = expression->AsProperty(); Property* property = expression->AsProperty();
return property != NULL && property->obj()->IsVariableProxy() && return property != NULL && property->obj()->IsVariableProxy() &&
property->obj()->AsVariableProxy()->is_this(); property->obj()->AsVariableProxy()->is_this();
} }
bool ParserBaseTraits<Parser>::IsIdentifier(Expression* expression) {
bool ParserTraits::IsIdentifier(Expression* expression) {
VariableProxy* operand = expression->AsVariableProxy(); VariableProxy* operand = expression->AsVariableProxy();
return operand != NULL && !operand->is_this(); return operand != NULL && !operand->is_this();
} }
void ParserBaseTraits<Parser>::PushPropertyName(FuncNameInferrer* fni,
void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
Expression* expression) { Expression* expression) {
if (expression->IsPropertyName()) { if (expression->IsPropertyName()) {
fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
} else { } else {
fni->PushLiteralName( fni->PushLiteralName(
parser_->ast_value_factory()->anonymous_function_string()); delegate()->ast_value_factory()->anonymous_function_string());
} }
} }
void ParserBaseTraits<Parser>::CheckAssigningFunctionLiteralToProperty(
void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, Expression* left, Expression* right) {
Expression* right) {
DCHECK(left != NULL); DCHECK(left != NULL);
if (left->IsProperty() && right->IsFunctionLiteral()) { if (left->IsProperty() && right->IsFunctionLiteral()) {
right->AsFunctionLiteral()->set_pretenure(); right->AsFunctionLiteral()->set_pretenure();
} }
} }
Expression* ParserBaseTraits<Parser>::MarkExpressionAsAssigned(
Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) { Expression* expression) {
VariableProxy* proxy = VariableProxy* proxy =
expression != NULL ? expression->AsVariableProxy() : NULL; expression != NULL ? expression->AsVariableProxy() : NULL;
if (proxy != NULL) proxy->set_is_assigned(); if (proxy != NULL) proxy->set_is_assigned();
return expression; return expression;
} }
bool ParserBaseTraits<Parser>::ShortcutNumericLiteralBinaryExpression(
bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
Expression** x, Expression* y, Token::Value op, int pos, Expression** x, Expression* y, Token::Value op, int pos,
AstNodeFactory* factory) { AstNodeFactory* factory) {
if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() && if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
...@@ -435,10 +434,8 @@ bool ParserTraits::ShortcutNumericLiteralBinaryExpression( ...@@ -435,10 +434,8 @@ bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
return false; return false;
} }
Expression* ParserBaseTraits<Parser>::BuildUnaryExpression(
Expression* ParserTraits::BuildUnaryExpression(Expression* expression, Expression* expression, Token::Value op, int pos, AstNodeFactory* factory) {
Token::Value op, int pos,
AstNodeFactory* factory) {
DCHECK(expression != NULL); DCHECK(expression != NULL);
if (expression->IsLiteral()) { if (expression->IsLiteral()) {
const AstValue* literal = expression->AsLiteral()->raw_value(); const AstValue* literal = expression->AsLiteral()->raw_value();
...@@ -480,10 +477,11 @@ Expression* ParserTraits::BuildUnaryExpression(Expression* expression, ...@@ -480,10 +477,11 @@ Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
return factory->NewUnaryOperation(op, expression, pos); return factory->NewUnaryOperation(op, expression, pos);
} }
Expression* ParserTraits::BuildIteratorResult(Expression* value, bool done) { Expression* ParserBaseTraits<Parser>::BuildIteratorResult(Expression* value,
bool done) {
int pos = kNoSourcePosition; int pos = kNoSourcePosition;
AstNodeFactory* factory = parser_->factory(); AstNodeFactory* factory = delegate()->factory();
Zone* zone = parser_->zone(); Zone* zone = delegate()->zone();
if (value == nullptr) value = factory->NewUndefinedLiteral(pos); if (value == nullptr) value = factory->NewUndefinedLiteral(pos);
...@@ -495,24 +493,21 @@ Expression* ParserTraits::BuildIteratorResult(Expression* value, bool done) { ...@@ -495,24 +493,21 @@ Expression* ParserTraits::BuildIteratorResult(Expression* value, bool done) {
pos); pos);
} }
Expression* ParserTraits::NewThrowReferenceError( Expression* ParserBaseTraits<Parser>::NewThrowReferenceError(
MessageTemplate::Template message, int pos) { MessageTemplate::Template message, int pos) {
return parser_->NewThrowError(Runtime::kNewReferenceError, message, return delegate()->NewThrowError(
parser_->ast_value_factory()->empty_string(), Runtime::kNewReferenceError, message,
pos); delegate()->ast_value_factory()->empty_string(), pos);
} }
Expression* ParserBaseTraits<Parser>::NewThrowSyntaxError(
Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message, MessageTemplate::Template message, const AstRawString* arg, int pos) {
const AstRawString* arg, return delegate()->NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
int pos) {
return parser_->NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
} }
Expression* ParserBaseTraits<Parser>::NewThrowTypeError(
Expression* ParserTraits::NewThrowTypeError(MessageTemplate::Template message, MessageTemplate::Template message, const AstRawString* arg, int pos) {
const AstRawString* arg, int pos) { return delegate()->NewThrowError(Runtime::kNewTypeError, message, arg, pos);
return parser_->NewThrowError(Runtime::kNewTypeError, message, arg, pos);
} }
Expression* Parser::NewThrowError(Runtime::FunctionId id, Expression* Parser::NewThrowError(Runtime::FunctionId id,
...@@ -525,68 +520,66 @@ Expression* Parser::NewThrowError(Runtime::FunctionId id, ...@@ -525,68 +520,66 @@ Expression* Parser::NewThrowError(Runtime::FunctionId id,
return factory()->NewThrow(call_constructor, pos); return factory()->NewThrow(call_constructor, pos);
} }
void ParserBaseTraits<Parser>::ReportMessageAt(
void ParserTraits::ReportMessageAt(Scanner::Location source_location, Scanner::Location source_location, MessageTemplate::Template message,
MessageTemplate::Template message,
const char* arg, ParseErrorType error_type) { const char* arg, ParseErrorType error_type) {
if (parser_->stack_overflow()) { if (delegate()->stack_overflow()) {
// Suppress the error message (syntax error or such) in the presence of a // Suppress the error message (syntax error or such) in the presence of a
// stack overflow. The isolate allows only one pending exception at at time // stack overflow. The isolate allows only one pending exception at at time
// and we want to report the stack overflow later. // and we want to report the stack overflow later.
return; return;
} }
parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos, delegate()->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
source_location.end_pos, source_location.end_pos,
message, arg, error_type); message, arg, error_type);
} }
void ParserBaseTraits<Parser>::ReportMessageAt(
void ParserTraits::ReportMessageAt(Scanner::Location source_location, Scanner::Location source_location, MessageTemplate::Template message,
MessageTemplate::Template message, const AstRawString* arg, ParseErrorType error_type) {
const AstRawString* arg, if (delegate()->stack_overflow()) {
ParseErrorType error_type) {
if (parser_->stack_overflow()) {
// Suppress the error message (syntax error or such) in the presence of a // Suppress the error message (syntax error or such) in the presence of a
// stack overflow. The isolate allows only one pending exception at at time // stack overflow. The isolate allows only one pending exception at at time
// and we want to report the stack overflow later. // and we want to report the stack overflow later.
return; return;
} }
parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos, delegate()->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
source_location.end_pos, source_location.end_pos,
message, arg, error_type); message, arg, error_type);
} }
const AstRawString* ParserBaseTraits<Parser>::GetSymbol(
const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) const { Scanner* scanner) const {
const AstRawString* result = const AstRawString* result =
parser_->scanner()->CurrentSymbol(parser_->ast_value_factory()); delegate()->scanner()->CurrentSymbol(delegate()->ast_value_factory());
DCHECK(result != NULL); DCHECK(result != NULL);
return result; return result;
} }
const AstRawString* ParserBaseTraits<Parser>::GetNumberAsSymbol(
const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) const { Scanner* scanner) const {
double double_value = parser_->scanner()->DoubleValue(); double double_value = delegate()->scanner()->DoubleValue();
char array[100]; char array[100];
const char* string = DoubleToCString(double_value, ArrayVector(array)); const char* string = DoubleToCString(double_value, ArrayVector(array));
return parser_->ast_value_factory()->GetOneByteString(string); return delegate()->ast_value_factory()->GetOneByteString(string);
} }
const AstRawString* ParserBaseTraits<Parser>::GetNextSymbol(
const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) const { Scanner* scanner) const {
return parser_->scanner()->NextSymbol(parser_->ast_value_factory()); return delegate()->scanner()->NextSymbol(delegate()->ast_value_factory());
} }
Expression* ParserTraits::ThisExpression(int pos) { Expression* ParserBaseTraits<Parser>::ThisExpression(int pos) {
return parser_->NewUnresolved(parser_->ast_value_factory()->this_string(), return delegate()->NewUnresolved(
pos, pos + 4, Variable::THIS); delegate()->ast_value_factory()->this_string(), pos, pos + 4,
Variable::THIS);
} }
Expression* ParserTraits::NewSuperPropertyReference(AstNodeFactory* factory, Expression* ParserBaseTraits<Parser>::NewSuperPropertyReference(
int pos) { AstNodeFactory* factory, int pos) {
// this_function[home_object_symbol] // this_function[home_object_symbol]
VariableProxy* this_function_proxy = parser_->NewUnresolved( VariableProxy* this_function_proxy = delegate()->NewUnresolved(
parser_->ast_value_factory()->this_function_string(), pos); delegate()->ast_value_factory()->this_function_string(), pos);
Expression* home_object_symbol_literal = Expression* home_object_symbol_literal =
factory->NewSymbolLiteral("home_object_symbol", kNoSourcePosition); factory->NewSymbolLiteral("home_object_symbol", kNoSourcePosition);
Expression* home_object = factory->NewProperty( Expression* home_object = factory->NewProperty(
...@@ -595,41 +588,40 @@ Expression* ParserTraits::NewSuperPropertyReference(AstNodeFactory* factory, ...@@ -595,41 +588,40 @@ Expression* ParserTraits::NewSuperPropertyReference(AstNodeFactory* factory,
ThisExpression(pos)->AsVariableProxy(), home_object, pos); ThisExpression(pos)->AsVariableProxy(), home_object, pos);
} }
Expression* ParserTraits::NewSuperCallReference(AstNodeFactory* factory, Expression* ParserBaseTraits<Parser>::NewSuperCallReference(
int pos) { AstNodeFactory* factory, int pos) {
VariableProxy* new_target_proxy = parser_->NewUnresolved( VariableProxy* new_target_proxy = delegate()->NewUnresolved(
parser_->ast_value_factory()->new_target_string(), pos); delegate()->ast_value_factory()->new_target_string(), pos);
VariableProxy* this_function_proxy = parser_->NewUnresolved( VariableProxy* this_function_proxy = delegate()->NewUnresolved(
parser_->ast_value_factory()->this_function_string(), pos); delegate()->ast_value_factory()->this_function_string(), pos);
return factory->NewSuperCallReference(ThisExpression(pos)->AsVariableProxy(), return factory->NewSuperCallReference(ThisExpression(pos)->AsVariableProxy(),
new_target_proxy, this_function_proxy, new_target_proxy, this_function_proxy,
pos); pos);
} }
Expression* ParserTraits::NewTargetExpression(int pos) { Expression* ParserBaseTraits<Parser>::NewTargetExpression(int pos) {
static const int kNewTargetStringLength = 10; static const int kNewTargetStringLength = 10;
auto proxy = auto proxy = delegate()->NewUnresolved(
parser_->NewUnresolved(parser_->ast_value_factory()->new_target_string(), delegate()->ast_value_factory()->new_target_string(), pos,
pos, pos + kNewTargetStringLength); pos + kNewTargetStringLength);
proxy->set_is_new_target(); proxy->set_is_new_target();
return proxy; return proxy;
} }
Expression* ParserTraits::FunctionSentExpression(AstNodeFactory* factory, Expression* ParserBaseTraits<Parser>::FunctionSentExpression(
int pos) const { AstNodeFactory* factory, int pos) const {
// We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator). // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
Zone* zone = parser_->zone(); Zone* zone = delegate()->zone();
ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone); ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone);
VariableProxy* generator = factory->NewVariableProxy( VariableProxy* generator = factory->NewVariableProxy(
parser_->function_state_->generator_object_variable()); delegate()->function_state_->generator_object_variable());
args->Add(generator, zone); args->Add(generator, zone);
return factory->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos, return factory->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
args, pos); args, pos);
} }
Literal* ParserBaseTraits<Parser>::ExpressionFromLiteral(
Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos, Token::Value token, int pos, Scanner* scanner,
Scanner* scanner,
AstNodeFactory* factory) const { AstNodeFactory* factory) const {
switch (token) { switch (token) {
case Token::NULL_LITERAL: case Token::NULL_LITERAL:
...@@ -653,78 +645,72 @@ Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos, ...@@ -653,78 +645,72 @@ Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
return NULL; return NULL;
} }
Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name, Expression* ParserBaseTraits<Parser>::ExpressionFromIdentifier(
int start_position, const AstRawString* name, int start_position, int end_position,
int end_position,
InferName infer) { InferName infer) {
if (infer == InferName::kYes && parser_->fni_ != NULL) { if (infer == InferName::kYes && delegate()->fni_ != NULL) {
parser_->fni_->PushVariableName(name); delegate()->fni_->PushVariableName(name);
} }
return parser_->NewUnresolved(name, start_position, end_position); return delegate()->NewUnresolved(name, start_position, end_position);
} }
Expression* ParserBaseTraits<Parser>::ExpressionFromString(
Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner, int pos, Scanner* scanner, AstNodeFactory* factory) const {
AstNodeFactory* factory) const {
const AstRawString* symbol = GetSymbol(scanner); const AstRawString* symbol = GetSymbol(scanner);
if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); if (delegate()->fni_ != NULL) delegate()->fni_->PushLiteralName(symbol);
return factory->NewStringLiteral(symbol, pos); return factory->NewStringLiteral(symbol, pos);
} }
Expression* ParserBaseTraits<Parser>::GetIterator(Expression* iterable,
Expression* ParserTraits::GetIterator(Expression* iterable, AstNodeFactory* factory,
AstNodeFactory* factory, int pos) { int pos) {
Expression* iterator_symbol_literal = Expression* iterator_symbol_literal =
factory->NewSymbolLiteral("iterator_symbol", kNoSourcePosition); factory->NewSymbolLiteral("iterator_symbol", kNoSourcePosition);
Expression* prop = Expression* prop =
factory->NewProperty(iterable, iterator_symbol_literal, pos); factory->NewProperty(iterable, iterator_symbol_literal, pos);
Zone* zone = parser_->zone(); Zone* zone = delegate()->zone();
ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone); ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
return factory->NewCall(prop, args, pos); return factory->NewCall(prop, args, pos);
} }
Literal* ParserBaseTraits<Parser>::GetLiteralTheHole(
Literal* ParserTraits::GetLiteralTheHole(int position, int position, AstNodeFactory* factory) const {
AstNodeFactory* factory) const {
return factory->NewTheHoleLiteral(kNoSourcePosition); return factory->NewTheHoleLiteral(kNoSourcePosition);
} }
Expression* ParserBaseTraits<Parser>::ParseV8Intrinsic(bool* ok) {
Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { return delegate()->ParseV8Intrinsic(ok);
return parser_->ParseV8Intrinsic(ok);
} }
FunctionLiteral* ParserBaseTraits<Parser>::ParseFunctionLiteral(
FunctionLiteral* ParserTraits::ParseFunctionLiteral(
const AstRawString* name, Scanner::Location function_name_location, const AstRawString* name, Scanner::Location function_name_location,
FunctionNameValidity function_name_validity, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type, int function_token_position, FunctionLiteral::FunctionType type,
LanguageMode language_mode, bool* ok) { LanguageMode language_mode, bool* ok) {
return parser_->ParseFunctionLiteral( return delegate()->ParseFunctionLiteral(
name, function_name_location, function_name_validity, kind, name, function_name_location, function_name_validity, kind,
function_token_position, type, language_mode, ok); function_token_position, type, language_mode, ok);
} }
Expression* ParserTraits::ParseClassLiteral( Expression* ParserBaseTraits<Parser>::ParseClassLiteral(
Type::ExpressionClassifier* classifier, const AstRawString* name, Type::ExpressionClassifier* classifier, const AstRawString* name,
Scanner::Location class_name_location, bool name_is_strict_reserved, Scanner::Location class_name_location, bool name_is_strict_reserved,
int pos, bool* ok) { int pos, bool* ok) {
return parser_->ParseClassLiteral(classifier, name, class_name_location, return delegate()->ParseClassLiteral(classifier, name, class_name_location,
name_is_strict_reserved, pos, ok); name_is_strict_reserved, pos, ok);
} }
void ParserTraits::MarkTailPosition(Expression* expression) { void ParserBaseTraits<Parser>::MarkTailPosition(Expression* expression) {
expression->MarkTail(); expression->MarkTail();
} }
void ParserTraits::MarkCollectedTailCallExpressions() { void ParserBaseTraits<Parser>::MarkCollectedTailCallExpressions() {
parser_->MarkCollectedTailCallExpressions(); delegate()->MarkCollectedTailCallExpressions();
} }
Parser::Parser(ParseInfo* info) Parser::Parser(ParseInfo* info)
: ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(), : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
info->extension(), info->ast_value_factory(), info->extension(), info->ast_value_factory(), NULL),
NULL, this),
scanner_(info->unicode_cache()), scanner_(info->unicode_cache()),
reusable_preparser_(NULL), reusable_preparser_(NULL),
original_scope_(NULL), original_scope_(NULL),
...@@ -954,7 +940,7 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) { ...@@ -954,7 +940,7 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
} }
if (ok) { if (ok) {
ParserTraits::RewriteDestructuringAssignments(); ParserBaseTraits<Parser>::RewriteDestructuringAssignments();
result = factory()->NewScriptOrEvalFunctionLiteral( result = factory()->NewScriptOrEvalFunctionLiteral(
scope, body, function_state.materialized_literal_count(), scope, body, function_state.materialized_literal_count(),
function_state.expected_property_count()); function_state.expected_property_count());
...@@ -2337,7 +2323,8 @@ Block* Parser::ParseVariableDeclarations( ...@@ -2337,7 +2323,8 @@ Block* Parser::ParseVariableDeclarations(
} }
} }
ParserTraits::SetFunctionNameFromIdentifierRef(value, pattern); ParserBaseTraits<Parser>::SetFunctionNameFromIdentifierRef(value,
pattern);
// End position of the initializer is after the assignment expression. // End position of the initializer is after the assignment expression.
initializer_position = scanner()->location().end_pos; initializer_position = scanner()->location().end_pos;
...@@ -3997,12 +3984,12 @@ void Parser::ParseArrowFunctionFormalParameters( ...@@ -3997,12 +3984,12 @@ void Parser::ParseArrowFunctionFormalParameters(
AddFormalParameter(parameters, expr, initializer, end_pos, is_rest); AddFormalParameter(parameters, expr, initializer, end_pos, is_rest);
} }
void ParserTraits::ParseAsyncArrowSingleExpressionBody( void ParserBaseTraits<Parser>::ParseAsyncArrowSingleExpressionBody(
ZoneList<Statement*>* body, bool accept_IN, ZoneList<Statement*>* body, bool accept_IN,
Type::ExpressionClassifier* classifier, int pos, bool* ok) { Type::ExpressionClassifier* classifier, int pos, bool* ok) {
parser_->DesugarAsyncFunctionBody( delegate()->DesugarAsyncFunctionBody(
parser_->ast_value_factory()->empty_string(), parser_->scope(), body, delegate()->ast_value_factory()->empty_string(), delegate()->scope(),
classifier, kAsyncArrowFunction, body, classifier, kAsyncArrowFunction,
Parser::FunctionBodyType::kSingleExpression, accept_IN, pos, ok); Parser::FunctionBodyType::kSingleExpression, accept_IN, pos, ok);
} }
...@@ -4043,7 +4030,7 @@ void Parser::DesugarAsyncFunctionBody(const AstRawString* function_name, ...@@ -4043,7 +4030,7 @@ void Parser::DesugarAsyncFunctionBody(const AstRawString* function_name,
} else { } else {
return_value = return_value =
ParseAssignmentExpression(accept_IN, classifier, CHECK_OK_VOID); ParseAssignmentExpression(accept_IN, classifier, CHECK_OK_VOID);
ParserTraits::RewriteNonPattern(classifier, CHECK_OK_VOID); ParserBaseTraits<Parser>::RewriteNonPattern(classifier, CHECK_OK_VOID);
} }
return_value = BuildPromiseResolve(return_value, return_value->position()); return_value = BuildPromiseResolve(return_value, return_value->position());
...@@ -4070,13 +4057,13 @@ DoExpression* Parser::ParseDoExpression(bool* ok) { ...@@ -4070,13 +4057,13 @@ DoExpression* Parser::ParseDoExpression(bool* ok) {
return expr; return expr;
} }
void ParserTraits::ParseArrowFunctionFormalParameterList( void ParserBaseTraits<Parser>::ParseArrowFunctionFormalParameterList(
ParserFormalParameters* parameters, Expression* expr, ParserFormalParameters* parameters, Expression* expr,
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
const Scope::Snapshot& scope_snapshot, bool* ok) { const Scope::Snapshot& scope_snapshot, bool* ok) {
if (expr->IsEmptyParentheses()) return; if (expr->IsEmptyParentheses()) return;
parser_->ParseArrowFunctionFormalParameters( delegate()->ParseArrowFunctionFormalParameters(
parameters, expr, params_loc.end_pos, CHECK_OK_VOID); parameters, expr, params_loc.end_pos, CHECK_OK_VOID);
scope_snapshot.Reparent(parameters->scope); scope_snapshot.Reparent(parameters->scope);
...@@ -4087,7 +4074,7 @@ void ParserTraits::ParseArrowFunctionFormalParameterList( ...@@ -4087,7 +4074,7 @@ void ParserTraits::ParseArrowFunctionFormalParameterList(
return; return;
} }
Type::ExpressionClassifier classifier(parser_); Type::ExpressionClassifier classifier(delegate());
if (!parameters->is_simple) { if (!parameters->is_simple) {
classifier.RecordNonSimpleParameter(); classifier.RecordNonSimpleParameter();
} }
...@@ -4101,9 +4088,9 @@ void ParserTraits::ParseArrowFunctionFormalParameterList( ...@@ -4101,9 +4088,9 @@ void ParserTraits::ParseArrowFunctionFormalParameterList(
DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters()); DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
} }
void ParserBaseTraits<Parser>::ReindexLiterals(
void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) { const ParserFormalParameters& parameters) {
if (parser_->function_state_->materialized_literal_count() > 0) { if (delegate()->function_state_->materialized_literal_count() > 0) {
AstLiteralReindexer reindexer; AstLiteralReindexer reindexer;
for (const auto p : parameters.params) { for (const auto p : parameters.params) {
...@@ -4112,7 +4099,7 @@ void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) { ...@@ -4112,7 +4099,7 @@ void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) {
} }
DCHECK(reindexer.count() <= DCHECK(reindexer.count() <=
parser_->function_state_->materialized_literal_count()); delegate()->function_state_->materialized_literal_count());
} }
} }
...@@ -4347,7 +4334,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -4347,7 +4334,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
if (body) { if (body) {
// If body can be inspected, rewrite queued destructuring assignments // If body can be inspected, rewrite queued destructuring assignments
ParserTraits::RewriteDestructuringAssignments(); ParserBaseTraits<Parser>::RewriteDestructuringAssignments();
} }
has_duplicate_parameters = has_duplicate_parameters =
!formals_classifier.is_valid_formal_parameter_list_without_duplicates(); !formals_classifier.is_valid_formal_parameter_list_without_duplicates();
...@@ -5369,9 +5356,9 @@ void Parser::ParseOnBackground(ParseInfo* info) { ...@@ -5369,9 +5356,9 @@ void Parser::ParseOnBackground(ParseInfo* info) {
} }
} }
ParserBaseTraits<Parser>::TemplateLiteralState Parser::OpenTemplateLiteral(
ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { int pos) {
return new (zone()) ParserTraits::TemplateLiteral(zone(), pos); return new (zone()) ParserBaseTraits<Parser>::TemplateLiteral(zone(), pos);
} }
...@@ -5636,9 +5623,9 @@ void Parser::MarkCollectedTailCallExpressions() { ...@@ -5636,9 +5623,9 @@ void Parser::MarkCollectedTailCallExpressions() {
} }
} }
Expression* ParserTraits::ExpressionListToExpression( Expression* ParserBaseTraits<Parser>::ExpressionListToExpression(
ZoneList<Expression*>* args) { ZoneList<Expression*>* args) {
AstNodeFactory* factory = parser_->factory(); AstNodeFactory* factory = delegate()->factory();
Expression* expr = args->at(0); Expression* expr = args->at(0);
for (int i = 1; i < args->length(); ++i) { for (int i = 1; i < args->length(); ++i) {
expr = factory->NewBinaryOperation(Token::COMMA, expr, args->at(i), expr = factory->NewBinaryOperation(Token::COMMA, expr, args->at(i),
...@@ -5647,40 +5634,40 @@ Expression* ParserTraits::ExpressionListToExpression( ...@@ -5647,40 +5634,40 @@ Expression* ParserTraits::ExpressionListToExpression(
return expr; return expr;
} }
void ParserTraits::RewriteDestructuringAssignments() { void ParserBaseTraits<Parser>::RewriteDestructuringAssignments() {
parser_->RewriteDestructuringAssignments(); delegate()->RewriteDestructuringAssignments();
} }
Expression* ParserTraits::RewriteExponentiation(Expression* left, Expression* ParserBaseTraits<Parser>::RewriteExponentiation(Expression* left,
Expression* right, int pos) {
return parser_->RewriteExponentiation(left, right, pos);
}
Expression* ParserTraits::RewriteAssignExponentiation(Expression* left,
Expression* right, Expression* right,
int pos) { int pos) {
return parser_->RewriteAssignExponentiation(left, right, pos); return delegate()->RewriteExponentiation(left, right, pos);
} }
void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, Expression* ParserBaseTraits<Parser>::RewriteAssignExponentiation(
bool* ok) { Expression* left, Expression* right, int pos) {
parser_->RewriteNonPattern(classifier, ok); return delegate()->RewriteAssignExponentiation(left, right, pos);
}
void ParserBaseTraits<Parser>::RewriteNonPattern(
Type::ExpressionClassifier* classifier, bool* ok) {
delegate()->RewriteNonPattern(classifier, ok);
} }
Expression* ParserTraits::RewriteAwaitExpression(Expression* value, Expression* ParserBaseTraits<Parser>::RewriteAwaitExpression(Expression* value,
int await_pos) { int await_pos) {
// yield %AsyncFunctionAwait(.generator_object, <operand>) // yield %AsyncFunctionAwait(.generator_object, <operand>)
Variable* generator_object_variable = Variable* generator_object_variable =
parser_->function_state_->generator_object_variable(); delegate()->function_state_->generator_object_variable();
// If generator_object_variable is null, // If generator_object_variable is null,
if (!generator_object_variable) return value; if (!generator_object_variable) return value;
auto factory = parser_->factory(); auto factory = delegate()->factory();
const int nopos = kNoSourcePosition; const int nopos = kNoSourcePosition;
Variable* temp_var = Variable* temp_var =
parser_->NewTemporary(parser_->ast_value_factory()->empty_string()); delegate()->NewTemporary(delegate()->ast_value_factory()->empty_string());
VariableProxy* temp_proxy = factory->NewVariableProxy(temp_var); VariableProxy* temp_proxy = factory->NewVariableProxy(temp_var);
Block* do_block = factory->NewBlock(nullptr, 2, false, nopos); Block* do_block = factory->NewBlock(nullptr, 2, false, nopos);
...@@ -5697,7 +5684,7 @@ Expression* ParserTraits::RewriteAwaitExpression(Expression* value, ...@@ -5697,7 +5684,7 @@ Expression* ParserTraits::RewriteAwaitExpression(Expression* value,
factory->NewVariableProxy(generator_object_variable); factory->NewVariableProxy(generator_object_variable);
async_function_await_args->Add(generator_object, zone()); async_function_await_args->Add(generator_object, zone());
async_function_await_args->Add(temp_proxy, zone()); async_function_await_args->Add(temp_proxy, zone());
Expression* async_function_await = parser_->factory()->NewCallRuntime( Expression* async_function_await = delegate()->factory()->NewCallRuntime(
Context::ASYNC_FUNCTION_AWAIT_INDEX, async_function_await_args, nopos); Context::ASYNC_FUNCTION_AWAIT_INDEX, async_function_await_args, nopos);
// Wrap await to provide a break location between value evaluation and yield. // Wrap await to provide a break location between value evaluation and yield.
Expression* await_assignment = factory->NewAssignment( Expression* await_assignment = factory->NewAssignment(
...@@ -5711,17 +5698,16 @@ Expression* ParserTraits::RewriteAwaitExpression(Expression* value, ...@@ -5711,17 +5698,16 @@ Expression* ParserTraits::RewriteAwaitExpression(Expression* value,
Yield::kOnExceptionRethrow); Yield::kOnExceptionRethrow);
} }
ZoneList<Expression*>* ParserTraits::GetNonPatternList() const { ZoneList<Expression*>* ParserBaseTraits<Parser>::GetNonPatternList() const {
return parser_->function_state_->non_patterns_to_rewrite(); return delegate()->function_state_->non_patterns_to_rewrite();
} }
ZoneList<typename ParserBaseTraits<Parser>::Type::ExpressionClassifier::Error>*
ZoneList<typename ParserTraits::Type::ExpressionClassifier::Error>* ParserBaseTraits<Parser>::GetReportedErrorList() const {
ParserTraits::GetReportedErrorList() const { return delegate()->function_state_->GetReportedErrorList();
return parser_->function_state_->GetReportedErrorList();
} }
Zone* ParserTraits::zone() const { return parser_->zone(); } Zone* ParserBaseTraits<Parser>::zone() const { return delegate()->zone(); }
class NonPatternRewriter : public AstExpressionRewriter { class NonPatternRewriter : public AstExpressionRewriter {
public: public:
...@@ -5921,21 +5907,20 @@ Expression* Parser::RewriteSpreads(ArrayLiteral* lit) { ...@@ -5921,21 +5907,20 @@ Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
return factory()->NewDoExpression(do_block, result, lit->position()); return factory()->NewDoExpression(do_block, result, lit->position());
} }
void ParserBaseTraits<Parser>::QueueDestructuringAssignmentForRewriting(
void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { Expression* expr) {
DCHECK(expr->IsRewritableExpression()); DCHECK(expr->IsRewritableExpression());
parser_->function_state_->AddDestructuringAssignment( delegate()->function_state_->AddDestructuringAssignment(
Parser::DestructuringAssignment(expr, parser_->scope())); Parser::DestructuringAssignment(expr, delegate()->scope()));
} }
void ParserBaseTraits<Parser>::QueueNonPatternForRewriting(Expression* expr,
void ParserTraits::QueueNonPatternForRewriting(Expression* expr, bool* ok) { bool* ok) {
DCHECK(expr->IsRewritableExpression()); DCHECK(expr->IsRewritableExpression());
parser_->function_state_->AddNonPatternForRewriting(expr, ok); delegate()->function_state_->AddNonPatternForRewriting(expr, ok);
} }
void ParserBaseTraits<Parser>::SetFunctionNameFromPropertyName(
void ParserTraits::SetFunctionNameFromPropertyName(
ObjectLiteralProperty* property, const AstRawString* name) { ObjectLiteralProperty* property, const AstRawString* name) {
Expression* value = property->value(); Expression* value = property->value();
...@@ -5951,10 +5936,10 @@ void ParserTraits::SetFunctionNameFromPropertyName( ...@@ -5951,10 +5936,10 @@ void ParserTraits::SetFunctionNameFromPropertyName(
if (is_getter || is_setter) { if (is_getter || is_setter) {
DCHECK_NOT_NULL(name); DCHECK_NOT_NULL(name);
const AstRawString* prefix = const AstRawString* prefix =
is_getter ? parser_->ast_value_factory()->get_space_string() is_getter ? delegate()->ast_value_factory()->get_space_string()
: parser_->ast_value_factory()->set_space_string(); : delegate()->ast_value_factory()->set_space_string();
function->set_raw_name( function->set_raw_name(
parser_->ast_value_factory()->NewConsString(prefix, name)); delegate()->ast_value_factory()->NewConsString(prefix, name));
return; return;
} }
} }
...@@ -5965,14 +5950,13 @@ void ParserTraits::SetFunctionNameFromPropertyName( ...@@ -5965,14 +5950,13 @@ void ParserTraits::SetFunctionNameFromPropertyName(
DCHECK(!value->IsAnonymousFunctionDefinition() || DCHECK(!value->IsAnonymousFunctionDefinition() ||
property->kind() == ObjectLiteralProperty::COMPUTED); property->kind() == ObjectLiteralProperty::COMPUTED);
parser_->SetFunctionName(value, name); delegate()->SetFunctionName(value, name);
} }
void ParserBaseTraits<Parser>::SetFunctionNameFromIdentifierRef(
void ParserTraits::SetFunctionNameFromIdentifierRef(Expression* value, Expression* value, Expression* identifier) {
Expression* identifier) {
if (!identifier->IsVariableProxy()) return; if (!identifier->IsVariableProxy()) return;
parser_->SetFunctionName(value, identifier->AsVariableProxy()->raw_name()); delegate()->SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
} }
void Parser::SetFunctionName(Expression* value, const AstRawString* name) { void Parser::SetFunctionName(Expression* value, const AstRawString* name) {
......
...@@ -137,14 +137,12 @@ struct ParserFormalParameters : FormalParametersBase { ...@@ -137,14 +137,12 @@ struct ParserFormalParameters : FormalParametersBase {
const Parameter& at(int i) const { return params[i]; } const Parameter& at(int i) const { return params[i]; }
}; };
template <>
class ParserTraits { class ParserBaseTraits<Parser> {
public: public:
struct Type { typedef ParserBaseTraits<Parser> ParserTraits;
// TODO(marja): To be removed. The Traits object should contain all the data
// it needs.
typedef v8::internal::Parser* Parser;
struct Type {
typedef Variable GeneratorVariable; typedef Variable GeneratorVariable;
typedef v8::internal::AstProperties AstProperties; typedef v8::internal::AstProperties AstProperties;
...@@ -170,7 +168,12 @@ class ParserTraits { ...@@ -170,7 +168,12 @@ class ParserTraits {
typedef AstNodeFactory Factory; typedef AstNodeFactory Factory;
}; };
explicit ParserTraits(Parser* parser) : parser_(parser) {} // TODO(nikolaos): The traits methods should not need to call methods
// of the implementation object.
Parser* delegate() { return reinterpret_cast<Parser*>(this); }
const Parser* delegate() const {
return reinterpret_cast<const Parser*>(this);
}
// Helper functions for recursive descent. // Helper functions for recursive descent.
bool IsEval(const AstRawString* identifier) const; bool IsEval(const AstRawString* identifier) const;
...@@ -468,13 +471,9 @@ class ParserTraits { ...@@ -468,13 +471,9 @@ class ParserTraits {
V8_INLINE Expression* RewriteYieldStar(Expression* generator, V8_INLINE Expression* RewriteYieldStar(Expression* generator,
Expression* expression, int pos); Expression* expression, int pos);
private:
Parser* parser_;
}; };
class Parser : public ParserBase<Parser> {
class Parser : public ParserBase<ParserTraits> {
public: public:
explicit Parser(ParseInfo* info); explicit Parser(ParseInfo* info);
~Parser() { ~Parser() {
...@@ -500,7 +499,9 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -500,7 +499,9 @@ class Parser : public ParserBase<ParserTraits> {
void HandleSourceURLComments(Isolate* isolate, Handle<Script> script); void HandleSourceURLComments(Isolate* isolate, Handle<Script> script);
private: private:
friend class ParserTraits; // TODO(nikolaos): This should not be necessary. It will be removed
// when the traits object stops delegating to the implementation object.
friend class ParserBaseTraits<Parser>;
// Runtime encoding of different completion modes. // Runtime encoding of different completion modes.
enum CompletionKind { enum CompletionKind {
...@@ -962,34 +963,32 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -962,34 +963,32 @@ class Parser : public ParserBase<ParserTraits> {
#endif // DEBUG #endif // DEBUG
}; };
bool ParserBaseTraits<Parser>::IsFutureStrictReserved(
bool ParserTraits::IsFutureStrictReserved(
const AstRawString* identifier) const { const AstRawString* identifier) const {
return parser_->scanner()->IdentifierIsFutureStrictReserved(identifier); return delegate()->scanner()->IdentifierIsFutureStrictReserved(identifier);
} }
const AstRawString* ParserTraits::EmptyIdentifierString() const { const AstRawString* ParserBaseTraits<Parser>::EmptyIdentifierString() const {
return parser_->ast_value_factory()->empty_string(); return delegate()->ast_value_factory()->empty_string();
} }
void ParserBaseTraits<Parser>::SkipLazyFunctionBody(
void ParserTraits::SkipLazyFunctionBody(int* materialized_literal_count, int* materialized_literal_count, int* expected_property_count, bool* ok,
int* expected_property_count, bool* ok,
Scanner::BookmarkScope* bookmark) { Scanner::BookmarkScope* bookmark) {
return parser_->SkipLazyFunctionBody(materialized_literal_count, return delegate()->SkipLazyFunctionBody(
expected_property_count, ok, bookmark); materialized_literal_count, expected_property_count, ok, bookmark);
} }
ZoneList<Statement*>* ParserBaseTraits<Parser>::ParseEagerFunctionBody(
ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
const AstRawString* name, int pos, const ParserFormalParameters& parameters, const AstRawString* name, int pos, const ParserFormalParameters& parameters,
FunctionKind kind, FunctionLiteral::FunctionType function_type, bool* ok) { FunctionKind kind, FunctionLiteral::FunctionType function_type, bool* ok) {
return parser_->ParseEagerFunctionBody(name, pos, parameters, kind, return delegate()->ParseEagerFunctionBody(name, pos, parameters, kind,
function_type, ok); function_type, ok);
} }
void ParserTraits::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { void ParserBaseTraits<Parser>::CheckConflictingVarDeclarations(Scope* scope,
parser_->CheckConflictingVarDeclarations(scope, ok); bool* ok) {
delegate()->CheckConflictingVarDeclarations(scope, ok);
} }
...@@ -1021,80 +1020,71 @@ class CompileTimeValue: public AllStatic { ...@@ -1021,80 +1020,71 @@ class CompileTimeValue: public AllStatic {
DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue); DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
}; };
ParserBaseTraits<Parser>::TemplateLiteralState
ParserTraits::TemplateLiteralState ParserTraits::OpenTemplateLiteral(int pos) { ParserBaseTraits<Parser>::OpenTemplateLiteral(int pos) {
return parser_->OpenTemplateLiteral(pos); return delegate()->OpenTemplateLiteral(pos);
} }
void ParserBaseTraits<Parser>::AddTemplateSpan(TemplateLiteralState* state,
void ParserTraits::AddTemplateSpan(TemplateLiteralState* state, bool tail) { bool tail) {
parser_->AddTemplateSpan(state, tail); delegate()->AddTemplateSpan(state, tail);
} }
void ParserBaseTraits<Parser>::AddTemplateExpression(
void ParserTraits::AddTemplateExpression(TemplateLiteralState* state, TemplateLiteralState* state, Expression* expression) {
Expression* expression) { delegate()->AddTemplateExpression(state, expression);
parser_->AddTemplateExpression(state, expression);
} }
Expression* ParserBaseTraits<Parser>::CloseTemplateLiteral(
Expression* ParserTraits::CloseTemplateLiteral(TemplateLiteralState* state, TemplateLiteralState* state, int start, Expression* tag) {
int start, Expression* tag) { return delegate()->CloseTemplateLiteral(state, start, tag);
return parser_->CloseTemplateLiteral(state, start, tag);
} }
ZoneList<v8::internal::Expression*>* ParserBaseTraits<
ZoneList<v8::internal::Expression*>* ParserTraits::PrepareSpreadArguments( Parser>::PrepareSpreadArguments(ZoneList<v8::internal::Expression*>* list) {
ZoneList<v8::internal::Expression*>* list) { return delegate()->PrepareSpreadArguments(list);
return parser_->PrepareSpreadArguments(list);
} }
Expression* ParserBaseTraits<Parser>::SpreadCall(
Expression* ParserTraits::SpreadCall(Expression* function, Expression* function, ZoneList<v8::internal::Expression*>* args, int pos) {
ZoneList<v8::internal::Expression*>* args, return delegate()->SpreadCall(function, args, pos);
int pos) {
return parser_->SpreadCall(function, args, pos);
} }
Expression* ParserBaseTraits<Parser>::SpreadCallNew(
Expression* ParserTraits::SpreadCallNew(
Expression* function, ZoneList<v8::internal::Expression*>* args, int pos) { Expression* function, ZoneList<v8::internal::Expression*>* args, int pos) {
return parser_->SpreadCallNew(function, args, pos); return delegate()->SpreadCallNew(function, args, pos);
} }
void ParserBaseTraits<Parser>::AddFormalParameter(
void ParserTraits::AddFormalParameter(ParserFormalParameters* parameters, ParserFormalParameters* parameters, Expression* pattern,
Expression* pattern, Expression* initializer, int initializer_end_position, bool is_rest) {
Expression* initializer,
int initializer_end_position,
bool is_rest) {
bool is_simple = pattern->IsVariableProxy() && initializer == nullptr; bool is_simple = pattern->IsVariableProxy() && initializer == nullptr;
const AstRawString* name = is_simple const AstRawString* name =
? pattern->AsVariableProxy()->raw_name() is_simple ? pattern->AsVariableProxy()->raw_name()
: parser_->ast_value_factory()->empty_string(); : delegate()->ast_value_factory()->empty_string();
parameters->params.Add( parameters->params.Add(
ParserFormalParameters::Parameter(name, pattern, initializer, ParserFormalParameters::Parameter(name, pattern, initializer,
initializer_end_position, is_rest), initializer_end_position, is_rest),
parameters->scope->zone()); parameters->scope->zone());
} }
void ParserTraits::DeclareFormalParameter( void ParserBaseTraits<Parser>::DeclareFormalParameter(
DeclarationScope* scope, const ParserFormalParameters::Parameter& parameter, DeclarationScope* scope, const ParserFormalParameters::Parameter& parameter,
Type::ExpressionClassifier* classifier) { Type::ExpressionClassifier* classifier) {
bool is_duplicate = false; bool is_duplicate = false;
bool is_simple = classifier->is_simple_parameter_list(); bool is_simple = classifier->is_simple_parameter_list();
auto name = is_simple || parameter.is_rest auto name = is_simple || parameter.is_rest
? parameter.name ? parameter.name
: parser_->ast_value_factory()->empty_string(); : delegate()->ast_value_factory()->empty_string();
auto mode = is_simple || parameter.is_rest ? VAR : TEMPORARY; auto mode = is_simple || parameter.is_rest ? VAR : TEMPORARY;
if (!is_simple) scope->SetHasNonSimpleParameters(); if (!is_simple) scope->SetHasNonSimpleParameters();
bool is_optional = parameter.initializer != nullptr; bool is_optional = parameter.initializer != nullptr;
Variable* var = Variable* var =
scope->DeclareParameter(name, mode, is_optional, parameter.is_rest, scope->DeclareParameter(name, mode, is_optional, parameter.is_rest,
&is_duplicate, parser_->ast_value_factory()); &is_duplicate, delegate()->ast_value_factory());
if (is_duplicate) { if (is_duplicate) {
classifier->RecordDuplicateFormalParameterError( classifier->RecordDuplicateFormalParameterError(
parser_->scanner()->location()); delegate()->scanner()->location());
} }
if (is_sloppy(scope->language_mode())) { if (is_sloppy(scope->language_mode())) {
// TODO(sigurds) Mark every parameter as maybe assigned. This is a // TODO(sigurds) Mark every parameter as maybe assigned. This is a
...@@ -1104,35 +1094,36 @@ void ParserTraits::DeclareFormalParameter( ...@@ -1104,35 +1094,36 @@ void ParserTraits::DeclareFormalParameter(
} }
} }
void ParserTraits::AddParameterInitializationBlock( void ParserBaseTraits<Parser>::AddParameterInitializationBlock(
const ParserFormalParameters& parameters, const ParserFormalParameters& parameters,
ZoneList<v8::internal::Statement*>* body, bool is_async, bool* ok) { ZoneList<v8::internal::Statement*>* body, bool is_async, bool* ok) {
if (!parameters.is_simple) { if (!parameters.is_simple) {
auto* init_block = auto* init_block =
parser_->BuildParameterInitializationBlock(parameters, ok); delegate()->BuildParameterInitializationBlock(parameters, ok);
if (!*ok) return; if (!*ok) return;
if (is_async) { if (is_async) {
init_block = parser_->BuildRejectPromiseOnException(init_block); init_block = delegate()->BuildRejectPromiseOnException(init_block);
} }
if (init_block != nullptr) { if (init_block != nullptr) {
body->Add(init_block, parser_->zone()); body->Add(init_block, delegate()->zone());
} }
} }
} }
Expression* ParserTraits::ParseAsyncFunctionExpression(bool* ok) { Expression* ParserBaseTraits<Parser>::ParseAsyncFunctionExpression(bool* ok) {
return parser_->ParseAsyncFunctionExpression(ok); return delegate()->ParseAsyncFunctionExpression(ok);
} }
DoExpression* ParserTraits::ParseDoExpression(bool* ok) { DoExpression* ParserBaseTraits<Parser>::ParseDoExpression(bool* ok) {
return parser_->ParseDoExpression(ok); return delegate()->ParseDoExpression(ok);
} }
Expression* ParserTraits::RewriteYieldStar(Expression* generator, Expression* ParserBaseTraits<Parser>::RewriteYieldStar(Expression* generator,
Expression* iterable, int pos) { Expression* iterable,
return parser_->RewriteYieldStar(generator, iterable, pos); int pos) {
return delegate()->RewriteYieldStar(generator, iterable, pos);
} }
} // namespace internal } // namespace internal
......
...@@ -41,24 +41,21 @@ namespace internal { ...@@ -41,24 +41,21 @@ namespace internal {
#define DUMMY ) // to make indentation work #define DUMMY ) // to make indentation work
#undef DUMMY #undef DUMMY
void PreParserTraits::ReportMessageAt(Scanner::Location source_location, void ParserBaseTraits<PreParser>::ReportMessageAt(
MessageTemplate::Template message, Scanner::Location source_location, MessageTemplate::Template message,
const char* arg, const char* arg, ParseErrorType error_type) {
ParseErrorType error_type) { delegate()->log_->LogMessage(source_location.beg_pos, source_location.end_pos,
pre_parser_->log_->LogMessage(source_location.beg_pos, message, arg, error_type);
source_location.end_pos, message, arg,
error_type);
} }
void PreParserTraits::ReportMessageAt(Scanner::Location source_location, void ParserBaseTraits<PreParser>::ReportMessageAt(
MessageTemplate::Template message, Scanner::Location source_location, MessageTemplate::Template message,
const AstRawString* arg, const AstRawString* arg, ParseErrorType error_type) {
ParseErrorType error_type) {
UNREACHABLE(); UNREACHABLE();
} }
PreParserIdentifier ParserBaseTraits<PreParser>::GetSymbol(
PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) const { Scanner* scanner) const {
switch (scanner->current_token()) { switch (scanner->current_token()) {
case Token::ENUM: case Token::ENUM:
return PreParserIdentifier::Enum(); return PreParserIdentifier::Enum();
...@@ -89,8 +86,7 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) const { ...@@ -89,8 +86,7 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) const {
} }
} }
PreParserExpression ParserBaseTraits<PreParser>::ExpressionFromString(
PreParserExpression PreParserTraits::ExpressionFromString(
int pos, Scanner* scanner, PreParserFactory* factory) const { int pos, Scanner* scanner, PreParserFactory* factory) const {
if (scanner->UnescapedLiteralMatches("use strict", 10)) { if (scanner->UnescapedLiteralMatches("use strict", 10)) {
return PreParserExpression::UseStrictStringLiteral(); return PreParserExpression::UseStrictStringLiteral();
...@@ -98,18 +94,16 @@ PreParserExpression PreParserTraits::ExpressionFromString( ...@@ -98,18 +94,16 @@ PreParserExpression PreParserTraits::ExpressionFromString(
return PreParserExpression::StringLiteral(); return PreParserExpression::StringLiteral();
} }
PreParserExpression ParserBaseTraits<PreParser>::ParseV8Intrinsic(bool* ok) {
PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) { return delegate()->ParseV8Intrinsic(ok);
return pre_parser_->ParseV8Intrinsic(ok);
} }
PreParserExpression ParserBaseTraits<PreParser>::ParseFunctionLiteral(
PreParserExpression PreParserTraits::ParseFunctionLiteral(
PreParserIdentifier name, Scanner::Location function_name_location, PreParserIdentifier name, Scanner::Location function_name_location,
FunctionNameValidity function_name_validity, FunctionKind kind, FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_position, FunctionLiteral::FunctionType type, int function_token_position, FunctionLiteral::FunctionType type,
LanguageMode language_mode, bool* ok) { LanguageMode language_mode, bool* ok) {
return pre_parser_->ParseFunctionLiteral( return delegate()->ParseFunctionLiteral(
name, function_name_location, function_name_validity, kind, name, function_name_location, function_name_validity, kind,
function_token_position, type, language_mode, ok); function_token_position, type, language_mode, ok);
} }
...@@ -154,11 +148,11 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction( ...@@ -154,11 +148,11 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
return kPreParseSuccess; return kPreParseSuccess;
} }
PreParserExpression PreParserTraits::ParseClassLiteral( PreParserExpression ParserBaseTraits<PreParser>::ParseClassLiteral(
Type::ExpressionClassifier* classifier, PreParserIdentifier name, Type::ExpressionClassifier* classifier, PreParserIdentifier name,
Scanner::Location class_name_location, bool name_is_strict_reserved, Scanner::Location class_name_location, bool name_is_strict_reserved,
int pos, bool* ok) { int pos, bool* ok) {
return pre_parser_->ParseClassLiteral(classifier, name, class_name_location, return delegate()->ParseClassLiteral(classifier, name, class_name_location,
name_is_strict_reserved, pos, ok); name_is_strict_reserved, pos, ok);
} }
...@@ -1280,13 +1274,13 @@ PreParserExpression PreParser::ParseDoExpression(bool* ok) { ...@@ -1280,13 +1274,13 @@ PreParserExpression PreParser::ParseDoExpression(bool* ok) {
return PreParserExpression::Default(); return PreParserExpression::Default();
} }
void PreParserTraits::ParseAsyncArrowSingleExpressionBody( void ParserBaseTraits<PreParser>::ParseAsyncArrowSingleExpressionBody(
PreParserStatementList body, bool accept_IN, PreParserStatementList body, bool accept_IN,
Type::ExpressionClassifier* classifier, int pos, bool* ok) { Type::ExpressionClassifier* classifier, int pos, bool* ok) {
Scope* scope = pre_parser_->scope(); Scope* scope = delegate()->scope();
scope->ForceContextAllocation(); scope->ForceContextAllocation();
PreParserExpression return_value = pre_parser_->ParseAssignmentExpression( PreParserExpression return_value = delegate()->ParseAssignmentExpression(
accept_IN, classifier, CHECK_OK_CUSTOM(Void)); accept_IN, classifier, CHECK_OK_CUSTOM(Void));
body->Add(PreParserStatement::ExpressionStatement(return_value), zone()); body->Add(PreParserStatement::ExpressionStatement(return_value), zone());
......
...@@ -585,13 +585,12 @@ struct PreParserFormalParameters : FormalParametersBase { ...@@ -585,13 +585,12 @@ struct PreParserFormalParameters : FormalParametersBase {
class PreParser; class PreParser;
class PreParserTraits { template <>
class ParserBaseTraits<PreParser> {
public: public:
struct Type { typedef ParserBaseTraits<PreParser> PreParserTraits;
// TODO(marja): To be removed. The Traits object should contain all the data
// it needs.
typedef PreParser* Parser;
struct Type {
// PreParser doesn't need to store generator variables. // PreParser doesn't need to store generator variables.
typedef void GeneratorVariable; typedef void GeneratorVariable;
...@@ -618,7 +617,12 @@ class PreParserTraits { ...@@ -618,7 +617,12 @@ class PreParserTraits {
typedef PreParserFactory Factory; typedef PreParserFactory Factory;
}; };
explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} // TODO(nikolaos): The traits methods should not need to call methods
// of the implementation object.
PreParser* delegate() { return reinterpret_cast<PreParser*>(this); }
const PreParser* delegate() const {
return reinterpret_cast<const PreParser*>(this);
}
// Helper functions for recursive descent. // Helper functions for recursive descent.
bool IsEval(PreParserIdentifier identifier) const { bool IsEval(PreParserIdentifier identifier) const {
...@@ -989,9 +993,6 @@ class PreParserTraits { ...@@ -989,9 +993,6 @@ class PreParserTraits {
inline PreParserExpression RewriteYieldStar(PreParserExpression generator, inline PreParserExpression RewriteYieldStar(PreParserExpression generator,
PreParserExpression expression, PreParserExpression expression,
int pos); int pos);
private:
PreParser* pre_parser_;
}; };
...@@ -1007,7 +1008,11 @@ class PreParserTraits { ...@@ -1007,7 +1008,11 @@ class PreParserTraits {
// rather it is to speed up properly written and correct programs. // rather it is to speed up properly written and correct programs.
// That means that contextual checks (like a label being declared where // That means that contextual checks (like a label being declared where
// it is used) are generally omitted. // it is used) are generally omitted.
class PreParser : public ParserBase<PreParserTraits> { class PreParser : public ParserBase<PreParser> {
// TODO(nikolaos): This should not be necessary. It will be removed
// when the traits object stops delegating to the implementation object.
friend class ParserBaseTraits<PreParser>;
public: public:
typedef PreParserIdentifier Identifier; typedef PreParserIdentifier Identifier;
typedef PreParserExpression Expression; typedef PreParserExpression Expression;
...@@ -1020,8 +1025,8 @@ class PreParser : public ParserBase<PreParserTraits> { ...@@ -1020,8 +1025,8 @@ class PreParser : public ParserBase<PreParserTraits> {
PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory, PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
ParserRecorder* log, uintptr_t stack_limit) ParserRecorder* log, uintptr_t stack_limit)
: ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL, : ParserBase<PreParser>(zone, scanner, stack_limit, NULL,
ast_value_factory, log, this), ast_value_factory, log),
use_counts_(nullptr) {} use_counts_(nullptr) {}
// Pre-parse the program from the character stream; returns true on // Pre-parse the program from the character stream; returns true on
...@@ -1075,8 +1080,6 @@ class PreParser : public ParserBase<PreParserTraits> { ...@@ -1075,8 +1080,6 @@ class PreParser : public ParserBase<PreParserTraits> {
int* use_counts); int* use_counts);
private: private:
friend class PreParserTraits;
static const int kLazyParseTrialLimit = 200; static const int kLazyParseTrialLimit = 200;
// These types form an algebra over syntactic categories that is just // These types form an algebra over syntactic categories that is just
...@@ -1153,27 +1156,24 @@ class PreParser : public ParserBase<PreParserTraits> { ...@@ -1153,27 +1156,24 @@ class PreParser : public ParserBase<PreParserTraits> {
int* use_counts_; int* use_counts_;
}; };
void ParserBaseTraits<PreParser>::MaterializeUnspreadArgumentsLiterals(
void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) { int count) {
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
pre_parser_->function_state_->NextMaterializedLiteralIndex(); delegate()->function_state_->NextMaterializedLiteralIndex();
} }
} }
PreParserExpression ParserBaseTraits<PreParser>::SpreadCall(
PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function, PreParserExpression function, PreParserExpressionList args, int pos) {
PreParserExpressionList args, return delegate()->factory()->NewCall(function, args, pos);
int pos) {
return pre_parser_->factory()->NewCall(function, args, pos);
} }
PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, PreParserExpression ParserBaseTraits<PreParser>::SpreadCallNew(
PreParserExpressionList args, PreParserExpression function, PreParserExpressionList args, int pos) {
int pos) { return delegate()->factory()->NewCallNew(function, args, pos);
return pre_parser_->factory()->NewCallNew(function, args, pos);
} }
void PreParserTraits::ParseArrowFunctionFormalParameterList( void ParserBaseTraits<PreParser>::ParseArrowFunctionFormalParameterList(
PreParserFormalParameters* parameters, PreParserExpression params, PreParserFormalParameters* parameters, PreParserExpression params,
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
const Scope::Snapshot& scope_snapshot, bool* ok) { const Scope::Snapshot& scope_snapshot, bool* ok) {
...@@ -1181,42 +1181,41 @@ void PreParserTraits::ParseArrowFunctionFormalParameterList( ...@@ -1181,42 +1181,41 @@ void PreParserTraits::ParseArrowFunctionFormalParameterList(
// lists that are too long. // lists that are too long.
} }
PreParserExpression PreParserTraits::ParseAsyncFunctionExpression(bool* ok) { PreParserExpression ParserBaseTraits<PreParser>::ParseAsyncFunctionExpression(
return pre_parser_->ParseAsyncFunctionExpression(ok); bool* ok) {
return delegate()->ParseAsyncFunctionExpression(ok);
} }
PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) { PreParserExpression ParserBaseTraits<PreParser>::ParseDoExpression(bool* ok) {
return pre_parser_->ParseDoExpression(ok); return delegate()->ParseDoExpression(ok);
} }
void ParserBaseTraits<PreParser>::RewriteNonPattern(
void PreParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, Type::ExpressionClassifier* classifier, bool* ok) {
bool* ok) { delegate()->ValidateExpression(classifier, ok);
pre_parser_->ValidateExpression(classifier, ok);
} }
PreParserExpression PreParserTraits::RewriteAwaitExpression( PreParserExpression ParserBaseTraits<PreParser>::RewriteAwaitExpression(
PreParserExpression value, int pos) { PreParserExpression value, int pos) {
return value; return value;
} }
ZoneList<PreParserExpression>* PreParserTraits::GetNonPatternList() const { ZoneList<PreParserExpression>* ParserBaseTraits<PreParser>::GetNonPatternList()
return pre_parser_->function_state_->non_patterns_to_rewrite(); const {
return delegate()->function_state_->non_patterns_to_rewrite();
} }
ZoneList<
ZoneList<typename PreParserTraits::Type::ExpressionClassifier::Error>* typename ParserBaseTraits<PreParser>::Type::ExpressionClassifier::Error>*
PreParserTraits::GetReportedErrorList() const { ParserBaseTraits<PreParser>::GetReportedErrorList() const {
return pre_parser_->function_state_->GetReportedErrorList(); return delegate()->function_state_->GetReportedErrorList();
} }
Zone* ParserBaseTraits<PreParser>::zone() const {
Zone* PreParserTraits::zone() const { return delegate()->function_state_->scope()->zone();
return pre_parser_->function_state_->scope()->zone();
} }
PreParserExpression ParserBaseTraits<PreParser>::RewriteYieldStar(
PreParserExpression PreParserTraits::RewriteYieldStar(
PreParserExpression generator, PreParserExpression expression, int pos) { PreParserExpression generator, PreParserExpression expression, int pos) {
return PreParserExpression::Default(); return PreParserExpression::Default();
} }
...@@ -1240,22 +1239,21 @@ PreParserStatementList PreParser::ParseEagerFunctionBody( ...@@ -1240,22 +1239,21 @@ PreParserStatementList PreParser::ParseEagerFunctionBody(
return PreParserStatementList(); return PreParserStatementList();
} }
PreParserStatementList ParserBaseTraits<PreParser>::ParseEagerFunctionBody(
PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
PreParserIdentifier function_name, int pos, PreParserIdentifier function_name, int pos,
const PreParserFormalParameters& parameters, FunctionKind kind, const PreParserFormalParameters& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, bool* ok) { FunctionLiteral::FunctionType function_type, bool* ok) {
return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters, return delegate()->ParseEagerFunctionBody(function_name, pos, parameters,
kind, function_type, ok); kind, function_type, ok);
} }
PreParserExpression PreParserTraits::CloseTemplateLiteral( PreParserExpression ParserBaseTraits<PreParser>::CloseTemplateLiteral(
TemplateLiteralState* state, int start, PreParserExpression tag) { TemplateLiteralState* state, int start, PreParserExpression tag) {
if (IsTaggedTemplate(tag)) { if (IsTaggedTemplate(tag)) {
// Emulate generation of array literals for tag callsite // Emulate generation of array literals for tag callsite
// 1st is array of cooked strings, second is array of raw strings // 1st is array of cooked strings, second is array of raw strings
pre_parser_->function_state_->NextMaterializedLiteralIndex(); delegate()->function_state_->NextMaterializedLiteralIndex();
pre_parser_->function_state_->NextMaterializedLiteralIndex(); delegate()->function_state_->NextMaterializedLiteralIndex();
} }
return EmptyExpression(); return EmptyExpression();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment