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

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: 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
« no previous file with comments | « src/lookup.h ('k') | src/mips/stub-cache-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 void LookupIterator::Next() {
14 ASSERT(IsFound());
15
16 State old_state = state_;
17 state_ = NOT_FOUND;
18 has_property_ = false;
19
20 if (old_state == ACCESS_CHECK) {
21 if (holder_map_->has_named_interceptor()) {
Igor Sheludko 2014/06/10 16:15:07 I think "check_interceptor() && " is missing here.
Toon Verwaest 2014/06/10 18:59:29 Done.
22 state_ = INTERCEPTOR;
23 } else {
24 LookupOwnRealNamedProperty();
25 }
26 if (IsFound()) return;
27 } else if (old_state == INTERCEPTOR) {
28 LookupOwnRealNamedProperty();
29 if (IsFound()) return;
30 }
31
32 // The prototype chain beyond a JSProxy has no meaning for lookup.
33 // Its trap should be used instead.
34 ASSERT(!holder_map_->IsJSProxyMap());
35
36 if (NextHolder()) ContinueLookup();
37 }
38
39
40 Handle<JSReceiver> LookupIterator::GetOrigin() const {
41 Handle<Object> receiver = GetReceiver();
42 if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver);
43 Context* native_context = isolate_->context()->native_context();
44 JSFunction* function;
45 if (receiver->IsNumber()) {
46 function = native_context->number_function();
47 } else if (receiver->IsString()) {
48 function = native_context->string_function();
49 } else if (receiver->IsSymbol()) {
50 function = native_context->symbol_function();
51 } else if (receiver->IsBoolean()) {
52 function = native_context->boolean_function();
53 } else {
54 UNREACHABLE();
55 function = NULL;
56 }
57 return handle(JSReceiver::cast(function->instance_prototype()));
58 }
59
60
61 Handle<Map> LookupIterator::GetReceiverMap() const {
62 Handle<Object> receiver = GetReceiver();
63 if (receiver->IsNumber()) return isolate_->factory()->heap_number_map();
64 return handle(Handle<HeapObject>::cast(receiver)->map());
65 }
66
67
68 bool LookupIterator::NextHolder() {
69 if (holder_map_->prototype()->IsNull()) return false;
70
71 Handle<JSReceiver> next(JSReceiver::cast(holder_map_->prototype()));
72
73 if (!check_derived() &&
74 // TODO(verwaest): Check if this is actually necessary currently. If it
75 // is, this should be handled by setting is_hidden_prototype on the
76 // global object behind the proxy.
77 !holder_map_->IsJSGlobalProxyMap() &&
78 !next->map()->is_hidden_prototype()) {
79 return false;
80 }
81
82 holder_map_ = handle(next->map());
83 maybe_holder_ = next;
84 return true;
85 }
86
87
88 void LookupIterator::ContinueLookup() {
89 ASSERT(!IsFound());
90 do {
91 LookupInHolder();
92 } while (!IsFound() && NextHolder());
93 }
94
95
96 void LookupIterator::LookupInHolder() {
97 if (holder_map_->IsJSProxyMap()) {
98 state_ = JSPROXY;
99 } else if (check_access_check() && holder_map_->is_access_check_needed()) {
100 state_ = ACCESS_CHECK;
101 } else if (check_interceptor() && holder_map_->has_named_interceptor()) {
102 state_ = INTERCEPTOR;
103 } else {
104 LookupOwnRealNamedProperty();
105 }
106 }
107
108
109 void LookupIterator::LookupOwnRealNamedProperty() {
110 if (holder_map_->is_dictionary_map()) {
111 property_encoding_ = DICTIONARY;
112 } else {
113 DescriptorArray* descriptors = holder_map_->instance_descriptors();
114 number_ = descriptors->SearchWithCache(*name_, *holder_map_);
115 if (number_ == DescriptorArray::kNotFound) return;
116 property_encoding_ = DESCRIPTOR;
117 }
118 state_ = PROPERTY;
119 }
120
121
122 bool LookupIterator::IsBootstrapping() const {
123 return isolate_->bootstrapper()->IsActive();
124 }
125
126
127 bool LookupIterator::HasAccess(v8::AccessType access_type) const {
128 ASSERT_EQ(ACCESS_CHECK, state_);
129 ASSERT(is_guaranteed_to_have_holder());
130 return isolate_->MayNamedAccess(GetHolder(), name_, access_type);
131 }
132
133
134 bool LookupIterator::HasProperty() {
135 ASSERT_EQ(PROPERTY, state_);
136 ASSERT(is_guaranteed_to_have_holder());
137
138 if (property_encoding_ == DICTIONARY) {
139 Handle<JSObject> holder = GetHolder();
140 number_ = holder->property_dictionary()->FindEntry(name_);
141 if (number_ == NameDictionary::kNotFound) return false;
142 }
143
144 has_property_ = true;
145 FetchDetails();
146
147 // Holes in dictionary cells are absent values unless marked as read-only.
148 if (property_encoding_ == DICTIONARY &&
149 GetHolder()->IsGlobalObject() &&
150 !property_details_.IsReadOnly() &&
151 FetchValue()->IsTheHole()) {
152 has_property_ = false;
153 return false;
Igor Sheludko 2014/06/10 16:15:07 "GlobalObject with property_details_.IsDeleted()"
154 }
155
156 switch (property_details_.type()) {
157 case v8::internal::FIELD:
158 case v8::internal::NORMAL:
159 case v8::internal::CONSTANT:
160 property_type_ = DATA;
161 break;
162 case v8::internal::CALLBACKS:
163 property_type_ = ACCESSORS;
164 break;
165 case v8::internal::HANDLER:
166 case v8::internal::NONEXISTENT:
167 case v8::internal::INTERCEPTOR:
168 UNREACHABLE();
169 }
170 return true;
171 }
172
173
174 Handle<Object> LookupIterator::FetchValue() const {
175 ASSERT(has_property_);
176 Object* result = NULL;
177 switch (property_encoding_) {
178 case DICTIONARY:
179 result = GetHolder()->property_dictionary()->ValueAt(number_);
180 if (GetHolder()->IsGlobalObject()) {
181 result = PropertyCell::cast(result)->value();
182 }
183 break;
184 case DESCRIPTOR:
185 if (property_details_.type() == v8::internal::FIELD) {
186 FieldIndex field_index = FieldIndex::ForDescriptor(
187 *holder_map_, number_);
188 return JSObject::FastPropertyAt(
189 GetHolder(), property_details_.representation(), field_index);
190 }
191 result = holder_map_->instance_descriptors()->GetValue(number_);
192 }
193 return handle(result, isolate_);
194 }
195
196
197 Handle<Object> LookupIterator::GetAccessors() const {
198 ASSERT(has_property_);
199 ASSERT_EQ(ACCESSORS, property_type_);
200 return FetchValue();
201 }
202
203
204 Handle<Object> LookupIterator::GetDataValue() const {
205 ASSERT(has_property_);
206 ASSERT_EQ(DATA, property_type_);
207 Handle<Object> value = FetchValue();
208 if (value->IsTheHole()) {
209 ASSERT_EQ(DICTIONARY, property_encoding_);
210 ASSERT(GetHolder()->IsGlobalObject());
211 ASSERT(property_details_.IsReadOnly());
212 return factory()->undefined_value();
213 }
214 return value;
215 }
216
217
218 void LookupIterator::FetchDetails() {
219 ASSERT(has_property_);
220 property_details_ = property_encoding_ == DICTIONARY
221 ? GetHolder()->property_dictionary()->DetailsAt(number_)
222 : holder_map_->instance_descriptors()->GetDetails(number_);
223 }
224
225
226 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/lookup.h ('k') | src/mips/stub-cache-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698