1 // Copyright 2020 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_OBJECTS_SCOPE_INFO_INL_H_
6 #define V8_OBJECTS_SCOPE_INFO_INL_H_
7
8 #include "src/heap/heap-write-barrier-inl.h"
9 #include "src/objects/fixed-array-inl.h"
10 #include "src/objects/scope-info.h"
11 #include "src/objects/string.h"
12 #include "src/roots/roots-inl.h"
13
14 // Has to be the last include (doesn't have include guards):
15 #include "src/objects/object-macros.h"
16
17 namespace v8 {
18 namespace internal {
19
20 #include "torque-generated/src/objects/scope-info-tq-inl.inc"
21
TQ_OBJECT_CONSTRUCTORS_IMPL(ScopeInfo)22 TQ_OBJECT_CONSTRUCTORS_IMPL(ScopeInfo)
23
24 bool ScopeInfo::IsAsmModule() const { return IsAsmModuleBit::decode(Flags()); }
25
HasSimpleParameters()26 bool ScopeInfo::HasSimpleParameters() const {
27 return HasSimpleParametersBit::decode(Flags());
28 }
29
Flags()30 int ScopeInfo::Flags() const { return flags(); }
ParameterCount()31 int ScopeInfo::ParameterCount() const { return parameter_count(); }
ContextLocalCount()32 int ScopeInfo::ContextLocalCount() const { return context_local_count(); }
33
data_start()34 ObjectSlot ScopeInfo::data_start() { return RawField(OffsetOfElementAt(0)); }
35
HasInlinedLocalNames()36 bool ScopeInfo::HasInlinedLocalNames() const {
37 return ContextLocalCount() < kScopeInfoMaxInlinedLocalNamesSize;
38 }
39
40 template <typename ScopeInfoPtr>
41 class ScopeInfo::LocalNamesRange {
42 public:
43 class Iterator {
44 public:
Iterator(const LocalNamesRange * range,InternalIndex index)45 Iterator(const LocalNamesRange* range, InternalIndex index)
46 : range_(range), index_(index) {
47 DCHECK_NOT_NULL(range);
48 if (!range_->inlined()) advance_hashtable_index();
49 }
50
51 Iterator& operator++() {
52 DCHECK_LT(index_, range_->max_index());
53 ++index_;
54 if (range_->inlined()) return *this;
55 advance_hashtable_index();
56 return *this;
57 }
58
59 friend bool operator==(const Iterator& a, const Iterator& b) {
60 return a.range_ == b.range_ && a.index_ == b.index_;
61 }
62
63 friend bool operator!=(const Iterator& a, const Iterator& b) {
64 return !(a == b);
65 }
66
name(PtrComprCageBase cage_base)67 String name(PtrComprCageBase cage_base) const {
68 DCHECK_LT(index_, range_->max_index());
69 if (range_->inlined()) {
70 return scope_info()->ContextInlinedLocalName(cage_base,
71 index_.as_int());
72 }
73 return String::cast(table().KeyAt(cage_base, index_));
74 }
75
name()76 String name() const {
77 PtrComprCageBase cage_base = GetPtrComprCageBase(*scope_info());
78 return name(cage_base);
79 }
80
81 const Iterator* operator*() const { return this; }
82
index()83 int index() const {
84 if (range_->inlined()) return index_.as_int();
85 return table().IndexAt(index_);
86 }
87
88 private:
89 const LocalNamesRange* range_;
90 InternalIndex index_;
91
scope_info()92 ScopeInfoPtr scope_info() const { return range_->scope_info_; }
93
table()94 NameToIndexHashTable table() const {
95 return scope_info()->context_local_names_hashtable();
96 }
97
advance_hashtable_index()98 void advance_hashtable_index() {
99 DisallowGarbageCollection no_gc;
100 ReadOnlyRoots roots = scope_info()->GetReadOnlyRoots();
101 InternalIndex max = range_->max_index();
102 // Increment until iterator points to a valid key or max.
103 while (index_ < max) {
104 Object key = table().KeyAt(index_);
105 if (table().IsKey(roots, key)) break;
106 ++index_;
107 }
108 }
109
110 friend class LocalNamesRange;
111 };
112
inlined()113 bool inlined() const { return scope_info_->HasInlinedLocalNames(); }
114
max_index()115 InternalIndex max_index() const {
116 int max = inlined()
117 ? scope_info_->ContextLocalCount()
118 : scope_info_->context_local_names_hashtable().Capacity();
119 return InternalIndex(max);
120 }
121
LocalNamesRange(ScopeInfoPtr scope_info)122 explicit LocalNamesRange(ScopeInfoPtr scope_info) : scope_info_(scope_info) {}
123
begin()124 inline Iterator begin() const { return Iterator(this, InternalIndex(0)); }
125
end()126 inline Iterator end() const { return Iterator(this, max_index()); }
127
128 private:
129 ScopeInfoPtr scope_info_;
130 };
131
132 // static
IterateLocalNames(Handle<ScopeInfo> scope_info)133 ScopeInfo::LocalNamesRange<Handle<ScopeInfo>> ScopeInfo::IterateLocalNames(
134 Handle<ScopeInfo> scope_info) {
135 return LocalNamesRange<Handle<ScopeInfo>>(scope_info);
136 }
137
138 // static
IterateLocalNames(ScopeInfo * scope_info,const DisallowGarbageCollection & no_gc)139 ScopeInfo::LocalNamesRange<ScopeInfo*> ScopeInfo::IterateLocalNames(
140 ScopeInfo* scope_info, const DisallowGarbageCollection& no_gc) {
141 USE(no_gc);
142 return LocalNamesRange<ScopeInfo*>(scope_info);
143 }
144
145 } // namespace internal
146 } // namespace v8
147
148 #include "src/objects/object-macros-undef.h"
149
150 #endif // V8_OBJECTS_SCOPE_INFO_INL_H_
151