| 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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 NameDictionary* property_dictionary = holder->property_dictionary(); | 511 NameDictionary* property_dictionary = holder->property_dictionary(); |
| 512 property_dictionary->ValueAtPut(dictionary_entry(), *value); | 512 property_dictionary->ValueAtPut(dictionary_entry(), *value); |
| 513 } else if (property_details_.type() == v8::internal::DATA) { | 513 } else if (property_details_.type() == v8::internal::DATA) { |
| 514 JSObject::cast(*holder)->WriteToField(descriptor_number(), *value); | 514 JSObject::cast(*holder)->WriteToField(descriptor_number(), *value); |
| 515 } else { | 515 } else { |
| 516 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type()); | 516 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type()); |
| 517 } | 517 } |
| 518 } | 518 } |
| 519 | 519 |
| 520 | 520 |
| 521 bool LookupIterator::IsIntegerIndexedExotic(JSReceiver* holder) { | |
| 522 DCHECK(!IsElement()); | |
| 523 if (!name_->IsString()) return false; | |
| 524 if (*receiver_ != holder) return false; | |
| 525 | |
| 526 Handle<String> name_string = Handle<String>::cast(name_); | |
| 527 if (name_string->length() == 0) return false; | |
| 528 | |
| 529 return IsSpecialIndex(isolate_->unicode_cache(), *name_string); | |
| 530 } | |
| 531 | |
| 532 | |
| 533 void LookupIterator::InternalizeName() { | 521 void LookupIterator::InternalizeName() { |
| 534 if (name_->IsUniqueName()) return; | 522 if (name_->IsUniqueName()) return; |
| 535 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); | 523 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); |
| 536 } | 524 } |
| 537 | 525 |
| 538 | 526 |
| 539 bool LookupIterator::HasInterceptor(Map* map) const { | 527 bool LookupIterator::HasInterceptor(Map* map) const { |
| 540 if (IsElement()) return map->has_indexed_interceptor(); | 528 if (IsElement()) return map->has_indexed_interceptor(); |
| 541 return map->has_named_interceptor(); | 529 return map->has_named_interceptor(); |
| 542 } | 530 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 572 !(check_hidden() && next->map()->is_hidden_prototype()) && | 560 !(check_hidden() && next->map()->is_hidden_prototype()) && |
| 573 // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even | 561 // Always lookup behind the JSGlobalProxy into the JSGlobalObject, even |
| 574 // when not checking other hidden prototypes. | 562 // when not checking other hidden prototypes. |
| 575 !map->IsJSGlobalProxyMap()) { | 563 !map->IsJSGlobalProxyMap()) { |
| 576 return NULL; | 564 return NULL; |
| 577 } | 565 } |
| 578 | 566 |
| 579 return next; | 567 return next; |
| 580 } | 568 } |
| 581 | 569 |
| 570 LookupIterator::State LookupIterator::NotFound(JSReceiver* const holder) const { |
| 571 DCHECK(!IsElement()); |
| 572 if (!holder->IsJSTypedArray() || !name_->IsString()) return NOT_FOUND; |
| 573 |
| 574 Handle<String> name_string = Handle<String>::cast(name_); |
| 575 if (name_string->length() == 0) return NOT_FOUND; |
| 576 |
| 577 return IsSpecialIndex(isolate_->unicode_cache(), *name_string) |
| 578 ? INTEGER_INDEXED_EXOTIC |
| 579 : NOT_FOUND; |
| 580 } |
| 582 | 581 |
| 583 LookupIterator::State LookupIterator::LookupInHolder(Map* const map, | 582 LookupIterator::State LookupIterator::LookupInHolder(Map* const map, |
| 584 JSReceiver* const holder) { | 583 JSReceiver* const holder) { |
| 585 STATIC_ASSERT(INTERCEPTOR == BEFORE_PROPERTY); | 584 STATIC_ASSERT(INTERCEPTOR == BEFORE_PROPERTY); |
| 586 DisallowHeapAllocation no_gc; | 585 DisallowHeapAllocation no_gc; |
| 587 if (interceptor_state_ == InterceptorState::kProcessNonMasking) { | 586 if (interceptor_state_ == InterceptorState::kProcessNonMasking) { |
| 588 return LookupNonMaskingInterceptorInHolder(map, holder); | 587 return LookupNonMaskingInterceptorInHolder(map, holder); |
| 589 } | 588 } |
| 590 switch (state_) { | 589 switch (state_) { |
| 591 case NOT_FOUND: | 590 case NOT_FOUND: |
| (...skipping 14 matching lines...) Expand all Loading... |
| 606 return INTERCEPTOR; | 605 return INTERCEPTOR; |
| 607 } | 606 } |
| 608 // Fall through. | 607 // Fall through. |
| 609 case INTERCEPTOR: | 608 case INTERCEPTOR: |
| 610 if (IsElement()) { | 609 if (IsElement()) { |
| 611 JSObject* js_object = JSObject::cast(holder); | 610 JSObject* js_object = JSObject::cast(holder); |
| 612 ElementsAccessor* accessor = js_object->GetElementsAccessor(); | 611 ElementsAccessor* accessor = js_object->GetElementsAccessor(); |
| 613 FixedArrayBase* backing_store = js_object->elements(); | 612 FixedArrayBase* backing_store = js_object->elements(); |
| 614 number_ = accessor->GetEntryForIndex(js_object, backing_store, index_); | 613 number_ = accessor->GetEntryForIndex(js_object, backing_store, index_); |
| 615 if (number_ == kMaxUInt32) { | 614 if (number_ == kMaxUInt32) { |
| 616 if (*receiver_ == holder && holder->IsJSTypedArray()) { | 615 return holder->IsJSTypedArray() ? INTEGER_INDEXED_EXOTIC : NOT_FOUND; |
| 617 return INTEGER_INDEXED_EXOTIC; | |
| 618 } | |
| 619 return NOT_FOUND; | |
| 620 } | 616 } |
| 621 property_details_ = accessor->GetDetails(js_object, number_); | 617 property_details_ = accessor->GetDetails(js_object, number_); |
| 622 } else if (holder->IsJSTypedArray() && IsIntegerIndexedExotic(holder)) { | |
| 623 return INTEGER_INDEXED_EXOTIC; | |
| 624 } else if (!map->is_dictionary_map()) { | 618 } else if (!map->is_dictionary_map()) { |
| 625 DescriptorArray* descriptors = map->instance_descriptors(); | 619 DescriptorArray* descriptors = map->instance_descriptors(); |
| 626 int number = descriptors->SearchWithCache(*name_, map); | 620 int number = descriptors->SearchWithCache(*name_, map); |
| 627 if (number == DescriptorArray::kNotFound) return NOT_FOUND; | 621 if (number == DescriptorArray::kNotFound) return NotFound(holder); |
| 628 number_ = static_cast<uint32_t>(number); | 622 number_ = static_cast<uint32_t>(number); |
| 629 property_details_ = descriptors->GetDetails(number_); | 623 property_details_ = descriptors->GetDetails(number_); |
| 630 } else if (map->IsJSGlobalObjectMap()) { | 624 } else if (map->IsJSGlobalObjectMap()) { |
| 631 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary(); | 625 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary(); |
| 632 int number = dict->FindEntry(name_); | 626 int number = dict->FindEntry(name_); |
| 633 if (number == GlobalDictionary::kNotFound) return NOT_FOUND; | 627 if (number == GlobalDictionary::kNotFound) return NOT_FOUND; |
| 634 number_ = static_cast<uint32_t>(number); | 628 number_ = static_cast<uint32_t>(number); |
| 635 DCHECK(dict->ValueAt(number_)->IsPropertyCell()); | 629 DCHECK(dict->ValueAt(number_)->IsPropertyCell()); |
| 636 PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_)); | 630 PropertyCell* cell = PropertyCell::cast(dict->ValueAt(number_)); |
| 637 if (cell->value()->IsTheHole()) return NOT_FOUND; | 631 if (cell->value()->IsTheHole()) return NOT_FOUND; |
| 638 property_details_ = cell->property_details(); | 632 property_details_ = cell->property_details(); |
| 639 } else { | 633 } else { |
| 640 NameDictionary* dict = holder->property_dictionary(); | 634 NameDictionary* dict = holder->property_dictionary(); |
| 641 int number = dict->FindEntry(name_); | 635 int number = dict->FindEntry(name_); |
| 642 if (number == NameDictionary::kNotFound) return NOT_FOUND; | 636 if (number == NameDictionary::kNotFound) return NotFound(holder); |
| 643 number_ = static_cast<uint32_t>(number); | 637 number_ = static_cast<uint32_t>(number); |
| 644 property_details_ = dict->DetailsAt(number_); | 638 property_details_ = dict->DetailsAt(number_); |
| 645 } | 639 } |
| 646 has_property_ = true; | 640 has_property_ = true; |
| 647 switch (property_details_.kind()) { | 641 switch (property_details_.kind()) { |
| 648 case v8::internal::kData: | 642 case v8::internal::kData: |
| 649 return DATA; | 643 return DATA; |
| 650 case v8::internal::kAccessor: | 644 case v8::internal::kAccessor: |
| 651 return ACCESSOR; | 645 return ACCESSOR; |
| 652 } | 646 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 674 // Fall through. | 668 // Fall through. |
| 675 default: | 669 default: |
| 676 return NOT_FOUND; | 670 return NOT_FOUND; |
| 677 } | 671 } |
| 678 UNREACHABLE(); | 672 UNREACHABLE(); |
| 679 return state_; | 673 return state_; |
| 680 } | 674 } |
| 681 | 675 |
| 682 } // namespace internal | 676 } // namespace internal |
| 683 } // namespace v8 | 677 } // namespace v8 |
| OLD | NEW |