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 : static bool MustAllocateInContext(Variable* var) {
17 2050 : return var->scope()->MustAllocateInContext(var);
18 : }
19 :
20 65590 : 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)) return;
28 :
29 115260 : if (scope->is_declaration_scope() &&
30 51435 : scope->AsDeclarationScope()->is_skipped_function()) {
31 : return;
32 : }
33 :
34 37265 : if (baseline->is_function_scope()) {
35 23310 : Variable* function = baseline->AsDeclarationScope()->function_var();
36 23310 : if (function != nullptr) {
37 160 : CompareVariables(function, scope->AsDeclarationScope()->function_var(),
38 160 : precise_maybe_assigned);
39 : } else {
40 23150 : CHECK_NULL(scope->AsDeclarationScope()->function_var());
41 : }
42 : }
43 :
44 132780 : for (auto baseline_local = baseline->locals()->begin(),
45 : scope_local = scope->locals()->begin();
46 : baseline_local != baseline->locals()->end();
47 : ++baseline_local, ++scope_local) {
48 145975 : if (scope_local->mode() == VariableMode::kVar ||
49 126700 : scope_local->mode() == VariableMode::kLet ||
50 : scope_local->mode() == VariableMode::kConst) {
51 88675 : CompareVariables(*baseline_local, *scope_local, precise_maybe_assigned);
52 : }
53 : }
54 :
55 48245 : for (Scope *baseline_inner = baseline->inner_scope(),
56 : *scope_inner = scope->inner_scope();
57 85510 : scope_inner != nullptr; scope_inner = scope_inner->sibling(),
58 : baseline_inner = baseline_inner->sibling()) {
59 48245 : CompareScopes(baseline_inner, scope_inner, precise_maybe_assigned);
60 : }
61 : }
62 :
63 88835 : static void CompareVariables(Variable* baseline_local, Variable* scope_local,
64 : bool precise_maybe_assigned) {
65 : // Sanity check the variable name. If this fails, the variable order
66 : // is not deterministic.
67 88835 : CHECK_EQ(scope_local->raw_name()->length(),
68 : baseline_local->raw_name()->length());
69 1422125 : for (int i = 0; i < scope_local->raw_name()->length(); ++i) {
70 666645 : CHECK_EQ(scope_local->raw_name()->raw_data()[i],
71 : baseline_local->raw_name()->raw_data()[i]);
72 : }
73 :
74 88835 : CHECK_EQ(scope_local->location(), baseline_local->location());
75 88835 : if (precise_maybe_assigned) {
76 86145 : CHECK_EQ(scope_local->maybe_assigned(), baseline_local->maybe_assigned());
77 : } else {
78 : STATIC_ASSERT(kMaybeAssigned > kNotAssigned);
79 2690 : CHECK_GE(scope_local->maybe_assigned(), baseline_local->maybe_assigned());
80 : }
81 88835 : }
82 :
83 : // Finds a scope given a start point and directions to it (which inner scope
84 : // to pick).
85 15000 : static Scope* FindScope(Scope* scope, const std::vector<unsigned>& location) {
86 29340 : for (auto n : location) {
87 : scope = scope->inner_scope();
88 14340 : CHECK_NOT_NULL(scope);
89 14340 : while (n-- > 0) {
90 : scope = scope->sibling();
91 0 : CHECK_NOT_NULL(scope);
92 : }
93 : }
94 15000 : return scope;
95 : }
96 :
97 : static void MarkInnerFunctionsAsSkipped(Scope* scope) {
98 : for (Scope* inner = scope->inner_scope(); inner != nullptr;
99 : inner = inner->sibling()) {
100 : if (inner->is_function_scope() &&
101 : !inner->AsDeclarationScope()->is_arrow_scope()) {
102 : inner->AsDeclarationScope()->set_is_skipped_function(true);
103 : }
104 : MarkInnerFunctionsAsSkipped(inner);
105 : }
106 : }
107 :
108 101900 : static bool HasSkippedFunctionInside(Scope* scope) {
109 188220 : if (scope->is_function_scope() &&
110 86320 : scope->AsDeclarationScope()->is_skipped_function()) {
111 : return true;
112 : }
113 181375 : for (Scope* inner = scope->inner_scope(); inner != nullptr;
114 : inner = inner->sibling()) {
115 67210 : if (HasSkippedFunctionInside(inner)) return true;
116 : }
117 : return false;
118 : }
119 : };
120 : } // namespace internal
121 : } // namespace v8
122 :
123 : #endif // V8_CCTEST_SCOPE_TEST_HELPER_H_
|