Commit 56bd11a1 authored by rossberg's avatar rossberg Committed by Commit bot

[es6] Refactor FormalParameter

Store arity in FormalParameters; store name (instead of var) and is_rest flag in individual parameters. Ensure that the arity is always maintained consistently.

This is preparation for more parameter destructuring adjustments. In particular, a follow-up CL will separate parameter recording from declaring the variables.

R=adamk@chromium.org, littledan@chromium.org
BUG=v8:811
LOG=N

Review URL: https://codereview.chromium.org/1259013003

Cr-Commit-Position: refs/heads/master@{#30002}
parent 479e0c03
...@@ -917,7 +917,7 @@ Parser::Parser(ParseInfo* info) ...@@ -917,7 +917,7 @@ Parser::Parser(ParseInfo* info)
set_allow_harmony_unicode(FLAG_harmony_unicode); set_allow_harmony_unicode(FLAG_harmony_unicode);
set_allow_harmony_computed_property_names( set_allow_harmony_computed_property_names(
FLAG_harmony_computed_property_names); FLAG_harmony_computed_property_names);
set_allow_harmony_rest_params(FLAG_harmony_rest_parameters); set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters);
set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls); set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls);
set_allow_harmony_destructuring(FLAG_harmony_destructuring); set_allow_harmony_destructuring(FLAG_harmony_destructuring);
set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays); set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays);
...@@ -3854,7 +3854,7 @@ void ParserTraits::ParseArrowFunctionFormalParameters( ...@@ -3854,7 +3854,7 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
ParserFormalParameters* parameters, Expression* expr, ParserFormalParameters* parameters, Expression* expr,
const Scanner::Location& params_loc, const Scanner::Location& params_loc,
Scanner::Location* duplicate_loc, bool* ok) { Scanner::Location* duplicate_loc, bool* ok) {
if (parameters->scope->num_parameters() >= Code::kMaxArguments) { if (parameters->arity >= Code::kMaxArguments) {
ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList); ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
*ok = false; *ok = false;
return; return;
...@@ -3908,6 +3908,7 @@ void ParserTraits::ParseArrowFunctionFormalParameters( ...@@ -3908,6 +3908,7 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
} }
++parameters->arity;
ExpressionClassifier classifier; ExpressionClassifier classifier;
DeclareFormalParameter(parameters, expr, is_rest, &classifier); DeclareFormalParameter(parameters, expr, is_rest, &classifier);
if (!duplicate_loc->IsValid()) { if (!duplicate_loc->IsValid()) {
...@@ -3996,7 +3997,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -3996,7 +3997,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
: NewScope(scope_, FUNCTION_SCOPE, kind); : NewScope(scope_, FUNCTION_SCOPE, kind);
scope->SetLanguageMode(language_mode); scope->SetLanguageMode(language_mode);
ZoneList<Statement*>* body = NULL; ZoneList<Statement*>* body = NULL;
int arity = 0; int arity = -1;
int materialized_literal_count = -1; int materialized_literal_count = -1;
int expected_property_count = -1; int expected_property_count = -1;
DuplicateFinder duplicate_finder(scanner()->unicode_cache()); DuplicateFinder duplicate_finder(scanner()->unicode_cache());
...@@ -4030,7 +4031,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -4030,7 +4031,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
int start_position = scanner()->location().beg_pos; int start_position = scanner()->location().beg_pos;
scope_->set_start_position(start_position); scope_->set_start_position(start_position);
ParserFormalParameters formals(scope); ParserFormalParameters formals(scope);
arity = ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
arity = formals.arity;
DCHECK(arity == formals.params.length());
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
int formals_end_position = scanner()->location().end_pos; int formals_end_position = scanner()->location().end_pos;
...@@ -4294,7 +4297,8 @@ Block* Parser::BuildParameterInitializationBlock( ...@@ -4294,7 +4297,8 @@ Block* Parser::BuildParameterInitializationBlock(
DCHECK(scope_->is_function_scope()); DCHECK(scope_->is_function_scope());
Block* init_block = Block* init_block =
factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
for (auto parameter : parameters.params) { for (int i = 0; i < parameters.params.length(); ++i) {
auto parameter = parameters.params[i];
if (parameter.pattern == nullptr) continue; if (parameter.pattern == nullptr) continue;
DeclarationDescriptor descriptor; DeclarationDescriptor descriptor;
descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
...@@ -4309,7 +4313,7 @@ Block* Parser::BuildParameterInitializationBlock( ...@@ -4309,7 +4313,7 @@ Block* Parser::BuildParameterInitializationBlock(
descriptor.init_op = Token::INIT_LET; descriptor.init_op = Token::INIT_LET;
DeclarationParsingResult::Declaration decl( DeclarationParsingResult::Declaration decl(
parameter.pattern, parameter.pattern->position(), parameter.pattern, parameter.pattern->position(),
factory()->NewVariableProxy(parameter.var)); factory()->NewVariableProxy(parameters.scope->parameter(i)));
PatternRewriter::DeclareAndInitializeVariables(init_block, &descriptor, PatternRewriter::DeclareAndInitializeVariables(init_block, &descriptor,
&decl, nullptr, CHECK_OK); &decl, nullptr, CHECK_OK);
} }
...@@ -4477,7 +4481,7 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( ...@@ -4477,7 +4481,7 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
SET_ALLOW(harmony_sloppy_let); SET_ALLOW(harmony_sloppy_let);
SET_ALLOW(harmony_unicode); SET_ALLOW(harmony_unicode);
SET_ALLOW(harmony_computed_property_names); SET_ALLOW(harmony_computed_property_names);
SET_ALLOW(harmony_rest_params); SET_ALLOW(harmony_rest_parameters);
SET_ALLOW(harmony_spreadcalls); SET_ALLOW(harmony_spreadcalls);
SET_ALLOW(harmony_destructuring); SET_ALLOW(harmony_destructuring);
SET_ALLOW(harmony_spread_arrays); SET_ALLOW(harmony_spread_arrays);
......
...@@ -541,10 +541,11 @@ class SingletonLogger; ...@@ -541,10 +541,11 @@ class SingletonLogger;
struct ParserFormalParameters : public PreParserFormalParameters { struct ParserFormalParameters : public PreParserFormalParameters {
struct Parameter { struct Parameter {
Parameter(Variable* var, Expression* pattern) Parameter(const AstRawString* name, Expression* pattern, bool is_rest)
: var(var), pattern(pattern) {} : name(name), pattern(pattern), is_rest(is_rest) {}
Variable* var; const AstRawString* name;
Expression* pattern; Expression* pattern;
bool is_rest;
}; };
explicit ParserFormalParameters(Scope* scope) explicit ParserFormalParameters(Scope* scope)
...@@ -552,8 +553,10 @@ struct ParserFormalParameters : public PreParserFormalParameters { ...@@ -552,8 +553,10 @@ struct ParserFormalParameters : public PreParserFormalParameters {
ZoneList<Parameter> params; ZoneList<Parameter> params;
void AddParameter(Variable* var, Expression* pattern) { void AddParameter(
params.Add(Parameter(var, pattern), scope->zone()); const AstRawString* name, Expression* pattern, bool is_rest) {
params.Add(Parameter(name, pattern, is_rest), scope->zone());
DCHECK_EQ(arity, params.length());
} }
}; };
...@@ -579,7 +582,7 @@ class ParserTraits { ...@@ -579,7 +582,7 @@ class ParserTraits {
typedef ObjectLiteral::Property* ObjectLiteralProperty; typedef ObjectLiteral::Property* ObjectLiteralProperty;
typedef ZoneList<v8::internal::Expression*>* ExpressionList; typedef ZoneList<v8::internal::Expression*>* ExpressionList;
typedef ZoneList<ObjectLiteral::Property*>* PropertyList; typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
typedef const v8::internal::AstRawString* FormalParameter; typedef ParserFormalParameters::Parameter FormalParameter;
typedef ParserFormalParameters FormalParameters; typedef ParserFormalParameters FormalParameters;
typedef ZoneList<v8::internal::Statement*>* StatementList; typedef ZoneList<v8::internal::Statement*>* StatementList;
...@@ -1320,7 +1323,7 @@ void ParserTraits::DeclareFormalParameter( ...@@ -1320,7 +1323,7 @@ void ParserTraits::DeclareFormalParameter(
VariableMode mode = is_simple ? VAR : TEMPORARY; VariableMode mode = is_simple ? VAR : TEMPORARY;
Variable* var = Variable* var =
parameters->scope->DeclareParameter(name, mode, is_rest, &is_duplicate); parameters->scope->DeclareParameter(name, mode, is_rest, &is_duplicate);
parameters->AddParameter(var, is_simple ? nullptr : pattern); parameters->AddParameter(name, is_simple ? nullptr : pattern, is_rest);
if (is_duplicate) { if (is_duplicate) {
classifier->RecordDuplicateFormalParameterError( classifier->RecordDuplicateFormalParameterError(
parser_->scanner()->location()); parser_->scanner()->location());
......
...@@ -1053,11 +1053,11 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -1053,11 +1053,11 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
int start_position = scanner()->location().beg_pos; int start_position = scanner()->location().beg_pos;
function_scope->set_start_position(start_position); function_scope->set_start_position(start_position);
PreParserFormalParameters formals(nullptr); PreParserFormalParameters formals(nullptr);
int arity = ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
int formals_end_position = scanner()->location().end_pos; int formals_end_position = scanner()->location().end_pos;
CheckArityRestrictions(arity, arity_restriction, CheckArityRestrictions(formals.arity, arity_restriction,
formals.has_rest, start_position, formals.has_rest, start_position,
formals_end_position, CHECK_OK); formals_end_position, CHECK_OK);
......
...@@ -103,7 +103,7 @@ class ParserBase : public Traits { ...@@ -103,7 +103,7 @@ class ParserBase : public Traits {
allow_harmony_sloppy_(false), allow_harmony_sloppy_(false),
allow_harmony_sloppy_let_(false), allow_harmony_sloppy_let_(false),
allow_harmony_computed_property_names_(false), allow_harmony_computed_property_names_(false),
allow_harmony_rest_params_(false), allow_harmony_rest_parameters_(false),
allow_harmony_spreadcalls_(false), allow_harmony_spreadcalls_(false),
allow_harmony_destructuring_(false), allow_harmony_destructuring_(false),
allow_harmony_spread_arrays_(false), allow_harmony_spread_arrays_(false),
...@@ -121,7 +121,7 @@ class ParserBase : public Traits { ...@@ -121,7 +121,7 @@ class ParserBase : public Traits {
ALLOW_ACCESSORS(harmony_sloppy); ALLOW_ACCESSORS(harmony_sloppy);
ALLOW_ACCESSORS(harmony_sloppy_let); ALLOW_ACCESSORS(harmony_sloppy_let);
ALLOW_ACCESSORS(harmony_computed_property_names); ALLOW_ACCESSORS(harmony_computed_property_names);
ALLOW_ACCESSORS(harmony_rest_params); ALLOW_ACCESSORS(harmony_rest_parameters);
ALLOW_ACCESSORS(harmony_spreadcalls); ALLOW_ACCESSORS(harmony_spreadcalls);
ALLOW_ACCESSORS(harmony_destructuring); ALLOW_ACCESSORS(harmony_destructuring);
ALLOW_ACCESSORS(harmony_spread_arrays); ALLOW_ACCESSORS(harmony_spread_arrays);
...@@ -702,8 +702,8 @@ class ParserBase : public Traits { ...@@ -702,8 +702,8 @@ class ParserBase : public Traits {
void ParseFormalParameter(bool is_rest, void ParseFormalParameter(bool is_rest,
FormalParametersT* parameters, FormalParametersT* parameters,
ExpressionClassifier* classifier, bool* ok); ExpressionClassifier* classifier, bool* ok);
int ParseFormalParameterList(FormalParametersT* parameters, void ParseFormalParameterList(FormalParametersT* parameters,
ExpressionClassifier* classifier, bool* ok); ExpressionClassifier* classifier, bool* ok);
void CheckArityRestrictions( void CheckArityRestrictions(
int param_count, FunctionLiteral::ArityRestriction arity_restriction, int param_count, FunctionLiteral::ArityRestriction arity_restriction,
bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok); bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok);
...@@ -801,7 +801,7 @@ class ParserBase : public Traits { ...@@ -801,7 +801,7 @@ class ParserBase : public Traits {
bool allow_harmony_sloppy_; bool allow_harmony_sloppy_;
bool allow_harmony_sloppy_let_; bool allow_harmony_sloppy_let_;
bool allow_harmony_computed_property_names_; bool allow_harmony_computed_property_names_;
bool allow_harmony_rest_params_; bool allow_harmony_rest_parameters_;
bool allow_harmony_spreadcalls_; bool allow_harmony_spreadcalls_;
bool allow_harmony_destructuring_; bool allow_harmony_destructuring_;
bool allow_harmony_spread_arrays_; bool allow_harmony_spread_arrays_;
...@@ -1315,10 +1315,12 @@ class PreParserFactory { ...@@ -1315,10 +1315,12 @@ class PreParserFactory {
struct PreParserFormalParameters { struct PreParserFormalParameters {
explicit PreParserFormalParameters(Scope* scope) explicit PreParserFormalParameters(Scope* scope)
: scope(scope), : scope(scope),
arity(0),
has_rest(false), has_rest(false),
is_simple(true), is_simple(true),
materialized_literals_count(0) {} materialized_literals_count(0) {}
Scope* scope; Scope* scope;
int arity;
bool has_rest; bool has_rest;
bool is_simple; bool is_simple;
int materialized_literals_count; int materialized_literals_count;
...@@ -2274,7 +2276,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -2274,7 +2276,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
result = this->ParseArrowFunctionLiteral(parameters, args_classifier, result = this->ParseArrowFunctionLiteral(parameters, args_classifier,
CHECK_OK); CHECK_OK);
} else if (allow_harmony_arrow_functions() && } else if (allow_harmony_arrow_functions() &&
allow_harmony_rest_params() && Check(Token::ELLIPSIS)) { allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) {
// (...x) => y // (...x) => y
Scope* scope = Scope* scope =
this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
...@@ -2386,7 +2388,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( ...@@ -2386,7 +2388,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
} }
Consume(Token::COMMA); Consume(Token::COMMA);
bool is_rest = false; bool is_rest = false;
if (allow_harmony_rest_params() && peek() == Token::ELLIPSIS) { if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) {
// 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
// as the formal parameters of'(x, y, ...z) => foo', and is not itself a // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
// valid expression or binding pattern. // valid expression or binding pattern.
...@@ -3645,12 +3647,13 @@ void ParserBase<Traits>::ParseFormalParameter( ...@@ -3645,12 +3647,13 @@ void ParserBase<Traits>::ParseFormalParameter(
*ok = false; *ok = false;
return; return;
} }
++parameters->arity;
Traits::DeclareFormalParameter(parameters, pattern, is_rest, classifier); Traits::DeclareFormalParameter(parameters, pattern, is_rest, classifier);
} }
template <class Traits> template <class Traits>
int ParserBase<Traits>::ParseFormalParameterList( void ParserBase<Traits>::ParseFormalParameterList(
FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
// FormalParameters[Yield,GeneratorParameter] : // FormalParameters[Yield,GeneratorParameter] :
// [empty] // [empty]
...@@ -3666,29 +3669,26 @@ int ParserBase<Traits>::ParseFormalParameterList( ...@@ -3666,29 +3669,26 @@ int ParserBase<Traits>::ParseFormalParameterList(
// FormalsList[?Yield, ?GeneratorParameter] , // FormalsList[?Yield, ?GeneratorParameter] ,
// FormalParameter[?Yield,?GeneratorParameter] // FormalParameter[?Yield,?GeneratorParameter]
int arity = 0; DCHECK_EQ(0, parameters->arity);
if (peek() != Token::RPAREN) { if (peek() != Token::RPAREN) {
do { do {
if (++arity > Code::kMaxArguments) { if (parameters->arity > Code::kMaxArguments) {
ReportMessage(MessageTemplate::kTooManyParameters); ReportMessage(MessageTemplate::kTooManyParameters);
*ok = false; *ok = false;
return -1; return;
} }
bool is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS); bool is_rest = allow_harmony_rest_parameters() && Check(Token::ELLIPSIS);
ParseFormalParameter(is_rest, parameters, classifier, ok); ParseFormalParameter(is_rest, parameters, classifier, ok);
if (!*ok) return -1; if (!*ok) return;
} while (!parameters->has_rest && Check(Token::COMMA)); } while (!parameters->has_rest && Check(Token::COMMA));
if (parameters->has_rest && peek() == Token::COMMA) { if (parameters->has_rest && peek() == Token::COMMA) {
ReportMessageAt(scanner()->peek_location(), ReportMessageAt(scanner()->peek_location(),
MessageTemplate::kParamAfterRest); MessageTemplate::kParamAfterRest);
*ok = false; *ok = false;
return -1;
} }
} }
return arity;
} }
......
...@@ -1457,7 +1457,7 @@ void SetParserFlags(i::ParserBase<Traits>* parser, ...@@ -1457,7 +1457,7 @@ void SetParserFlags(i::ParserBase<Traits>* parser,
parser->set_allow_harmony_modules(flags.Contains(kAllowHarmonyModules)); parser->set_allow_harmony_modules(flags.Contains(kAllowHarmonyModules));
parser->set_allow_harmony_arrow_functions( parser->set_allow_harmony_arrow_functions(
flags.Contains(kAllowHarmonyArrowFunctions)); flags.Contains(kAllowHarmonyArrowFunctions));
parser->set_allow_harmony_rest_params( parser->set_allow_harmony_rest_parameters(
flags.Contains(kAllowHarmonyRestParameters)); flags.Contains(kAllowHarmonyRestParameters));
parser->set_allow_harmony_spreadcalls( parser->set_allow_harmony_spreadcalls(
flags.Contains(kAllowHarmonySpreadCalls)); flags.Contains(kAllowHarmonySpreadCalls));
......
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