blob: 35dbe1f2c658b59edfdd5cc9ec459ebdccf5a777 [file] [log] [blame]
// Copyright 2020 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_OBJECTS_SCOPE_INFO_INL_H_
#define V8_OBJECTS_SCOPE_INFO_INL_H_
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/fixed-array-inl.h"
#include "src/objects/scope-info.h"
#include "src/objects/string.h"
#include "src/roots/roots-inl.h"
#include "src/torque/runtime-macro-shims.h"
#include "src/torque/runtime-support.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
#include "torque-generated/src/objects/scope-info-tq-inl.inc"
TQ_OBJECT_CONSTRUCTORS_IMPL(ScopeInfo)
bool ScopeInfo::IsAsmModule() const { return IsAsmModuleBit::decode(Flags()); }
bool ScopeInfo::HasSimpleParameters() const {
return HasSimpleParametersBit::decode(Flags());
}
int ScopeInfo::Flags() const { return flags(); }
int ScopeInfo::ParameterCount() const { return parameter_count(); }
int ScopeInfo::ContextLocalCount() const { return context_local_count(); }
ObjectSlot ScopeInfo::data_start() { return RawField(OffsetOfElementAt(0)); }
bool ScopeInfo::HasInlinedLocalNames() const {
return ContextLocalCount() < kScopeInfoMaxInlinedLocalNamesSize;
}
template <typename ScopeInfoPtr>
class ScopeInfo::LocalNamesRange {
public:
class Iterator {
public:
Iterator(const LocalNamesRange* range, InternalIndex index)
: range_(range), index_(index) {
DCHECK_NOT_NULL(range);
if (!range_->inlined()) advance_hashtable_index();
}
Iterator& operator++() {
DCHECK_LT(index_, range_->max_index());
++index_;
if (range_->inlined()) return *this;
advance_hashtable_index();
return *this;
}
friend bool operator==(const Iterator& a, const Iterator& b) {
return a.range_ == b.range_ && a.index_ == b.index_;
}
friend bool operator!=(const Iterator& a, const Iterator& b) {
return !(a == b);
}
Tagged<String> name(PtrComprCageBase cage_base) const {
DCHECK_LT(index_, range_->max_index());
if (range_->inlined()) {
return scope_info()->ContextInlinedLocalName(cage_base,
index_.as_int());
}
return String::cast(table()->KeyAt(cage_base, index_));
}
Tagged<String> name() const {
PtrComprCageBase cage_base = GetPtrComprCageBase(*scope_info());
return name(cage_base);
}
const Iterator* operator*() const { return this; }
int index() const {
if (range_->inlined()) return index_.as_int();
return table()->IndexAt(index_);
}
private:
const LocalNamesRange* range_;
InternalIndex index_;
ScopeInfoPtr scope_info() const { return range_->scope_info_; }
Tagged<NameToIndexHashTable> table() const {
return scope_info()->context_local_names_hashtable();
}
void advance_hashtable_index() {
DisallowGarbageCollection no_gc;
ReadOnlyRoots roots = scope_info()->GetReadOnlyRoots();
InternalIndex max = range_->max_index();
// Increment until iterator points to a valid key or max.
while (index_ < max) {
Tagged<Object> key = table()->KeyAt(index_);
if (table()->IsKey(roots, key)) break;
++index_;
}
}
friend class LocalNamesRange;
};
bool inlined() const { return scope_info_->HasInlinedLocalNames(); }
InternalIndex max_index() const {
int max = inlined()
? scope_info_->ContextLocalCount()
: scope_info_->context_local_names_hashtable()->Capacity();
return InternalIndex(max);
}
explicit LocalNamesRange(ScopeInfoPtr scope_info) : scope_info_(scope_info) {}
inline Iterator begin() const { return Iterator(this, InternalIndex(0)); }
inline Iterator end() const { return Iterator(this, max_index()); }
private:
ScopeInfoPtr scope_info_;
};
// static
ScopeInfo::LocalNamesRange<Handle<ScopeInfo>> ScopeInfo::IterateLocalNames(
Handle<ScopeInfo> scope_info) {
return LocalNamesRange<Handle<ScopeInfo>>(scope_info);
}
// static
ScopeInfo::LocalNamesRange<Tagged<ScopeInfo>> ScopeInfo::IterateLocalNames(
Tagged<ScopeInfo> scope_info, const DisallowGarbageCollection& no_gc) {
USE(no_gc);
return LocalNamesRange<Tagged<ScopeInfo>>(scope_info);
}
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_SCOPE_INFO_INL_H_