[parser] Clean up (pre)parser traits, part 5, last
This patch moves the following methods from the traits objects to the (pre)parser implementation objects: - AddFormalParameter - AddParameterInitializationBlock - DeclareFormalParameter - ExpressionListToExpression - GetNonPatternList - GetReportedErrorList - IsTaggedTemplate - MaterializeUnspreadArgumentsLiterals - NoTemplateTag - ParseArrowFunctionFormalParameterList - ReindexLiterals - SetFunctionNameFromIdentifierRef - SetFunctionNameFromPropertyName It moves the Void method from the preparser traits object to the preparser implementation object. It also removes the traits zone method and replaces it with that of ParserBase, which it turns to public. After all this, the traits objects contain just typedefs and the delegate methods are no more necessary. R=adamk@chromium.org, marja@chromium.org BUG= LOG=N Review-Url: https://codereview.chromium.org/2277843002 Cr-Commit-Position: refs/heads/master@{#38892}
This commit is contained in:
parent
955606506c
commit
ba9367db60
@ -77,21 +77,11 @@ class ExpressionClassifier {
|
||||
NonSimpleParameter = 1 << 0
|
||||
};
|
||||
|
||||
explicit ExpressionClassifier(const Traits* t)
|
||||
: zone_(t->zone()),
|
||||
non_patterns_to_rewrite_(t->GetNonPatternList()),
|
||||
reported_errors_(t->GetReportedErrorList()),
|
||||
duplicate_finder_(nullptr),
|
||||
invalid_productions_(0),
|
||||
function_properties_(0) {
|
||||
reported_errors_begin_ = reported_errors_end_ = reported_errors_->length();
|
||||
non_pattern_begin_ = non_patterns_to_rewrite_->length();
|
||||
}
|
||||
|
||||
ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder)
|
||||
: zone_(t->zone()),
|
||||
non_patterns_to_rewrite_(t->GetNonPatternList()),
|
||||
reported_errors_(t->GetReportedErrorList()),
|
||||
explicit ExpressionClassifier(const typename Traits::Type::Base* base,
|
||||
DuplicateFinder* duplicate_finder = nullptr)
|
||||
: zone_(base->impl()->zone()),
|
||||
non_patterns_to_rewrite_(base->impl()->GetNonPatternList()),
|
||||
reported_errors_(base->impl()->GetReportedErrorList()),
|
||||
duplicate_finder_(duplicate_finder),
|
||||
invalid_productions_(0),
|
||||
function_properties_(0) {
|
||||
|
@ -161,10 +161,6 @@ struct FormalParametersBase {
|
||||
//
|
||||
// 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.
|
||||
|
||||
// The traits class template encapsulates the differences between
|
||||
// parser/pre-parser implementations. In particular:
|
||||
|
||||
@ -179,15 +175,14 @@ struct FormalParametersBase {
|
||||
// interface as AstNodeFactory, so ParserBase doesn't need to care which one is
|
||||
// used.
|
||||
|
||||
// - Miscellaneous other tasks interleaved with the recursive descent. For
|
||||
// example, Parser keeps track of which function literals should be marked as
|
||||
// pretenured, and PreParser doesn't care.
|
||||
|
||||
// The traits are expected to contain the following typedefs:
|
||||
// template <>
|
||||
// class ParserBaseTraits<Impl> {
|
||||
// // In particular...
|
||||
// struct Type {
|
||||
// // Synonyms for ParserBase<Impl> and Impl, respectively.
|
||||
// typedef Base;
|
||||
// typedef Impl;
|
||||
// typedef GeneratorVariable;
|
||||
// typedef AstProperties;
|
||||
// typedef ExpressionClassifier;
|
||||
@ -280,6 +275,8 @@ class ParserBase : public ParserBaseTraits<Impl> {
|
||||
|
||||
void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
|
||||
|
||||
Zone* zone() const { return zone_; }
|
||||
|
||||
protected:
|
||||
enum AllowRestrictedIdentifiers {
|
||||
kAllowRestrictedIdentifiers,
|
||||
@ -696,7 +693,6 @@ class ParserBase : public ParserBaseTraits<Impl> {
|
||||
bool stack_overflow() const { return stack_overflow_; }
|
||||
void set_stack_overflow() { stack_overflow_ = true; }
|
||||
Mode mode() const { return mode_; }
|
||||
Zone* zone() const { return zone_; }
|
||||
|
||||
INLINE(Token::Value peek()) {
|
||||
if (stack_overflow_) return Token::ILLEGAL;
|
||||
@ -1469,7 +1465,7 @@ ParserBase<Impl>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
|
||||
}
|
||||
return impl()->GetSymbol();
|
||||
} else {
|
||||
this->ReportUnexpectedToken(next);
|
||||
ReportUnexpectedToken(next);
|
||||
*ok = false;
|
||||
return impl()->EmptyIdentifier();
|
||||
}
|
||||
@ -1507,7 +1503,7 @@ typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName(
|
||||
next != Token::FUTURE_STRICT_RESERVED_WORD &&
|
||||
next != Token::ESCAPED_KEYWORD &&
|
||||
next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
|
||||
this->ReportUnexpectedToken(next);
|
||||
ReportUnexpectedToken(next);
|
||||
*ok = false;
|
||||
return impl()->EmptyIdentifier();
|
||||
}
|
||||
@ -1610,13 +1606,13 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
|
||||
case Token::DIV:
|
||||
classifier->RecordBindingPatternError(
|
||||
scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
|
||||
return this->ParseRegExpLiteral(ok);
|
||||
return ParseRegExpLiteral(ok);
|
||||
|
||||
case Token::LBRACK:
|
||||
return this->ParseArrayLiteral(classifier, ok);
|
||||
return ParseArrayLiteral(classifier, ok);
|
||||
|
||||
case Token::LBRACE:
|
||||
return this->ParseObjectLiteral(classifier, ok);
|
||||
return ParseObjectLiteral(classifier, ok);
|
||||
|
||||
case Token::LPAREN: {
|
||||
// Arrow function formal parameters are either a single identifier or a
|
||||
@ -1647,8 +1643,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
|
||||
Token::String(Token::ELLIPSIS));
|
||||
classifier->RecordNonSimpleParameter();
|
||||
ExpressionClassifier binding_classifier(this);
|
||||
ExpressionT expr = this->ParseAssignmentExpression(
|
||||
true, &binding_classifier, CHECK_OK);
|
||||
ExpressionT expr =
|
||||
ParseAssignmentExpression(true, &binding_classifier, CHECK_OK);
|
||||
classifier->Accumulate(&binding_classifier,
|
||||
ExpressionClassifier::AllProductions);
|
||||
if (!impl()->IsIdentifier(expr) && !IsValidPattern(expr)) {
|
||||
@ -1669,7 +1665,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
|
||||
// seeing the call parentheses.
|
||||
function_state_->set_next_function_is_parenthesized(peek() ==
|
||||
Token::FUNCTION);
|
||||
ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK);
|
||||
ExpressionT expr = ParseExpression(true, classifier, CHECK_OK);
|
||||
Expect(Token::RPAREN, CHECK_OK);
|
||||
return expr;
|
||||
}
|
||||
@ -1694,8 +1690,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
|
||||
case Token::TEMPLATE_SPAN:
|
||||
case Token::TEMPLATE_TAIL:
|
||||
BindingPatternUnexpectedToken(classifier);
|
||||
return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
|
||||
classifier, ok);
|
||||
return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, classifier,
|
||||
ok);
|
||||
|
||||
case Token::MOD:
|
||||
if (allow_natives() || extension_ != NULL) {
|
||||
@ -1739,8 +1735,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression(
|
||||
ExpressionT result;
|
||||
{
|
||||
ExpressionClassifier binding_classifier(this);
|
||||
result = this->ParseAssignmentExpression(accept_IN, &binding_classifier,
|
||||
CHECK_OK);
|
||||
result =
|
||||
ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
|
||||
classifier->Accumulate(&binding_classifier,
|
||||
ExpressionClassifier::AllProductions);
|
||||
}
|
||||
@ -1771,8 +1767,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression(
|
||||
}
|
||||
int pos = position(), expr_pos = peek_position();
|
||||
ExpressionClassifier binding_classifier(this);
|
||||
ExpressionT right = this->ParseAssignmentExpression(
|
||||
accept_IN, &binding_classifier, CHECK_OK);
|
||||
ExpressionT right =
|
||||
ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
|
||||
classifier->Accumulate(&binding_classifier,
|
||||
ExpressionClassifier::AllProductions);
|
||||
if (is_rest) {
|
||||
@ -1813,7 +1809,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral(
|
||||
Consume(Token::ELLIPSIS);
|
||||
int expr_pos = peek_position();
|
||||
ExpressionT argument =
|
||||
this->ParseAssignmentExpression(true, classifier, CHECK_OK);
|
||||
ParseAssignmentExpression(true, classifier, CHECK_OK);
|
||||
CheckNoTailCallExpressions(classifier, CHECK_OK);
|
||||
elem = factory()->NewSpread(argument, start_pos, expr_pos);
|
||||
|
||||
@ -1837,7 +1833,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral(
|
||||
}
|
||||
} else {
|
||||
int beg_pos = peek_position();
|
||||
elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
|
||||
elem = ParseAssignmentExpression(true, classifier, CHECK_OK);
|
||||
CheckNoTailCallExpressions(classifier, CHECK_OK);
|
||||
CheckDestructuringElement(elem, classifier, beg_pos,
|
||||
scanner()->location().end_pos);
|
||||
@ -1972,7 +1968,7 @@ ParserBase<Impl>::ParsePropertyDefinition(
|
||||
}
|
||||
Consume(Token::COLON);
|
||||
int beg_pos = peek_position();
|
||||
ExpressionT value = this->ParseAssignmentExpression(
|
||||
ExpressionT value = ParseAssignmentExpression(
|
||||
true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
||||
CheckDestructuringElement(value, classifier, beg_pos,
|
||||
scanner()->location().end_pos);
|
||||
@ -2019,7 +2015,7 @@ ParserBase<Impl>::ParsePropertyDefinition(
|
||||
if (peek() == Token::ASSIGN) {
|
||||
Consume(Token::ASSIGN);
|
||||
ExpressionClassifier rhs_classifier(this);
|
||||
ExpressionT rhs = this->ParseAssignmentExpression(
|
||||
ExpressionT rhs = ParseAssignmentExpression(
|
||||
true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
||||
impl()->RewriteNonPattern(&rhs_classifier,
|
||||
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
||||
@ -2031,7 +2027,7 @@ ParserBase<Impl>::ParsePropertyDefinition(
|
||||
Scanner::Location(next_beg_pos, scanner()->location().end_pos),
|
||||
MessageTemplate::kInvalidCoverInitializedName);
|
||||
|
||||
Traits::SetFunctionNameFromIdentifierRef(rhs, lhs);
|
||||
impl()->SetFunctionNameFromIdentifierRef(rhs, lhs);
|
||||
} else {
|
||||
value = lhs;
|
||||
}
|
||||
@ -2165,7 +2161,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
|
||||
const bool has_extends = false;
|
||||
bool is_computed_name = false;
|
||||
IdentifierT name = impl()->EmptyIdentifier();
|
||||
ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
|
||||
ObjectLiteralPropertyT property = ParsePropertyDefinition(
|
||||
&checker, in_class, has_extends, MethodKind::kNormal, &is_computed_name,
|
||||
NULL, classifier, &name, CHECK_OK);
|
||||
|
||||
@ -2186,7 +2182,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
|
||||
|
||||
if (fni_ != nullptr) fni_->Infer();
|
||||
|
||||
Traits::SetFunctionNameFromPropertyName(property, name);
|
||||
impl()->SetFunctionNameFromPropertyName(property, name);
|
||||
}
|
||||
Expect(Token::RBRACE, CHECK_OK);
|
||||
|
||||
@ -2218,7 +2214,7 @@ ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc,
|
||||
bool is_spread = Check(Token::ELLIPSIS);
|
||||
int expr_pos = peek_position();
|
||||
|
||||
ExpressionT argument = this->ParseAssignmentExpression(
|
||||
ExpressionT argument = ParseAssignmentExpression(
|
||||
true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
|
||||
CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList));
|
||||
if (!maybe_arrow) {
|
||||
@ -2274,7 +2270,7 @@ ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc,
|
||||
// Unspread parameter sequences are translated into array literals in the
|
||||
// parser. Ensure that the number of materialized literals matches between
|
||||
// the parser and preparser
|
||||
Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
|
||||
impl()->MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2295,7 +2291,7 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN,
|
||||
int lhs_beg_pos = peek_position();
|
||||
|
||||
if (peek() == Token::YIELD && is_generator()) {
|
||||
return this->ParseYieldExpression(accept_IN, classifier, ok);
|
||||
return ParseYieldExpression(accept_IN, classifier, ok);
|
||||
}
|
||||
|
||||
FuncNameInferrer::State fni_state(fni_);
|
||||
@ -2318,10 +2314,10 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN,
|
||||
// that we have only a trivial expression to parse.
|
||||
ExpressionT expression;
|
||||
if (IsTrivialExpression()) {
|
||||
expression = this->ParsePrimaryExpression(&arrow_formals_classifier,
|
||||
&is_async, CHECK_OK);
|
||||
expression =
|
||||
ParsePrimaryExpression(&arrow_formals_classifier, &is_async, CHECK_OK);
|
||||
} else {
|
||||
expression = this->ParseConditionalExpression(
|
||||
expression = ParseConditionalExpression(
|
||||
accept_IN, &arrow_formals_classifier, CHECK_OK);
|
||||
}
|
||||
|
||||
@ -2352,8 +2348,8 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN,
|
||||
|
||||
Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
|
||||
DeclarationScope* scope =
|
||||
this->NewFunctionScope(is_async ? FunctionKind::kAsyncArrowFunction
|
||||
: FunctionKind::kArrowFunction);
|
||||
NewFunctionScope(is_async ? FunctionKind::kAsyncArrowFunction
|
||||
: FunctionKind::kArrowFunction);
|
||||
// Because the arrow's parameters were parsed in the outer scope, any
|
||||
// usage flags that might have been triggered there need to be copied
|
||||
// to the arrow scope.
|
||||
@ -2368,14 +2364,14 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN,
|
||||
|
||||
scope->set_start_position(lhs_beg_pos);
|
||||
Scanner::Location duplicate_loc = Scanner::Location::invalid();
|
||||
this->ParseArrowFunctionFormalParameterList(
|
||||
impl()->ParseArrowFunctionFormalParameterList(
|
||||
¶meters, expression, loc, &duplicate_loc, scope_snapshot, CHECK_OK);
|
||||
if (duplicate_loc.IsValid()) {
|
||||
arrow_formals_classifier.RecordDuplicateFormalParameterError(
|
||||
duplicate_loc);
|
||||
}
|
||||
expression = this->ParseArrowFunctionLiteral(
|
||||
accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK);
|
||||
expression = ParseArrowFunctionLiteral(accept_IN, parameters, is_async,
|
||||
arrow_formals_classifier, CHECK_OK);
|
||||
arrow_formals_classifier.Discard();
|
||||
classifier->RecordPatternError(arrow_loc,
|
||||
MessageTemplate::kUnexpectedToken,
|
||||
@ -2433,7 +2429,7 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN,
|
||||
if (is_destructuring_assignment) {
|
||||
ValidateAssignmentPattern(classifier, CHECK_OK);
|
||||
} else {
|
||||
expression = this->CheckAndRewriteReferenceExpression(
|
||||
expression = CheckAndRewriteReferenceExpression(
|
||||
expression, lhs_beg_pos, scanner()->location().end_pos,
|
||||
MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
|
||||
}
|
||||
@ -2451,7 +2447,7 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN,
|
||||
ExpressionClassifier rhs_classifier(this);
|
||||
|
||||
ExpressionT right =
|
||||
this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
|
||||
ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
|
||||
CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK);
|
||||
impl()->RewriteNonPattern(&rhs_classifier, CHECK_OK);
|
||||
classifier->Accumulate(
|
||||
@ -2484,7 +2480,7 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN,
|
||||
}
|
||||
|
||||
if (op == Token::ASSIGN) {
|
||||
Traits::SetFunctionNameFromIdentifierRef(right, expression);
|
||||
impl()->SetFunctionNameFromIdentifierRef(right, expression);
|
||||
}
|
||||
|
||||
if (op == Token::ASSIGN_EXP) {
|
||||
@ -2565,8 +2561,7 @@ ParserBase<Impl>::ParseTailCallExpression(ExpressionClassifier* classifier,
|
||||
Expect(Token::CONTINUE, CHECK_OK);
|
||||
int pos = position();
|
||||
int sub_expression_pos = peek_position();
|
||||
ExpressionT expression =
|
||||
this->ParseLeftHandSideExpression(classifier, CHECK_OK);
|
||||
ExpressionT expression = ParseLeftHandSideExpression(classifier, CHECK_OK);
|
||||
CheckNoTailCallExpressions(classifier, CHECK_OK);
|
||||
|
||||
Scanner::Location loc(pos, scanner()->location().end_pos);
|
||||
@ -2630,7 +2625,7 @@ ParserBase<Impl>::ParseConditionalExpression(bool accept_IN,
|
||||
int pos = peek_position();
|
||||
// We start using the binary expression parser for prec >= 4 only!
|
||||
ExpressionT expression =
|
||||
this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
|
||||
ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
|
||||
if (peek() != Token::CONDITIONAL) return expression;
|
||||
CheckNoTailCallExpressions(classifier, CHECK_OK);
|
||||
impl()->RewriteNonPattern(classifier, CHECK_OK);
|
||||
@ -2655,7 +2650,7 @@ template <typename Impl>
|
||||
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
|
||||
int prec, bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
|
||||
DCHECK(prec >= 4);
|
||||
ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
|
||||
ExpressionT x = ParseUnaryExpression(classifier, CHECK_OK);
|
||||
for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
|
||||
// prec1 >= 4
|
||||
while (Precedence(peek(), accept_IN) == prec1) {
|
||||
@ -2755,9 +2750,9 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
|
||||
ArrowFormalParametersUnexpectedToken(classifier);
|
||||
op = Next();
|
||||
int beg_pos = peek_position();
|
||||
ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
|
||||
ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
|
||||
CheckNoTailCallExpressions(classifier, CHECK_OK);
|
||||
expression = this->CheckAndRewriteReferenceExpression(
|
||||
expression = CheckAndRewriteReferenceExpression(
|
||||
expression, beg_pos, scanner()->location().end_pos,
|
||||
MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
|
||||
expression = impl()->MarkExpressionAsAssigned(expression);
|
||||
@ -2780,7 +2775,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
|
||||
|
||||
return impl()->RewriteAwaitExpression(value, await_pos);
|
||||
} else {
|
||||
return this->ParsePostfixExpression(classifier, ok);
|
||||
return ParsePostfixExpression(classifier, ok);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2791,15 +2786,14 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression(
|
||||
// LeftHandSideExpression ('++' | '--')?
|
||||
|
||||
int lhs_beg_pos = peek_position();
|
||||
ExpressionT expression =
|
||||
this->ParseLeftHandSideExpression(classifier, CHECK_OK);
|
||||
ExpressionT expression = ParseLeftHandSideExpression(classifier, CHECK_OK);
|
||||
if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
|
||||
Token::IsCountOp(peek())) {
|
||||
CheckNoTailCallExpressions(classifier, CHECK_OK);
|
||||
BindingPatternUnexpectedToken(classifier);
|
||||
ArrowFormalParametersUnexpectedToken(classifier);
|
||||
|
||||
expression = this->CheckAndRewriteReferenceExpression(
|
||||
expression = CheckAndRewriteReferenceExpression(
|
||||
expression, lhs_beg_pos, scanner()->location().end_pos,
|
||||
MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
|
||||
expression = impl()->MarkExpressionAsAssigned(expression);
|
||||
@ -2823,12 +2817,12 @@ ParserBase<Impl>::ParseLeftHandSideExpression(ExpressionClassifier* classifier,
|
||||
// (NewExpression | MemberExpression) ...
|
||||
|
||||
if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) {
|
||||
return this->ParseTailCallExpression(classifier, ok);
|
||||
return ParseTailCallExpression(classifier, ok);
|
||||
}
|
||||
|
||||
bool is_async = false;
|
||||
ExpressionT result = this->ParseMemberWithNewPrefixesExpression(
|
||||
classifier, &is_async, CHECK_OK);
|
||||
ExpressionT result =
|
||||
ParseMemberWithNewPrefixesExpression(classifier, &is_async, CHECK_OK);
|
||||
|
||||
while (true) {
|
||||
switch (peek()) {
|
||||
@ -2890,7 +2884,7 @@ ParserBase<Impl>::ParseLeftHandSideExpression(ExpressionClassifier* classifier,
|
||||
}
|
||||
if (args->length()) {
|
||||
// async ( Arguments ) => ...
|
||||
return Traits::ExpressionListToExpression(args);
|
||||
return impl()->ExpressionListToExpression(args);
|
||||
}
|
||||
// async () => ...
|
||||
return factory()->NewEmptyParentheses(pos);
|
||||
@ -3000,15 +2994,15 @@ ParserBase<Impl>::ParseMemberWithNewPrefixesExpression(
|
||||
} else if (peek() == Token::PERIOD) {
|
||||
return ParseNewTargetExpression(CHECK_OK);
|
||||
} else {
|
||||
result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async,
|
||||
CHECK_OK);
|
||||
result =
|
||||
ParseMemberWithNewPrefixesExpression(classifier, is_async, CHECK_OK);
|
||||
}
|
||||
impl()->RewriteNonPattern(classifier, CHECK_OK);
|
||||
if (peek() == Token::LPAREN) {
|
||||
// NewExpression with arguments.
|
||||
Scanner::Location spread_pos;
|
||||
typename Traits::Type::ExpressionList args =
|
||||
this->ParseArguments(&spread_pos, classifier, CHECK_OK);
|
||||
ParseArguments(&spread_pos, classifier, CHECK_OK);
|
||||
|
||||
if (spread_pos.IsValid()) {
|
||||
args = impl()->PrepareSpreadArguments(args);
|
||||
@ -3017,15 +3011,15 @@ ParserBase<Impl>::ParseMemberWithNewPrefixesExpression(
|
||||
result = factory()->NewCallNew(result, args, new_pos);
|
||||
}
|
||||
// The expression can still continue with . or [ after the arguments.
|
||||
result = this->ParseMemberExpressionContinuation(result, is_async,
|
||||
classifier, CHECK_OK);
|
||||
result = ParseMemberExpressionContinuation(result, is_async, classifier,
|
||||
CHECK_OK);
|
||||
return result;
|
||||
}
|
||||
// NewExpression without arguments.
|
||||
return factory()->NewCallNew(result, impl()->NewExpressionList(0), new_pos);
|
||||
}
|
||||
// No 'new' or 'super' keyword.
|
||||
return this->ParseMemberExpression(classifier, is_async, ok);
|
||||
return ParseMemberExpression(classifier, is_async, ok);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
@ -3172,7 +3166,7 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(
|
||||
|
||||
Consume(Token::LBRACK);
|
||||
int pos = position();
|
||||
ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
|
||||
ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
|
||||
impl()->RewriteNonPattern(classifier, CHECK_OK);
|
||||
expression = factory()->NewProperty(expression, index, pos);
|
||||
if (fni_ != NULL) {
|
||||
@ -3260,10 +3254,10 @@ void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters,
|
||||
init_classifier.Discard();
|
||||
classifier->RecordNonSimpleParameter();
|
||||
|
||||
Traits::SetFunctionNameFromIdentifierRef(initializer, pattern);
|
||||
impl()->SetFunctionNameFromIdentifierRef(initializer, pattern);
|
||||
}
|
||||
|
||||
Traits::AddFormalParameter(parameters, pattern, initializer,
|
||||
impl()->AddFormalParameter(parameters, pattern, initializer,
|
||||
scanner()->location().end_pos, is_rest);
|
||||
}
|
||||
|
||||
@ -3314,7 +3308,7 @@ void ParserBase<Impl>::ParseFormalParameterList(
|
||||
|
||||
for (int i = 0; i < parameters->Arity(); ++i) {
|
||||
auto parameter = parameters->at(i);
|
||||
Traits::DeclareFormalParameter(parameters->scope, parameter, classifier);
|
||||
impl()->DeclareFormalParameter(parameters->scope, parameter, classifier);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3417,7 +3411,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
|
||||
function_state.SkipMaterializedLiterals(
|
||||
formal_parameters.materialized_literals_count);
|
||||
|
||||
this->ReindexLiterals(formal_parameters);
|
||||
impl()->ReindexLiterals(formal_parameters);
|
||||
|
||||
Expect(Token::ARROW, CHECK_OK);
|
||||
|
||||
@ -3451,8 +3445,8 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
|
||||
ReturnExprScope allow_tail_calls(
|
||||
function_state_, ReturnExprContext::kInsideValidReturnStatement);
|
||||
body = impl()->NewStatementList(1);
|
||||
this->AddParameterInitializationBlock(formal_parameters, body, is_async,
|
||||
CHECK_OK);
|
||||
impl()->AddParameterInitializationBlock(formal_parameters, body, is_async,
|
||||
CHECK_OK);
|
||||
ExpressionClassifier classifier(this);
|
||||
if (is_async) {
|
||||
impl()->ParseAsyncArrowSingleExpressionBody(body, accept_IN,
|
||||
@ -3480,8 +3474,8 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
|
||||
// that duplicates are not allowed. Of course, the arrow function may
|
||||
// itself be strict as well.
|
||||
const bool allow_duplicate_parameters = false;
|
||||
this->ValidateFormalParameters(&formals_classifier, language_mode(),
|
||||
allow_duplicate_parameters, CHECK_OK);
|
||||
ValidateFormalParameters(&formals_classifier, language_mode(),
|
||||
allow_duplicate_parameters, CHECK_OK);
|
||||
|
||||
// Validate strict mode.
|
||||
if (is_strict(language_mode())) {
|
||||
@ -3563,7 +3557,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
|
||||
}
|
||||
|
||||
int expr_pos = peek_position();
|
||||
ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
|
||||
ExpressionT expression = ParseExpression(true, classifier, CHECK_OK);
|
||||
CheckNoTailCallExpressions(classifier, CHECK_OK);
|
||||
impl()->RewriteNonPattern(classifier, CHECK_OK);
|
||||
impl()->AddTemplateExpression(&ts, expression);
|
||||
@ -3608,8 +3602,8 @@ typename ParserBase<Impl>::ExpressionT
|
||||
ParserBase<Impl>::CheckAndRewriteReferenceExpression(
|
||||
ExpressionT expression, int beg_pos, int end_pos,
|
||||
MessageTemplate::Template message, bool* ok) {
|
||||
return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
|
||||
message, kReferenceError, ok);
|
||||
return CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
|
||||
message, kReferenceError, ok);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
|
@ -2125,8 +2125,7 @@ Block* Parser::ParseVariableDeclarations(
|
||||
}
|
||||
}
|
||||
|
||||
ParserBaseTraits<Parser>::SetFunctionNameFromIdentifierRef(value,
|
||||
pattern);
|
||||
SetFunctionNameFromIdentifierRef(value, pattern);
|
||||
|
||||
// End position of the initializer is after the assignment expression.
|
||||
initializer_position = scanner()->location().end_pos;
|
||||
@ -3558,7 +3557,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
|
||||
|
||||
if (is_for_each) {
|
||||
if (!is_destructuring) {
|
||||
expression = this->CheckAndRewriteReferenceExpression(
|
||||
expression = CheckAndRewriteReferenceExpression(
|
||||
expression, lhs_beg_pos, lhs_end_pos,
|
||||
MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
|
||||
}
|
||||
@ -3849,25 +3848,24 @@ DoExpression* Parser::ParseDoExpression(bool* ok) {
|
||||
return expr;
|
||||
}
|
||||
|
||||
void ParserBaseTraits<Parser>::ParseArrowFunctionFormalParameterList(
|
||||
void Parser::ParseArrowFunctionFormalParameterList(
|
||||
ParserFormalParameters* parameters, Expression* expr,
|
||||
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
|
||||
const Scope::Snapshot& scope_snapshot, bool* ok) {
|
||||
if (expr->IsEmptyParentheses()) return;
|
||||
|
||||
delegate()->ParseArrowFunctionFormalParameters(
|
||||
parameters, expr, params_loc.end_pos, CHECK_OK_VOID);
|
||||
ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
|
||||
CHECK_OK_VOID);
|
||||
|
||||
scope_snapshot.Reparent(parameters->scope);
|
||||
|
||||
if (parameters->Arity() > Code::kMaxArguments) {
|
||||
delegate()->ReportMessageAt(params_loc,
|
||||
MessageTemplate::kMalformedArrowFunParamList);
|
||||
ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Type::ExpressionClassifier classifier(delegate());
|
||||
Type::ExpressionClassifier classifier(this);
|
||||
if (!parameters->is_simple) {
|
||||
classifier.RecordNonSimpleParameter();
|
||||
}
|
||||
@ -3881,9 +3879,8 @@ void ParserBaseTraits<Parser>::ParseArrowFunctionFormalParameterList(
|
||||
DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
|
||||
}
|
||||
|
||||
void ParserBaseTraits<Parser>::ReindexLiterals(
|
||||
const ParserFormalParameters& parameters) {
|
||||
if (delegate()->function_state_->materialized_literal_count() > 0) {
|
||||
void Parser::ReindexLiterals(const ParserFormalParameters& parameters) {
|
||||
if (function_state_->materialized_literal_count() > 0) {
|
||||
AstLiteralReindexer reindexer;
|
||||
|
||||
for (const auto p : parameters.params) {
|
||||
@ -3891,8 +3888,7 @@ void ParserBaseTraits<Parser>::ReindexLiterals(
|
||||
if (p.initializer != nullptr) reindexer.Reindex(p.initializer);
|
||||
}
|
||||
|
||||
DCHECK(reindexer.count() <=
|
||||
delegate()->function_state_->materialized_literal_count());
|
||||
DCHECK(reindexer.count() <= function_state_->materialized_literal_count());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3966,7 +3962,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
// To make this additional case work, both Parser and PreParser implement a
|
||||
// logic where only top-level functions will be parsed lazily.
|
||||
bool is_lazily_parsed = mode() == PARSE_LAZILY &&
|
||||
this->scope()->AllowsLazyParsing() &&
|
||||
scope()->AllowsLazyParsing() &&
|
||||
!function_state_->next_function_is_parenthesized();
|
||||
|
||||
// Determine whether the function body can be discarded after parsing.
|
||||
@ -4266,9 +4262,9 @@ Statement* Parser::BuildAssertIsCoercible(Variable* var) {
|
||||
Token::EQ_STRICT, factory()->NewVariableProxy(var),
|
||||
factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
|
||||
kNoSourcePosition);
|
||||
Expression* throw_type_error = this->NewThrowTypeError(
|
||||
MessageTemplate::kNonCoercible, ast_value_factory()->empty_string(),
|
||||
kNoSourcePosition);
|
||||
Expression* throw_type_error =
|
||||
NewThrowTypeError(MessageTemplate::kNonCoercible,
|
||||
ast_value_factory()->empty_string(), kNoSourcePosition);
|
||||
IfStatement* if_statement = factory()->NewIfStatement(
|
||||
condition,
|
||||
factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
|
||||
@ -4540,8 +4536,8 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
|
||||
}
|
||||
|
||||
if (IsSubclassConstructor(kind)) {
|
||||
body->Add(factory()->NewReturnStatement(
|
||||
this->ThisExpression(kNoSourcePosition), kNoSourcePosition),
|
||||
body->Add(factory()->NewReturnStatement(ThisExpression(kNoSourcePosition),
|
||||
kNoSourcePosition),
|
||||
zone());
|
||||
}
|
||||
}
|
||||
@ -5413,13 +5409,11 @@ void Parser::MarkCollectedTailCallExpressions() {
|
||||
}
|
||||
}
|
||||
|
||||
Expression* ParserBaseTraits<Parser>::ExpressionListToExpression(
|
||||
ZoneList<Expression*>* args) {
|
||||
AstNodeFactory* factory = delegate()->factory();
|
||||
Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
|
||||
Expression* expr = args->at(0);
|
||||
for (int i = 1; i < args->length(); ++i) {
|
||||
expr = factory->NewBinaryOperation(Token::COMMA, expr, args->at(i),
|
||||
expr->position());
|
||||
expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
|
||||
expr->position());
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
@ -5427,57 +5421,44 @@ Expression* ParserBaseTraits<Parser>::ExpressionListToExpression(
|
||||
Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
|
||||
// yield %AsyncFunctionAwait(.generator_object, <operand>)
|
||||
Variable* generator_object_variable =
|
||||
delegate()->function_state_->generator_object_variable();
|
||||
function_state_->generator_object_variable();
|
||||
|
||||
// If generator_object_variable is null,
|
||||
if (!generator_object_variable) return value;
|
||||
|
||||
auto factory = delegate()->factory();
|
||||
const int nopos = kNoSourcePosition;
|
||||
|
||||
Variable* temp_var =
|
||||
delegate()->NewTemporary(delegate()->ast_value_factory()->empty_string());
|
||||
VariableProxy* temp_proxy = factory->NewVariableProxy(temp_var);
|
||||
Block* do_block = factory->NewBlock(nullptr, 2, false, nopos);
|
||||
Variable* temp_var = NewTemporary(ast_value_factory()->empty_string());
|
||||
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp_var);
|
||||
Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
|
||||
|
||||
// Wrap value evaluation to provide a break location.
|
||||
Expression* value_assignment =
|
||||
factory->NewAssignment(Token::ASSIGN, temp_proxy, value, nopos);
|
||||
factory()->NewAssignment(Token::ASSIGN, temp_proxy, value, nopos);
|
||||
do_block->statements()->Add(
|
||||
factory->NewExpressionStatement(value_assignment, value->position()),
|
||||
factory()->NewExpressionStatement(value_assignment, value->position()),
|
||||
zone());
|
||||
|
||||
ZoneList<Expression*>* async_function_await_args =
|
||||
new (zone()) ZoneList<Expression*>(2, zone());
|
||||
Expression* generator_object =
|
||||
factory->NewVariableProxy(generator_object_variable);
|
||||
factory()->NewVariableProxy(generator_object_variable);
|
||||
async_function_await_args->Add(generator_object, zone());
|
||||
async_function_await_args->Add(temp_proxy, zone());
|
||||
Expression* async_function_await = delegate()->factory()->NewCallRuntime(
|
||||
Expression* async_function_await = factory()->NewCallRuntime(
|
||||
Context::ASYNC_FUNCTION_AWAIT_INDEX, async_function_await_args, nopos);
|
||||
// Wrap await to provide a break location between value evaluation and yield.
|
||||
Expression* await_assignment = factory->NewAssignment(
|
||||
Expression* await_assignment = factory()->NewAssignment(
|
||||
Token::ASSIGN, temp_proxy, async_function_await, nopos);
|
||||
do_block->statements()->Add(
|
||||
factory->NewExpressionStatement(await_assignment, await_pos), zone());
|
||||
Expression* do_expr = factory->NewDoExpression(do_block, temp_var, nopos);
|
||||
factory()->NewExpressionStatement(await_assignment, await_pos), zone());
|
||||
Expression* do_expr = factory()->NewDoExpression(do_block, temp_var, nopos);
|
||||
|
||||
generator_object = factory->NewVariableProxy(generator_object_variable);
|
||||
return factory->NewYield(generator_object, do_expr, nopos,
|
||||
Yield::kOnExceptionRethrow);
|
||||
generator_object = factory()->NewVariableProxy(generator_object_variable);
|
||||
return factory()->NewYield(generator_object, do_expr, nopos,
|
||||
Yield::kOnExceptionRethrow);
|
||||
}
|
||||
|
||||
ZoneList<Expression*>* ParserBaseTraits<Parser>::GetNonPatternList() const {
|
||||
return delegate()->function_state_->non_patterns_to_rewrite();
|
||||
}
|
||||
|
||||
ZoneList<typename ParserBaseTraits<Parser>::Type::ExpressionClassifier::Error>*
|
||||
ParserBaseTraits<Parser>::GetReportedErrorList() const {
|
||||
return delegate()->function_state_->GetReportedErrorList();
|
||||
}
|
||||
|
||||
Zone* ParserBaseTraits<Parser>::zone() const { return delegate()->zone(); }
|
||||
|
||||
class NonPatternRewriter : public AstExpressionRewriter {
|
||||
public:
|
||||
NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
|
||||
@ -5565,8 +5546,8 @@ Expression* Parser::RewriteAssignExponentiation(Expression* left,
|
||||
|
||||
Expression* result;
|
||||
DCHECK_NOT_NULL(lhs->raw_name());
|
||||
result = this->ExpressionFromIdentifier(lhs->raw_name(), lhs->position(),
|
||||
lhs->end_position());
|
||||
result = ExpressionFromIdentifier(lhs->raw_name(), lhs->position(),
|
||||
lhs->end_position());
|
||||
args->Add(left, zone());
|
||||
args->Add(right, zone());
|
||||
Expression* call =
|
||||
@ -5678,7 +5659,7 @@ Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
|
||||
void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) {
|
||||
DCHECK(expr->IsRewritableExpression());
|
||||
function_state_->AddDestructuringAssignment(
|
||||
DestructuringAssignment(expr, delegate()->scope()));
|
||||
DestructuringAssignment(expr, scope()));
|
||||
}
|
||||
|
||||
void Parser::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
|
||||
@ -5686,8 +5667,8 @@ void Parser::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
|
||||
function_state_->AddNonPatternForRewriting(expr, ok);
|
||||
}
|
||||
|
||||
void ParserBaseTraits<Parser>::SetFunctionNameFromPropertyName(
|
||||
ObjectLiteralProperty* property, const AstRawString* name) {
|
||||
void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
|
||||
const AstRawString* name) {
|
||||
Expression* value = property->value();
|
||||
|
||||
// Computed name setting must happen at runtime.
|
||||
@ -5702,10 +5683,9 @@ void ParserBaseTraits<Parser>::SetFunctionNameFromPropertyName(
|
||||
if (is_getter || is_setter) {
|
||||
DCHECK_NOT_NULL(name);
|
||||
const AstRawString* prefix =
|
||||
is_getter ? delegate()->ast_value_factory()->get_space_string()
|
||||
: delegate()->ast_value_factory()->set_space_string();
|
||||
function->set_raw_name(
|
||||
delegate()->ast_value_factory()->NewConsString(prefix, name));
|
||||
is_getter ? ast_value_factory()->get_space_string()
|
||||
: ast_value_factory()->set_space_string();
|
||||
function->set_raw_name(ast_value_factory()->NewConsString(prefix, name));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -5716,13 +5696,13 @@ void ParserBaseTraits<Parser>::SetFunctionNameFromPropertyName(
|
||||
|
||||
DCHECK(!value->IsAnonymousFunctionDefinition() ||
|
||||
property->kind() == ObjectLiteralProperty::COMPUTED);
|
||||
delegate()->SetFunctionName(value, name);
|
||||
SetFunctionName(value, name);
|
||||
}
|
||||
|
||||
void ParserBaseTraits<Parser>::SetFunctionNameFromIdentifierRef(
|
||||
Expression* value, Expression* identifier) {
|
||||
void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
|
||||
Expression* identifier) {
|
||||
if (!identifier->IsVariableProxy()) return;
|
||||
delegate()->SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
|
||||
SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
|
||||
}
|
||||
|
||||
void Parser::SetFunctionName(Expression* value, const AstRawString* name) {
|
||||
|
@ -140,14 +140,15 @@ struct ParserFormalParameters : FormalParametersBase {
|
||||
template <>
|
||||
class ParserBaseTraits<Parser> {
|
||||
public:
|
||||
typedef ParserBaseTraits<Parser> ParserTraits;
|
||||
|
||||
struct Type {
|
||||
typedef ParserBase<Parser> Base;
|
||||
typedef Parser Impl;
|
||||
|
||||
typedef Variable GeneratorVariable;
|
||||
|
||||
typedef v8::internal::AstProperties AstProperties;
|
||||
|
||||
typedef v8::internal::ExpressionClassifier<ParserTraits>
|
||||
typedef v8::internal::ExpressionClassifier<ParserBaseTraits<Parser>>
|
||||
ExpressionClassifier;
|
||||
|
||||
// Return types for traversing functions.
|
||||
@ -167,53 +168,6 @@ class ParserBaseTraits<Parser> {
|
||||
// For constructing objects returned by the traversing functions.
|
||||
typedef AstNodeFactory Factory;
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
V8_INLINE void AddParameterInitializationBlock(
|
||||
const ParserFormalParameters& parameters,
|
||||
ZoneList<v8::internal::Statement*>* body, bool is_async, bool* ok);
|
||||
|
||||
V8_INLINE void AddFormalParameter(ParserFormalParameters* parameters,
|
||||
Expression* pattern,
|
||||
Expression* initializer,
|
||||
int initializer_end_position, bool is_rest);
|
||||
V8_INLINE void DeclareFormalParameter(
|
||||
DeclarationScope* scope,
|
||||
const ParserFormalParameters::Parameter& parameter,
|
||||
Type::ExpressionClassifier* classifier);
|
||||
void ParseArrowFunctionFormalParameterList(
|
||||
ParserFormalParameters* parameters, Expression* params,
|
||||
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
|
||||
const Scope::Snapshot& scope_snapshot, bool* ok);
|
||||
|
||||
void ReindexLiterals(const ParserFormalParameters& parameters);
|
||||
|
||||
V8_INLINE Expression* NoTemplateTag() { return NULL; }
|
||||
V8_INLINE static bool IsTaggedTemplate(const Expression* tag) {
|
||||
return tag != NULL;
|
||||
}
|
||||
|
||||
V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {}
|
||||
|
||||
Expression* ExpressionListToExpression(ZoneList<Expression*>* args);
|
||||
|
||||
void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
|
||||
const AstRawString* name);
|
||||
|
||||
void SetFunctionNameFromIdentifierRef(Expression* value,
|
||||
Expression* identifier);
|
||||
|
||||
V8_INLINE ZoneList<typename Type::ExpressionClassifier::Error>*
|
||||
GetReportedErrorList() const;
|
||||
V8_INLINE Zone* zone() const;
|
||||
|
||||
V8_INLINE ZoneList<Expression*>* GetNonPatternList() const;
|
||||
};
|
||||
|
||||
class Parser : public ParserBase<Parser> {
|
||||
@ -243,9 +197,7 @@ class Parser : public ParserBase<Parser> {
|
||||
|
||||
private:
|
||||
friend class ParserBase<Parser>;
|
||||
// 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>;
|
||||
friend class v8::internal::ExpressionClassifier<ParserBaseTraits<Parser>>;
|
||||
|
||||
// Runtime encoding of different completion modes.
|
||||
enum CompletionKind {
|
||||
@ -1004,6 +956,88 @@ class Parser : public ParserBase<Parser> {
|
||||
return new (zone()) ZoneList<v8::internal::Statement*>(size, zone());
|
||||
}
|
||||
|
||||
V8_INLINE void AddParameterInitializationBlock(
|
||||
const ParserFormalParameters& parameters,
|
||||
ZoneList<v8::internal::Statement*>* body, bool is_async, bool* ok) {
|
||||
if (parameters.is_simple) return;
|
||||
auto* init_block = BuildParameterInitializationBlock(parameters, ok);
|
||||
if (!*ok) return;
|
||||
if (is_async) init_block = BuildRejectPromiseOnException(init_block);
|
||||
if (init_block != nullptr) body->Add(init_block, zone());
|
||||
}
|
||||
|
||||
V8_INLINE void AddFormalParameter(ParserFormalParameters* parameters,
|
||||
Expression* pattern,
|
||||
Expression* initializer,
|
||||
int initializer_end_position,
|
||||
bool is_rest) {
|
||||
bool is_simple = pattern->IsVariableProxy() && initializer == nullptr;
|
||||
const AstRawString* name = is_simple
|
||||
? pattern->AsVariableProxy()->raw_name()
|
||||
: ast_value_factory()->empty_string();
|
||||
parameters->params.Add(
|
||||
ParserFormalParameters::Parameter(name, pattern, initializer,
|
||||
initializer_end_position, is_rest),
|
||||
parameters->scope->zone());
|
||||
}
|
||||
|
||||
V8_INLINE void DeclareFormalParameter(
|
||||
DeclarationScope* scope,
|
||||
const ParserFormalParameters::Parameter& parameter,
|
||||
Type::ExpressionClassifier* classifier) {
|
||||
bool is_duplicate = false;
|
||||
bool is_simple = classifier->is_simple_parameter_list();
|
||||
auto name = is_simple || parameter.is_rest
|
||||
? parameter.name
|
||||
: ast_value_factory()->empty_string();
|
||||
auto mode = is_simple || parameter.is_rest ? VAR : TEMPORARY;
|
||||
if (!is_simple) scope->SetHasNonSimpleParameters();
|
||||
bool is_optional = parameter.initializer != nullptr;
|
||||
Variable* var =
|
||||
scope->DeclareParameter(name, mode, is_optional, parameter.is_rest,
|
||||
&is_duplicate, ast_value_factory());
|
||||
if (is_duplicate) {
|
||||
classifier->RecordDuplicateFormalParameterError(scanner()->location());
|
||||
}
|
||||
if (is_sloppy(scope->language_mode())) {
|
||||
// TODO(sigurds) Mark every parameter as maybe assigned. This is a
|
||||
// conservative approximation necessary to account for parameters
|
||||
// that are assigned via the arguments array.
|
||||
var->set_maybe_assigned();
|
||||
}
|
||||
}
|
||||
|
||||
void ParseArrowFunctionFormalParameterList(
|
||||
ParserFormalParameters* parameters, Expression* params,
|
||||
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
|
||||
const Scope::Snapshot& scope_snapshot, bool* ok);
|
||||
|
||||
void ReindexLiterals(const ParserFormalParameters& parameters);
|
||||
|
||||
V8_INLINE Expression* NoTemplateTag() { return NULL; }
|
||||
V8_INLINE static bool IsTaggedTemplate(const Expression* tag) {
|
||||
return tag != NULL;
|
||||
}
|
||||
|
||||
V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {}
|
||||
|
||||
Expression* ExpressionListToExpression(ZoneList<Expression*>* args);
|
||||
|
||||
void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
|
||||
const AstRawString* name);
|
||||
|
||||
void SetFunctionNameFromIdentifierRef(Expression* value,
|
||||
Expression* identifier);
|
||||
|
||||
V8_INLINE ZoneList<typename Type::ExpressionClassifier::Error>*
|
||||
GetReportedErrorList() const {
|
||||
return function_state_->GetReportedErrorList();
|
||||
}
|
||||
|
||||
V8_INLINE ZoneList<Expression*>* GetNonPatternList() const {
|
||||
return function_state_->non_patterns_to_rewrite();
|
||||
}
|
||||
|
||||
// Parser's private field members.
|
||||
|
||||
Scanner scanner_;
|
||||
@ -1057,63 +1091,6 @@ class CompileTimeValue: public AllStatic {
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
|
||||
};
|
||||
|
||||
void ParserBaseTraits<Parser>::AddFormalParameter(
|
||||
ParserFormalParameters* parameters, Expression* pattern,
|
||||
Expression* initializer, int initializer_end_position, bool is_rest) {
|
||||
bool is_simple = pattern->IsVariableProxy() && initializer == nullptr;
|
||||
const AstRawString* name =
|
||||
is_simple ? pattern->AsVariableProxy()->raw_name()
|
||||
: delegate()->ast_value_factory()->empty_string();
|
||||
parameters->params.Add(
|
||||
ParserFormalParameters::Parameter(name, pattern, initializer,
|
||||
initializer_end_position, is_rest),
|
||||
parameters->scope->zone());
|
||||
}
|
||||
|
||||
void ParserBaseTraits<Parser>::DeclareFormalParameter(
|
||||
DeclarationScope* scope, const ParserFormalParameters::Parameter& parameter,
|
||||
Type::ExpressionClassifier* classifier) {
|
||||
bool is_duplicate = false;
|
||||
bool is_simple = classifier->is_simple_parameter_list();
|
||||
auto name = is_simple || parameter.is_rest
|
||||
? parameter.name
|
||||
: delegate()->ast_value_factory()->empty_string();
|
||||
auto mode = is_simple || parameter.is_rest ? VAR : TEMPORARY;
|
||||
if (!is_simple) scope->SetHasNonSimpleParameters();
|
||||
bool is_optional = parameter.initializer != nullptr;
|
||||
Variable* var =
|
||||
scope->DeclareParameter(name, mode, is_optional, parameter.is_rest,
|
||||
&is_duplicate, delegate()->ast_value_factory());
|
||||
if (is_duplicate) {
|
||||
classifier->RecordDuplicateFormalParameterError(
|
||||
delegate()->scanner()->location());
|
||||
}
|
||||
if (is_sloppy(scope->language_mode())) {
|
||||
// TODO(sigurds) Mark every parameter as maybe assigned. This is a
|
||||
// conservative approximation necessary to account for parameters
|
||||
// that are assigned via the arguments array.
|
||||
var->set_maybe_assigned();
|
||||
}
|
||||
}
|
||||
|
||||
void ParserBaseTraits<Parser>::AddParameterInitializationBlock(
|
||||
const ParserFormalParameters& parameters,
|
||||
ZoneList<v8::internal::Statement*>* body, bool is_async, bool* ok) {
|
||||
if (!parameters.is_simple) {
|
||||
auto* init_block =
|
||||
delegate()->BuildParameterInitializationBlock(parameters, ok);
|
||||
if (!*ok) return;
|
||||
|
||||
if (is_async) {
|
||||
init_block = delegate()->BuildRejectPromiseOnException(init_block);
|
||||
}
|
||||
|
||||
if (init_block != nullptr) {
|
||||
body->Add(init_block, delegate()->zone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
class PreParserIdentifier {
|
||||
public:
|
||||
PreParserIdentifier() : type_(kUnknownIdentifier) {}
|
||||
@ -588,15 +587,16 @@ class PreParser;
|
||||
template <>
|
||||
class ParserBaseTraits<PreParser> {
|
||||
public:
|
||||
typedef ParserBaseTraits<PreParser> PreParserTraits;
|
||||
|
||||
struct Type {
|
||||
typedef ParserBase<PreParser> Base;
|
||||
typedef PreParser Impl;
|
||||
|
||||
// PreParser doesn't need to store generator variables.
|
||||
typedef void GeneratorVariable;
|
||||
|
||||
typedef int AstProperties;
|
||||
|
||||
typedef v8::internal::ExpressionClassifier<PreParserTraits>
|
||||
typedef v8::internal::ExpressionClassifier<ParserBaseTraits<PreParser>>
|
||||
ExpressionClassifier;
|
||||
|
||||
// Return types for traversing functions.
|
||||
@ -616,66 +616,6 @@ class ParserBaseTraits<PreParser> {
|
||||
// For constructing objects returned by the traversing functions.
|
||||
typedef PreParserFactory Factory;
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// A dummy function, just useful as an argument to CHECK_OK_CUSTOM.
|
||||
static void Void() {}
|
||||
|
||||
void AddParameterInitializationBlock(
|
||||
const PreParserFormalParameters& parameters, PreParserStatementList body,
|
||||
bool is_async, bool* ok) {}
|
||||
|
||||
void AddFormalParameter(PreParserFormalParameters* parameters,
|
||||
PreParserExpression pattern,
|
||||
PreParserExpression initializer,
|
||||
int initializer_end_position, bool is_rest) {
|
||||
++parameters->arity;
|
||||
}
|
||||
|
||||
void DeclareFormalParameter(DeclarationScope* scope,
|
||||
PreParserIdentifier parameter,
|
||||
Type::ExpressionClassifier* classifier) {
|
||||
if (!classifier->is_simple_parameter_list()) {
|
||||
scope->SetHasNonSimpleParameters();
|
||||
}
|
||||
}
|
||||
|
||||
V8_INLINE void ParseArrowFunctionFormalParameterList(
|
||||
PreParserFormalParameters* parameters, PreParserExpression params,
|
||||
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
|
||||
const Scope::Snapshot& scope_snapshot, bool* ok);
|
||||
|
||||
void ReindexLiterals(const PreParserFormalParameters& parameters) {}
|
||||
|
||||
V8_INLINE PreParserExpression NoTemplateTag() {
|
||||
return PreParserExpression::NoTemplateTag();
|
||||
}
|
||||
V8_INLINE static bool IsTaggedTemplate(const PreParserExpression tag) {
|
||||
return !tag.IsNoTemplateTag();
|
||||
}
|
||||
|
||||
inline void MaterializeUnspreadArgumentsLiterals(int count);
|
||||
|
||||
inline PreParserExpression ExpressionListToExpression(
|
||||
PreParserExpressionList args) {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
|
||||
void SetFunctionNameFromPropertyName(PreParserExpression property,
|
||||
PreParserIdentifier name) {}
|
||||
void SetFunctionNameFromIdentifierRef(PreParserExpression value,
|
||||
PreParserExpression identifier) {}
|
||||
|
||||
V8_INLINE ZoneList<typename Type::ExpressionClassifier::Error>*
|
||||
GetReportedErrorList() const;
|
||||
V8_INLINE Zone* zone() const;
|
||||
V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const;
|
||||
};
|
||||
|
||||
|
||||
@ -693,9 +633,7 @@ class ParserBaseTraits<PreParser> {
|
||||
// it is used) are generally omitted.
|
||||
class PreParser : public ParserBase<PreParser> {
|
||||
friend class 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>;
|
||||
friend class v8::internal::ExpressionClassifier<ParserBaseTraits<PreParser>>;
|
||||
|
||||
public:
|
||||
typedef PreParserIdentifier Identifier;
|
||||
@ -763,6 +701,9 @@ class PreParser : public ParserBase<PreParser> {
|
||||
Scanner::BookmarkScope* bookmark,
|
||||
int* use_counts);
|
||||
|
||||
// A dummy function, just useful as an argument to CHECK_OK_CUSTOM.
|
||||
static void Void() {}
|
||||
|
||||
private:
|
||||
static const int kLazyParseTrialLimit = 200;
|
||||
|
||||
@ -1139,18 +1080,75 @@ class PreParser : public ParserBase<PreParser> {
|
||||
return PreParserStatementList();
|
||||
}
|
||||
|
||||
V8_INLINE void AddParameterInitializationBlock(
|
||||
const PreParserFormalParameters& parameters, PreParserStatementList body,
|
||||
bool is_async, bool* ok) {}
|
||||
|
||||
V8_INLINE void AddFormalParameter(PreParserFormalParameters* parameters,
|
||||
PreParserExpression pattern,
|
||||
PreParserExpression initializer,
|
||||
int initializer_end_position,
|
||||
bool is_rest) {
|
||||
++parameters->arity;
|
||||
}
|
||||
|
||||
V8_INLINE void DeclareFormalParameter(
|
||||
DeclarationScope* scope, PreParserIdentifier parameter,
|
||||
Type::ExpressionClassifier* classifier) {
|
||||
if (!classifier->is_simple_parameter_list()) {
|
||||
scope->SetHasNonSimpleParameters();
|
||||
}
|
||||
}
|
||||
|
||||
V8_INLINE void ParseArrowFunctionFormalParameterList(
|
||||
PreParserFormalParameters* parameters, PreParserExpression params,
|
||||
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
|
||||
const Scope::Snapshot& scope_snapshot, bool* ok) {
|
||||
// TODO(wingo): Detect duplicated identifiers in paramlists. Detect
|
||||
// parameter
|
||||
// lists that are too long.
|
||||
}
|
||||
|
||||
V8_INLINE void ReindexLiterals(const PreParserFormalParameters& parameters) {}
|
||||
|
||||
V8_INLINE PreParserExpression NoTemplateTag() {
|
||||
return PreParserExpression::NoTemplateTag();
|
||||
}
|
||||
|
||||
V8_INLINE static bool IsTaggedTemplate(const PreParserExpression tag) {
|
||||
return !tag.IsNoTemplateTag();
|
||||
}
|
||||
|
||||
V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
function_state_->NextMaterializedLiteralIndex();
|
||||
}
|
||||
}
|
||||
|
||||
V8_INLINE PreParserExpression
|
||||
ExpressionListToExpression(PreParserExpressionList args) {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
|
||||
V8_INLINE void SetFunctionNameFromPropertyName(PreParserExpression property,
|
||||
PreParserIdentifier name) {}
|
||||
V8_INLINE void SetFunctionNameFromIdentifierRef(
|
||||
PreParserExpression value, PreParserExpression identifier) {}
|
||||
|
||||
V8_INLINE ZoneList<typename Type::ExpressionClassifier::Error>*
|
||||
GetReportedErrorList() const {
|
||||
return function_state_->GetReportedErrorList();
|
||||
}
|
||||
|
||||
V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const {
|
||||
return function_state_->non_patterns_to_rewrite();
|
||||
}
|
||||
|
||||
// Preparser's private field members.
|
||||
|
||||
int* use_counts_;
|
||||
};
|
||||
|
||||
void ParserBaseTraits<PreParser>::MaterializeUnspreadArgumentsLiterals(
|
||||
int count) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
delegate()->function_state_->NextMaterializedLiteralIndex();
|
||||
}
|
||||
}
|
||||
|
||||
PreParserExpression PreParser::SpreadCall(PreParserExpression function,
|
||||
PreParserExpressionList args,
|
||||
int pos) {
|
||||
@ -1163,29 +1161,6 @@ PreParserExpression PreParser::SpreadCallNew(PreParserExpression function,
|
||||
return factory()->NewCallNew(function, args, pos);
|
||||
}
|
||||
|
||||
void ParserBaseTraits<PreParser>::ParseArrowFunctionFormalParameterList(
|
||||
PreParserFormalParameters* parameters, PreParserExpression params,
|
||||
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
|
||||
const Scope::Snapshot& scope_snapshot, bool* ok) {
|
||||
// TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
|
||||
// lists that are too long.
|
||||
}
|
||||
|
||||
ZoneList<PreParserExpression>* ParserBaseTraits<PreParser>::GetNonPatternList()
|
||||
const {
|
||||
return delegate()->function_state_->non_patterns_to_rewrite();
|
||||
}
|
||||
|
||||
ZoneList<
|
||||
typename ParserBaseTraits<PreParser>::Type::ExpressionClassifier::Error>*
|
||||
ParserBaseTraits<PreParser>::GetReportedErrorList() const {
|
||||
return delegate()->function_state_->GetReportedErrorList();
|
||||
}
|
||||
|
||||
Zone* ParserBaseTraits<PreParser>::zone() const {
|
||||
return delegate()->function_state_->scope()->zone();
|
||||
}
|
||||
|
||||
PreParserStatementList PreParser::ParseEagerFunctionBody(
|
||||
PreParserIdentifier function_name, int pos,
|
||||
const PreParserFormalParameters& parameters, FunctionKind kind,
|
||||
|
Loading…
Reference in New Issue
Block a user