Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_CCTEST_SCOPE_TEST_HELPER_H_
6 : #define V8_CCTEST_SCOPE_TEST_HELPER_H_
7 :
8 : #include "src/ast/scopes.h"
9 : #include "src/ast/variables.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 :
14 : class ScopeTestHelper {
15 : public:
16 2050 : static bool MustAllocateInContext(Variable* var) {
17 2050 : return var->scope()->MustAllocateInContext(var);
18 : }
19 :
20 140120 : static void CompareScopes(Scope* baseline, Scope* scope,
21 : bool precise_maybe_assigned) {
22 65590 : CHECK_EQ(baseline->scope_type(), scope->scope_type());
23 65590 : CHECK_IMPLIES(baseline->is_declaration_scope(),
24 : baseline->AsDeclarationScope()->function_kind() ==
25 : scope->AsDeclarationScope()->function_kind());
26 :
27 65590 : if (!PreparseDataBuilder::ScopeNeedsData(baseline)) {
28 : return;
29 : }
30 :
31 115260 : if (scope->is_declaration_scope() &&
32 51435 : scope->AsDeclarationScope()->is_skipped_function()) {
33 : return;
34 : }
35 :
36 37265 : if (baseline->scope_type() == ScopeType::FUNCTION_SCOPE) {
37 23310 : Variable* function = baseline->AsDeclarationScope()->function_var();
38 23310 : if (function != nullptr) {
39 : CompareVariables(function, scope->AsDeclarationScope()->function_var(),
40 160 : precise_maybe_assigned);
41 : } else {
42 23150 : CHECK_NULL(scope->AsDeclarationScope()->function_var());
43 : }
44 : }
45 :
46 187665 : for (auto baseline_local = baseline->locals()->begin(),
47 : scope_local = scope->locals()->begin();
48 150400 : baseline_local != baseline->locals()->end();
49 : ++baseline_local, ++scope_local) {
50 276730 : if (scope_local->mode() == VariableMode::kVar ||
51 144320 : scope_local->mode() == VariableMode::kLet ||
52 : scope_local->mode() == VariableMode::kConst) {
53 106295 : CompareVariables(*baseline_local, *scope_local, precise_maybe_assigned);
54 : }
55 : }
56 :
57 85510 : for (Scope *baseline_inner = baseline->inner_scope(),
58 48245 : *scope_inner = scope->inner_scope();
59 : scope_inner != nullptr; scope_inner = scope_inner->sibling(),
60 : baseline_inner = baseline_inner->sibling()) {
61 48245 : CompareScopes(baseline_inner, scope_inner, precise_maybe_assigned);
62 : }
63 : }
64 :
65 425820 : static void CompareVariables(Variable* baseline_local, Variable* scope_local,
66 : bool precise_maybe_assigned) {
67 : // Sanity check the variable name. If this fails, the variable order
68 : // is not deterministic.
69 106455 : CHECK_EQ(scope_local->raw_name()->length(),
70 : baseline_local->raw_name()->length());
71 1580705 : for (int i = 0; i < scope_local->raw_name()->length(); ++i) {
72 1474250 : CHECK_EQ(scope_local->raw_name()->raw_data()[i],
73 : baseline_local->raw_name()->raw_data()[i]);
74 : }
75 :
76 106455 : CHECK_EQ(scope_local->location(), baseline_local->location());
77 106455 : if (precise_maybe_assigned) {
78 103285 : CHECK_EQ(scope_local->maybe_assigned(), baseline_local->maybe_assigned());
79 : } else {
80 : STATIC_ASSERT(kMaybeAssigned > kNotAssigned);
81 3170 : CHECK_GE(scope_local->maybe_assigned(), baseline_local->maybe_assigned());
82 : }
83 106455 : }
84 :
85 : // Finds a scope given a start point and directions to it (which inner scope
86 : // to pick).
87 29340 : static Scope* FindScope(Scope* scope, const std::vector<unsigned>& location) {
88 44340 : for (auto n : location) {
89 : scope = scope->inner_scope();
90 14340 : CHECK_NOT_NULL(scope);
91 14340 : while (n-- > 0) {
92 : scope = scope->sibling();
93 0 : CHECK_NOT_NULL(scope);
94 : }
95 : }
96 15000 : return scope;
97 : }
98 :
99 : static void MarkInnerFunctionsAsSkipped(Scope* scope) {
100 : for (Scope* inner = scope->inner_scope(); inner != nullptr;
101 : inner = inner->sibling()) {
102 : if (inner->scope_type() == ScopeType::FUNCTION_SCOPE &&
103 : !inner->AsDeclarationScope()->is_arrow_scope()) {
104 : inner->AsDeclarationScope()->set_is_skipped_function(true);
105 : }
106 : MarkInnerFunctionsAsSkipped(inner);
107 : }
108 : }
109 :
110 186455 : static bool HasSkippedFunctionInside(Scope* scope) {
111 188220 : if (scope->scope_type() == ScopeType::FUNCTION_SCOPE &&
112 86320 : scope->AsDeclarationScope()->is_skipped_function()) {
113 : return true;
114 : }
115 132965 : for (Scope* inner = scope->inner_scope(); inner != nullptr;
116 : inner = inner->sibling()) {
117 67210 : if (HasSkippedFunctionInside(inner)) {
118 : return true;
119 : }
120 : }
121 : return false;
122 : }
123 : };
124 : } // namespace internal
125 : } // namespace v8
126 :
127 : #endif // V8_CCTEST_SCOPE_TEST_HELPER_H_
|