| 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/lookup.h" | 5 #include "src/lookup.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/elements.h" | 9 #include "src/elements.h" |
| 10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 if (!isolate()->IsInternallyUsedPropertyName(name()) && | 238 if (!isolate()->IsInternallyUsedPropertyName(name()) && |
| 239 !receiver->map()->is_extensible()) { | 239 !receiver->map()->is_extensible()) { |
| 240 return; | 240 return; |
| 241 } | 241 } |
| 242 | 242 |
| 243 auto transition = Map::TransitionToDataProperty( | 243 auto transition = Map::TransitionToDataProperty( |
| 244 handle(receiver->map(), isolate_), name_, value, attributes, store_mode); | 244 handle(receiver->map(), isolate_), name_, value, attributes, store_mode); |
| 245 state_ = TRANSITION; | 245 state_ = TRANSITION; |
| 246 transition_ = transition; | 246 transition_ = transition; |
| 247 | 247 |
| 248 if (receiver->IsGlobalObject()) { | 248 if (receiver->IsJSGlobalObject()) { |
| 249 // Install a property cell. | 249 // Install a property cell. |
| 250 InternalizeName(); | 250 InternalizeName(); |
| 251 auto cell = GlobalObject::EnsurePropertyCell( | 251 auto cell = JSGlobalObject::EnsurePropertyCell( |
| 252 Handle<GlobalObject>::cast(receiver), name()); | 252 Handle<JSGlobalObject>::cast(receiver), name()); |
| 253 DCHECK(cell->value()->IsTheHole()); | 253 DCHECK(cell->value()->IsTheHole()); |
| 254 transition_ = cell; | 254 transition_ = cell; |
| 255 } else if (!transition->is_dictionary_map()) { | 255 } else if (!transition->is_dictionary_map()) { |
| 256 property_details_ = transition->GetLastDescriptorDetails(); | 256 property_details_ = transition->GetLastDescriptorDetails(); |
| 257 has_property_ = true; | 257 has_property_ = true; |
| 258 } | 258 } |
| 259 } | 259 } |
| 260 | 260 |
| 261 | 261 |
| 262 void LookupIterator::ApplyTransitionToDataProperty() { | 262 void LookupIterator::ApplyTransitionToDataProperty() { |
| 263 DCHECK_EQ(TRANSITION, state_); | 263 DCHECK_EQ(TRANSITION, state_); |
| 264 | 264 |
| 265 Handle<JSObject> receiver = GetStoreTarget(); | 265 Handle<JSObject> receiver = GetStoreTarget(); |
| 266 if (receiver->IsGlobalObject()) return; | 266 if (receiver->IsJSGlobalObject()) return; |
| 267 holder_ = receiver; | 267 holder_ = receiver; |
| 268 holder_map_ = transition_map(); | 268 holder_map_ = transition_map(); |
| 269 JSObject::MigrateToMap(receiver, holder_map_); | 269 JSObject::MigrateToMap(receiver, holder_map_); |
| 270 ReloadPropertyInformation(); | 270 ReloadPropertyInformation(); |
| 271 } | 271 } |
| 272 | 272 |
| 273 | 273 |
| 274 void LookupIterator::Delete() { | 274 void LookupIterator::Delete() { |
| 275 Handle<JSObject> holder = Handle<JSObject>::cast(holder_); | 275 Handle<JSObject> holder = Handle<JSObject>::cast(holder_); |
| 276 if (IsElement()) { | 276 if (IsElement()) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 // TODO(verwaest): Optimize. | 420 // TODO(verwaest): Optimize. |
| 421 if (holder->IsStringObjectWithCharacterAt(index_)) { | 421 if (holder->IsStringObjectWithCharacterAt(index_)) { |
| 422 Handle<JSValue> js_value = Handle<JSValue>::cast(holder); | 422 Handle<JSValue> js_value = Handle<JSValue>::cast(holder); |
| 423 Handle<String> string(String::cast(js_value->value())); | 423 Handle<String> string(String::cast(js_value->value())); |
| 424 return factory()->LookupSingleCharacterStringFromCode( | 424 return factory()->LookupSingleCharacterStringFromCode( |
| 425 String::Flatten(string)->Get(index_)); | 425 String::Flatten(string)->Get(index_)); |
| 426 } | 426 } |
| 427 | 427 |
| 428 ElementsAccessor* accessor = holder->GetElementsAccessor(); | 428 ElementsAccessor* accessor = holder->GetElementsAccessor(); |
| 429 return accessor->Get(handle(holder->elements()), number_); | 429 return accessor->Get(handle(holder->elements()), number_); |
| 430 } else if (holder_map_->IsGlobalObjectMap()) { | 430 } else if (holder_map_->IsJSGlobalObjectMap()) { |
| 431 result = holder->global_dictionary()->ValueAt(number_); | 431 result = holder->global_dictionary()->ValueAt(number_); |
| 432 DCHECK(result->IsPropertyCell()); | 432 DCHECK(result->IsPropertyCell()); |
| 433 result = PropertyCell::cast(result)->value(); | 433 result = PropertyCell::cast(result)->value(); |
| 434 } else if (holder_map_->is_dictionary_map()) { | 434 } else if (holder_map_->is_dictionary_map()) { |
| 435 result = holder->property_dictionary()->ValueAt(number_); | 435 result = holder->property_dictionary()->ValueAt(number_); |
| 436 } else if (property_details_.type() == v8::internal::DATA) { | 436 } else if (property_details_.type() == v8::internal::DATA) { |
| 437 FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_); | 437 FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_); |
| 438 return JSObject::FastPropertyAt(holder, property_details_.representation(), | 438 return JSObject::FastPropertyAt(holder, property_details_.representation(), |
| 439 field_index); | 439 field_index); |
| 440 } else { | 440 } else { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 DCHECK_EQ(v8::internal::DATA, property_details_.type()); | 479 DCHECK_EQ(v8::internal::DATA, property_details_.type()); |
| 480 return handle( | 480 return handle( |
| 481 holder_map_->instance_descriptors()->GetFieldType(descriptor_number()), | 481 holder_map_->instance_descriptors()->GetFieldType(descriptor_number()), |
| 482 isolate_); | 482 isolate_); |
| 483 } | 483 } |
| 484 | 484 |
| 485 | 485 |
| 486 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { | 486 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { |
| 487 DCHECK(!IsElement()); | 487 DCHECK(!IsElement()); |
| 488 Handle<JSObject> holder = GetHolder<JSObject>(); | 488 Handle<JSObject> holder = GetHolder<JSObject>(); |
| 489 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); | 489 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(holder); |
| 490 Object* value = global->global_dictionary()->ValueAt(dictionary_entry()); | 490 Object* value = global->global_dictionary()->ValueAt(dictionary_entry()); |
| 491 DCHECK(value->IsPropertyCell()); | 491 DCHECK(value->IsPropertyCell()); |
| 492 return handle(PropertyCell::cast(value)); | 492 return handle(PropertyCell::cast(value)); |
| 493 } | 493 } |
| 494 | 494 |
| 495 | 495 |
| 496 Handle<Object> LookupIterator::GetAccessors() const { | 496 Handle<Object> LookupIterator::GetAccessors() const { |
| 497 DCHECK_EQ(ACCESSOR, state_); | 497 DCHECK_EQ(ACCESSOR, state_); |
| 498 return FetchValue(); | 498 return FetchValue(); |
| 499 } | 499 } |
| 500 | 500 |
| 501 | 501 |
| 502 Handle<Object> LookupIterator::GetDataValue() const { | 502 Handle<Object> LookupIterator::GetDataValue() const { |
| 503 DCHECK_EQ(DATA, state_); | 503 DCHECK_EQ(DATA, state_); |
| 504 Handle<Object> value = FetchValue(); | 504 Handle<Object> value = FetchValue(); |
| 505 return value; | 505 return value; |
| 506 } | 506 } |
| 507 | 507 |
| 508 | 508 |
| 509 void LookupIterator::WriteDataValue(Handle<Object> value) { | 509 void LookupIterator::WriteDataValue(Handle<Object> value) { |
| 510 DCHECK_EQ(DATA, state_); | 510 DCHECK_EQ(DATA, state_); |
| 511 Handle<JSObject> holder = GetHolder<JSObject>(); | 511 Handle<JSObject> holder = GetHolder<JSObject>(); |
| 512 if (IsElement()) { | 512 if (IsElement()) { |
| 513 ElementsAccessor* accessor = holder->GetElementsAccessor(); | 513 ElementsAccessor* accessor = holder->GetElementsAccessor(); |
| 514 accessor->Set(holder->elements(), number_, *value); | 514 accessor->Set(holder->elements(), number_, *value); |
| 515 } else if (holder->IsGlobalObject()) { | 515 } else if (holder->IsJSGlobalObject()) { |
| 516 Handle<GlobalDictionary> property_dictionary = | 516 Handle<GlobalDictionary> property_dictionary = |
| 517 handle(holder->global_dictionary()); | 517 handle(holder->global_dictionary()); |
| 518 PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value, | 518 PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value, |
| 519 property_details_); | 519 property_details_); |
| 520 } else if (holder_map_->is_dictionary_map()) { | 520 } else if (holder_map_->is_dictionary_map()) { |
| 521 NameDictionary* property_dictionary = holder->property_dictionary(); | 521 NameDictionary* property_dictionary = holder->property_dictionary(); |
| 522 property_dictionary->ValueAtPut(dictionary_entry(), *value); | 522 property_dictionary->ValueAtPut(dictionary_entry(), *value); |
| 523 } else if (property_details_.type() == v8::internal::DATA) { | 523 } else if (property_details_.type() == v8::internal::DATA) { |
| 524 holder->WriteToField(descriptor_number(), *value); | 524 holder->WriteToField(descriptor_number(), *value); |
| 525 } else { | 525 } else { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 } | 594 } |
| 595 return interceptor_state_ == InterceptorState::kProcessNonMasking; | 595 return interceptor_state_ == InterceptorState::kProcessNonMasking; |
| 596 } | 596 } |
| 597 | 597 |
| 598 | 598 |
| 599 JSReceiver* LookupIterator::NextHolder(Map* map) { | 599 JSReceiver* LookupIterator::NextHolder(Map* map) { |
| 600 DisallowHeapAllocation no_gc; | 600 DisallowHeapAllocation no_gc; |
| 601 if (!map->prototype()->IsJSReceiver()) return NULL; | 601 if (!map->prototype()->IsJSReceiver()) return NULL; |
| 602 | 602 |
| 603 JSReceiver* next = JSReceiver::cast(map->prototype()); | 603 JSReceiver* next = JSReceiver::cast(map->prototype()); |
| 604 DCHECK(!next->map()->IsGlobalObjectMap() || | 604 DCHECK(!next->map()->IsJSGlobalObjectMap() || |
| 605 next->map()->is_hidden_prototype()); | 605 next->map()->is_hidden_prototype()); |
| 606 | 606 |
| 607 if (!check_prototype_chain() && | 607 if (!check_prototype_chain() && |
| 608 !(check_hidden() && next->map()->is_hidden_prototype()) && | 608 !(check_hidden() && next->map()->is_hidden_prototype()) && |
| 609 // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even | 609 // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even |
| 610 // when not checking other hidden prototypes. | 610 // when not checking other hidden prototypes. |
| 611 !map->IsJSGlobalProxyMap()) { | 611 !map->IsJSGlobalProxyMap()) { |
| 612 return NULL; | 612 return NULL; |
| 613 } | 613 } |
| 614 | 614 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 accessor->GetEntryForIndex(js_object, backing_store, index_); | 661 accessor->GetEntryForIndex(js_object, backing_store, index_); |
| 662 if (number_ == kMaxUInt32) return NOT_FOUND; | 662 if (number_ == kMaxUInt32) return NOT_FOUND; |
| 663 property_details_ = accessor->GetDetails(backing_store, number_); | 663 property_details_ = accessor->GetDetails(backing_store, number_); |
| 664 } | 664 } |
| 665 } else if (!map->is_dictionary_map()) { | 665 } else if (!map->is_dictionary_map()) { |
| 666 DescriptorArray* descriptors = map->instance_descriptors(); | 666 DescriptorArray* descriptors = map->instance_descriptors(); |
| 667 int number = descriptors->SearchWithCache(*name_, map); | 667 int number = descriptors->SearchWithCache(*name_, map); |
| 668 if (number == DescriptorArray::kNotFound) return NOT_FOUND; | 668 if (number == DescriptorArray::kNotFound) return NOT_FOUND; |
| 669 number_ = static_cast<uint32_t>(number); | 669 number_ = static_cast<uint32_t>(number); |
| 670 property_details_ = descriptors->GetDetails(number_); | 670 property_details_ = descriptors->GetDetails(number_); |
| 671 } else if (map->IsGlobalObjectMap()) { | 671 } else if (map->IsJSGlobalObjectMap()) { |
| 672 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary(); | 672 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary(); |
| 673 int number = dict->FindEntry(name_); | 673 int number = dict->FindEntry(name_); |
| 674 if (number == GlobalDictionary::kNotFound) return NOT_FOUND; | 674 if (number == GlobalDictionary::kNotFound) return NOT_FOUND; |
| 675 number_ = static_cast<uint32_t>(number); | 675 number_ = static_cast<uint32_t>(number); |
| 676 DCHECK(dict->ValueAt(number_)->IsPropertyCell()); | 676 DCHECK(dict->ValueAt(number_)->IsPropertyCell()); |
| 677 PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_)); | 677 PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_)); |
| 678 if (cell->value()->IsTheHole()) return NOT_FOUND; | 678 if (cell->value()->IsTheHole()) return NOT_FOUND; |
| 679 property_details_ = cell->property_details(); | 679 property_details_ = cell->property_details(); |
| 680 } else { | 680 } else { |
| 681 NameDictionary* dict = JSObject::cast(holder)->property_dictionary(); | 681 NameDictionary* dict = JSObject::cast(holder)->property_dictionary(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 // Fall through. | 715 // Fall through. |
| 716 default: | 716 default: |
| 717 return NOT_FOUND; | 717 return NOT_FOUND; |
| 718 } | 718 } |
| 719 UNREACHABLE(); | 719 UNREACHABLE(); |
| 720 return state_; | 720 return state_; |
| 721 } | 721 } |
| 722 | 722 |
| 723 } // namespace internal | 723 } // namespace internal |
| 724 } // namespace v8 | 724 } // namespace v8 |
| OLD | NEW |