Commit 712800a6 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[parser] Skipping inner funcs: params part 3

Produce the same scopes / variables for parameters (part 3).

This CL fixes the ordering + variable types in PreParser when there are
simple parameters + a rest parameter. In that case, Parser declares
unnamed temporaries for the non-rest params, then the rest param, then
the named variables (which are not parameters) for the non-rest params.

BUG=v8:5516
R=vogelheim@chromium.org

Change-Id: I9b006595039c8002b0508d1d2a200aa9a0f3eae0
Reviewed-on: https://chromium-review.googlesource.com/443527Reviewed-by: 's avatarDaniel Vogelheim <vogelheim@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43241}
parent 4123a3dd
...@@ -148,14 +148,20 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -148,14 +148,20 @@ PreParser::PreParseResult PreParser::PreParseFunction(
&formals, has_duplicate_parameters, may_abort, ok); &formals, has_duplicate_parameters, may_abort, ok);
} }
if (is_sloppy(inner_scope->language_mode())) {
inner_scope->HoistSloppyBlockFunctions(nullptr);
}
if (!formals.is_simple) { if (!formals.is_simple) {
BuildParameterInitializationBlock(formals, ok);
if (is_sloppy(inner_scope->language_mode())) {
inner_scope->HoistSloppyBlockFunctions(nullptr);
}
SetLanguageMode(function_scope, inner_scope->language_mode()); SetLanguageMode(function_scope, inner_scope->language_mode());
inner_scope->set_end_position(scanner()->peek_location().end_pos); inner_scope->set_end_position(scanner()->peek_location().end_pos);
inner_scope->FinalizeBlockScope(); inner_scope->FinalizeBlockScope();
} else {
if (is_sloppy(function_scope->language_mode())) {
function_scope->HoistSloppyBlockFunctions(nullptr);
}
} }
if (!IsArrowFunction(kind) && track_unresolved_variables_) { if (!IsArrowFunction(kind) && track_unresolved_variables_) {
......
...@@ -791,13 +791,19 @@ class PreParserFactory { ...@@ -791,13 +791,19 @@ class PreParserFactory {
struct PreParserFormalParameters : FormalParametersBase { struct PreParserFormalParameters : FormalParametersBase {
struct Parameter : public ZoneObject { struct Parameter : public ZoneObject {
Parameter(PreParserExpression pattern, bool is_rest) Parameter(PreParserExpression pattern, bool is_destructuring, bool is_rest)
: pattern(pattern), is_rest(is_rest) {} : pattern(pattern),
is_destructuring(is_destructuring),
is_rest(is_rest) {}
Parameter** next() { return &next_parameter; } Parameter** next() { return &next_parameter; }
Parameter* const* next() const { return &next_parameter; } Parameter* const* next() const { return &next_parameter; }
bool is_nondestructuring_rest() const {
return is_rest && !is_destructuring;
}
PreParserExpression pattern; PreParserExpression pattern;
Parameter* next_parameter = nullptr; Parameter* next_parameter = nullptr;
bool is_rest; bool is_destructuring : 1;
bool is_rest : 1;
}; };
explicit PreParserFormalParameters(DeclarationScope* scope) explicit PreParserFormalParameters(DeclarationScope* scope)
: FormalParametersBase(scope) {} : FormalParametersBase(scope) {}
...@@ -1378,6 +1384,16 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1378,6 +1384,16 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE PreParserStatement BuildParameterInitializationBlock( V8_INLINE PreParserStatement BuildParameterInitializationBlock(
const PreParserFormalParameters& parameters, bool* ok) { const PreParserFormalParameters& parameters, bool* ok) {
if (track_unresolved_variables_) {
for (auto parameter : parameters.params) {
if (parameter->is_nondestructuring_rest()) break;
if (parameter->pattern.variables_ != nullptr) {
for (auto variable : *parameter->pattern.variables_) {
scope()->DeclareVariableName(variable->raw_name(), LET);
}
}
}
}
return PreParserStatement::Default(); return PreParserStatement::Default();
} }
...@@ -1598,8 +1614,8 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1598,8 +1614,8 @@ class PreParser : public ParserBase<PreParser> {
bool is_rest) { bool is_rest) {
if (track_unresolved_variables_) { if (track_unresolved_variables_) {
DCHECK(FLAG_lazy_inner_functions); DCHECK(FLAG_lazy_inner_functions);
parameters->params.Add( parameters->params.Add(new (zone()) PreParserFormalParameters::Parameter(
new (zone()) PreParserFormalParameters::Parameter(pattern, is_rest)); pattern, !IsIdentifier(pattern), is_rest));
} }
parameters->UpdateArityAndFunctionLength(!initializer.IsEmpty(), is_rest); parameters->UpdateArityAndFunctionLength(!initializer.IsEmpty(), is_rest);
} }
...@@ -1607,17 +1623,18 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1607,17 +1623,18 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE void DeclareFormalParameters( V8_INLINE void DeclareFormalParameters(
DeclarationScope* scope, DeclarationScope* scope,
const ThreadedList<PreParserFormalParameters::Parameter>& parameters) { const ThreadedList<PreParserFormalParameters::Parameter>& parameters) {
if (!classifier()->is_simple_parameter_list()) { bool is_simple = classifier()->is_simple_parameter_list();
scope->SetHasNonSimpleParameters(); if (!is_simple) scope->SetHasNonSimpleParameters();
}
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) {
if (parameter->pattern.variables_ != nullptr) { bool use_name = is_simple || parameter->is_nondestructuring_rest();
for (auto variable : *parameter->pattern.variables_) { if (use_name) {
scope->DeclareParameterName( DCHECK_NOT_NULL(parameter->pattern.variables_);
variable->raw_name(), parameter->is_rest, ast_value_factory()); DCHECK_EQ(parameter->pattern.variables_->length(), 1);
} auto variable = (*parameter->pattern.variables_)[0];
scope->DeclareParameterName(variable->raw_name(), parameter->is_rest,
ast_value_factory());
} }
} }
} }
......
...@@ -327,6 +327,16 @@ TEST(PreParserScopeAnalysis) { ...@@ -327,6 +327,16 @@ TEST(PreParserScopeAnalysis) {
{"var1", "function f1() { var1; }"}, {"var1", "function f1() { var1; }"},
{"var1", "function f1() { var1 = 9; }"}, {"var1", "function f1() { var1 = 9; }"},
{"var1, var2", ""},
{"var1, var2", "var2;"},
{"var1, var2", "var2 = 9;"},
{"var1, var2", "function f1() { var2; }"},
{"var1, var2", "function f1() { var2 = 9; }"},
{"var1, var2", "var1;"},
{"var1, var2", "var1 = 9;"},
{"var1, var2", "function f1() { var1; }"},
{"var1, var2", "function f1() { var1 = 9; }"},
// Duplicate parameters. // Duplicate parameters.
{"var1, var1", ""}, {"var1, var1", ""},
{"var1, var1", "var1;"}, {"var1, var1", "var1;"},
...@@ -341,11 +351,18 @@ TEST(PreParserScopeAnalysis) { ...@@ -341,11 +351,18 @@ TEST(PreParserScopeAnalysis) {
{"...var2", "function f1() { var2; }"}, {"...var2", "function f1() { var2; }"},
{"...var2", "function f1() { var2 = 9; }"}, {"...var2", "function f1() { var2 = 9; }"},
{"var1, ...var2", ""},
{"var1, ...var2", "var2;"},
{"var1, ...var2", "var2 = 9;"},
{"var1, ...var2", "function f1() { var2; }"},
{"var1, ...var2", "function f1() { var2 = 9; }"},
// FIXME(marja): destructuring parameters, default parameters, shadowing // FIXME(marja): destructuring parameters, default parameters, shadowing
// parameters, default parameters referring to other parameters, arguments // parameters, default parameters referring to other parameters, arguments
// parameter, eval in default parameter, params and locals, multiple // parameter, eval in default parameter, params and locals, multiple
// params, many params and rest, destructuring rest, rest with default // params, destructuring rest, locals shadowing params, locals shadowing
// value, locals shadowing params. // rest, locals shadowing destructuring params, shadowing by a hoisted
// sloppy block function.
}; };
for (unsigned outer_ix = 0; outer_ix < arraysize(outers); ++outer_ix) { for (unsigned outer_ix = 0; outer_ix < arraysize(outers); ++outer_ix) {
......
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