Commit 804ac5f6 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[parser] Skipping inner funcs: fix parameter count in preparser.

For non-simple param lists, the parser first declares a TEMPORARY for each
param, and then the named variables as locals. The TEMPORARY variables determine
the parameter count.

This CL makes the PreParser produce the same parameter count as the Parser.

BUG=v8:5516

Change-Id: I8a794d6a8342145ab7934d922e2d69450d67b199
Reviewed-on: https://chromium-review.googlesource.com/517944
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarDaniel Vogelheim <vogelheim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45566}
parent b90c98fc
...@@ -1035,8 +1035,8 @@ Variable* DeclarationScope::DeclareParameter( ...@@ -1035,8 +1035,8 @@ Variable* DeclarationScope::DeclareParameter(
} }
Variable* DeclarationScope::DeclareParameterName( Variable* DeclarationScope::DeclareParameterName(
const AstRawString* name, bool is_rest, const AstRawString* name, bool is_rest, AstValueFactory* ast_value_factory,
AstValueFactory* ast_value_factory) { bool declare_as_local, bool add_parameter) {
DCHECK(!already_resolved_); DCHECK(!already_resolved_);
DCHECK(is_function_scope() || is_module_scope()); DCHECK(is_function_scope() || is_module_scope());
DCHECK(!has_rest_ || is_rest); DCHECK(!has_rest_ || is_rest);
...@@ -1046,8 +1046,16 @@ Variable* DeclarationScope::DeclareParameterName( ...@@ -1046,8 +1046,16 @@ Variable* DeclarationScope::DeclareParameterName(
has_arguments_parameter_ = true; has_arguments_parameter_ = true;
} }
if (FLAG_experimental_preparser_scope_analysis) { if (FLAG_experimental_preparser_scope_analysis) {
Variable* var = Declare(zone(), name, VAR); Variable* var;
params_.Add(var, zone()); if (declare_as_local) {
var = Declare(zone(), name, VAR);
} else {
var = new (zone())
Variable(this, name, TEMPORARY, NORMAL_VARIABLE, kCreatedInitialized);
}
if (add_parameter) {
params_.Add(var, zone());
}
return var; return var;
} }
DeclareVariableName(name, VAR); DeclareVariableName(name, VAR);
......
...@@ -733,7 +733,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { ...@@ -733,7 +733,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
// Declares that a parameter with the name exists. Creates a Variable and // Declares that a parameter with the name exists. Creates a Variable and
// returns it if FLAG_preparser_scope_analysis is on. // returns it if FLAG_preparser_scope_analysis is on.
Variable* DeclareParameterName(const AstRawString* name, bool is_rest, Variable* DeclareParameterName(const AstRawString* name, bool is_rest,
AstValueFactory* ast_value_factory); AstValueFactory* ast_value_factory,
bool declare_local, bool add_parameter);
// Declare an implicit global variable in this scope which must be a // Declare an implicit global variable in this scope which must be a
// script scope. The variable was introduced (possibly from an inner // script scope. The variable was introduced (possibly from an inner
......
...@@ -137,7 +137,7 @@ void PreParsedScopeData::RestoreData(Scope* scope, uint32_t* index_ptr) const { ...@@ -137,7 +137,7 @@ void PreParsedScopeData::RestoreData(Scope* scope, uint32_t* index_ptr) const {
function_index_.GetFunctionData(scope->start_position()); function_index_.GetFunctionData(scope->start_position());
DCHECK(data.is_valid()); DCHECK(data.is_valid());
DCHECK_EQ(data.end, scope->end_position()); DCHECK_EQ(data.end, scope->end_position());
// FIXME(marja): unify num_parameters too and DCHECK here. DCHECK_EQ(data.num_parameters, scope->num_parameters());
DCHECK_EQ(data.language_mode, scope->language_mode()); DCHECK_EQ(data.language_mode, scope->language_mode());
DCHECK_EQ(data.uses_super_property, DCHECK_EQ(data.uses_super_property,
scope->AsDeclarationScope()->uses_super_property()); scope->AsDeclarationScope()->uses_super_property());
......
...@@ -1625,12 +1625,29 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1625,12 +1625,29 @@ class PreParser : public ParserBase<PreParser> {
if (track_unresolved_variables_) { if (track_unresolved_variables_) {
DCHECK(FLAG_lazy_inner_functions); DCHECK(FLAG_lazy_inner_functions);
for (auto parameter : parameters) { for (auto parameter : parameters) {
DCHECK_IMPLIES(is_simple, parameter->variables_ != nullptr);
DCHECK_IMPLIES(is_simple, parameter->variables_->length() == 1);
// Make sure each parameter is added only once even if it's a
// destructuring parameter which contains multiple names.
bool add_parameter = true;
if (parameter->variables_ != nullptr) { if (parameter->variables_ != nullptr) {
for (auto variable : (*parameter->variables_)) { for (auto variable : (*parameter->variables_)) {
scope->DeclareParameterName( // We declare the parameter name for all names, but only create a
variable->raw_name(), parameter->is_rest, ast_value_factory()); // parameter entry for the first one.
scope->DeclareParameterName(variable->raw_name(),
parameter->is_rest, ast_value_factory(),
true, add_parameter);
add_parameter = false;
} }
} }
if (add_parameter) {
// No names were declared; declare a dummy one here to up the
// parameter count.
DCHECK(!is_simple);
scope->DeclareParameterName(ast_value_factory()->empty_string(),
parameter->is_rest, ast_value_factory(),
false, add_parameter);
}
} }
} }
} }
......
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