[parser] Track accept_IN with scopes and a different precendece table

Change-Id: I6da7a3cbf681a5ae691fe0aee2e69536a84f0df0
Reviewed-on: https://chromium-review.googlesource.com/c/1329174
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57400}
This commit is contained in:
Toon Verwaest 2018-11-09 16:19:17 +01:00 committed by Commit Bot
parent 1e9ead8ac6
commit d0049fb7ac
5 changed files with 119 additions and 81 deletions

View File

@ -997,7 +997,7 @@ class ParserBase {
// corresponds to what's inside the parentheses generated by the symbol
// "CoverParenthesizedExpressionAndArrowParameterList" in the ES 2017
// specification).
ExpressionT ParseExpressionCoverGrammar(bool accept_IN);
ExpressionT ParseExpressionCoverGrammar();
ExpressionT ParseArrowFormalsWithRest(ExpressionListT* list);
ExpressionT ParseArrayLiteral();
@ -1027,14 +1027,12 @@ class ParserBase {
ParseArguments(args, has_spread, false);
}
ExpressionT ParseAssignmentExpression(bool accept_IN);
ExpressionT ParseYieldExpression(bool accept_IN);
V8_INLINE ExpressionT ParseConditionalExpression(bool accept_IN);
ExpressionT ParseConditionalContinuation(ExpressionT expression,
bool accept_IN, int pos);
ExpressionT ParseBinaryContinuation(ExpressionT x, int prec, int prec1,
bool accept_IN);
V8_INLINE ExpressionT ParseBinaryExpression(int prec, bool accept_IN);
ExpressionT ParseAssignmentExpression();
ExpressionT ParseYieldExpression();
V8_INLINE ExpressionT ParseConditionalExpression();
ExpressionT ParseConditionalContinuation(ExpressionT expression, int pos);
ExpressionT ParseBinaryContinuation(ExpressionT x, int prec, int prec1);
V8_INLINE ExpressionT ParseBinaryExpression(int prec);
ExpressionT ParseUnaryOpExpression();
ExpressionT ParseAwaitExpression();
ExpressionT ParsePrefixExpression();
@ -1057,8 +1055,7 @@ class ParserBase {
// queue in the parent function state, prior to parsing of formal parameters.
// If the arrow function is lazy, any items added during formal parameter
// parsing are removed from the queue.
ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
const FormalParametersT& parameters,
ExpressionT ParseArrowFunctionLiteral(const FormalParametersT& parameters,
int rewritable_length);
void ParseAsyncFunctionBody(Scope* scope, StatementListT* body);
ExpressionT ParseAsyncFunctionLiteral();
@ -1099,7 +1096,7 @@ class ParserBase {
int pos, const FormalParametersT& parameters,
FunctionKind kind,
FunctionLiteral::FunctionType function_type,
FunctionBodyType body_type, bool accept_IN);
FunctionBodyType body_type);
// Under some circumstances, we allow preparsing to abort if the preparsed
// function is "long and trivial", and fully parse instead. Our current
@ -1389,6 +1386,20 @@ class ParserBase {
classifier_ = previous;
}
class AcceptINScope final {
public:
AcceptINScope(ParserBase* parser, bool accept_IN)
: parser_(parser), previous_accept_IN_(parser->accept_IN_) {
parser_->accept_IN_ = accept_IN;
}
~AcceptINScope() { parser_->accept_IN_ = previous_accept_IN_; }
private:
ParserBase* parser_;
bool previous_accept_IN_;
};
V8_INLINE void AccumulateNonBindingPatternErrors() {
this->Accumulate(ExpressionClassifier::AllProductions &
~(ExpressionClassifier::BindingPatternProduction |
@ -1441,6 +1452,8 @@ class ParserBase {
int function_literal_id_;
int script_id_;
bool accept_IN_ = true;
bool allow_natives_;
bool allow_harmony_public_fields_;
bool allow_harmony_static_fields_;
@ -1757,7 +1770,8 @@ ParserBase<Impl>::ParsePrimaryExpression() {
(peek() == Token::ASYNC && PeekAhead() == Token::FUNCTION)) {
function_state_->set_next_function_is_likely_called();
}
ExpressionT expr = ParseExpressionCoverGrammar(true);
AcceptINScope scope(this, true);
ExpressionT expr = ParseExpressionCoverGrammar();
Expect(Token::RPAREN);
// Parenthesized parameters have to be followed immediately by an arrow to
// be valid.
@ -1809,14 +1823,15 @@ ParserBase<Impl>::ParsePrimaryExpression() {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression() {
ExpressionClassifier classifier(this);
ExpressionT result = ParseExpressionCoverGrammar(true);
AcceptINScope scope(this, true);
ExpressionT result = ParseExpressionCoverGrammar();
ValidateExpression();
return result;
}
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseExpressionCoverGrammar(bool accept_IN) {
ParserBase<Impl>::ParseExpressionCoverGrammar() {
// Expression ::
// AssignmentExpression
// Expression ',' AssignmentExpression
@ -1828,7 +1843,7 @@ ParserBase<Impl>::ParseExpressionCoverGrammar(bool accept_IN) {
if (V8_UNLIKELY(peek() == Token::ELLIPSIS)) {
return ParseArrowFormalsWithRest(&list);
}
expression = ParseAssignmentExpression(accept_IN);
expression = ParseAssignmentExpression();
// No need to accumulate binding pattern-related errors, since
// an Expression can't be a binding pattern anyway.
AccumulateNonBindingPatternErrors();
@ -1913,7 +1928,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral() {
} else if (Check(Token::ELLIPSIS)) {
int start_pos = position();
int expr_pos = peek_position();
ExpressionT argument = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
ExpressionT argument = ParseAssignmentExpression();
elem = factory()->NewSpread(argument, start_pos, expr_pos);
if (first_spread_index < 0) {
@ -1935,7 +1951,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral() {
}
} else {
int beg_pos = peek_position();
elem = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
elem = ParseAssignmentExpression();
CheckDestructuringElement(elem, beg_pos, end_position());
}
values.Add(elem);
@ -2064,7 +2081,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
*is_computed_name = true;
Consume(Token::LBRACK);
ExpressionClassifier computed_name_classifier(this);
ExpressionT expression = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
ExpressionT expression = ParseAssignmentExpression();
ValidateExpression();
AccumulateFormalParameterContainmentErrors();
Expect(Token::RBRACK);
@ -2078,7 +2096,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
if (*kind == ParsePropertyKind::kNotSet) {
*name = impl()->NullIdentifier();
Consume(Token::ELLIPSIS);
ExpressionT expression = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
ExpressionT expression = ParseAssignmentExpression();
*kind = ParsePropertyKind::kSpread;
if (!impl()->IsIdentifier(expression)) {
@ -2307,7 +2326,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberInitializer(
initializer_scope);
ExpressionClassifier expression_classifier(this);
initializer = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
initializer = ParseAssignmentExpression();
ValidateExpression();
// TODO(gsathya): In the future, this could be changed to be
@ -2373,7 +2393,8 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
}
Consume(Token::COLON);
int beg_pos = peek_position();
ExpressionT value = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
ExpressionT value = ParseAssignmentExpression();
CheckDestructuringElement(value, beg_pos, end_position());
ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
@ -2422,7 +2443,8 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
if (peek() == Token::ASSIGN) {
Consume(Token::ASSIGN);
ExpressionClassifier rhs_classifier(this);
ExpressionT rhs = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
ExpressionT rhs = ParseAssignmentExpression();
ValidateExpression();
AccumulateFormalParameterContainmentErrors();
value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
@ -2586,7 +2608,8 @@ void ParserBase<Impl>::ParseArguments(
bool is_spread = Check(Token::ELLIPSIS);
int expr_pos = peek_position();
ExpressionT argument = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
ExpressionT argument = ParseAssignmentExpression();
if (maybe_arrow) {
if (!impl()->IsIdentifier(argument)) {
classifier()->previous()->RecordNonSimpleParameter();
@ -2625,7 +2648,7 @@ void ParserBase<Impl>::ParseArguments(
// Precedence = 2
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN) {
ParserBase<Impl>::ParseAssignmentExpression() {
// AssignmentExpression ::
// ConditionalExpression
// ArrowFunction
@ -2634,7 +2657,7 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN) {
int lhs_beg_pos = peek_position();
if (peek() == Token::YIELD && is_generator()) {
return ParseYieldExpression(accept_IN);
return ParseYieldExpression();
}
FuncNameInferrerState fni_state(&fni_);
@ -2647,7 +2670,7 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN) {
bool parenthesized_formals =
(is_async ? PeekAhead() : peek()) == Token::LPAREN;
ExpressionT expression = ParseConditionalExpression(accept_IN);
ExpressionT expression = ParseConditionalExpression();
Token::Value op = peek();
@ -2694,8 +2717,7 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN) {
scope->set_start_position(lhs_beg_pos);
impl()->DeclareArrowFunctionFormalParameters(&parameters, expression, loc);
expression =
ParseArrowFunctionLiteral(accept_IN, parameters, rewritable_length);
expression = ParseArrowFunctionLiteral(parameters, rewritable_length);
Accumulate(ExpressionClassifier::AsyncArrowFormalParametersProduction);
classifier()->RecordPatternError(arrow_loc,
MessageTemplate::kUnexpectedToken,
@ -2720,7 +2742,7 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN) {
ExpressionClassifier rhs_classifier(this);
ExpressionT right = ParseAssignmentExpression(accept_IN);
ExpressionT right = ParseAssignmentExpression();
ValidateExpression();
AccumulateFormalParameterContainmentErrors();
@ -2745,7 +2767,7 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN) {
ExpressionClassifier rhs_classifier(this);
ExpressionT right = ParseAssignmentExpression(accept_IN);
ExpressionT right = ParseAssignmentExpression();
ValidateExpression();
AccumulateFormalParameterContainmentErrors();
@ -2778,8 +2800,8 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN) {
}
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
bool accept_IN) {
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseYieldExpression() {
// YieldExpression ::
// 'yield' ([no line terminator] '*'? AssignmentExpression)?
int pos = peek_position();
@ -2813,7 +2835,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
// Delegating yields require an RHS; fall through.
V8_FALLTHROUGH;
default:
expression = ParseAssignmentExpression(accept_IN);
expression = ParseAssignmentExpression();
break;
}
}
@ -2842,23 +2864,23 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
// Precedence = 3
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseConditionalExpression(bool accept_IN) {
ParserBase<Impl>::ParseConditionalExpression() {
// ConditionalExpression ::
// LogicalOrExpression
// LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
int pos = peek_position();
// We start using the binary expression parser for prec >= 4 only!
ExpressionT expression = ParseBinaryExpression(4, accept_IN);
ExpressionT expression = ParseBinaryExpression(4);
return peek() == Token::CONDITIONAL
? ParseConditionalContinuation(expression, accept_IN, pos)
? ParseConditionalContinuation(expression, pos)
: expression;
}
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseConditionalContinuation(ExpressionT expression,
bool accept_IN, int pos) {
int pos) {
SourceRange then_range, else_range;
BindingPatternUnexpectedToken();
@ -2871,13 +2893,14 @@ ParserBase<Impl>::ParseConditionalContinuation(ExpressionT expression,
// In parsing the first assignment expression in conditional
// expressions we always accept the 'in' keyword; see ECMA-262,
// section 11.12, page 58.
left = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
left = ParseAssignmentExpression();
}
ExpressionT right;
{
SourceRangeScope range_scope(scanner(), &else_range);
Expect(Token::COLON);
right = ParseAssignmentExpression(accept_IN);
right = ParseAssignmentExpression();
}
ExpressionT expr = factory()->NewConditional(expression, left, right, pos);
impl()->RecordConditionalSourceRange(expr, then_range, else_range);
@ -2888,13 +2911,11 @@ ParserBase<Impl>::ParseConditionalContinuation(ExpressionT expression,
// Precedence >= 4
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseBinaryContinuation(ExpressionT x, int prec, int prec1,
bool accept_IN) {
if (!accept_IN && peek() == Token::IN) return x;
ParserBase<Impl>::ParseBinaryContinuation(ExpressionT x, int prec, int prec1) {
BindingPatternUnexpectedToken();
do {
// prec1 >= 4
while (Token::Precedence(peek()) == prec1) {
while (Token::Precedence(peek(), accept_IN_) == prec1) {
SourceRange right_range;
int pos = peek_position();
ExpressionT y;
@ -2905,7 +2926,7 @@ ParserBase<Impl>::ParseBinaryContinuation(ExpressionT x, int prec, int prec1,
const bool is_right_associative = op == Token::EXP;
const int next_prec = is_right_associative ? prec1 : prec1 + 1;
y = ParseBinaryExpression(next_prec, accept_IN);
y = ParseBinaryExpression(next_prec);
}
// For now we distinguish between comparisons and other binary
@ -2933,7 +2954,6 @@ ParserBase<Impl>::ParseBinaryContinuation(ExpressionT x, int prec, int prec1,
impl()->RecordBinaryOperationSourceRange(x, right_range);
}
}
if (!accept_IN && peek() == Token::IN) return x;
}
--prec1;
} while (prec1 >= prec);
@ -2944,12 +2964,12 @@ ParserBase<Impl>::ParseBinaryContinuation(ExpressionT x, int prec, int prec1,
// Precedence >= 4
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
int prec, bool accept_IN) {
int prec) {
DCHECK_GE(prec, 4);
ExpressionT x = ParseUnaryExpression();
int prec1 = Token::Precedence(peek());
int prec1 = Token::Precedence(peek(), accept_IN_);
if (prec1 >= prec) {
return ParseBinaryContinuation(x, prec, prec1, accept_IN);
return ParseBinaryContinuation(x, prec, prec1);
}
return x;
}
@ -3108,7 +3128,8 @@ ParserBase<Impl>::ParseLeftHandSideContinuation(ExpressionT result) {
case Token::LBRACK: {
Consume(Token::LBRACK);
int pos = position();
ExpressionT index = ParseExpressionCoverGrammar(true);
AcceptINScope scope(this, true);
ExpressionT index = ParseExpressionCoverGrammar();
result = factory()->NewProperty(result, index, pos);
Expect(Token::RBRACK);
break;
@ -3376,7 +3397,8 @@ ParserBase<Impl>::ParseImportExpressions() {
MessageTemplate::kImportMissingSpecifier);
return impl()->FailureExpression();
}
ExpressionT arg = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
ExpressionT arg = ParseAssignmentExpression();
Expect(Token::RPAREN);
return factory()->NewImportCallExpression(arg, pos);
}
@ -3452,7 +3474,8 @@ ParserBase<Impl>::DoParseMemberExpressionContinuation(ExpressionT expression) {
case Token::LBRACK: {
Consume(Token::LBRACK);
int pos = position();
ExpressionT index = ParseExpressionCoverGrammar(true);
AcceptINScope scope(this, true);
ExpressionT index = ParseExpressionCoverGrammar();
expression = factory()->NewProperty(expression, index, pos);
impl()->PushPropertyName(index);
Expect(Token::RBRACK);
@ -3508,7 +3531,8 @@ void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters) {
}
{
ExpressionClassifier init_classifier(this);
initializer = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
initializer = ParseAssignmentExpression();
ValidateExpression();
ValidateFormalParameterInitializer();
parameters->is_simple = false;
@ -3640,7 +3664,8 @@ typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations(
value_beg_position = peek_position();
ExpressionClassifier classifier(this);
value = ParseAssignmentExpression(var_context != kForStatement);
AcceptINScope scope(this, var_context != kForStatement);
value = ParseAssignmentExpression();
ValidateExpression();
variable_loc.end_pos = end_position();
@ -3887,8 +3912,7 @@ template <typename Impl>
void ParserBase<Impl>::ParseFunctionBody(
typename ParserBase<Impl>::StatementListT* body, IdentifierT function_name,
int pos, const FormalParametersT& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, FunctionBodyType body_type,
bool accept_IN) {
FunctionLiteral::FunctionType function_type, FunctionBodyType body_type) {
DeclarationScope* function_scope = scope()->AsDeclarationScope();
DeclarationScope* inner_scope = function_scope;
@ -3904,7 +3928,7 @@ void ParserBase<Impl>::ParseFunctionBody(
if (body_type == FunctionBodyType::kExpression) {
ExpressionClassifier classifier(this);
ExpressionT expression = ParseAssignmentExpression(accept_IN);
ExpressionT expression = ParseAssignmentExpression();
ValidateExpression();
if (IsAsyncFunction(kind)) {
@ -3914,7 +3938,7 @@ void ParserBase<Impl>::ParseFunctionBody(
body->Add(BuildReturnStatement(expression, expression->position()));
}
} else {
DCHECK(accept_IN);
DCHECK(accept_IN_);
DCHECK_EQ(FunctionBodyType::kBlock, body_type);
// If we are parsing the source as if it is wrapped in a function, the
// source ends without a closing brace.
@ -4052,8 +4076,7 @@ bool ParserBase<Impl>::IsNextLetKeyword() {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseArrowFunctionLiteral(
bool accept_IN, const FormalParametersT& formal_parameters,
int rewritable_length) {
const FormalParametersT& formal_parameters, int rewritable_length) {
const RuntimeCallCounterId counters[2][2] = {
{RuntimeCallCounterId::kParseBackgroundArrowFunctionLiteral,
RuntimeCallCounterId::kParseArrowFunctionLiteral},
@ -4134,19 +4157,21 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
// In case we did not sucessfully preparse the function because of an
// unidentified error we do a full reparse to return the error.
Consume(Token::LBRACE);
AcceptINScope scope(this, true);
ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
formal_parameters, kind,
FunctionLiteral::kAnonymousExpression,
FunctionBodyType::kBlock, true);
FunctionBodyType::kBlock);
CHECK(has_error());
return impl()->FailureExpression();
}
} else {
Consume(Token::LBRACE);
AcceptINScope scope(this, true);
ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
formal_parameters, kind,
FunctionLiteral::kAnonymousExpression,
FunctionBodyType::kBlock, true);
FunctionBodyType::kBlock);
expected_property_count = function_state.expected_property_count();
}
} else {
@ -4155,7 +4180,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
formal_parameters, kind,
FunctionLiteral::kAnonymousExpression,
FunctionBodyType::kExpression, accept_IN);
FunctionBodyType::kExpression);
expected_property_count = function_state.expected_property_count();
}
@ -4395,7 +4420,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
next = peek();
int expr_pos = peek_position();
ExpressionT expression = ParseExpressionCoverGrammar(true);
AcceptINScope scope(this, true);
ExpressionT expression = ParseExpressionCoverGrammar();
impl()->AddTemplateExpression(&ts, expression);
if (peek() != Token::RBRACE) {
@ -5410,7 +5436,11 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
// The initializer does not contain declarations.
int lhs_beg_pos = peek_position();
ExpressionClassifier classifier(this);
ExpressionT expression = ParseExpressionCoverGrammar(false);
ExpressionT expression;
{
AcceptINScope scope(this, false);
expression = ParseExpressionCoverGrammar();
}
int lhs_end_pos = end_position();
bool is_for_each = CheckInOrOf(&for_info.mode);
@ -5482,7 +5512,8 @@ ParserBase<Impl>::ParseForEachStatementWithDeclarations(
ExpressionT enumerable = impl()->NullExpression();
if (for_info->mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier(this);
enumerable = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
enumerable = ParseAssignmentExpression();
ValidateExpression();
} else {
enumerable = ParseExpression();
@ -5562,7 +5593,8 @@ ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
ExpressionT enumerable = impl()->NullExpression();
if (for_info->mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier(this);
enumerable = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
enumerable = ParseAssignmentExpression();
ValidateExpression();
} else {
enumerable = ParseExpression();
@ -5767,7 +5799,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
{
ExpressionClassifier classifier(this);
iterable = ParseAssignmentExpression(kAllowIn);
AcceptINScope scope(this, kAllowIn);
iterable = ParseAssignmentExpression();
ValidateExpression();
}

View File

@ -812,14 +812,11 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
SkipFunctionLiterals(info->function_literal_id() - 1);
}
// Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
// not be observable, or else the preparser would have failed.
const bool accept_IN = true;
// Any destructuring assignments in the current FunctionState
// actually belong to the arrow function itself.
const int rewritable_length = 0;
Expression* expression =
ParseArrowFunctionLiteral(accept_IN, formals, rewritable_length);
ParseArrowFunctionLiteral(formals, rewritable_length);
// Scanning must end at the same position that was recorded
// previously. If not, parsing has been interrupted due to a stack
// overflow, at which point the partially parsed arrow function
@ -1153,7 +1150,8 @@ Statement* Parser::ParseExportDefault() {
default: {
int pos = position();
ExpressionClassifier classifier(this);
Expression* value = ParseAssignmentExpression(true);
AcceptINScope scope(this, true);
Expression* value = ParseAssignmentExpression();
ValidateExpression();
SetFunctionName(value, ast_value_factory()->default_string());
@ -3012,8 +3010,9 @@ void Parser::ParseFunction(
*num_parameters = formals.num_parameters();
*function_length = formals.function_length;
AcceptINScope scope(this, true);
ParseFunctionBody(body, function_name, pos, formals, kind, function_type,
FunctionBodyType::kBlock, true);
FunctionBodyType::kBlock);
RewriteDestructuringAssignments();

View File

@ -302,8 +302,9 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
PreParserScopedStatementList body(pointer_buffer());
int pos = function_token_pos == kNoSourcePosition ? peek_position()
: function_token_pos;
AcceptINScope scope(this, true);
ParseFunctionBody(&body, function_name, pos, formals, kind, function_type,
FunctionBodyType::kBlock, true);
FunctionBodyType::kBlock);
// Parsing the body may change the language mode in our scope.
language_mode = function_scope->language_mode();

View File

@ -25,9 +25,14 @@ constexpr uint8_t length(const char* str) {
const uint8_t Token::string_length_[NUM_TOKENS] = {TOKEN_LIST(T, T, T)};
#undef T
#define T(name, string, precedence) precedence,
const int8_t Token::precedence_[NUM_TOKENS] = {TOKEN_LIST(T, T, T)};
#undef T
#define T1(name, string, precedence) \
((Token::name == Token::IN) ? 0 : precedence),
#define T2(name, string, precedence) precedence,
// precedence_[0] for accept_IN == false, precedence_[1] for accept_IN = true.
const int8_t Token::precedence_[2][NUM_TOKENS] = {{TOKEN_LIST(T1, T1, T1)},
{TOKEN_LIST(T2, T2, T2)}};
#undef T2
#undef T1
#define KT(a, b, c) 'T',
#define KK(a, b, c) 'K',

View File

@ -326,16 +326,16 @@ class Token {
// Returns the precedence > 0 for binary and compare
// operators; returns 0 otherwise.
static int Precedence(Value token) {
static int Precedence(Value token, bool accept_IN) {
DCHECK_GT(NUM_TOKENS, token); // token is unsigned
return precedence_[token];
return precedence_[accept_IN][token];
}
private:
static const char* const name_[NUM_TOKENS];
static const char* const string_[NUM_TOKENS];
static const uint8_t string_length_[NUM_TOKENS];
static const int8_t precedence_[NUM_TOKENS];
static const int8_t precedence_[2][NUM_TOKENS];
static const char token_type[NUM_TOKENS];
};