v8/test/cctest/scope-test-helper.h
Marja Hölttä 14ac291a03 [parser] Skipping inner funcs: simplify rest parameter handling.
With the params (a, b, ...c) the param / variable declaration order used to be
"temp, temp, c, a, b". Now it is "temp, temp, a, b, c" as you'd expect. This
makes it easier for PreParser to match the parameter order of Parser.

R=verwaest@chromium.org
BUG=v8:5516

Change-Id: I79da04ef3f812bf52c032bed6263c009fecb7988
Reviewed-on: https://chromium-review.googlesource.com/447677
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43490}
2017-02-28 15:08:31 +00:00

96 lines
3.2 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);
}
static void CompareScopeToData(Scope* scope, const PreParsedScopeData* data,
size_t& index, bool precise_maybe_assigned) {
CHECK(PreParsedScopeData::HasVariablesWhichNeedAllocationData(scope));
CHECK_GT(data->backing_store_.size(), index + 4);
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()) {
if (PreParsedScopeData::HasVariablesWhichNeedAllocationData(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
// Allow PreParser to not distinguish between parameter / local; that
// information is not relevant for deciding the allocation (potentially
// skipped inner functions don't affect it).
int location = data->backing_store_[index++];
switch (local->location()) {
case PARAMETER:
case LOCAL:
CHECK(location == PARAMETER || location == LOCAL);
break;
case CONTEXT:
case UNALLOCATED:
CHECK_EQ(location, local->location());
break;
default:
CHECK(false);
}
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 (PreParsedScopeData::HasVariablesWhichNeedAllocationData(inner)) {
CompareScopeToData(inner, data, index, precise_maybe_assigned);
}
}
}
};
} // namespace internal
} // namespace v8
#endif // V8_CCTEST_SCOPE_TEST_HELPER_H_