Commit f6740454 authored by Dan Elphick's avatar Dan Elphick Committed by Commit Bot

[parser] Fix destructured parameters in arrowheads

Always unmark arrowhead parameters as assigned directly after their
initialization as the parser doesn't know when it first sees the
"assignment" that it may be in an arrowhead.

Bug: chromium:1003403, v8:8510
Change-Id: Iad5a4136d5ec06331fc43b81a809fd72cee2dd65
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1815131
Commit-Queue: Dan Elphick <delphick@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63947}
parent 0ceee9ad
...@@ -84,6 +84,9 @@ class Variable final : public ZoneObject { ...@@ -84,6 +84,9 @@ class Variable final : public ZoneObject {
MaybeAssignedFlag maybe_assigned() const { MaybeAssignedFlag maybe_assigned() const {
return MaybeAssignedFlagField::decode(bit_field_); return MaybeAssignedFlagField::decode(bit_field_);
} }
void clear_maybe_assigned() {
bit_field_ = MaybeAssignedFlagField::update(bit_field_, kNotAssigned);
}
void SetMaybeAssigned() { void SetMaybeAssigned() {
if (mode() == VariableMode::kConst) return; if (mode() == VariableMode::kConst) return;
......
...@@ -3599,7 +3599,19 @@ void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters) { ...@@ -3599,7 +3599,19 @@ void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters) {
auto declaration_end = scope()->declarations()->end(); auto declaration_end = scope()->declarations()->end();
int initializer_end = end_position(); int initializer_end = end_position();
for (; declaration_it != declaration_end; ++declaration_it) { for (; declaration_it != declaration_end; ++declaration_it) {
declaration_it->var()->set_initializer_position(initializer_end); Variable* var = declaration_it->var();
// The first time a variable is initialized (i.e. when the initializer
// position is unset), clear its maybe_assigned flag as it is not a true
// assignment. Since this is done directly on the Variable objects, it has
// no effect on VariableProxy objects appearing on the left-hand side of
// true assignments, so x will be still be marked as maybe_assigned for:
// (x = 1, y = (x = 2)) => {}
// and even:
// (x = (x = 2)) => {}.
if (var->initializer_position() == kNoSourcePosition)
var->clear_maybe_assigned();
var->set_initializer_position(initializer_end);
} }
impl()->AddFormalParameter(parameters, pattern, initializer, end_position(), impl()->AddFormalParameter(parameters, pattern, initializer, end_position(),
......
...@@ -3608,6 +3608,14 @@ TEST(MaybeAssignedParameters) { ...@@ -3608,6 +3608,14 @@ TEST(MaybeAssignedParameters) {
"g(arg)}"}, "g(arg)}"},
{true, "function f(arg) {g(arg); eval('arguments[0] = 42'); g(arg)}"}, {true, "function f(arg) {g(arg); eval('arguments[0] = 42'); g(arg)}"},
{true, "function f(arg) {g(arg); g(() => arguments[0] = 42); g(arg)}"}, {true, "function f(arg) {g(arg); g(() => arguments[0] = 42); g(arg)}"},
// default values
{false, "function f({x:arg = 1}) {}"},
{true, "function f({x:arg = 1}, {y:b=(arg=2)}) {}"},
{true, "function f({x:arg = (arg = 2)}) {}"},
{false, "var f = ({x:arg = 1}) => {}"},
{true, "var f = ({x:arg = 1}, {y:b=(arg=2)}) => {}"},
{true, "var f = ({x:arg = (arg = 2)}) => {}"},
}; };
const char* suffix = "; f"; const char* suffix = "; f";
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --enable-lazy-source-positions --stress-lazy-source-positions
// Flags: --no-lazy
({ x: b = 0 }) => {
try { b; } catch (e) {}
function a() { b }
}
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