5f9c89af70
Reason for revert: False alarm, bot hiccup Original issue's description: > Revert of [parsing] Fix maybe-assigned for loop variables. (patchset #3 id:40001 of https://codereview.chromium.org/2673403003/ ) > > Reason for revert: > Speculative revert because of https://codereview.chromium.org/2679163002/. > > Original issue's description: > > [parsing] Fix maybe-assigned for loop variables. > > > > Due to hoisting, the value of a 'var'-declared variable may actually change even > > if the code contains only the "initial" assignment, namely when that assignment > > occurs inside a loop. For example: > > > > let i = 10; > > do { var x = i } while (i--): > > > > As a simple and very conservative approximation of this, we explicitly mark > > as maybe-assigned any non-lexical variable whose "declaration" does not > > syntactically occur in the function scope. (In the example above, it > > occurs in a block scope.) > > > > BUG=v8:5636 > > > > Review-Url: https://codereview.chromium.org/2673403003 > > Cr-Commit-Position: refs/heads/master@{#42989} > > Committed:a33fcd663b
> > TBR=marja@chromium.org,adamk@chromium.org,neis@chromium.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=v8:5636 > > Review-Url: https://codereview.chromium.org/2679263002 > Cr-Commit-Position: refs/heads/master@{#43010} > Committed:f3ae5ccf57
TBR=marja@chromium.org,adamk@chromium.org,neis@chromium.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=v8:5636 Review-Url: https://codereview.chromium.org/2686663002 Cr-Commit-Position: refs/heads/master@{#43013}
94 lines
3.0 KiB
C++
94 lines
3.0 KiB
C++
// Copyright 2017 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.
|
|
|
|
#ifndef V8_CCTEST_SCOPE_TEST_HELPER_H_
|
|
#define V8_CCTEST_SCOPE_TEST_HELPER_H_
|
|
|
|
#include "src/ast/scopes.h"
|
|
#include "src/ast/variables.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
class ScopeTestHelper {
|
|
public:
|
|
static bool MustAllocateInContext(Variable* var) {
|
|
return var->scope()->MustAllocateInContext(var);
|
|
}
|
|
|
|
// True if the scope is and its entire subscope tree are hidden.
|
|
static bool ScopeTreeIsHidden(Scope* scope) {
|
|
if (!scope->is_hidden()) {
|
|
return false;
|
|
}
|
|
for (Scope* inner = scope->inner_scope(); inner != nullptr;
|
|
inner = inner->sibling()) {
|
|
if (!ScopeTreeIsHidden(inner)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void CompareScopeToData(Scope* scope, const PreParsedScopeData* data,
|
|
size_t& index, bool precise_maybe_assigned) {
|
|
CHECK_EQ(data->backing_store_[index++], scope->scope_type());
|
|
CHECK_EQ(data->backing_store_[index++], scope->start_position());
|
|
CHECK_EQ(data->backing_store_[index++], scope->end_position());
|
|
|
|
int inner_scope_count = 0;
|
|
for (Scope* inner = scope->inner_scope(); inner != nullptr;
|
|
inner = inner->sibling()) {
|
|
// FIXME(marja): This is probably not the right condition for knowing what
|
|
// scopes are present in the preparse data.
|
|
if (!ScopeTreeIsHidden(inner)) {
|
|
++inner_scope_count;
|
|
}
|
|
}
|
|
CHECK_EQ(data->backing_store_[index++], inner_scope_count);
|
|
|
|
int variable_count = 0;
|
|
for (Variable* local : scope->locals_) {
|
|
if (local->mode() == VAR || local->mode() == LET ||
|
|
local->mode() == CONST) {
|
|
++variable_count;
|
|
}
|
|
}
|
|
|
|
CHECK_EQ(data->backing_store_[index++], variable_count);
|
|
|
|
for (Variable* local : scope->locals_) {
|
|
if (local->mode() == VAR || local->mode() == LET ||
|
|
local->mode() == CONST) {
|
|
#ifdef DEBUG
|
|
const AstRawString* local_name = local->raw_name();
|
|
int name_length = data->backing_store_[index++];
|
|
CHECK_EQ(name_length, local_name->length());
|
|
for (int i = 0; i < name_length; ++i) {
|
|
CHECK_EQ(data->backing_store_[index++], local_name->raw_data()[i]);
|
|
}
|
|
#endif
|
|
CHECK_EQ(data->backing_store_[index++], local->location());
|
|
if (precise_maybe_assigned) {
|
|
CHECK_EQ(data->backing_store_[index++], local->maybe_assigned());
|
|
} else {
|
|
STATIC_ASSERT(kMaybeAssigned > kNotAssigned);
|
|
CHECK_GE(data->backing_store_[index++], local->maybe_assigned());
|
|
}
|
|
}
|
|
}
|
|
|
|
for (Scope* inner = scope->inner_scope(); inner != nullptr;
|
|
inner = inner->sibling()) {
|
|
if (!ScopeTreeIsHidden(inner)) {
|
|
CompareScopeToData(inner, data, index, precise_maybe_assigned);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
} // namespace internal
|
|
} // namespace v8
|
|
|
|
#endif // V8_CCTEST_SCOPE_TEST_HELPER_H_
|