5 #ifndef V8_PROTOTYPE_INL_H_ 6 #define V8_PROTOTYPE_INL_H_ 8 #include "src/prototype.h" 10 #include "src/handles-inl.h" 11 #include "src/objects/map-inl.h" 16 PrototypeIterator::PrototypeIterator(Isolate* isolate,
17 Handle<JSReceiver> receiver,
18 WhereToStart where_to_start,
19 WhereToEnd where_to_end)
23 where_to_end_(where_to_end),
26 CHECK(!handle_.is_null());
27 if (where_to_start == kStartAtPrototype) Advance();
30 PrototypeIterator::PrototypeIterator(Isolate* isolate, JSReceiver* receiver,
31 WhereToStart where_to_start,
32 WhereToEnd where_to_end)
35 where_to_end_(where_to_end),
38 if (where_to_start == kStartAtPrototype) Advance();
41 PrototypeIterator::PrototypeIterator(Isolate* isolate, Map receiver_map,
42 WhereToEnd where_to_end)
44 object_(receiver_map->GetPrototypeChainRootMap(isolate_)->prototype()),
45 where_to_end_(where_to_end),
46 is_at_end_(object_->IsNull(isolate_)),
48 if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
49 DCHECK(object_->IsJSReceiver());
50 Map map = JSReceiver::cast(object_)->map();
51 is_at_end_ = !map->has_hidden_prototype();
55 PrototypeIterator::PrototypeIterator(Isolate* isolate, Handle<Map> receiver_map,
56 WhereToEnd where_to_end)
59 handle_(receiver_map->GetPrototypeChainRootMap(isolate_)->prototype(),
61 where_to_end_(where_to_end),
62 is_at_end_(handle_->IsNull(isolate_)),
64 if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
65 DCHECK(handle_->IsJSReceiver());
66 Map map = JSReceiver::cast(*handle_)->map();
67 is_at_end_ = !map->has_hidden_prototype();
71 bool PrototypeIterator::HasAccess()
const {
74 DCHECK(!handle_.is_null());
75 if (handle_->IsAccessCheckNeeded()) {
76 return isolate_->MayAccess(handle(isolate_->context(), isolate_),
77 Handle<JSObject>::cast(handle_));
82 void PrototypeIterator::Advance() {
83 if (handle_.is_null() && object_->IsJSProxy()) {
85 object_ = ReadOnlyRoots(isolate_).null_value();
87 }
else if (!handle_.is_null() && handle_->IsJSProxy()) {
89 handle_ = isolate_->factory()->null_value();
92 AdvanceIgnoringProxies();
95 void PrototypeIterator::AdvanceIgnoringProxies() {
96 Object*
object = handle_.is_null() ? object_ : *handle_;
97 Map map = HeapObject::cast(
object)->map();
99 Object* prototype = map->prototype();
100 is_at_end_ = where_to_end_ == END_AT_NON_HIDDEN ? !map->has_hidden_prototype()
101 : prototype->IsNull(isolate_);
103 if (handle_.is_null()) {
106 handle_ = handle(prototype, isolate_);
110 V8_WARN_UNUSED_RESULT
bool PrototypeIterator::AdvanceFollowingProxies() {
111 DCHECK(!(handle_.is_null() && object_->IsJSProxy()));
114 handle_ = isolate_->factory()->null_value();
118 return AdvanceFollowingProxiesIgnoringAccessChecks();
121 V8_WARN_UNUSED_RESULT
bool 122 PrototypeIterator::AdvanceFollowingProxiesIgnoringAccessChecks() {
123 if (handle_.is_null() || !handle_->IsJSProxy()) {
124 AdvanceIgnoringProxies();
131 if (seen_proxies_ > JSProxy::kMaxIterationLimit) {
132 isolate_->StackOverflow();
135 MaybeHandle<Object> proto =
136 JSProxy::GetPrototype(Handle<JSProxy>::cast(handle_));
137 if (!proto.ToHandle(&handle_))
return false;
138 is_at_end_ = where_to_end_ == END_AT_NON_HIDDEN || handle_->IsNull(isolate_);
145 #endif // V8_PROTOTYPE_INL_H_