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 {
int materialized_literal_count() { return materialized_literal_count_; }
int expected_property_count() { return expected_property_count_; }
int parameter_count() { return parameter_count_; }
int function_length() { return function_length_; }
bool AllowsLazyCompilation();
......@@ -2710,7 +2711,7 @@ class FunctionLiteral final : public Expression {
AstValueFactory* ast_value_factory, DeclarationScope* scope,
ZoneList<Statement*>* body, int materialized_literal_count,
int expected_property_count, int parameter_count,
FunctionType function_type,
int function_length, FunctionType function_type,
ParameterFlag has_duplicate_parameters,
EagerCompileHint eager_compile_hint, int position,
bool is_function)
......@@ -2718,6 +2719,7 @@ class FunctionLiteral final : public Expression {
materialized_literal_count_(materialized_literal_count),
expected_property_count_(expected_property_count),
parameter_count_(parameter_count),
function_length_(function_length),
function_token_position_(kNoSourcePosition),
yield_count_(0),
raw_name_(name),
......@@ -2754,6 +2756,7 @@ class FunctionLiteral final : public Expression {
int materialized_literal_count_;
int expected_property_count_;
int parameter_count_;
int function_length_;
int function_token_position_;
int yield_count_;
......@@ -3453,15 +3456,15 @@ class AstNodeFactory final BASE_EMBEDDED {
FunctionLiteral* NewFunctionLiteral(
const AstRawString* name, DeclarationScope* scope,
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::FunctionType function_type,
FunctionLiteral::EagerCompileHint eager_compile_hint, int position) {
return new (zone_) FunctionLiteral(zone_, name, ast_value_factory_, scope,
body, materialized_literal_count,
expected_property_count, parameter_count,
function_type, has_duplicate_parameters,
eager_compile_hint, position, true);
return new (zone_) FunctionLiteral(
zone_, name, ast_value_factory_, scope, body,
materialized_literal_count, expected_property_count, parameter_count,
function_length, function_type, has_duplicate_parameters,
eager_compile_hint, position, true);
}
// Creates a FunctionLiteral representing a top-level script, the
......@@ -3474,7 +3477,7 @@ class AstNodeFactory final BASE_EMBEDDED {
return new (zone_) FunctionLiteral(
zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope,
body, materialized_literal_count, expected_property_count,
parameter_count, FunctionLiteral::kAnonymousExpression,
parameter_count, parameter_count, FunctionLiteral::kAnonymousExpression,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kShouldLazyCompile, 0, false);
}
......
......@@ -271,7 +271,6 @@ void DeclarationScope::SetDefaults() {
function_ = nullptr;
arguments_ = nullptr;
this_function_ = nullptr;
arity_ = 0;
}
void Scope::SetDefaults() {
......@@ -840,9 +839,6 @@ Variable* DeclarationScope::DeclareParameter(
// TODO(wingo): Avoid O(n^2) check.
*is_duplicate = IsDeclaredParameter(name);
}
if (!is_optional && !is_rest && arity_ == params_.length()) {
++arity_;
}
has_rest_ = is_rest;
params_.Add(var, zone());
if (name == ast_value_factory->arguments_string()) {
......
......@@ -706,16 +706,6 @@ class DeclarationScope : public Scope {
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
// parameter. Examples:
// function foo(a, b) {} ==> 2
......@@ -848,8 +838,6 @@ class DeclarationScope : public Scope {
// This scope uses "super" property ('super.foo').
bool scope_uses_super_property_ : 1;
// Info about the parameter list of a function.
int arity_;
// Parameter list in source order.
ZoneList<Variable*> params_;
// Map of function names to lists of functions defined in sloppy blocks
......
......@@ -13823,7 +13823,7 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
Handle<SharedFunctionInfo> shared_info, FunctionLiteral* lit) {
// When adding fields here, make sure DeclarationScope::AnalyzePartially is
// 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_function_token_position(lit->function_token_position());
shared_info->set_start_position(lit->start_position());
......
......@@ -59,10 +59,27 @@ static inline bool operator&(ParseFunctionFlags bitfield,
struct FormalParametersBase {
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;
bool has_rest = false;
bool is_simple = true;
int materialized_literals_count = 0;
int function_length = 0;
int arity = 0;
};
......@@ -2284,7 +2301,7 @@ ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer,
FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
impl()->EmptyIdentifierString(), initializer_scope, body,
initializer_state.materialized_literal_count(),
initializer_state.expected_property_count(), 0,
initializer_state.expected_property_count(), 0, 0,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_,
initializer_scope->start_position());
......@@ -3479,11 +3496,11 @@ void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters,
// FormalParameter[?Yield]
// FormalParameterList[?Yield] , FormalParameter[?Yield]
DCHECK_EQ(0, parameters->Arity());
DCHECK_EQ(0, parameters->arity);
if (peek() != Token::RPAREN) {
while (true) {
if (parameters->Arity() > Code::kMaxArguments) {
if (parameters->arity > Code::kMaxArguments) {
ReportMessage(MessageTemplate::kTooManyParameters);
*ok = false;
return;
......@@ -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);
impl()->DeclareFormalParameter(parameters->scope, parameter);
}
......@@ -3912,7 +3929,6 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
}
StatementListT body = impl()->NullStatementList();
int num_parameters = formal_parameters.scope->num_parameters();
int materialized_literal_count = -1;
int expected_property_count = -1;
......@@ -4027,7 +4043,8 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
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::kAnonymousExpression, eager_compile_hint,
formal_parameters.scope->start_position());
......
......@@ -221,7 +221,7 @@ FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
LanguageMode language_mode) {
int materialized_literal_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();
FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor
......@@ -284,7 +284,7 @@ FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
name, function_scope, body, materialized_literal_count,
expected_property_count, parameter_count,
expected_property_count, parameter_count, parameter_count,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos);
......@@ -2496,7 +2496,7 @@ void Parser::DeclareArrowFunctionFormalParameters(
AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
CHECK_OK_VOID);
if (parameters->Arity() > Code::kMaxArguments) {
if (parameters->arity > Code::kMaxArguments) {
ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
*ok = false;
return;
......@@ -2506,7 +2506,7 @@ void Parser::DeclareArrowFunctionFormalParameters(
if (!parameters->is_simple) {
this->classifier()->RecordNonSimpleParameter();
}
for (int i = 0; i < parameters->Arity(); ++i) {
for (int i = 0; i < parameters->arity; ++i) {
auto parameter = parameters->at(i);
DeclareFormalParameter(parameters->scope, parameter);
if (!this->classifier()
......@@ -2656,7 +2656,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
SetLanguageMode(scope, language_mode);
ZoneList<Statement*>* body = nullptr;
int arity = -1;
int materialized_literal_count = -1;
int expected_property_count = -1;
DuplicateFinder duplicate_finder(scanner()->unicode_cache());
......@@ -2677,17 +2676,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
this->scope()->set_start_position(start_position);
ParserFormalParameters formals(scope);
ParseFormalParameterList(&formals, CHECK_OK);
arity = formals.Arity();
Expect(Token::RPAREN, CHECK_OK);
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);
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
......@@ -2788,7 +2782,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// Note that the FunctionLiteral needs to be created in the main Zone again.
FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
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);
function_literal->set_function_token_position(function_token_pos);
if (should_be_used_once_hint)
......@@ -3437,12 +3432,11 @@ FunctionLiteral* Parser::SynthesizeClassFieldInitializer(int count) {
FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
ast_value_factory()->empty_string(), initializer_scope, body,
initializer_state.materialized_literal_count(),
initializer_state.expected_property_count(), 0,
initializer_state.expected_property_count(), 0, count,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression,
FunctionLiteral::kShouldLazyCompile, initializer_scope->start_position());
function_literal->set_is_class_field_initializer(true);
function_literal->scope()->set_arity(count);
return function_literal;
}
......
......@@ -134,7 +134,6 @@ struct ParserFormalParameters : FormalParametersBase {
: FormalParametersBase(scope), params(4, scope->zone()) {}
ZoneList<Parameter> params;
int Arity() const { return params.length(); }
const Parameter& at(int i) const { return params[i]; }
};
......@@ -999,6 +998,7 @@ class Parser : public ParserBase<Parser> {
Expression* initializer,
int initializer_end_position,
bool is_rest) {
parameters->UpdateArityAndFunctionLength(initializer != nullptr, is_rest);
bool is_simple = pattern->IsVariableProxy() && initializer == nullptr;
const AstRawString* name = is_simple
? pattern->AsVariableProxy()->raw_name()
......
......@@ -658,7 +658,7 @@ class PreParserFactory {
PreParserExpression NewFunctionLiteral(
PreParserIdentifier name, Scope* scope, PreParserStatementList body,
int materialized_literal_count, int expected_property_count,
int parameter_count,
int parameter_count, int function_length,
FunctionLiteral::ParameterFlag has_duplicate_parameters,
FunctionLiteral::FunctionType function_type,
FunctionLiteral::EagerCompileHint eager_compile_hint, int position) {
......@@ -761,9 +761,6 @@ class PreParserFactory {
struct PreParserFormalParameters : FormalParametersBase {
explicit PreParserFormalParameters(DeclarationScope* scope)
: FormalParametersBase(scope) {}
int arity = 0;
int Arity() const { return arity; }
PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy
};
......@@ -1436,7 +1433,7 @@ class PreParser : public ParserBase<PreParser> {
PreParserExpression initializer,
int initializer_end_position,
bool is_rest) {
++parameters->arity;
parameters->UpdateArityAndFunctionLength(!initializer.IsEmpty(), is_rest);
}
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