| 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 |