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/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
9 #include "src/lookup.h" | 9 #include "src/lookup.h" |
10 #include "src/lookup-inl.h" | 10 #include "src/lookup-inl.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 auto root = handle(receiver->GetRootMap(isolate)->prototype(), isolate); | 78 auto root = handle(receiver->GetRootMap(isolate)->prototype(), isolate); |
79 if (root->IsNull()) { | 79 if (root->IsNull()) { |
80 unsigned int magic = 0xbbbbbbbb; | 80 unsigned int magic = 0xbbbbbbbb; |
81 isolate->PushStackTraceAndDie(magic, *receiver, NULL, magic); | 81 isolate->PushStackTraceAndDie(magic, *receiver, NULL, magic); |
82 } | 82 } |
83 return Handle<JSReceiver>::cast(root); | 83 return Handle<JSReceiver>::cast(root); |
84 } | 84 } |
85 | 85 |
86 | 86 |
87 Handle<Map> LookupIterator::GetReceiverMap() const { | 87 Handle<Map> LookupIterator::GetReceiverMap() const { |
88 if (receiver_->IsNumber()) return isolate_->factory()->heap_number_map(); | 88 if (receiver_->IsNumber()) return factory()->heap_number_map(); |
89 return handle(Handle<HeapObject>::cast(receiver_)->map(), isolate_); | 89 return handle(Handle<HeapObject>::cast(receiver_)->map(), isolate_); |
90 } | 90 } |
91 | 91 |
92 | 92 |
93 Handle<JSObject> LookupIterator::GetStoreTarget() const { | 93 Handle<JSObject> LookupIterator::GetStoreTarget() const { |
94 if (receiver_->IsJSGlobalProxy()) { | 94 if (receiver_->IsJSGlobalProxy()) { |
95 PrototypeIterator iter(isolate(), receiver_); | 95 PrototypeIterator iter(isolate(), receiver_); |
96 if (iter.IsAtEnd()) return Handle<JSGlobalProxy>::cast(receiver_); | 96 if (iter.IsAtEnd()) return Handle<JSGlobalProxy>::cast(receiver_); |
97 return Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); | 97 return Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); |
98 } | 98 } |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 | 271 |
272 void LookupIterator::TransitionToAccessorProperty( | 272 void LookupIterator::TransitionToAccessorProperty( |
273 AccessorComponent component, Handle<Object> accessor, | 273 AccessorComponent component, Handle<Object> accessor, |
274 PropertyAttributes attributes) { | 274 PropertyAttributes attributes) { |
275 DCHECK(!accessor->IsNull()); | 275 DCHECK(!accessor->IsNull()); |
276 // Can only be called when the receiver is a JSObject. JSProxy has to be | 276 // Can only be called when the receiver is a JSObject. JSProxy has to be |
277 // handled via a trap. Adding properties to primitive values is not | 277 // handled via a trap. Adding properties to primitive values is not |
278 // observable. | 278 // observable. |
279 Handle<JSObject> receiver = GetStoreTarget(); | 279 Handle<JSObject> receiver = GetStoreTarget(); |
280 holder_ = receiver; | 280 holder_ = receiver; |
281 holder_map_ = | |
282 Map::TransitionToAccessorProperty(handle(receiver->map(), isolate_), | |
283 name_, component, accessor, attributes); | |
284 JSObject::MigrateToMap(receiver, holder_map_); | |
285 | 281 |
286 ReloadPropertyInformation(); | 282 if (!IsElement() && !receiver->map()->is_dictionary_map()) { |
| 283 holder_map_ = Map::TransitionToAccessorProperty( |
| 284 handle(receiver->map(), isolate_), name_, component, accessor, |
| 285 attributes); |
| 286 JSObject::MigrateToMap(receiver, holder_map_); |
287 | 287 |
288 if (!holder_map_->is_dictionary_map()) return; | 288 ReloadPropertyInformation(); |
289 | 289 |
| 290 if (!holder_map_->is_dictionary_map()) return; |
| 291 } |
290 | 292 |
291 // Install the accessor into the dictionary-mode object. | |
292 PropertyDetails details(attributes, ACCESSOR_CONSTANT, 0, | 293 PropertyDetails details(attributes, ACCESSOR_CONSTANT, 0, |
293 PropertyCellType::kMutable); | 294 PropertyCellType::kMutable); |
294 Handle<AccessorPair> pair; | 295 Handle<AccessorPair> pair; |
295 if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) { | 296 if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) { |
296 pair = Handle<AccessorPair>::cast(GetAccessors()); | 297 pair = Handle<AccessorPair>::cast(GetAccessors()); |
297 // If the component and attributes are identical, nothing has to be done. | 298 // If the component and attributes are identical, nothing has to be done. |
298 if (pair->get(component) == *accessor) { | 299 if (pair->get(component) == *accessor) { |
299 if (property_details().attributes() == attributes) return; | 300 if (property_details().attributes() == attributes) return; |
300 } else { | 301 } else { |
301 pair = AccessorPair::Copy(pair); | 302 pair = AccessorPair::Copy(pair); |
302 pair->set(component, *accessor); | 303 pair->set(component, *accessor); |
303 } | 304 } |
304 } else { | 305 } else { |
305 pair = isolate()->factory()->NewAccessorPair(); | 306 pair = factory()->NewAccessorPair(); |
306 pair->set(component, *accessor); | 307 pair->set(component, *accessor); |
307 } | 308 } |
308 JSObject::SetNormalizedProperty(receiver, name_, pair, details); | |
309 | 309 |
310 JSObject::ReoptimizeIfPrototype(receiver); | 310 if (IsElement()) { |
| 311 // TODO(verwaest): Remove this hack once we have a quick way to check the |
| 312 // prototype chain in element setters. |
| 313 // TODO(verwaest): Move code into the element accessor. |
| 314 bool was_dictionary = receiver->HasDictionaryElements(); |
| 315 Handle<SeededNumberDictionary> dictionary = |
| 316 JSObject::NormalizeElements(receiver); |
| 317 was_dictionary = was_dictionary && dictionary->requires_slow_elements(); |
| 318 |
| 319 dictionary = SeededNumberDictionary::Set(dictionary, index_, pair, details); |
| 320 dictionary->set_requires_slow_elements(); |
| 321 |
| 322 if (receiver->HasSlowArgumentsElements()) { |
| 323 FixedArray* parameter_map = FixedArray::cast(receiver->elements()); |
| 324 uint32_t length = parameter_map->length() - 2; |
| 325 if (number_ < length) { |
| 326 parameter_map->set(number_ + 2, heap()->the_hole_value()); |
| 327 } |
| 328 FixedArray::cast(receiver->elements())->set(1, *dictionary); |
| 329 } else { |
| 330 receiver->set_elements(*dictionary); |
| 331 if (!was_dictionary) heap()->ClearAllICsByKind(Code::KEYED_STORE_IC); |
| 332 } |
| 333 } else { |
| 334 JSObject::SetNormalizedProperty(receiver, name_, pair, details); |
| 335 JSObject::ReoptimizeIfPrototype(receiver); |
| 336 } |
| 337 |
311 holder_map_ = handle(receiver->map(), isolate_); | 338 holder_map_ = handle(receiver->map(), isolate_); |
312 ReloadPropertyInformation(); | 339 ReloadPropertyInformation(); |
313 } | 340 } |
314 | 341 |
315 | 342 |
316 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { | 343 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { |
317 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); | 344 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); |
318 return InternalHolderIsReceiverOrHiddenPrototype(); | 345 return InternalHolderIsReceiverOrHiddenPrototype(); |
319 } | 346 } |
320 | 347 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 case InterceptorState::kSkipNonMasking: | 543 case InterceptorState::kSkipNonMasking: |
517 return true; | 544 return true; |
518 case InterceptorState::kProcessNonMasking: | 545 case InterceptorState::kProcessNonMasking: |
519 return false; | 546 return false; |
520 } | 547 } |
521 } | 548 } |
522 return interceptor_state_ == InterceptorState::kProcessNonMasking; | 549 return interceptor_state_ == InterceptorState::kProcessNonMasking; |
523 } | 550 } |
524 } // namespace internal | 551 } // namespace internal |
525 } // namespace v8 | 552 } // namespace v8 |
OLD | NEW |