| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
| 9 #include "src/elements.h" | 9 #include "src/elements.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 ElementsAccessorSubclass::ValidateContents(holder, length); | 578 ElementsAccessorSubclass::ValidateContents(holder, length); |
| 579 } | 579 } |
| 580 | 580 |
| 581 void Validate(Handle<JSObject> holder) final { | 581 void Validate(Handle<JSObject> holder) final { |
| 582 DisallowHeapAllocation no_gc; | 582 DisallowHeapAllocation no_gc; |
| 583 ElementsAccessorSubclass::ValidateImpl(holder); | 583 ElementsAccessorSubclass::ValidateImpl(holder); |
| 584 } | 584 } |
| 585 | 585 |
| 586 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, | 586 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, |
| 587 Handle<FixedArrayBase> backing_store) { | 587 Handle<FixedArrayBase> backing_store) { |
| 588 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, | 588 return ElementsAccessorSubclass::GetAttributesImpl( |
| 589 backing_store) != ABSENT; | 589 *holder, key, *backing_store) != ABSENT; |
| 590 } | 590 } |
| 591 | 591 |
| 592 virtual bool HasElement(Handle<JSObject> holder, uint32_t key, | 592 virtual bool HasElement(Handle<JSObject> holder, uint32_t key, |
| 593 Handle<FixedArrayBase> backing_store) final { | 593 Handle<FixedArrayBase> backing_store) final { |
| 594 return ElementsAccessorSubclass::HasElementImpl(holder, key, backing_store); | 594 return ElementsAccessorSubclass::HasElementImpl(holder, key, backing_store); |
| 595 } | 595 } |
| 596 | 596 |
| 597 MUST_USE_RESULT virtual MaybeHandle<Object> Get( | 597 virtual Handle<Object> Get(Handle<JSObject> holder, uint32_t key, |
| 598 Handle<Object> receiver, Handle<JSObject> holder, uint32_t key, | 598 Handle<FixedArrayBase> backing_store) final { |
| 599 Handle<FixedArrayBase> backing_store) final { | |
| 600 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) && | 599 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) && |
| 601 FLAG_trace_js_array_abuse) { | 600 FLAG_trace_js_array_abuse) { |
| 602 CheckArrayAbuse(holder, "elements read", key); | 601 CheckArrayAbuse(holder, "elements read", key); |
| 603 } | 602 } |
| 604 | 603 |
| 605 if (IsExternalArrayElementsKind(ElementsTraits::Kind) && | 604 if (IsExternalArrayElementsKind(ElementsTraits::Kind) && |
| 606 FLAG_trace_external_array_abuse) { | 605 FLAG_trace_external_array_abuse) { |
| 607 CheckArrayAbuse(holder, "external elements read", key); | 606 CheckArrayAbuse(holder, "external elements read", key); |
| 608 } | 607 } |
| 609 | 608 |
| 610 return ElementsAccessorSubclass::GetImpl( | 609 return ElementsAccessorSubclass::GetImpl(holder, key, backing_store); |
| 611 receiver, holder, key, backing_store); | |
| 612 } | 610 } |
| 613 | 611 |
| 614 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( | 612 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, |
| 615 Handle<Object> receiver, | 613 Handle<FixedArrayBase> backing_store) { |
| 616 Handle<JSObject> obj, | |
| 617 uint32_t key, | |
| 618 Handle<FixedArrayBase> backing_store) { | |
| 619 if (key < ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) { | 614 if (key < ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) { |
| 620 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); | 615 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
| 621 } else { | 616 } else { |
| 622 return backing_store->GetIsolate()->factory()->the_hole_value(); | 617 return backing_store->GetIsolate()->factory()->the_hole_value(); |
| 623 } | 618 } |
| 624 } | 619 } |
| 625 | 620 |
| 626 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( | 621 virtual PropertyAttributes GetAttributes( |
| 627 Handle<JSObject> holder, uint32_t key, | 622 JSObject* holder, uint32_t key, FixedArrayBase* backing_store) final { |
| 628 Handle<FixedArrayBase> backing_store) final { | |
| 629 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, | 623 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, |
| 630 backing_store); | 624 backing_store); |
| 631 } | 625 } |
| 632 | 626 |
| 633 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 627 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key, |
| 634 Handle<JSObject> obj, | 628 FixedArrayBase* backing_store) { |
| 635 uint32_t key, | 629 if (key >= ElementsAccessorSubclass::GetCapacityImpl(obj, backing_store)) { |
| 636 Handle<FixedArrayBase> backing_store) { | |
| 637 if (key >= | |
| 638 ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) { | |
| 639 return ABSENT; | 630 return ABSENT; |
| 640 } | 631 } |
| 641 return | 632 return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE; |
| 642 Handle<BackingStore>::cast(backing_store)->is_the_hole(key) | |
| 643 ? ABSENT : NONE; | |
| 644 } | 633 } |
| 645 | 634 |
| 646 MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( | 635 virtual MaybeHandle<AccessorPair> GetAccessorPair( |
| 647 Handle<JSObject> holder, uint32_t key, | 636 Handle<JSObject> holder, uint32_t key, |
| 648 Handle<FixedArrayBase> backing_store) final { | 637 Handle<FixedArrayBase> backing_store) final { |
| 649 return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key, | 638 return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key, |
| 650 backing_store); | 639 backing_store); |
| 651 } | 640 } |
| 652 | 641 |
| 653 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( | 642 static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
| 654 Handle<JSObject> obj, | 643 Handle<JSObject> obj, uint32_t key, |
| 655 uint32_t key, | |
| 656 Handle<FixedArrayBase> backing_store) { | 644 Handle<FixedArrayBase> backing_store) { |
| 657 return MaybeHandle<AccessorPair>(); | 645 return MaybeHandle<AccessorPair>(); |
| 658 } | 646 } |
| 659 | 647 |
| 660 MUST_USE_RESULT virtual MaybeHandle<Object> SetLength( | 648 MUST_USE_RESULT virtual MaybeHandle<Object> SetLength( |
| 661 Handle<JSArray> array, Handle<Object> length) final { | 649 Handle<JSArray> array, Handle<Object> length) final { |
| 662 return ElementsAccessorSubclass::SetLengthImpl( | 650 return ElementsAccessorSubclass::SetLengthImpl( |
| 663 array, length, handle(array->elements())); | 651 array, length, handle(array->elements())); |
| 664 } | 652 } |
| 665 | 653 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 // intentionally to avoid ArrayConcat() builtin performance degradation. | 715 // intentionally to avoid ArrayConcat() builtin performance degradation. |
| 728 // | 716 // |
| 729 // Details: The idea is that allocations actually happen only in case of | 717 // Details: The idea is that allocations actually happen only in case of |
| 730 // copying from object with fast double elements to object with object | 718 // copying from object with fast double elements to object with object |
| 731 // elements. In all the other cases there are no allocations performed and | 719 // elements. In all the other cases there are no allocations performed and |
| 732 // handle creation causes noticeable performance degradation of the builtin. | 720 // handle creation causes noticeable performance degradation of the builtin. |
| 733 ElementsAccessorSubclass::CopyElementsImpl( | 721 ElementsAccessorSubclass::CopyElementsImpl( |
| 734 from, from_start, *to, from_kind, to_start, packed_size, copy_size); | 722 from, from_start, *to, from_kind, to_start, packed_size, copy_size); |
| 735 } | 723 } |
| 736 | 724 |
| 737 virtual MaybeHandle<FixedArray> AddElementsToFixedArray( | 725 virtual Handle<FixedArray> AddElementsToFixedArray( |
| 738 Handle<JSObject> receiver, Handle<FixedArray> to, | 726 Handle<JSObject> receiver, Handle<FixedArray> to, |
| 739 FixedArray::KeyFilter filter) final { | 727 FixedArray::KeyFilter filter) final { |
| 740 Handle<FixedArrayBase> from(receiver->elements()); | 728 Handle<FixedArrayBase> from(receiver->elements()); |
| 741 | 729 |
| 742 int len0 = to->length(); | 730 int len0 = to->length(); |
| 743 #ifdef ENABLE_SLOW_DCHECKS | 731 #ifdef ENABLE_SLOW_DCHECKS |
| 744 if (FLAG_enable_slow_asserts) { | 732 if (FLAG_enable_slow_asserts) { |
| 745 for (int i = 0; i < len0; i++) { | 733 for (int i = 0; i < len0; i++) { |
| 746 DCHECK(!to->get(i)->IsTheHole()); | 734 DCHECK(!to->get(i)->IsTheHole()); |
| 747 } | 735 } |
| 748 } | 736 } |
| 749 #endif | 737 #endif |
| 750 | 738 |
| 751 // Optimize if 'other' is empty. | 739 // Optimize if 'other' is empty. |
| 752 // We cannot optimize if 'this' is empty, as other may have holes. | 740 // We cannot optimize if 'this' is empty, as other may have holes. |
| 753 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); | 741 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); |
| 754 if (len1 == 0) return to; | 742 if (len1 == 0) return to; |
| 755 | 743 |
| 756 Isolate* isolate = from->GetIsolate(); | 744 Isolate* isolate = from->GetIsolate(); |
| 757 | 745 |
| 758 // Compute how many elements are not in other. | 746 // Compute how many elements are not in other. |
| 759 uint32_t extra = 0; | 747 uint32_t extra = 0; |
| 760 for (uint32_t y = 0; y < len1; y++) { | 748 for (uint32_t y = 0; y < len1; y++) { |
| 761 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); | 749 if (ElementsAccessorSubclass::HasIndexImpl(*from, y)) { |
| 762 if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) { | 750 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); |
| 763 Handle<Object> value; | 751 Handle<Object> value = |
| 764 ASSIGN_RETURN_ON_EXCEPTION( | 752 ElementsAccessorSubclass::GetImpl(receiver, key, from); |
| 765 isolate, value, | |
| 766 ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from), | |
| 767 FixedArray); | |
| 768 | 753 |
| 769 DCHECK(!value->IsTheHole()); | 754 DCHECK(!value->IsTheHole()); |
| 755 DCHECK(!value->IsAccessorPair()); |
| 756 DCHECK(!value->IsExecutableAccessorInfo()); |
| 770 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { | 757 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { |
| 771 continue; | 758 continue; |
| 772 } | 759 } |
| 773 if (!HasKey(to, value)) { | 760 if (!HasKey(to, value)) { |
| 774 extra++; | 761 extra++; |
| 775 } | 762 } |
| 776 } | 763 } |
| 777 } | 764 } |
| 778 | 765 |
| 779 if (extra == 0) return to; | 766 if (extra == 0) return to; |
| 780 | 767 |
| 781 // Allocate the result | 768 // Allocate the result |
| 782 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra); | 769 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra); |
| 783 | 770 |
| 784 // Fill in the content | 771 // Fill in the content |
| 785 { | 772 { |
| 786 DisallowHeapAllocation no_gc; | 773 DisallowHeapAllocation no_gc; |
| 787 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 774 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 788 for (int i = 0; i < len0; i++) { | 775 for (int i = 0; i < len0; i++) { |
| 789 Object* e = to->get(i); | 776 Object* e = to->get(i); |
| 790 DCHECK(e->IsString() || e->IsNumber()); | 777 DCHECK(e->IsString() || e->IsNumber()); |
| 791 result->set(i, e, mode); | 778 result->set(i, e, mode); |
| 792 } | 779 } |
| 793 } | 780 } |
| 794 // Fill in the extra values. | 781 // Fill in the extra values. |
| 795 uint32_t index = 0; | 782 uint32_t index = 0; |
| 796 for (uint32_t y = 0; y < len1; y++) { | 783 for (uint32_t y = 0; y < len1; y++) { |
| 797 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); | 784 if (ElementsAccessorSubclass::HasIndexImpl(*from, y)) { |
| 798 if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) { | 785 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); |
| 799 Handle<Object> value; | 786 Handle<Object> value = |
| 800 ASSIGN_RETURN_ON_EXCEPTION( | 787 ElementsAccessorSubclass::GetImpl(receiver, key, from); |
| 801 isolate, value, | 788 DCHECK(!value->IsAccessorPair()); |
| 802 ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from), | 789 DCHECK(!value->IsExecutableAccessorInfo()); |
| 803 FixedArray); | |
| 804 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { | 790 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { |
| 805 continue; | 791 continue; |
| 806 } | 792 } |
| 807 if (!value->IsTheHole() && !HasKey(to, value)) { | 793 if (!value->IsTheHole() && !HasKey(to, value)) { |
| 808 result->set(len0 + index, *value); | 794 result->set(len0 + index, *value); |
| 809 index++; | 795 index++; |
| 810 } | 796 } |
| 811 } | 797 } |
| 812 } | 798 } |
| 813 DCHECK(extra == index); | 799 DCHECK(extra == index); |
| 814 return result; | 800 return result; |
| 815 } | 801 } |
| 816 | 802 |
| 817 protected: | 803 protected: |
| 818 static uint32_t GetCapacityImpl(JSObject* holder, | 804 static uint32_t GetCapacityImpl(JSObject* holder, |
| 819 FixedArrayBase* backing_store) { | 805 FixedArrayBase* backing_store) { |
| 820 return backing_store->length(); | 806 return backing_store->length(); |
| 821 } | 807 } |
| 822 | 808 |
| 823 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { | 809 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { |
| 824 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); | 810 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); |
| 825 } | 811 } |
| 826 | 812 |
| 813 static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) { |
| 814 return true; |
| 815 } |
| 816 |
| 817 virtual bool HasIndex(FixedArrayBase* backing_store, uint32_t index) final { |
| 818 return ElementsAccessorSubclass::HasIndexImpl(backing_store, index); |
| 819 } |
| 820 |
| 827 static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store, | 821 static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store, |
| 828 uint32_t index) { | 822 uint32_t index) { |
| 829 return index; | 823 return index; |
| 830 } | 824 } |
| 831 | 825 |
| 832 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, | 826 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, |
| 833 uint32_t index) final { | 827 uint32_t index) final { |
| 834 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); | 828 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); |
| 835 } | 829 } |
| 836 | 830 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 static bool HasElementImpl( | 995 static bool HasElementImpl( |
| 1002 Handle<JSObject> holder, | 996 Handle<JSObject> holder, |
| 1003 uint32_t key, | 997 uint32_t key, |
| 1004 Handle<FixedArrayBase> backing_store) { | 998 Handle<FixedArrayBase> backing_store) { |
| 1005 if (key >= static_cast<uint32_t>(backing_store->length())) { | 999 if (key >= static_cast<uint32_t>(backing_store->length())) { |
| 1006 return false; | 1000 return false; |
| 1007 } | 1001 } |
| 1008 return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key); | 1002 return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key); |
| 1009 } | 1003 } |
| 1010 | 1004 |
| 1005 static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) { |
| 1006 return !BackingStore::cast(backing_store)->is_the_hole(index); |
| 1007 } |
| 1008 |
| 1011 static void ValidateContents(Handle<JSObject> holder, int length) { | 1009 static void ValidateContents(Handle<JSObject> holder, int length) { |
| 1012 #if DEBUG | 1010 #if DEBUG |
| 1013 Isolate* isolate = holder->GetIsolate(); | 1011 Isolate* isolate = holder->GetIsolate(); |
| 1014 HandleScope scope(isolate); | 1012 HandleScope scope(isolate); |
| 1015 Handle<FixedArrayBase> elements(holder->elements(), isolate); | 1013 Handle<FixedArrayBase> elements(holder->elements(), isolate); |
| 1016 Map* map = elements->map(); | 1014 Map* map = elements->map(); |
| 1017 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && | 1015 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && |
| 1018 (map == isolate->heap()->fixed_array_map() || | 1016 (map == isolate->heap()->fixed_array_map() || |
| 1019 map == isolate->heap()->fixed_cow_array_map())) || | 1017 map == isolate->heap()->fixed_cow_array_map())) || |
| 1020 (IsFastDoubleElementsKind(KindTraits::Kind) == | 1018 (IsFastDoubleElementsKind(KindTraits::Kind) == |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1277 : ElementsAccessorBase<AccessorClass, | 1275 : ElementsAccessorBase<AccessorClass, |
| 1278 ElementsKindTraits<Kind> >(name) {} | 1276 ElementsKindTraits<Kind> >(name) {} |
| 1279 | 1277 |
| 1280 protected: | 1278 protected: |
| 1281 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; | 1279 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; |
| 1282 typedef TypedElementsAccessor<Kind> AccessorClass; | 1280 typedef TypedElementsAccessor<Kind> AccessorClass; |
| 1283 | 1281 |
| 1284 friend class ElementsAccessorBase<AccessorClass, | 1282 friend class ElementsAccessorBase<AccessorClass, |
| 1285 ElementsKindTraits<Kind> >; | 1283 ElementsKindTraits<Kind> >; |
| 1286 | 1284 |
| 1287 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( | 1285 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, |
| 1288 Handle<Object> receiver, | 1286 Handle<FixedArrayBase> backing_store) { |
| 1289 Handle<JSObject> obj, | |
| 1290 uint32_t key, | |
| 1291 Handle<FixedArrayBase> backing_store) { | |
| 1292 if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) { | 1287 if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) { |
| 1293 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); | 1288 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
| 1294 } else { | 1289 } else { |
| 1295 return backing_store->GetIsolate()->factory()->undefined_value(); | 1290 return backing_store->GetIsolate()->factory()->undefined_value(); |
| 1296 } | 1291 } |
| 1297 } | 1292 } |
| 1298 | 1293 |
| 1299 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1294 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key, |
| 1300 Handle<JSObject> obj, | 1295 FixedArrayBase* backing_store) { |
| 1301 uint32_t key, | 1296 return key < AccessorClass::GetCapacityImpl(obj, backing_store) ? NONE |
| 1302 Handle<FixedArrayBase> backing_store) { | 1297 : ABSENT; |
| 1303 return key < AccessorClass::GetCapacityImpl(*obj, *backing_store) ? NONE | |
| 1304 : ABSENT; | |
| 1305 } | 1298 } |
| 1306 | 1299 |
| 1307 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( | 1300 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( |
| 1308 Handle<JSObject> obj, | 1301 Handle<JSObject> obj, |
| 1309 Handle<Object> length, | 1302 Handle<Object> length, |
| 1310 Handle<FixedArrayBase> backing_store) { | 1303 Handle<FixedArrayBase> backing_store) { |
| 1311 // External arrays do not support changing their length. | 1304 // External arrays do not support changing their length. |
| 1312 UNREACHABLE(); | 1305 UNREACHABLE(); |
| 1313 return obj; | 1306 return obj; |
| 1314 } | 1307 } |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1474 | 1467 |
| 1475 protected: | 1468 protected: |
| 1476 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 1469 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
| 1477 ElementsKindTraits<DICTIONARY_ELEMENTS> >; | 1470 ElementsKindTraits<DICTIONARY_ELEMENTS> >; |
| 1478 | 1471 |
| 1479 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( | 1472 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( |
| 1480 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { | 1473 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { |
| 1481 return DeleteCommon(obj, key, language_mode); | 1474 return DeleteCommon(obj, key, language_mode); |
| 1482 } | 1475 } |
| 1483 | 1476 |
| 1484 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( | 1477 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, |
| 1485 Handle<Object> receiver, | 1478 Handle<FixedArrayBase> store) { |
| 1486 Handle<JSObject> obj, | |
| 1487 uint32_t key, | |
| 1488 Handle<FixedArrayBase> store) { | |
| 1489 Handle<SeededNumberDictionary> backing_store = | 1479 Handle<SeededNumberDictionary> backing_store = |
| 1490 Handle<SeededNumberDictionary>::cast(store); | 1480 Handle<SeededNumberDictionary>::cast(store); |
| 1491 Isolate* isolate = backing_store->GetIsolate(); | 1481 Isolate* isolate = backing_store->GetIsolate(); |
| 1492 int entry = backing_store->FindEntry(key); | 1482 int entry = backing_store->FindEntry(key); |
| 1493 if (entry != SeededNumberDictionary::kNotFound) { | 1483 if (entry != SeededNumberDictionary::kNotFound) { |
| 1494 Handle<Object> element(backing_store->ValueAt(entry), isolate); | 1484 return handle(backing_store->ValueAt(entry), isolate); |
| 1495 PropertyDetails details = backing_store->DetailsAt(entry); | |
| 1496 if (details.type() == ACCESSOR_CONSTANT) { | |
| 1497 return JSObject::GetElementWithCallback( | |
| 1498 obj, receiver, element, key, obj); | |
| 1499 } else { | |
| 1500 return element; | |
| 1501 } | |
| 1502 } | 1485 } |
| 1503 return isolate->factory()->the_hole_value(); | 1486 return isolate->factory()->the_hole_value(); |
| 1504 } | 1487 } |
| 1505 | 1488 |
| 1506 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1489 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key, |
| 1507 Handle<JSObject> obj, | 1490 FixedArrayBase* backing_store) { |
| 1508 uint32_t key, | 1491 SeededNumberDictionary* dictionary = |
| 1509 Handle<FixedArrayBase> backing_store) { | 1492 SeededNumberDictionary::cast(backing_store); |
| 1510 Handle<SeededNumberDictionary> dictionary = | |
| 1511 Handle<SeededNumberDictionary>::cast(backing_store); | |
| 1512 int entry = dictionary->FindEntry(key); | 1493 int entry = dictionary->FindEntry(key); |
| 1513 if (entry != SeededNumberDictionary::kNotFound) { | 1494 if (entry != SeededNumberDictionary::kNotFound) { |
| 1514 return dictionary->DetailsAt(entry).attributes(); | 1495 return dictionary->DetailsAt(entry).attributes(); |
| 1515 } | 1496 } |
| 1516 return ABSENT; | 1497 return ABSENT; |
| 1517 } | 1498 } |
| 1518 | 1499 |
| 1519 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( | 1500 static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
| 1520 Handle<JSObject> obj, | 1501 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> store) { |
| 1521 uint32_t key, | |
| 1522 Handle<FixedArrayBase> store) { | |
| 1523 Handle<SeededNumberDictionary> backing_store = | 1502 Handle<SeededNumberDictionary> backing_store = |
| 1524 Handle<SeededNumberDictionary>::cast(store); | 1503 Handle<SeededNumberDictionary>::cast(store); |
| 1525 int entry = backing_store->FindEntry(key); | 1504 int entry = backing_store->FindEntry(key); |
| 1526 if (entry != SeededNumberDictionary::kNotFound && | 1505 if (entry != SeededNumberDictionary::kNotFound && |
| 1527 backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT && | 1506 backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT && |
| 1528 backing_store->ValueAt(entry)->IsAccessorPair()) { | 1507 backing_store->ValueAt(entry)->IsAccessorPair()) { |
| 1529 return handle(AccessorPair::cast(backing_store->ValueAt(entry))); | 1508 return handle(AccessorPair::cast(backing_store->ValueAt(entry))); |
| 1530 } | 1509 } |
| 1531 return MaybeHandle<AccessorPair>(); | 1510 return MaybeHandle<AccessorPair>(); |
| 1532 } | 1511 } |
| 1533 | 1512 |
| 1534 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, | 1513 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, |
| 1535 Handle<FixedArrayBase> store) { | 1514 Handle<FixedArrayBase> store) { |
| 1536 Handle<SeededNumberDictionary> backing_store = | 1515 Handle<SeededNumberDictionary> backing_store = |
| 1537 Handle<SeededNumberDictionary>::cast(store); | 1516 Handle<SeededNumberDictionary>::cast(store); |
| 1538 return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound; | 1517 return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound; |
| 1539 } | 1518 } |
| 1540 | 1519 |
| 1520 static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) { |
| 1521 DisallowHeapAllocation no_gc; |
| 1522 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
| 1523 Object* key = dict->KeyAt(index); |
| 1524 return !key->IsTheHole(); |
| 1525 } |
| 1526 |
| 1541 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) { | 1527 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) { |
| 1542 DisallowHeapAllocation no_gc; | 1528 DisallowHeapAllocation no_gc; |
| 1543 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1529 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
| 1544 Object* key = dict->KeyAt(index); | 1530 Object* key = dict->KeyAt(index); |
| 1545 return Smi::cast(key)->value(); | 1531 return Smi::cast(key)->value(); |
| 1546 } | 1532 } |
| 1547 | 1533 |
| 1548 static uint32_t GetIndexForKeyImpl(FixedArrayBase* store, uint32_t key) { | 1534 static uint32_t GetIndexForKeyImpl(FixedArrayBase* store, uint32_t key) { |
| 1549 DisallowHeapAllocation no_gc; | 1535 DisallowHeapAllocation no_gc; |
| 1550 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1536 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1568 public: | 1554 public: |
| 1569 explicit SloppyArgumentsElementsAccessor(const char* name) | 1555 explicit SloppyArgumentsElementsAccessor(const char* name) |
| 1570 : ElementsAccessorBase< | 1556 : ElementsAccessorBase< |
| 1571 SloppyArgumentsElementsAccessor, | 1557 SloppyArgumentsElementsAccessor, |
| 1572 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} | 1558 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} |
| 1573 protected: | 1559 protected: |
| 1574 friend class ElementsAccessorBase< | 1560 friend class ElementsAccessorBase< |
| 1575 SloppyArgumentsElementsAccessor, | 1561 SloppyArgumentsElementsAccessor, |
| 1576 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >; | 1562 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >; |
| 1577 | 1563 |
| 1578 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( | 1564 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, |
| 1579 Handle<Object> receiver, | 1565 Handle<FixedArrayBase> parameters) { |
| 1580 Handle<JSObject> obj, | |
| 1581 uint32_t key, | |
| 1582 Handle<FixedArrayBase> parameters) { | |
| 1583 Isolate* isolate = obj->GetIsolate(); | 1566 Isolate* isolate = obj->GetIsolate(); |
| 1584 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); | 1567 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |
| 1585 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | 1568 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); |
| 1586 if (!probe->IsTheHole()) { | 1569 if (!probe->IsTheHole()) { |
| 1587 DisallowHeapAllocation no_gc; | 1570 DisallowHeapAllocation no_gc; |
| 1588 Context* context = Context::cast(parameter_map->get(0)); | 1571 Context* context = Context::cast(parameter_map->get(0)); |
| 1589 int context_index = Handle<Smi>::cast(probe)->value(); | 1572 int context_index = Handle<Smi>::cast(probe)->value(); |
| 1590 DCHECK(!context->get(context_index)->IsTheHole()); | 1573 DCHECK(!context->get(context_index)->IsTheHole()); |
| 1591 return handle(context->get(context_index), isolate); | 1574 return handle(context->get(context_index), isolate); |
| 1592 } else { | 1575 } else { |
| 1593 // Object is not mapped, defer to the arguments. | 1576 // Object is not mapped, defer to the arguments. |
| 1594 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), | 1577 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), |
| 1595 isolate); | 1578 isolate); |
| 1596 Handle<Object> result; | 1579 Handle<Object> result = |
| 1597 ASSIGN_RETURN_ON_EXCEPTION( | 1580 ElementsAccessor::ForArray(arguments)->Get(obj, key, arguments); |
| 1598 isolate, result, | |
| 1599 ElementsAccessor::ForArray(arguments)->Get( | |
| 1600 receiver, obj, key, arguments), | |
| 1601 Object); | |
| 1602 // Elements of the arguments object in slow mode might be slow aliases. | 1581 // Elements of the arguments object in slow mode might be slow aliases. |
| 1603 if (result->IsAliasedArgumentsEntry()) { | 1582 if (result->IsAliasedArgumentsEntry()) { |
| 1604 DisallowHeapAllocation no_gc; | 1583 DisallowHeapAllocation no_gc; |
| 1605 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); | 1584 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); |
| 1606 Context* context = Context::cast(parameter_map->get(0)); | 1585 Context* context = Context::cast(parameter_map->get(0)); |
| 1607 int context_index = entry->aliased_context_slot(); | 1586 int context_index = entry->aliased_context_slot(); |
| 1608 DCHECK(!context->get(context_index)->IsTheHole()); | 1587 DCHECK(!context->get(context_index)->IsTheHole()); |
| 1609 return handle(context->get(context_index), isolate); | 1588 return handle(context->get(context_index), isolate); |
| 1610 } else { | 1589 } else { |
| 1611 return result; | 1590 return result; |
| 1612 } | 1591 } |
| 1613 } | 1592 } |
| 1614 } | 1593 } |
| 1615 | 1594 |
| 1616 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1595 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key, |
| 1617 Handle<JSObject> obj, | 1596 FixedArrayBase* backing_store) { |
| 1618 uint32_t key, | 1597 FixedArray* parameter_map = FixedArray::cast(backing_store); |
| 1619 Handle<FixedArrayBase> backing_store) { | 1598 Object* probe = GetParameterMapArg(parameter_map, key); |
| 1620 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); | |
| 1621 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | |
| 1622 if (!probe->IsTheHole()) { | 1599 if (!probe->IsTheHole()) { |
| 1623 return NONE; | 1600 return NONE; |
| 1624 } else { | 1601 } else { |
| 1625 // If not aliased, check the arguments. | 1602 // If not aliased, check the arguments. |
| 1626 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); | 1603 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 1627 return ElementsAccessor::ForArray(arguments) | 1604 return ElementsAccessor::ForArray(arguments) |
| 1628 ->GetAttributes(obj, key, arguments); | 1605 ->GetAttributes(obj, key, arguments); |
| 1629 } | 1606 } |
| 1630 } | 1607 } |
| 1631 | 1608 |
| 1632 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( | 1609 static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
| 1633 Handle<JSObject> obj, | 1610 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) { |
| 1634 uint32_t key, | |
| 1635 Handle<FixedArrayBase> parameters) { | |
| 1636 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); | 1611 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |
| 1637 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | 1612 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), |
| 1613 obj->GetIsolate()); |
| 1638 if (!probe->IsTheHole()) { | 1614 if (!probe->IsTheHole()) { |
| 1639 return MaybeHandle<AccessorPair>(); | 1615 return MaybeHandle<AccessorPair>(); |
| 1640 } else { | 1616 } else { |
| 1641 // If not aliased, check the arguments. | 1617 // If not aliased, check the arguments. |
| 1642 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); | 1618 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
| 1643 return ElementsAccessor::ForArray(arguments) | 1619 return ElementsAccessor::ForArray(arguments) |
| 1644 ->GetAccessorPair(obj, key, arguments); | 1620 ->GetAccessorPair(obj, key, arguments); |
| 1645 } | 1621 } |
| 1646 } | 1622 } |
| 1647 | 1623 |
| 1648 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( | 1624 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( |
| 1649 Handle<JSObject> obj, | 1625 Handle<JSObject> obj, |
| 1650 Handle<Object> length, | 1626 Handle<Object> length, |
| 1651 Handle<FixedArrayBase> parameter_map) { | 1627 Handle<FixedArrayBase> parameter_map) { |
| 1652 // TODO(mstarzinger): This was never implemented but will be used once we | 1628 // TODO(mstarzinger): This was never implemented but will be used once we |
| 1653 // correctly implement [[DefineOwnProperty]] on arrays. | 1629 // correctly implement [[DefineOwnProperty]] on arrays. |
| 1654 UNIMPLEMENTED(); | 1630 UNIMPLEMENTED(); |
| 1655 return obj; | 1631 return obj; |
| 1656 } | 1632 } |
| 1657 | 1633 |
| 1658 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( | 1634 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( |
| 1659 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { | 1635 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { |
| 1660 Isolate* isolate = obj->GetIsolate(); | 1636 Isolate* isolate = obj->GetIsolate(); |
| 1661 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); | 1637 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); |
| 1662 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | 1638 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); |
| 1663 if (!probe->IsTheHole()) { | 1639 if (!probe->IsTheHole()) { |
| 1664 // TODO(kmillikin): We could check if this was the last aliased | 1640 // TODO(kmillikin): We could check if this was the last aliased |
| 1665 // parameter, and revert to normal elements in that case. That | 1641 // parameter, and revert to normal elements in that case. That |
| 1666 // would enable GC of the context. | 1642 // would enable GC of the context. |
| 1667 parameter_map->set_the_hole(key + 2); | 1643 parameter_map->set_the_hole(key + 2); |
| 1668 } else { | 1644 } else { |
| 1669 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); | 1645 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
| 1670 if (arguments->IsDictionary()) { | 1646 if (arguments->IsDictionary()) { |
| 1671 return DictionaryElementsAccessor::DeleteCommon(obj, key, | 1647 return DictionaryElementsAccessor::DeleteCommon(obj, key, |
| 1672 language_mode); | 1648 language_mode); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1685 FixedArrayBase* to, ElementsKind from_kind, | 1661 FixedArrayBase* to, ElementsKind from_kind, |
| 1686 uint32_t to_start, int packed_size, | 1662 uint32_t to_start, int packed_size, |
| 1687 int copy_size) { | 1663 int copy_size) { |
| 1688 UNREACHABLE(); | 1664 UNREACHABLE(); |
| 1689 } | 1665 } |
| 1690 | 1666 |
| 1691 static uint32_t GetCapacityImpl(JSObject* holder, | 1667 static uint32_t GetCapacityImpl(JSObject* holder, |
| 1692 FixedArrayBase* backing_store) { | 1668 FixedArrayBase* backing_store) { |
| 1693 FixedArray* parameter_map = FixedArray::cast(backing_store); | 1669 FixedArray* parameter_map = FixedArray::cast(backing_store); |
| 1694 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 1670 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
| 1695 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 1671 return parameter_map->length() - 2 + |
| 1696 ForArray(arguments)->GetCapacity(holder, arguments)); | 1672 ForArray(arguments)->GetCapacity(holder, arguments); |
| 1697 } | 1673 } |
| 1698 | 1674 |
| 1699 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, uint32_t index) { | 1675 static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) { |
| 1700 return index; | 1676 FixedArray* parameter_map = FixedArray::cast(parameters); |
| 1677 uint32_t length = parameter_map->length() - 2; |
| 1678 if (index < length) { |
| 1679 return !GetParameterMapArg(parameter_map, index)->IsTheHole(); |
| 1680 } |
| 1681 |
| 1682 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
| 1683 return ForArray(arguments)->HasIndex(arguments, index - length); |
| 1701 } | 1684 } |
| 1702 | 1685 |
| 1703 static uint32_t GetIndexForKeyImpl(FixedArrayBase* dict, uint32_t key) { | 1686 static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters, |
| 1704 return key; | 1687 uint32_t index) { |
| 1688 FixedArray* parameter_map = FixedArray::cast(parameters); |
| 1689 uint32_t length = parameter_map->length() - 2; |
| 1690 if (index < length) return index; |
| 1691 |
| 1692 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 1693 return ForArray(arguments)->GetKeyForIndex(arguments, index - length); |
| 1705 } | 1694 } |
| 1706 | 1695 |
| 1707 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 1696 static uint32_t GetIndexForKeyImpl(FixedArrayBase* parameters, uint32_t key) { |
| 1708 uint32_t index) { | 1697 FixedArray* parameter_map = FixedArray::cast(parameters); |
| 1709 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); | 1698 Object* probe = GetParameterMapArg(parameter_map, key); |
| 1699 if (!probe->IsTheHole()) return key; |
| 1700 |
| 1701 uint32_t length = parameter_map->length() - 2; |
| 1702 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 1703 return length + |
| 1704 ElementsAccessor::ForArray(arguments) |
| 1705 ->GetIndexForKey(arguments, key); |
| 1710 } | 1706 } |
| 1711 | 1707 |
| 1708 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, |
| 1709 uint32_t index) { |
| 1710 FixedArray* parameter_map = FixedArray::cast(parameters); |
| 1711 uint32_t length = parameter_map->length() - 2; |
| 1712 if (index < length) { |
| 1713 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); |
| 1714 } |
| 1715 index -= length; |
| 1716 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 1717 return ElementsAccessor::ForArray(arguments)->GetDetails(arguments, index); |
| 1718 } |
| 1712 | 1719 |
| 1713 private: | 1720 private: |
| 1714 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, | 1721 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) { |
| 1715 Handle<FixedArray> parameter_map, | 1722 uint32_t length = parameter_map->length() - 2; |
| 1716 uint32_t key) { | 1723 return key < length |
| 1717 Isolate* isolate = holder->GetIsolate(); | 1724 ? parameter_map->get(key + 2) |
| 1718 uint32_t length = holder->IsJSArray() | 1725 : Object::cast(parameter_map->GetHeap()->the_hole_value()); |
| 1719 ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value() | |
| 1720 : parameter_map->length(); | |
| 1721 return key < (length - 2) | |
| 1722 ? handle(parameter_map->get(key + 2), isolate) | |
| 1723 : Handle<Object>::cast(isolate->factory()->the_hole_value()); | |
| 1724 } | 1726 } |
| 1725 }; | 1727 }; |
| 1726 | 1728 |
| 1727 | 1729 |
| 1728 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { | 1730 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { |
| 1729 return elements_accessors_[ElementsKindForArray(array)]; | 1731 return elements_accessors_[ElementsKindForArray(array)]; |
| 1730 } | 1732 } |
| 1731 | 1733 |
| 1732 | 1734 |
| 1733 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) { | 1735 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1794 } | 1796 } |
| 1795 } else { | 1797 } else { |
| 1796 return ThrowArrayLengthRangeError(isolate); | 1798 return ThrowArrayLengthRangeError(isolate); |
| 1797 } | 1799 } |
| 1798 } | 1800 } |
| 1799 | 1801 |
| 1800 // Slow case: The new length does not fit into a Smi or conversion | 1802 // Slow case: The new length does not fit into a Smi or conversion |
| 1801 // to slow elements is needed for other reasons. | 1803 // to slow elements is needed for other reasons. |
| 1802 if (length->IsNumber()) { | 1804 if (length->IsNumber()) { |
| 1803 uint32_t value; | 1805 uint32_t value; |
| 1804 if (length->ToArrayIndex(&value)) { | 1806 if (length->ToArrayLength(&value)) { |
| 1805 Handle<SeededNumberDictionary> dictionary = | 1807 Handle<SeededNumberDictionary> dictionary = |
| 1806 JSObject::NormalizeElements(array); | 1808 JSObject::NormalizeElements(array); |
| 1807 DCHECK(!dictionary.is_null()); | 1809 DCHECK(!dictionary.is_null()); |
| 1808 | 1810 |
| 1809 Handle<Object> new_length = DictionaryElementsAccessor:: | 1811 Handle<Object> new_length = DictionaryElementsAccessor:: |
| 1810 SetLengthWithoutNormalize(dictionary, array, length, value); | 1812 SetLengthWithoutNormalize(dictionary, array, length, value); |
| 1811 DCHECK(!new_length.is_null()); | 1813 DCHECK(!new_length.is_null()); |
| 1812 | 1814 |
| 1813 DCHECK(new_length->IsNumber()); | 1815 DCHECK(new_length->IsNumber()); |
| 1814 array->set_length(*new_length); | 1816 array->set_length(*new_length); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1914 break; | 1916 break; |
| 1915 } | 1917 } |
| 1916 | 1918 |
| 1917 array->set_elements(*elms); | 1919 array->set_elements(*elms); |
| 1918 array->set_length(Smi::FromInt(number_of_elements)); | 1920 array->set_length(Smi::FromInt(number_of_elements)); |
| 1919 return array; | 1921 return array; |
| 1920 } | 1922 } |
| 1921 | 1923 |
| 1922 } // namespace internal | 1924 } // namespace internal |
| 1923 } // namespace v8 | 1925 } // namespace v8 |
| OLD | NEW |