OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/lookup.h" | 8 #include "src/lookup.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 return state_; | 91 return state_; |
92 } | 92 } |
93 | 93 |
94 | 94 |
95 bool LookupIterator::IsBootstrapping() const { | 95 bool LookupIterator::IsBootstrapping() const { |
96 return isolate_->bootstrapper()->IsActive(); | 96 return isolate_->bootstrapper()->IsActive(); |
97 } | 97 } |
98 | 98 |
99 | 99 |
100 bool LookupIterator::HasAccess(v8::AccessType access_type) const { | 100 bool LookupIterator::HasAccess(v8::AccessType access_type) const { |
101 ASSERT_EQ(ACCESS_CHECK, state_); | 101 DCHECK_EQ(ACCESS_CHECK, state_); |
102 ASSERT(is_guaranteed_to_have_holder()); | 102 DCHECK(is_guaranteed_to_have_holder()); |
103 return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type); | 103 return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type); |
104 } | 104 } |
105 | 105 |
106 | 106 |
107 bool LookupIterator::HasProperty() { | 107 bool LookupIterator::HasProperty() { |
108 ASSERT_EQ(PROPERTY, state_); | 108 DCHECK_EQ(PROPERTY, state_); |
109 ASSERT(is_guaranteed_to_have_holder()); | 109 DCHECK(is_guaranteed_to_have_holder()); |
110 | 110 |
111 if (property_encoding_ == DICTIONARY) { | 111 if (property_encoding_ == DICTIONARY) { |
112 Handle<JSObject> holder = GetHolder<JSObject>(); | 112 Handle<JSObject> holder = GetHolder<JSObject>(); |
113 number_ = holder->property_dictionary()->FindEntry(name_); | 113 number_ = holder->property_dictionary()->FindEntry(name_); |
114 if (number_ == NameDictionary::kNotFound) return false; | 114 if (number_ == NameDictionary::kNotFound) return false; |
115 | 115 |
116 property_details_ = holder->property_dictionary()->DetailsAt(number_); | 116 property_details_ = holder->property_dictionary()->DetailsAt(number_); |
117 // Holes in dictionary cells are absent values. | 117 // Holes in dictionary cells are absent values. |
118 if (holder->IsGlobalObject() && | 118 if (holder->IsGlobalObject() && |
119 (property_details_.IsDeleted() || FetchValue()->IsTheHole())) { | 119 (property_details_.IsDeleted() || FetchValue()->IsTheHole())) { |
(...skipping 19 matching lines...) Expand all Loading... |
139 case v8::internal::INTERCEPTOR: | 139 case v8::internal::INTERCEPTOR: |
140 UNREACHABLE(); | 140 UNREACHABLE(); |
141 } | 141 } |
142 | 142 |
143 has_property_ = true; | 143 has_property_ = true; |
144 return true; | 144 return true; |
145 } | 145 } |
146 | 146 |
147 | 147 |
148 void LookupIterator::PrepareForDataProperty(Handle<Object> value) { | 148 void LookupIterator::PrepareForDataProperty(Handle<Object> value) { |
149 ASSERT(has_property_); | 149 DCHECK(has_property_); |
150 ASSERT(HolderIsReceiverOrHiddenPrototype()); | 150 DCHECK(HolderIsReceiverOrHiddenPrototype()); |
151 if (property_encoding_ == DICTIONARY) return; | 151 if (property_encoding_ == DICTIONARY) return; |
152 holder_map_ = | 152 holder_map_ = |
153 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); | 153 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); |
154 JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_); | 154 JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_); |
155 // Reload property information. | 155 // Reload property information. |
156 if (holder_map_->is_dictionary_map()) { | 156 if (holder_map_->is_dictionary_map()) { |
157 property_encoding_ = DICTIONARY; | 157 property_encoding_ = DICTIONARY; |
158 } else { | 158 } else { |
159 property_encoding_ = DESCRIPTOR; | 159 property_encoding_ = DESCRIPTOR; |
160 } | 160 } |
161 CHECK(HasProperty()); | 161 CHECK(HasProperty()); |
162 } | 162 } |
163 | 163 |
164 | 164 |
165 void LookupIterator::TransitionToDataProperty( | 165 void LookupIterator::TransitionToDataProperty( |
166 Handle<Object> value, PropertyAttributes attributes, | 166 Handle<Object> value, PropertyAttributes attributes, |
167 Object::StoreFromKeyed store_mode) { | 167 Object::StoreFromKeyed store_mode) { |
168 ASSERT(!has_property_ || !HolderIsReceiverOrHiddenPrototype()); | 168 DCHECK(!has_property_ || !HolderIsReceiverOrHiddenPrototype()); |
169 | 169 |
170 // Can only be called when the receiver is a JSObject. JSProxy has to be | 170 // Can only be called when the receiver is a JSObject. JSProxy has to be |
171 // handled via a trap. Adding properties to primitive values is not | 171 // handled via a trap. Adding properties to primitive values is not |
172 // observable. | 172 // observable. |
173 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver()); | 173 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver()); |
174 | 174 |
175 // Properties have to be added to context extension objects through | 175 // Properties have to be added to context extension objects through |
176 // SetOwnPropertyIgnoreAttributes. | 176 // SetOwnPropertyIgnoreAttributes. |
177 ASSERT(!receiver->IsJSContextExtensionObject()); | 177 DCHECK(!receiver->IsJSContextExtensionObject()); |
178 | 178 |
179 if (receiver->IsJSGlobalProxy()) { | 179 if (receiver->IsJSGlobalProxy()) { |
180 PrototypeIterator iter(isolate(), receiver); | 180 PrototypeIterator iter(isolate(), receiver); |
181 receiver = | 181 receiver = |
182 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); | 182 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); |
183 } | 183 } |
184 | 184 |
185 maybe_holder_ = receiver; | 185 maybe_holder_ = receiver; |
186 holder_map_ = Map::TransitionToDataProperty(handle(receiver->map()), name_, | 186 holder_map_ = Map::TransitionToDataProperty(handle(receiver->map()), name_, |
187 value, attributes, store_mode); | 187 value, attributes, store_mode); |
188 JSObject::MigrateToMap(receiver, holder_map_); | 188 JSObject::MigrateToMap(receiver, holder_map_); |
189 | 189 |
190 // Reload the information. | 190 // Reload the information. |
191 state_ = NOT_FOUND; | 191 state_ = NOT_FOUND; |
192 configuration_ = CHECK_OWN_REAL; | 192 configuration_ = CHECK_OWN_REAL; |
193 state_ = LookupInHolder(); | 193 state_ = LookupInHolder(); |
194 ASSERT(IsFound()); | 194 DCHECK(IsFound()); |
195 HasProperty(); | 195 HasProperty(); |
196 } | 196 } |
197 | 197 |
198 | 198 |
199 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { | 199 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { |
200 ASSERT(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); | 200 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); |
201 DisallowHeapAllocation no_gc; | 201 DisallowHeapAllocation no_gc; |
202 Handle<Object> receiver = GetReceiver(); | 202 Handle<Object> receiver = GetReceiver(); |
203 if (!receiver->IsJSReceiver()) return false; | 203 if (!receiver->IsJSReceiver()) return false; |
204 Object* current = *receiver; | 204 Object* current = *receiver; |
205 JSReceiver* holder = *maybe_holder_.ToHandleChecked(); | 205 JSReceiver* holder = *maybe_holder_.ToHandleChecked(); |
206 // JSProxy do not occur as hidden prototypes. | 206 // JSProxy do not occur as hidden prototypes. |
207 if (current->IsJSProxy()) { | 207 if (current->IsJSProxy()) { |
208 return JSReceiver::cast(current) == holder; | 208 return JSReceiver::cast(current) == holder; |
209 } | 209 } |
210 PrototypeIterator iter(isolate(), current, | 210 PrototypeIterator iter(isolate(), current, |
211 PrototypeIterator::START_AT_RECEIVER); | 211 PrototypeIterator::START_AT_RECEIVER); |
212 do { | 212 do { |
213 if (JSReceiver::cast(iter.GetCurrent()) == holder) return true; | 213 if (JSReceiver::cast(iter.GetCurrent()) == holder) return true; |
214 ASSERT(!current->IsJSProxy()); | 214 DCHECK(!current->IsJSProxy()); |
215 iter.Advance(); | 215 iter.Advance(); |
216 } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); | 216 } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); |
217 return false; | 217 return false; |
218 } | 218 } |
219 | 219 |
220 | 220 |
221 Handle<Object> LookupIterator::FetchValue() const { | 221 Handle<Object> LookupIterator::FetchValue() const { |
222 Object* result = NULL; | 222 Object* result = NULL; |
223 Handle<JSObject> holder = GetHolder<JSObject>(); | 223 Handle<JSObject> holder = GetHolder<JSObject>(); |
224 switch (property_encoding_) { | 224 switch (property_encoding_) { |
(...skipping 10 matching lines...) Expand all Loading... |
235 return JSObject::FastPropertyAt( | 235 return JSObject::FastPropertyAt( |
236 holder, property_details_.representation(), field_index); | 236 holder, property_details_.representation(), field_index); |
237 } | 237 } |
238 result = holder_map_->instance_descriptors()->GetValue(number_); | 238 result = holder_map_->instance_descriptors()->GetValue(number_); |
239 } | 239 } |
240 return handle(result, isolate_); | 240 return handle(result, isolate_); |
241 } | 241 } |
242 | 242 |
243 | 243 |
244 FieldIndex LookupIterator::GetFieldIndex() const { | 244 FieldIndex LookupIterator::GetFieldIndex() const { |
245 ASSERT_EQ(PROPERTY, state_); | 245 DCHECK_EQ(PROPERTY, state_); |
246 int index = | 246 int index = |
247 holder_map()->instance_descriptors()->GetFieldIndex(descriptor_number()); | 247 holder_map()->instance_descriptors()->GetFieldIndex(descriptor_number()); |
248 bool is_double = representation().IsDouble(); | 248 bool is_double = representation().IsDouble(); |
249 return FieldIndex::ForPropertyIndex(*holder_map(), index, is_double); | 249 return FieldIndex::ForPropertyIndex(*holder_map(), index, is_double); |
250 } | 250 } |
251 | 251 |
252 | 252 |
253 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { | 253 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { |
254 Handle<JSObject> holder = GetHolder<JSObject>(); | 254 Handle<JSObject> holder = GetHolder<JSObject>(); |
255 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); | 255 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); |
256 Object* value = global->property_dictionary()->ValueAt(dictionary_entry()); | 256 Object* value = global->property_dictionary()->ValueAt(dictionary_entry()); |
257 return Handle<PropertyCell>(PropertyCell::cast(value)); | 257 return Handle<PropertyCell>(PropertyCell::cast(value)); |
258 } | 258 } |
259 | 259 |
260 | 260 |
261 Handle<Object> LookupIterator::GetAccessors() const { | 261 Handle<Object> LookupIterator::GetAccessors() const { |
262 ASSERT(has_property_); | 262 DCHECK(has_property_); |
263 ASSERT_EQ(ACCESSOR, property_kind_); | 263 DCHECK_EQ(ACCESSOR, property_kind_); |
264 return FetchValue(); | 264 return FetchValue(); |
265 } | 265 } |
266 | 266 |
267 | 267 |
268 Handle<Object> LookupIterator::GetDataValue() const { | 268 Handle<Object> LookupIterator::GetDataValue() const { |
269 ASSERT(has_property_); | 269 DCHECK(has_property_); |
270 ASSERT_EQ(DATA, property_kind_); | 270 DCHECK_EQ(DATA, property_kind_); |
271 Handle<Object> value = FetchValue(); | 271 Handle<Object> value = FetchValue(); |
272 return value; | 272 return value; |
273 } | 273 } |
274 | 274 |
275 | 275 |
276 void LookupIterator::WriteDataValue(Handle<Object> value) { | 276 void LookupIterator::WriteDataValue(Handle<Object> value) { |
277 ASSERT(is_guaranteed_to_have_holder()); | 277 DCHECK(is_guaranteed_to_have_holder()); |
278 ASSERT(has_property_); | 278 DCHECK(has_property_); |
279 Handle<JSObject> holder = GetHolder<JSObject>(); | 279 Handle<JSObject> holder = GetHolder<JSObject>(); |
280 if (property_encoding_ == DICTIONARY) { | 280 if (property_encoding_ == DICTIONARY) { |
281 NameDictionary* property_dictionary = holder->property_dictionary(); | 281 NameDictionary* property_dictionary = holder->property_dictionary(); |
282 if (holder->IsGlobalObject()) { | 282 if (holder->IsGlobalObject()) { |
283 Handle<PropertyCell> cell( | 283 Handle<PropertyCell> cell( |
284 PropertyCell::cast(property_dictionary->ValueAt(dictionary_entry()))); | 284 PropertyCell::cast(property_dictionary->ValueAt(dictionary_entry()))); |
285 PropertyCell::SetValueInferType(cell, value); | 285 PropertyCell::SetValueInferType(cell, value); |
286 } else { | 286 } else { |
287 property_dictionary->ValueAtPut(dictionary_entry(), *value); | 287 property_dictionary->ValueAtPut(dictionary_entry(), *value); |
288 } | 288 } |
289 } else if (property_details_.type() == v8::internal::FIELD) { | 289 } else if (property_details_.type() == v8::internal::FIELD) { |
290 holder->WriteToField(descriptor_number(), *value); | 290 holder->WriteToField(descriptor_number(), *value); |
291 } else { | 291 } else { |
292 ASSERT_EQ(v8::internal::CONSTANT, property_details_.type()); | 292 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); |
293 } | 293 } |
294 } | 294 } |
295 | 295 |
296 | 296 |
297 void LookupIterator::InternalizeName() { | 297 void LookupIterator::InternalizeName() { |
298 if (name_->IsUniqueName()) return; | 298 if (name_->IsUniqueName()) return; |
299 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); | 299 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); |
300 } | 300 } |
301 } } // namespace v8::internal | 301 } } // namespace v8::internal |
OLD | NEW |