Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: src/lookup.cc

Issue 314953006: Implement LookupIterator designed to replace LookupResult (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Adding to BUILD.gn Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 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 #include "src/v8.h"
6
7 #include "src/bootstrapper.h"
8 #include "src/lookup.h"
9
10 namespace v8 {
11 namespace internal {
12
13
14 void LookupIterator::Next() {
15 has_property_ = false;
16 do {
17 LookupInHolder();
18 } while (!IsFound() && NextHolder());
19 }
20
21
22 Handle<JSReceiver> LookupIterator::GetOrigin() const {
23 Handle<Object> receiver = GetReceiver();
24 if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver);
25 Context* native_context = isolate_->context()->native_context();
26 JSFunction* function;
27 if (receiver->IsNumber()) {
28 function = native_context->number_function();
29 } else if (receiver->IsString()) {
30 function = native_context->string_function();
31 } else if (receiver->IsSymbol()) {
32 function = native_context->symbol_function();
33 } else if (receiver->IsBoolean()) {
34 function = native_context->boolean_function();
35 } else {
36 UNREACHABLE();
37 function = NULL;
38 }
39 return handle(JSReceiver::cast(function->instance_prototype()));
40 }
41
42
43 Handle<Map> LookupIterator::GetReceiverMap() const {
44 Handle<Object> receiver = GetReceiver();
45 if (receiver->IsNumber()) return isolate_->factory()->heap_number_map();
46 return handle(Handle<HeapObject>::cast(receiver)->map());
47 }
48
49
50 bool LookupIterator::NextHolder() {
51 if (holder_map_->prototype()->IsNull()) return false;
52
53 Handle<JSReceiver> next(JSReceiver::cast(holder_map_->prototype()));
54
55 if (!check_derived() &&
56 // TODO(verwaest): Check if this is actually necessary currently. If it
57 // is, this should be handled by setting is_hidden_prototype on the
58 // global object behind the proxy.
59 !holder_map_->IsJSGlobalProxyMap() &&
60 !next->map()->is_hidden_prototype()) {
61 return false;
62 }
63
64 holder_map_ = handle(next->map());
65 maybe_holder_ = next;
66 return true;
67 }
68
69
70 void LookupIterator::LookupInHolder() {
71 State old_state = state_;
72 state_ = NOT_FOUND;
rossberg 2014/06/11 15:37:00 Might be clearer to not pre-default this. There ar
Toon Verwaest 2014/06/11 17:32:18 Done.
73 switch (old_state) {
74 case NOT_FOUND:
75 if (holder_map_->IsJSProxyMap()) {
76 state_ = JSPROXY;
77 return;
78 }
79 if (check_access_check() && holder_map_->is_access_check_needed()) {
80 state_ = ACCESS_CHECK;
81 return;
82 }
rossberg 2014/06/11 15:37:00 Put a fall-through comment here and below.
Toon Verwaest 2014/06/11 17:32:18 Done.
83 case ACCESS_CHECK:
84 if (check_interceptor() && holder_map_->has_named_interceptor()) {
85 state_ = INTERCEPTOR;
86 return;
87 }
88 case INTERCEPTOR:
89 if (holder_map_->is_dictionary_map()) {
90 property_encoding_ = DICTIONARY;
91 } else {
92 DescriptorArray* descriptors = holder_map_->instance_descriptors();
93 number_ = descriptors->SearchWithCache(*name_, *holder_map_);
94 if (number_ == DescriptorArray::kNotFound) return;
95 property_encoding_ = DESCRIPTOR;
96 }
97 state_ = PROPERTY;
98 case PROPERTY:
99 return;
100 case JSPROXY:
101 UNREACHABLE();
102 }
103 }
104
105
106 bool LookupIterator::IsBootstrapping() const {
107 return isolate_->bootstrapper()->IsActive();
108 }
109
110
111 bool LookupIterator::HasAccess(v8::AccessType access_type) const {
112 ASSERT_EQ(ACCESS_CHECK, state_);
113 ASSERT(is_guaranteed_to_have_holder());
114 return isolate_->MayNamedAccess(GetHolder(), name_, access_type);
115 }
116
117
118 bool LookupIterator::HasProperty() {
119 ASSERT_EQ(PROPERTY, state_);
120 ASSERT(is_guaranteed_to_have_holder());
121
122 if (property_encoding_ == DICTIONARY) {
123 Handle<JSObject> holder = GetHolder();
124 number_ = holder->property_dictionary()->FindEntry(name_);
125 if (number_ == NameDictionary::kNotFound) return false;
126
127 property_details_ = GetHolder()->property_dictionary()->DetailsAt(number_);
128 // Holes in dictionary cells are absent values unless marked as read-only.
129 if (holder->IsGlobalObject() &&
130 (property_details_.IsDeleted() ||
131 (!property_details_.IsReadOnly() && FetchValue()->IsTheHole()))) {
132 return false;
133 }
134 } else {
135 property_details_ = holder_map_->instance_descriptors()->GetDetails(
136 number_);
137 }
138
139 switch (property_details_.type()) {
140 case v8::internal::FIELD:
141 case v8::internal::NORMAL:
142 case v8::internal::CONSTANT:
143 property_type_ = DATA;
144 break;
145 case v8::internal::CALLBACKS:
146 property_type_ = ACCESSORS;
147 break;
148 case v8::internal::HANDLER:
149 case v8::internal::NONEXISTENT:
150 case v8::internal::INTERCEPTOR:
151 UNREACHABLE();
152 }
153
154 has_property_ = true;
155 return true;
156 }
157
158
159 Handle<Object> LookupIterator::FetchValue() const {
160 Object* result = NULL;
161 switch (property_encoding_) {
162 case DICTIONARY:
163 result = GetHolder()->property_dictionary()->ValueAt(number_);
164 if (GetHolder()->IsGlobalObject()) {
165 result = PropertyCell::cast(result)->value();
166 }
167 break;
168 case DESCRIPTOR:
169 if (property_details_.type() == v8::internal::FIELD) {
170 FieldIndex field_index = FieldIndex::ForDescriptor(
171 *holder_map_, number_);
172 return JSObject::FastPropertyAt(
173 GetHolder(), property_details_.representation(), field_index);
174 }
175 result = holder_map_->instance_descriptors()->GetValue(number_);
176 }
177 return handle(result, isolate_);
178 }
179
180
181 Handle<Object> LookupIterator::GetAccessors() const {
182 ASSERT(has_property_);
183 ASSERT_EQ(ACCESSORS, property_type_);
184 return FetchValue();
185 }
186
187
188 Handle<Object> LookupIterator::GetDataValue() const {
189 ASSERT(has_property_);
190 ASSERT_EQ(DATA, property_type_);
191 Handle<Object> value = FetchValue();
192 if (value->IsTheHole()) {
193 ASSERT_EQ(DICTIONARY, property_encoding_);
194 ASSERT(GetHolder()->IsGlobalObject());
195 ASSERT(property_details_.IsReadOnly());
196 return factory()->undefined_value();
197 }
198 return value;
199 }
200
201
202 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698