Commit a726e85f authored by marja's avatar marja Committed by Commit bot

Move function length tracking from Scope to (Pre)?ParserFormalParameters.

It belongs there more logically. In addition, this is a pre-step needed
for preparsing the parameters of a preparsed function.

In addition, move the "subtract rest parameter from arity" logic from
Parser to (Pre)?ParserFormalParameters.

BUG=v8:5515

Review-Url: https://codereview.chromium.org/2414003002
Cr-Commit-Position: refs/heads/master@{#40258}
parent b022c81f
...@@ -2597,6 +2597,7 @@ class FunctionLiteral final : public Expression { ...@@ -2597,6 +2597,7 @@ class FunctionLiteral final : public Expression {
int materialized_literal_count() { return materialized_literal_count_; } int materialized_literal_count() { return materialized_literal_count_; }
int expected_property_count() { return expected_property_count_; } int expected_property_count() { return expected_property_count_; }
int parameter_count() { return parameter_count_; } int parameter_count() { return parameter_count_; }
int function_length() { return function_length_; }
bool AllowsLazyCompilation(); bool AllowsLazyCompilation();
...@@ -2710,7 +2711,7 @@ class FunctionLiteral final : public Expression { ...@@ -2710,7 +2711,7 @@ class FunctionLiteral final : public Expression {
AstValueFactory* ast_value_factory, DeclarationScope* scope, AstValueFactory* ast_value_factory, DeclarationScope* scope,
ZoneList<Statement*>* body, int materialized_literal_count, ZoneList<Statement*>* body, int materialized_literal_count,
int expected_property_count, int parameter_count, int expected_property_count, int parameter_count,
FunctionType function_type, int function_length, FunctionType function_type,
ParameterFlag has_duplicate_parameters, ParameterFlag has_duplicate_parameters,
EagerCompileHint eager_compile_hint, int position, EagerCompileHint eager_compile_hint, int position,
bool is_function) bool is_function)
...@@ -2718,6 +2719,7 @@ class FunctionLiteral final : public Expression { ...@@ -2718,6 +2719,7 @@ class FunctionLiteral final : public Expression {
materialized_literal_count_(materialized_literal_count), materialized_literal_count_(materialized_literal_count),
expected_property_count_(expected_property_count), expected_property_count_(expected_property_count),
parameter_count_(parameter_count), parameter_count_(parameter_count),
function_length_(function_length),
function_token_position_(kNoSourcePosition), function_token_position_(kNoSourcePosition),
yield_count_(0), yield_count_(0),
raw_name_(name), raw_name_(name),
...@@ -2754,6 +2756,7 @@ class FunctionLiteral final : public Expression { ...@@ -2754,6 +2756,7 @@ class FunctionLiteral final : public Expression {
int materialized_literal_count_; int materialized_literal_count_;
int expected_property_count_; int expected_property_count_;
int parameter_count_; int parameter_count_;
int function_length_;
int function_token_position_; int function_token_position_;
int yield_count_; int yield_count_;
...@@ -3453,15 +3456,15 @@ class AstNodeFactory final BASE_EMBEDDED { ...@@ -3453,15 +3456,15 @@ class AstNodeFactory final BASE_EMBEDDED {
FunctionLiteral* NewFunctionLiteral( FunctionLiteral* NewFunctionLiteral(
const AstRawString* name, DeclarationScope* scope, const AstRawString* name, DeclarationScope* scope,
ZoneList<Statement*>* body, int materialized_literal_count, ZoneList<Statement*>* body, int materialized_literal_count,
int expected_property_count, int parameter_count, int expected_property_count, int parameter_count, int function_length,
FunctionLiteral::ParameterFlag has_duplicate_parameters, FunctionLiteral::ParameterFlag has_duplicate_parameters,
FunctionLiteral::FunctionType function_type, FunctionLiteral::FunctionType function_type,
FunctionLiteral::EagerCompileHint eager_compile_hint, int position) { FunctionLiteral::EagerCompileHint eager_compile_hint, int position) {
return new (zone_) FunctionLiteral(zone_, name, ast_value_factory_, scope, return new (zone_) FunctionLiteral(
body, materialized_literal_count, zone_, name, ast_value_factory_, scope, body,
expected_property_count, parameter_count, materialized_literal_count, expected_property_count, parameter_count,
function_type, has_duplicate_parameters, function_length, function_type, has_duplicate_parameters,
eager_compile_hint, position, true); eager_compile_hint, position, true);
} }
// Creates a FunctionLiteral representing a top-level script, the // Creates a FunctionLiteral representing a top-level script, the
...@@ -3474,7 +3477,7 @@ class AstNodeFactory final BASE_EMBEDDED { ...@@ -3474,7 +3477,7 @@ class AstNodeFactory final BASE_EMBEDDED {
return new (zone_) FunctionLiteral( return new (zone_) FunctionLiteral(
zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope, zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope,
body, materialized_literal_count, expected_property_count, body, materialized_literal_count, expected_property_count,
parameter_count, FunctionLiteral::kAnonymousExpression, parameter_count, parameter_count, FunctionLiteral::kAnonymousExpression,
FunctionLiteral::kNoDuplicateParameters, FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kShouldLazyCompile, 0, false); FunctionLiteral::kShouldLazyCompile, 0, false);
} }
......
...@@ -271,7 +271,6 @@ void DeclarationScope::SetDefaults() { ...@@ -271,7 +271,6 @@ void DeclarationScope::SetDefaults() {
function_ = nullptr; function_ = nullptr;
arguments_ = nullptr; arguments_ = nullptr;
this_function_ = nullptr; this_function_ = nullptr;
arity_ = 0;
} }
void Scope::SetDefaults() { void Scope::SetDefaults() {
...@@ -840,9 +839,6 @@ Variable* DeclarationScope::DeclareParameter( ...@@ -840,9 +839,6 @@ Variable* DeclarationScope::DeclareParameter(
// TODO(wingo): Avoid O(n^2) check. // TODO(wingo): Avoid O(n^2) check.
*is_duplicate = IsDeclaredParameter(name); *is_duplicate = IsDeclaredParameter(name);
} }
if (!is_optional && !is_rest && arity_ == params_.length()) {
++arity_;
}
has_rest_ = is_rest; has_rest_ = is_rest;
params_.Add(var, zone()); params_.Add(var, zone());
if (name == ast_value_factory->arguments_string()) { if (name == ast_value_factory->arguments_string()) {
......
...@@ -706,16 +706,6 @@ class DeclarationScope : public Scope { ...@@ -706,16 +706,6 @@ class DeclarationScope : public Scope {
return params_[index]; return params_[index];
} }
// Returns the default function arity excluding default or rest parameters.
// This will be used to set the length of the function, by default.
// Class field initializers use this property to indicate the number of
// fields being initialized.
int arity() const { return arity_; }
// Normal code should not need to call this. Class field initializers use this
// property to indicate the number of fields being initialized.
void set_arity(int arity) { arity_ = arity; }
// Returns the number of formal parameters, excluding a possible rest // Returns the number of formal parameters, excluding a possible rest
// parameter. Examples: // parameter. Examples:
// function foo(a, b) {} ==> 2 // function foo(a, b) {} ==> 2
...@@ -848,8 +838,6 @@ class DeclarationScope : public Scope { ...@@ -848,8 +838,6 @@ class DeclarationScope : public Scope {
// This scope uses "super" property ('super.foo'). // This scope uses "super" property ('super.foo').
bool scope_uses_super_property_ : 1; bool scope_uses_super_property_ : 1;
// Info about the parameter list of a function.
int arity_;
// Parameter list in source order. // Parameter list in source order.
ZoneList<Variable*> params_; ZoneList<Variable*> params_;
// Map of function names to lists of functions defined in sloppy blocks // Map of function names to lists of functions defined in sloppy blocks
......
...@@ -13823,7 +13823,7 @@ void SharedFunctionInfo::InitFromFunctionLiteral( ...@@ -13823,7 +13823,7 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
Handle<SharedFunctionInfo> shared_info, FunctionLiteral* lit) { Handle<SharedFunctionInfo> shared_info, FunctionLiteral* lit) {
// When adding fields here, make sure DeclarationScope::AnalyzePartially is // When adding fields here, make sure DeclarationScope::AnalyzePartially is
// updated accordingly. // updated accordingly.
shared_info->set_length(lit->scope()->arity()); shared_info->set_length(lit->function_length());
shared_info->set_internal_formal_parameter_count(lit->parameter_count()); shared_info->set_internal_formal_parameter_count(lit->parameter_count());
shared_info->set_function_token_position(lit->function_token_position()); shared_info->set_function_token_position(lit->function_token_position());
shared_info->set_start_position(lit->start_position()); shared_info->set_start_position(lit->start_position());
......
...@@ -59,10 +59,27 @@ static inline bool operator&(ParseFunctionFlags bitfield, ...@@ -59,10 +59,27 @@ static inline bool operator&(ParseFunctionFlags bitfield,
struct FormalParametersBase { struct FormalParametersBase {
explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {} explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {}
int num_parameters() const {
// Don't include the rest parameter into the function's formal parameter
// count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
// which says whether we need to create an arguments adaptor frame).
return arity - has_rest;
}
void UpdateArityAndFunctionLength(bool is_optional, bool is_rest) {
if (!is_optional && !is_rest && function_length == arity) {
++function_length;
}
++arity;
}
DeclarationScope* scope; DeclarationScope* scope;
bool has_rest = false; bool has_rest = false;
bool is_simple = true; bool is_simple = true;
int materialized_literals_count = 0; int materialized_literals_count = 0;
int function_length = 0;
int arity = 0;
}; };
...@@ -2284,7 +2301,7 @@ ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer, ...@@ -2284,7 +2301,7 @@ ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer,
FunctionLiteralT function_literal = factory()->NewFunctionLiteral( FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
impl()->EmptyIdentifierString(), initializer_scope, body, impl()->EmptyIdentifierString(), initializer_scope, body,
initializer_state.materialized_literal_count(), initializer_state.materialized_literal_count(),
initializer_state.expected_property_count(), 0, initializer_state.expected_property_count(), 0, 0,
FunctionLiteral::kNoDuplicateParameters, FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_, FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_,
initializer_scope->start_position()); initializer_scope->start_position());
...@@ -3479,11 +3496,11 @@ void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters, ...@@ -3479,11 +3496,11 @@ void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters,
// FormalParameter[?Yield] // FormalParameter[?Yield]
// FormalParameterList[?Yield] , FormalParameter[?Yield] // FormalParameterList[?Yield] , FormalParameter[?Yield]
DCHECK_EQ(0, parameters->Arity()); DCHECK_EQ(0, parameters->arity);
if (peek() != Token::RPAREN) { if (peek() != Token::RPAREN) {
while (true) { while (true) {
if (parameters->Arity() > Code::kMaxArguments) { if (parameters->arity > Code::kMaxArguments) {
ReportMessage(MessageTemplate::kTooManyParameters); ReportMessage(MessageTemplate::kTooManyParameters);
*ok = false; *ok = false;
return; return;
...@@ -3510,7 +3527,7 @@ void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters, ...@@ -3510,7 +3527,7 @@ void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters,
} }
} }
for (int i = 0; i < parameters->Arity(); ++i) { for (int i = 0; i < parameters->arity; ++i) {
auto parameter = parameters->at(i); auto parameter = parameters->at(i);
impl()->DeclareFormalParameter(parameters->scope, parameter); impl()->DeclareFormalParameter(parameters->scope, parameter);
} }
...@@ -3912,7 +3929,6 @@ ParserBase<Impl>::ParseArrowFunctionLiteral( ...@@ -3912,7 +3929,6 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
} }
StatementListT body = impl()->NullStatementList(); StatementListT body = impl()->NullStatementList();
int num_parameters = formal_parameters.scope->num_parameters();
int materialized_literal_count = -1; int materialized_literal_count = -1;
int expected_property_count = -1; int expected_property_count = -1;
...@@ -4027,7 +4043,8 @@ ParserBase<Impl>::ParseArrowFunctionLiteral( ...@@ -4027,7 +4043,8 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
FunctionLiteralT function_literal = factory()->NewFunctionLiteral( FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
impl()->EmptyIdentifierString(), formal_parameters.scope, body, impl()->EmptyIdentifierString(), formal_parameters.scope, body,
materialized_literal_count, expected_property_count, num_parameters, materialized_literal_count, expected_property_count,
formal_parameters.num_parameters(), formal_parameters.function_length,
FunctionLiteral::kNoDuplicateParameters, FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression, eager_compile_hint, FunctionLiteral::kAnonymousExpression, eager_compile_hint,
formal_parameters.scope->start_position()); formal_parameters.scope->start_position());
......
...@@ -221,7 +221,7 @@ FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, ...@@ -221,7 +221,7 @@ FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
LanguageMode language_mode) { LanguageMode language_mode) {
int materialized_literal_count = -1; int materialized_literal_count = -1;
int expected_property_count = -1; int expected_property_count = -1;
int parameter_count = 0; const int parameter_count = 0;
if (name == nullptr) name = ast_value_factory()->empty_string(); if (name == nullptr) name = ast_value_factory()->empty_string();
FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor
...@@ -284,7 +284,7 @@ FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, ...@@ -284,7 +284,7 @@ FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
FunctionLiteral* function_literal = factory()->NewFunctionLiteral( FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
name, function_scope, body, materialized_literal_count, name, function_scope, body, materialized_literal_count,
expected_property_count, parameter_count, expected_property_count, parameter_count, parameter_count,
FunctionLiteral::kNoDuplicateParameters, FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos); FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos);
...@@ -2496,7 +2496,7 @@ void Parser::DeclareArrowFunctionFormalParameters( ...@@ -2496,7 +2496,7 @@ void Parser::DeclareArrowFunctionFormalParameters(
AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
CHECK_OK_VOID); CHECK_OK_VOID);
if (parameters->Arity() > Code::kMaxArguments) { if (parameters->arity > Code::kMaxArguments) {
ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList); ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
*ok = false; *ok = false;
return; return;
...@@ -2506,7 +2506,7 @@ void Parser::DeclareArrowFunctionFormalParameters( ...@@ -2506,7 +2506,7 @@ void Parser::DeclareArrowFunctionFormalParameters(
if (!parameters->is_simple) { if (!parameters->is_simple) {
this->classifier()->RecordNonSimpleParameter(); this->classifier()->RecordNonSimpleParameter();
} }
for (int i = 0; i < parameters->Arity(); ++i) { for (int i = 0; i < parameters->arity; ++i) {
auto parameter = parameters->at(i); auto parameter = parameters->at(i);
DeclareFormalParameter(parameters->scope, parameter); DeclareFormalParameter(parameters->scope, parameter);
if (!this->classifier() if (!this->classifier()
...@@ -2656,7 +2656,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2656,7 +2656,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
SetLanguageMode(scope, language_mode); SetLanguageMode(scope, language_mode);
ZoneList<Statement*>* body = nullptr; ZoneList<Statement*>* body = nullptr;
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());
...@@ -2677,17 +2676,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2677,17 +2676,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
this->scope()->set_start_position(start_position); this->scope()->set_start_position(start_position);
ParserFormalParameters formals(scope); ParserFormalParameters formals(scope);
ParseFormalParameterList(&formals, CHECK_OK); ParseFormalParameterList(&formals, CHECK_OK);
arity = formals.Arity();
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, kind, formals.has_rest, start_position, CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position,
formals_end_position, CHECK_OK); formals_end_position, CHECK_OK);
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE, CHECK_OK);
// Don't include the rest parameter into the function's formal parameter
// count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
// which says whether we need to create an arguments adaptor frame).
if (formals.has_rest) arity--;
{ {
// Temporary zones can nest. When we migrate free variables (see below), we // Temporary zones can nest. When we migrate free variables (see below), we
...@@ -2788,7 +2782,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2788,7 +2782,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// Note that the FunctionLiteral needs to be created in the main Zone again. // Note that the FunctionLiteral needs to be created in the main Zone again.
FunctionLiteral* function_literal = factory()->NewFunctionLiteral( FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
function_name, scope, body, materialized_literal_count, function_name, scope, body, materialized_literal_count,
expected_property_count, arity, duplicate_parameters, function_type, expected_property_count, formals.num_parameters(),
formals.function_length, duplicate_parameters, function_type,
eager_compile_hint, pos); eager_compile_hint, pos);
function_literal->set_function_token_position(function_token_pos); function_literal->set_function_token_position(function_token_pos);
if (should_be_used_once_hint) if (should_be_used_once_hint)
...@@ -3437,12 +3432,11 @@ FunctionLiteral* Parser::SynthesizeClassFieldInitializer(int count) { ...@@ -3437,12 +3432,11 @@ FunctionLiteral* Parser::SynthesizeClassFieldInitializer(int count) {
FunctionLiteral* function_literal = factory()->NewFunctionLiteral( FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
ast_value_factory()->empty_string(), initializer_scope, body, ast_value_factory()->empty_string(), initializer_scope, body,
initializer_state.materialized_literal_count(), initializer_state.materialized_literal_count(),
initializer_state.expected_property_count(), 0, initializer_state.expected_property_count(), 0, count,
FunctionLiteral::kNoDuplicateParameters, FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression, FunctionLiteral::kAnonymousExpression,
FunctionLiteral::kShouldLazyCompile, initializer_scope->start_position()); FunctionLiteral::kShouldLazyCompile, initializer_scope->start_position());
function_literal->set_is_class_field_initializer(true); function_literal->set_is_class_field_initializer(true);
function_literal->scope()->set_arity(count);
return function_literal; return function_literal;
} }
......
...@@ -134,7 +134,6 @@ struct ParserFormalParameters : FormalParametersBase { ...@@ -134,7 +134,6 @@ struct ParserFormalParameters : FormalParametersBase {
: FormalParametersBase(scope), params(4, scope->zone()) {} : FormalParametersBase(scope), params(4, scope->zone()) {}
ZoneList<Parameter> params; ZoneList<Parameter> params;
int Arity() const { return params.length(); }
const Parameter& at(int i) const { return params[i]; } const Parameter& at(int i) const { return params[i]; }
}; };
...@@ -999,6 +998,7 @@ class Parser : public ParserBase<Parser> { ...@@ -999,6 +998,7 @@ class Parser : public ParserBase<Parser> {
Expression* initializer, Expression* initializer,
int initializer_end_position, int initializer_end_position,
bool is_rest) { bool is_rest) {
parameters->UpdateArityAndFunctionLength(initializer != nullptr, is_rest);
bool is_simple = pattern->IsVariableProxy() && initializer == nullptr; bool is_simple = pattern->IsVariableProxy() && initializer == nullptr;
const AstRawString* name = is_simple const AstRawString* name = is_simple
? pattern->AsVariableProxy()->raw_name() ? pattern->AsVariableProxy()->raw_name()
......
...@@ -658,7 +658,7 @@ class PreParserFactory { ...@@ -658,7 +658,7 @@ class PreParserFactory {
PreParserExpression NewFunctionLiteral( PreParserExpression NewFunctionLiteral(
PreParserIdentifier name, Scope* scope, PreParserStatementList body, PreParserIdentifier name, Scope* scope, PreParserStatementList body,
int materialized_literal_count, int expected_property_count, int materialized_literal_count, int expected_property_count,
int parameter_count, int parameter_count, int function_length,
FunctionLiteral::ParameterFlag has_duplicate_parameters, FunctionLiteral::ParameterFlag has_duplicate_parameters,
FunctionLiteral::FunctionType function_type, FunctionLiteral::FunctionType function_type,
FunctionLiteral::EagerCompileHint eager_compile_hint, int position) { FunctionLiteral::EagerCompileHint eager_compile_hint, int position) {
...@@ -761,9 +761,6 @@ class PreParserFactory { ...@@ -761,9 +761,6 @@ class PreParserFactory {
struct PreParserFormalParameters : FormalParametersBase { struct PreParserFormalParameters : FormalParametersBase {
explicit PreParserFormalParameters(DeclarationScope* scope) explicit PreParserFormalParameters(DeclarationScope* scope)
: FormalParametersBase(scope) {} : FormalParametersBase(scope) {}
int arity = 0;
int Arity() const { return arity; }
PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy
}; };
...@@ -1436,7 +1433,7 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1436,7 +1433,7 @@ class PreParser : public ParserBase<PreParser> {
PreParserExpression initializer, PreParserExpression initializer,
int initializer_end_position, int initializer_end_position,
bool is_rest) { bool is_rest) {
++parameters->arity; parameters->UpdateArityAndFunctionLength(!initializer.IsEmpty(), is_rest);
} }
V8_INLINE void DeclareFormalParameter(DeclarationScope* scope, V8_INLINE void DeclareFormalParameter(DeclarationScope* scope,
......
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