Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1391)

Unified Diff: src/preparser.h

Issue 1061983004: Allow eval/arguments in arrow functions (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index 0b00f819abe1f1bcc0543c7f823b8981ee3a2cfb..1313c5c57e90c5f629fd0a9a5f897cea752139e1 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -539,7 +539,7 @@ class ParserBase : public Traits {
*ok = false;
return;
}
- if (locs.reserved_.IsValid()) {
+ if (is_strict(language_mode) && locs.reserved_.IsValid()) {
Traits::ReportMessageAt(locs.reserved_, "unexpected_strict_reserved");
*ok = false;
return;
@@ -621,8 +621,9 @@ class ParserBase : public Traits {
ExpressionT ParseMemberExpression(bool* ok);
ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
bool* ok);
- ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
- bool* ok);
+ ExpressionT ParseArrowFunctionLiteral(
+ int start_pos, FormalParameterListT params,
+ const FormalParameterErrorLocations& error_locs, bool has_rest, bool* ok);
ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
void AddTemplateExpression(ExpressionT);
ExpressionT ParseSuperExpression(bool is_new, bool* ok);
@@ -941,7 +942,8 @@ class PreParserExpression {
return IsIdentifier() || IsProperty();
}
- bool IsValidArrowParamList(FormalParameterErrorLocations* locs) const {
+ bool IsValidArrowParamList(FormalParameterErrorLocations* locs,
+ const Scanner::Location& params_loc) const {
ValidArrowParam valid = ValidateArrowParams();
if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) {
return false;
@@ -951,7 +953,12 @@ class PreParserExpression {
} else if (valid == kInvalidStrongArrowParam) {
// Return true for now regardless of strong mode for compatibility with
// parser.
- locs->undefined_ = Scanner::Location();
+ locs->undefined_ = params_loc;
+ return true;
+ } else if (valid == kInvalidStrictArrowParam) {
+ // TODO(wingo): Distinguish eval/arguments from other words reserved in
+ // strict mode.
+ locs->reserved_ = params_loc;
return true;
} else {
return false;
@@ -1023,6 +1030,7 @@ class PreParserExpression {
enum ValidArrowParam {
kInvalidArrowParam,
+ kInvalidStrictArrowParam,
kInvalidStrongArrowParam,
kValidArrowParam
};
@@ -1042,7 +1050,7 @@ class PreParserExpression {
// except for eval, arguments, yield, and reserved keywords.
if (ident.IsEval() || ident.IsArguments() ||
ident.IsFutureStrictReserved()) {
- return kInvalidArrowParam;
+ return kInvalidStrictArrowParam;
}
// In strong mode, 'undefined' is similarly restricted.
if (ident.IsUndefined()) {
@@ -1555,15 +1563,9 @@ class PreParserTraits {
Variable* fvar, Token::Value fvar_init_op,
FunctionKind kind, bool* ok);
- // Utility functions
- V8_INLINE int DeclareArrowParametersFromExpression(
- PreParserExpression expression, Scope* scope,
- FormalParameterErrorLocations* locs, bool* ok) {
- // TODO(wingo): Detect duplicated identifiers in paramlists. Detect eval or
- // arguments. Detect reserved words.
- *ok = expression.IsValidArrowParamList(locs);
- return 0;
- }
+ V8_INLINE PreParserFormalParameterList ParseArrowFunctionFormalParameterList(
+ PreParserExpression expression, const Scanner::Location& params_loc,
+ FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok);
struct TemplateLiteralState {};
@@ -1589,6 +1591,11 @@ class PreParserTraits {
return !tag.IsNoTemplateTag();
}
+ int DeclareFormalParameters(PreParserFormalParameterList params, Scope* scope,
+ bool has_rest, bool* ok) {
+ return params->length();
+ }
+
void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
// Temporary glue; these functions will move to ParserBase.
@@ -1777,6 +1784,22 @@ PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
}
+PreParserFormalParameterList
+PreParserTraits::ParseArrowFunctionFormalParameterList(
+ PreParserExpression params, const Scanner::Location& params_loc,
+ FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) {
+ // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
+ // lists that are too long.
+ if (!params.IsValidArrowParamList(error_locs, params_loc)) {
+ *ok = false;
+ ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list");
+ return this->NullFormalParameterList();
+ }
+
+ return PreParserFormalParameterList();
+}
+
+
PreParserStatementList PreParser::ParseEagerFunctionBody(
PreParserIdentifier function_name, int pos, Variable* fvar,
Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
@@ -2072,12 +2095,14 @@ ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
case Token::LPAREN:
Consume(Token::LPAREN);
- if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) {
+ if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) {
// Arrow functions are the only expression type constructions
// for which an empty parameter list "()" is valid input.
- Consume(Token::RPAREN);
- result = this->ParseArrowFunctionLiteral(
- beg_pos, this->EmptyArrowParamList(), CHECK_OK);
+ FormalParameterListT params = this->NewFormalParameterList(0, zone());
+ FormalParameterErrorLocations error_locs;
+ bool has_rest = false;
+ result = this->ParseArrowFunctionLiteral(beg_pos, params, error_locs,
+ has_rest, CHECK_OK);
} else {
// Heuristically try to detect immediately called functions before
// seeing the call parentheses.
@@ -2535,8 +2560,13 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
checkpoint.Restore();
- expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
- expression, CHECK_OK);
+ FormalParameterErrorLocations error_locs;
+ Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos);
+ bool has_rest = false;
+ FormalParameterListT params = this->ParseArrowFunctionFormalParameterList(
+ expression, loc, &error_locs, &has_rest, CHECK_OK);
+ expression = this->ParseArrowFunctionLiteral(
+ lhs_location.beg_pos, params, error_locs, has_rest, CHECK_OK);
return expression;
}
@@ -3164,11 +3194,12 @@ void ParserBase<Traits>::CheckArityRestrictions(
}
}
+
template <class Traits>
typename ParserBase<Traits>::ExpressionT
-ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
- ExpressionT params_ast,
- bool* ok) {
+ParserBase<Traits>::ParseArrowFunctionLiteral(
+ int start_pos, FormalParameterListT params,
+ const FormalParameterErrorLocations& error_locs, bool has_rest, bool* ok) {
if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
// ASI inserts `;` after arrow parameters if a line terminator is found.
// `=> ...` is never a valid expression, so report as syntax error.
@@ -3190,27 +3221,8 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
typename Traits::Type::Factory function_factory(ast_value_factory());
FunctionState function_state(&function_state_, &scope_, scope,
kArrowFunction, &function_factory);
- FormalParameterErrorLocations error_locs;
- num_parameters = Traits::DeclareArrowParametersFromExpression(
- params_ast, scope_, &error_locs, ok);
- if (!*ok) {
- ReportMessageAt(
- Scanner::Location(start_pos, scanner()->location().beg_pos),
- "malformed_arrow_function_parameter_list");
- return this->EmptyExpression();
- }
-
- if (error_locs.undefined_.IsValid()) {
- // Workaround for preparser not keeping track of positions.
- error_locs.undefined_ =
- Scanner::Location(start_pos, scanner()->location().end_pos);
- }
- if (num_parameters > Code::kMaxArguments) {
- ReportMessageAt(Scanner::Location(params_ast->position(), position()),
- "too_many_parameters");
- *ok = false;
- return this->EmptyExpression();
- }
+ num_parameters =
+ this->DeclareFormalParameters(params, scope_, has_rest, CHECK_OK);
Expect(Token::ARROW, CHECK_OK);

Powered by Google App Engine
This is Rietveld 408576698