v8/test/cctest/scope-test-helper.h
hablich f3ae5ccf57 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}
2017-02-07 19:40:24 +00:00

89 lines
2.7 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) {
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());
CHECK_EQ(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);
}
}
}
};
} // namespace internal
} // namespace v8
#endif // V8_CCTEST_SCOPE_TEST_HELPER_H_