Commit 62960a03 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[parser] Skipping inner funcs: fix async arrow funcs.

Track whether the async arrow func parameter list was simple or not; the
information is already there, we just didn't pipe it through correctly. It's
needed by PreParser so that it can create the correct Scope structure.

Implementation notes:

- I could've used async_classifier for transmitting the "is_simple" bit, but I
  made it explicit (it would be unnecessary to use ExpressionClassifier for
  this, as we're not classifying any expressions) instead.

- I'm also moving work (setting parameter_list.is_simple) from Parser to
  ParserBase, and adding a DCHECK in Parser to assert that the work was indeed
  already done.

BUG=v8:5516,chromium:765532

Change-Id: Iacf91b150d1b57996544b5e64baa7d91ac134445
Reviewed-on: https://chromium-review.googlesource.com/674695
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48132}
parent 7816413f
......@@ -1088,10 +1088,11 @@ class ParserBase {
ObjectLiteralChecker* checker, bool* is_computed_name,
bool* is_rest_property, bool* ok);
ExpressionListT ParseArguments(Scanner::Location* first_spread_pos,
bool maybe_arrow, bool* ok);
bool maybe_arrow,
bool* is_simple_parameter_list, bool* ok);
ExpressionListT ParseArguments(Scanner::Location* first_spread_pos,
bool* ok) {
return ParseArguments(first_spread_pos, false, ok);
return ParseArguments(first_spread_pos, false, nullptr, ok);
}
ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
......@@ -2660,7 +2661,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
template <typename Impl>
typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments(
Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) {
Scanner::Location* first_spread_arg_loc, bool maybe_arrow,
bool* is_simple_parameter_list, bool* ok) {
// Arguments ::
// '(' (AssignmentExpression)*[','] ')'
......@@ -2675,10 +2677,17 @@ typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments(
ExpressionT argument =
ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpressionList));
if (!impl()->IsIdentifier(argument) &&
is_simple_parameter_list != nullptr) {
*is_simple_parameter_list = false;
}
if (!maybe_arrow) {
impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList));
}
if (is_spread) {
if (is_simple_parameter_list != nullptr) {
*is_simple_parameter_list = false;
}
if (!spread_arg.IsValid()) {
spread_arg.beg_pos = start_pos;
spread_arg.end_pos = peek_position();
......@@ -3238,7 +3247,9 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
ExpressionListT args;
if (V8_UNLIKELY(is_async && impl()->IsIdentifier(result))) {
ExpressionClassifier async_classifier(this);
args = ParseArguments(&spread_pos, true, CHECK_OK);
bool is_simple_parameter_list = true;
args = ParseArguments(&spread_pos, true, &is_simple_parameter_list,
CHECK_OK);
if (peek() == Token::ARROW) {
if (fni_) {
fni_->RemoveAsyncKeywordFromEnd();
......@@ -3253,6 +3264,9 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
}
if (args->length()) {
// async ( Arguments ) => ...
if (!is_simple_parameter_list) {
async_classifier.previous()->RecordNonSimpleParameter();
}
return impl()->ExpressionListToExpression(args);
}
// async () => ...
......@@ -3261,7 +3275,7 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
AccumulateFormalParameterContainmentErrors();
}
} else {
args = ParseArguments(&spread_pos, false, CHECK_OK);
args = ParseArguments(&spread_pos, CHECK_OK);
}
ArrowFormalParametersUnexpectedToken();
......
......@@ -2389,9 +2389,8 @@ void Parser::AddArrowFunctionFormalParameters(
expr = expr->AsSpread()->expression();
parameters->has_rest = true;
}
if (parameters->is_simple) {
parameters->is_simple = !is_rest && expr->IsVariableProxy();
}
DCHECK_IMPLIES(parameters->is_simple, !is_rest);
DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy());
Expression* initializer = nullptr;
if (expr->IsAssignment()) {
......
......@@ -314,3 +314,27 @@ TestSkippableFunctionInForOfHeaderAndBody();
assertEquals(3, lazy(9)().next().value);
assertEquals(19, result);
})();
(function TestRestoringDataToAsyncArrowFunctionWithNonSimpleParams_1() {
// Regression test for
// https://bugs.chromium.org/p/chromium/issues/detail?id=765532
function lazy() {
// The arrow function is not skippable, but we need to traverse its scopes
// and restore data to them.
async(a=0) => { const d = 0; }
function skippable() {}
}
lazy();
})();
(function TestRestoringDataToAsyncArrowFunctionWithNonSimpleParams_2() {
// Regression test for
// https://bugs.chromium.org/p/chromium/issues/detail?id=765532
function lazy() {
// The arrow function is not skippable, but we need to traverse its scopes
// and restore data to them.
async(...a) => { const d = 0; }
function skippable() {}
}
lazy();
})();
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