• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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