fc4bcce132
The previous fix for this bug (crrev.com/c/1678365) pessimistically would mark all shadowed variables as maybe_assigned. Unfortunately, this doesn't work across a parse/preparse boundary, where the shadowing variable is found via Scope::AnalyzePartially while the shadowed variable is outside of the preparser entry point. In those cases, the referencing proxy is copied to the outer scope, in which case the dynamicness of the original lookup is lost and the maybe_assigned pessimisation no longer applies. This means that maybe_assigned status of a variable is dependent on which function is being parsed. In particular, it can cause bytecode to change on recompilation, causing issues for lazy source positions. This patch allows SetMaybeAssigned to walk its shadowed variables, and recursively set them to maybe_assigned too. Checking for maybe_assigned changing prevents this recursion from having a quadratic performance failure mode. Bug: v8:8510 Bug: v8:9394 Change-Id: Id19fe1fad5ec8f0f9aa03b00eb24497f88f71216 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1677265 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#62458}
24 lines
823 B
JavaScript
24 lines
823 B
JavaScript
// 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
|
|
|
|
function test() {
|
|
function f() {
|
|
with ({}) {
|
|
// This is a non-assigning shadowing access to value. If both f and test
|
|
// are fully parsed or both are preparsed, then this is resolved during
|
|
// scope analysis to the outer value, and the outer value knows it can be
|
|
// shadowed. If test is fully parsed and f is preparsed, value here
|
|
// doesn't resolve to anything during partial analysis, and the outer
|
|
// value does not know it can be shadowed.
|
|
return value;
|
|
}
|
|
}
|
|
var value = 2;
|
|
var status = f();
|
|
return value;
|
|
}
|
|
test();
|