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 |