OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 static const ElementsKind Kind = KindParam; \ | 139 static const ElementsKind Kind = KindParam; \ |
140 typedef Store BackingStore; \ | 140 typedef Store BackingStore; \ |
141 }; | 141 }; |
142 ELEMENTS_LIST(ELEMENTS_TRAITS) | 142 ELEMENTS_LIST(ELEMENTS_TRAITS) |
143 #undef ELEMENTS_TRAITS | 143 #undef ELEMENTS_TRAITS |
144 | 144 |
145 | 145 |
146 ElementsAccessor** ElementsAccessor::elements_accessors_; | 146 ElementsAccessor** ElementsAccessor::elements_accessors_; |
147 | 147 |
148 | 148 |
149 static bool HasKey(FixedArray* array, Object* key) { | 149 static bool HasKey(Handle<FixedArray> array, Handle<Object> key_handle) { |
| 150 DisallowHeapAllocation no_gc; |
| 151 Object* key = *key_handle; |
150 int len0 = array->length(); | 152 int len0 = array->length(); |
151 for (int i = 0; i < len0; i++) { | 153 for (int i = 0; i < len0; i++) { |
152 Object* element = array->get(i); | 154 Object* element = array->get(i); |
153 if (element->IsSmi() && element == key) return true; | 155 if (element->IsSmi() && element == key) return true; |
154 if (element->IsString() && | 156 if (element->IsString() && |
155 key->IsString() && String::cast(element)->Equals(String::cast(key))) { | 157 key->IsString() && String::cast(element)->Equals(String::cast(key))) { |
156 return true; | 158 return true; |
157 } | 159 } |
158 } | 160 } |
159 return false; | 161 return false; |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 virtual void Validate(Handle<JSObject> holder) V8_FINAL V8_OVERRIDE { | 616 virtual void Validate(Handle<JSObject> holder) V8_FINAL V8_OVERRIDE { |
615 DisallowHeapAllocation no_gc; | 617 DisallowHeapAllocation no_gc; |
616 ElementsAccessorSubclass::ValidateImpl(*holder); | 618 ElementsAccessorSubclass::ValidateImpl(*holder); |
617 } | 619 } |
618 | 620 |
619 static bool HasElementImpl(Handle<Object> receiver, | 621 static bool HasElementImpl(Handle<Object> receiver, |
620 Handle<JSObject> holder, | 622 Handle<JSObject> holder, |
621 uint32_t key, | 623 uint32_t key, |
622 Handle<FixedArrayBase> backing_store) { | 624 Handle<FixedArrayBase> backing_store) { |
623 return ElementsAccessorSubclass::GetAttributesImpl( | 625 return ElementsAccessorSubclass::GetAttributesImpl( |
624 *receiver, *holder, key, *backing_store) != ABSENT; | 626 receiver, holder, key, backing_store) != ABSENT; |
625 } | 627 } |
626 | 628 |
627 virtual bool HasElement( | 629 virtual bool HasElement( |
628 Handle<Object> receiver, | 630 Handle<Object> receiver, |
629 Handle<JSObject> holder, | 631 Handle<JSObject> holder, |
630 uint32_t key, | 632 uint32_t key, |
631 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { | 633 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { |
632 return ElementsAccessorSubclass::HasElementImpl( | 634 return ElementsAccessorSubclass::HasElementImpl( |
633 receiver, holder, key, backing_store); | 635 receiver, holder, key, backing_store); |
634 } | 636 } |
(...skipping 15 matching lines...) Expand all Loading... |
650 } | 652 } |
651 | 653 |
652 return ElementsAccessorSubclass::GetImpl( | 654 return ElementsAccessorSubclass::GetImpl( |
653 receiver, holder, key, backing_store); | 655 receiver, holder, key, backing_store); |
654 } | 656 } |
655 | 657 |
656 static Handle<Object> GetImpl(Handle<Object> receiver, | 658 static Handle<Object> GetImpl(Handle<Object> receiver, |
657 Handle<JSObject> obj, | 659 Handle<JSObject> obj, |
658 uint32_t key, | 660 uint32_t key, |
659 Handle<FixedArrayBase> backing_store) { | 661 Handle<FixedArrayBase> backing_store) { |
660 if (key < ElementsAccessorSubclass::GetCapacityImpl(*backing_store)) { | 662 if (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { |
661 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); | 663 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
662 } else { | 664 } else { |
663 return backing_store->GetIsolate()->factory()->the_hole_value(); | 665 return backing_store->GetIsolate()->factory()->the_hole_value(); |
664 } | 666 } |
665 } | 667 } |
666 | 668 |
667 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( | 669 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( |
668 Handle<Object> receiver, | 670 Handle<Object> receiver, |
669 Handle<JSObject> holder, | 671 Handle<JSObject> holder, |
670 uint32_t key, | 672 uint32_t key, |
671 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { | 673 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { |
672 return ElementsAccessorSubclass::GetAttributesImpl( | 674 return ElementsAccessorSubclass::GetAttributesImpl( |
673 *receiver, *holder, key, *backing_store); | |
674 } | |
675 | |
676 // TODO(ishell): To be removed once elements.cc is handlified. | |
677 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( | |
678 Object* receiver, | |
679 JSObject* holder, | |
680 uint32_t key, | |
681 FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE { | |
682 return ElementsAccessorSubclass::GetAttributesImpl( | |
683 receiver, holder, key, backing_store); | 675 receiver, holder, key, backing_store); |
684 } | 676 } |
685 | 677 |
686 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 678 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
687 Object* receiver, | 679 Handle<Object> receiver, |
688 JSObject* obj, | 680 Handle<JSObject> obj, |
689 uint32_t key, | 681 uint32_t key, |
690 FixedArrayBase* backing_store) { | 682 Handle<FixedArrayBase> backing_store) { |
691 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { | 683 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { |
692 return ABSENT; | 684 return ABSENT; |
693 } | 685 } |
694 return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE; | 686 return |
| 687 Handle<BackingStore>::cast(backing_store)->is_the_hole(key) |
| 688 ? ABSENT : NONE; |
695 } | 689 } |
696 | 690 |
697 MUST_USE_RESULT virtual PropertyType GetType( | 691 MUST_USE_RESULT virtual PropertyType GetType( |
698 Handle<Object> receiver, | 692 Handle<Object> receiver, |
699 Handle<JSObject> holder, | 693 Handle<JSObject> holder, |
700 uint32_t key, | 694 uint32_t key, |
701 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { | 695 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { |
702 return ElementsAccessorSubclass::GetTypeImpl( | 696 return ElementsAccessorSubclass::GetTypeImpl( |
703 *receiver, *holder, key, *backing_store); | |
704 } | |
705 | |
706 // TODO(ishell): To be removed once elements.cc is handlified. | |
707 MUST_USE_RESULT virtual PropertyType GetType( | |
708 Object* receiver, | |
709 JSObject* holder, | |
710 uint32_t key, | |
711 FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE { | |
712 return ElementsAccessorSubclass::GetTypeImpl( | |
713 receiver, holder, key, backing_store); | 697 receiver, holder, key, backing_store); |
714 } | 698 } |
715 | 699 |
716 MUST_USE_RESULT static PropertyType GetTypeImpl( | 700 MUST_USE_RESULT static PropertyType GetTypeImpl( |
717 Object* receiver, | 701 Handle<Object> receiver, |
718 JSObject* obj, | 702 Handle<JSObject> obj, |
719 uint32_t key, | 703 uint32_t key, |
720 FixedArrayBase* backing_store) { | 704 Handle<FixedArrayBase> backing_store) { |
721 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { | 705 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { |
722 return NONEXISTENT; | 706 return NONEXISTENT; |
723 } | 707 } |
724 return BackingStore::cast(backing_store)->is_the_hole(key) | 708 return |
725 ? NONEXISTENT : FIELD; | 709 Handle<BackingStore>::cast(backing_store)->is_the_hole(key) |
| 710 ? NONEXISTENT : FIELD; |
726 } | 711 } |
727 | 712 |
728 MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( | 713 MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( |
729 Handle<Object> receiver, | 714 Handle<Object> receiver, |
730 Handle<JSObject> holder, | 715 Handle<JSObject> holder, |
731 uint32_t key, | 716 uint32_t key, |
732 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { | 717 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { |
733 return ElementsAccessorSubclass::GetAccessorPairImpl( | 718 return ElementsAccessorSubclass::GetAccessorPairImpl( |
734 receiver, holder, key, backing_store); | 719 receiver, holder, key, backing_store); |
735 } | 720 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 #ifdef ENABLE_SLOW_ASSERTS | 813 #ifdef ENABLE_SLOW_ASSERTS |
829 if (FLAG_enable_slow_asserts) { | 814 if (FLAG_enable_slow_asserts) { |
830 for (int i = 0; i < len0; i++) { | 815 for (int i = 0; i < len0; i++) { |
831 ASSERT(!to->get(i)->IsTheHole()); | 816 ASSERT(!to->get(i)->IsTheHole()); |
832 } | 817 } |
833 } | 818 } |
834 #endif | 819 #endif |
835 | 820 |
836 // Optimize if 'other' is empty. | 821 // Optimize if 'other' is empty. |
837 // We cannot optimize if 'this' is empty, as other may have holes. | 822 // We cannot optimize if 'this' is empty, as other may have holes. |
838 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*from); | 823 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from); |
839 if (len1 == 0) return to; | 824 if (len1 == 0) return to; |
840 | 825 |
841 // Compute how many elements are not in other. | 826 // Compute how many elements are not in other. |
842 uint32_t extra = 0; | 827 uint32_t extra = 0; |
843 for (uint32_t y = 0; y < len1; y++) { | 828 for (uint32_t y = 0; y < len1; y++) { |
844 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); | 829 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); |
845 if (ElementsAccessorSubclass::HasElementImpl( | 830 if (ElementsAccessorSubclass::HasElementImpl( |
846 receiver, holder, key, from)) { | 831 receiver, holder, key, from)) { |
847 Handle<Object> value = | 832 Handle<Object> value = |
848 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); | 833 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); |
849 | 834 |
850 ASSERT(!value->IsTheHole()); | 835 ASSERT(!value->IsTheHole()); |
851 if (!HasKey(*to, *value)) { | 836 if (!HasKey(to, value)) { |
852 extra++; | 837 extra++; |
853 } | 838 } |
854 } | 839 } |
855 } | 840 } |
856 | 841 |
857 if (extra == 0) return to; | 842 if (extra == 0) return to; |
858 | 843 |
859 // Allocate the result | 844 // Allocate the result |
860 Isolate* isolate = from->GetIsolate(); | 845 Isolate* isolate = from->GetIsolate(); |
861 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra); | 846 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra); |
862 | 847 |
863 // Fill in the content | 848 // Fill in the content |
864 { | 849 { |
865 DisallowHeapAllocation no_gc; | 850 DisallowHeapAllocation no_gc; |
866 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 851 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
867 for (int i = 0; i < len0; i++) { | 852 for (int i = 0; i < len0; i++) { |
868 Object* e = to->get(i); | 853 Object* e = to->get(i); |
869 ASSERT(e->IsString() || e->IsNumber()); | 854 ASSERT(e->IsString() || e->IsNumber()); |
870 result->set(i, e, mode); | 855 result->set(i, e, mode); |
871 } | 856 } |
872 } | 857 } |
873 // Fill in the extra values. | 858 // Fill in the extra values. |
874 uint32_t index = 0; | 859 uint32_t index = 0; |
875 for (uint32_t y = 0; y < len1; y++) { | 860 for (uint32_t y = 0; y < len1; y++) { |
876 uint32_t key = | 861 uint32_t key = |
877 ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); | 862 ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); |
878 if (ElementsAccessorSubclass::HasElementImpl( | 863 if (ElementsAccessorSubclass::HasElementImpl( |
879 receiver, holder, key, from)) { | 864 receiver, holder, key, from)) { |
880 Handle<Object> value = | 865 Handle<Object> value = |
881 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); | 866 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); |
882 if (!value->IsTheHole() && !HasKey(*to, *value)) { | 867 if (!value->IsTheHole() && !HasKey(to, value)) { |
883 result->set(len0 + index, *value); | 868 result->set(len0 + index, *value); |
884 index++; | 869 index++; |
885 } | 870 } |
886 } | 871 } |
887 } | 872 } |
888 ASSERT(extra == index); | 873 ASSERT(extra == index); |
889 return result; | 874 return result; |
890 } | 875 } |
891 | 876 |
892 protected: | 877 protected: |
893 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { | 878 static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) { |
894 return backing_store->length(); | 879 return backing_store->length(); |
895 } | 880 } |
896 | 881 |
897 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) | 882 virtual uint32_t GetCapacity(Handle<FixedArrayBase> backing_store) |
898 V8_FINAL V8_OVERRIDE { | 883 V8_FINAL V8_OVERRIDE { |
899 return ElementsAccessorSubclass::GetCapacityImpl(backing_store); | 884 return ElementsAccessorSubclass::GetCapacityImpl(backing_store); |
900 } | 885 } |
901 | 886 |
902 static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store, | 887 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> backing_store, |
903 uint32_t index) { | 888 uint32_t index) { |
904 return index; | 889 return index; |
905 } | 890 } |
906 | 891 |
907 virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store, | 892 virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store, |
908 uint32_t index) V8_FINAL V8_OVERRIDE { | 893 uint32_t index) V8_FINAL V8_OVERRIDE { |
909 return ElementsAccessorSubclass::GetKeyForIndexImpl(*backing_store, index); | 894 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); |
910 } | 895 } |
911 | 896 |
912 private: | 897 private: |
913 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); | 898 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); |
914 }; | 899 }; |
915 | 900 |
916 | 901 |
917 // Super class for all fast element arrays. | 902 // Super class for all fast element arrays. |
918 template<typename FastElementsAccessorSubclass, | 903 template<typename FastElementsAccessorSubclass, |
919 typename KindTraits, | 904 typename KindTraits, |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1087 ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) || | 1072 ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) || |
1088 static_cast<Object*>(backing_store->get(i))->IsSmi()) || | 1073 static_cast<Object*>(backing_store->get(i))->IsSmi()) || |
1089 (IsFastHoleyElementsKind(KindTraits::Kind) == | 1074 (IsFastHoleyElementsKind(KindTraits::Kind) == |
1090 backing_store->is_the_hole(i))); | 1075 backing_store->is_the_hole(i))); |
1091 } | 1076 } |
1092 #endif | 1077 #endif |
1093 } | 1078 } |
1094 }; | 1079 }; |
1095 | 1080 |
1096 | 1081 |
1097 static inline ElementsKind ElementsKindForArray(FixedArrayBase* array) { | 1082 static inline ElementsKind ElementsKindForArray(Handle<FixedArrayBase> array) { |
1098 switch (array->map()->instance_type()) { | 1083 switch (array->map()->instance_type()) { |
1099 case FIXED_ARRAY_TYPE: | 1084 case FIXED_ARRAY_TYPE: |
1100 if (array->IsDictionary()) { | 1085 if (array->IsDictionary()) { |
1101 return DICTIONARY_ELEMENTS; | 1086 return DICTIONARY_ELEMENTS; |
1102 } else { | 1087 } else { |
1103 return FAST_HOLEY_ELEMENTS; | 1088 return FAST_HOLEY_ELEMENTS; |
1104 } | 1089 } |
1105 case FIXED_DOUBLE_ARRAY_TYPE: | 1090 case FIXED_DOUBLE_ARRAY_TYPE: |
1106 return FAST_HOLEY_DOUBLE_ELEMENTS; | 1091 return FAST_HOLEY_DOUBLE_ELEMENTS; |
1107 | 1092 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1158 CopyDictionaryToObjectElements( | 1143 CopyDictionaryToObjectElements( |
1159 from, from_start, to, to_kind, to_start, copy_size); | 1144 from, from_start, to, to_kind, to_start, copy_size); |
1160 break; | 1145 break; |
1161 case SLOPPY_ARGUMENTS_ELEMENTS: { | 1146 case SLOPPY_ARGUMENTS_ELEMENTS: { |
1162 // TODO(verwaest): This is a temporary hack to support extending | 1147 // TODO(verwaest): This is a temporary hack to support extending |
1163 // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength. | 1148 // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength. |
1164 // This case should be UNREACHABLE(). | 1149 // This case should be UNREACHABLE(). |
1165 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(from); | 1150 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(from); |
1166 Handle<FixedArrayBase> arguments( | 1151 Handle<FixedArrayBase> arguments( |
1167 FixedArrayBase::cast(parameter_map->get(1))); | 1152 FixedArrayBase::cast(parameter_map->get(1))); |
1168 ElementsKind from_kind = ElementsKindForArray(*arguments); | 1153 ElementsKind from_kind = ElementsKindForArray(arguments); |
1169 CopyElementsImpl(arguments, from_start, to, from_kind, | 1154 CopyElementsImpl(arguments, from_start, to, from_kind, |
1170 to_start, packed_size, copy_size); | 1155 to_start, packed_size, copy_size); |
1171 break; | 1156 break; |
1172 } | 1157 } |
1173 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 1158 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
1174 case EXTERNAL_##TYPE##_ELEMENTS: \ | 1159 case EXTERNAL_##TYPE##_ELEMENTS: \ |
1175 case TYPE##_ELEMENTS: \ | 1160 case TYPE##_ELEMENTS: \ |
1176 UNREACHABLE(); | 1161 UNREACHABLE(); |
1177 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1162 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
1178 #undef TYPED_ARRAY_CASE | 1163 #undef TYPED_ARRAY_CASE |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1345 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; | 1330 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; |
1346 typedef TypedElementsAccessor<Kind> AccessorClass; | 1331 typedef TypedElementsAccessor<Kind> AccessorClass; |
1347 | 1332 |
1348 friend class ElementsAccessorBase<AccessorClass, | 1333 friend class ElementsAccessorBase<AccessorClass, |
1349 ElementsKindTraits<Kind> >; | 1334 ElementsKindTraits<Kind> >; |
1350 | 1335 |
1351 static Handle<Object> GetImpl(Handle<Object> receiver, | 1336 static Handle<Object> GetImpl(Handle<Object> receiver, |
1352 Handle<JSObject> obj, | 1337 Handle<JSObject> obj, |
1353 uint32_t key, | 1338 uint32_t key, |
1354 Handle<FixedArrayBase> backing_store) { | 1339 Handle<FixedArrayBase> backing_store) { |
1355 if (key < AccessorClass::GetCapacityImpl(*backing_store)) { | 1340 if (key < AccessorClass::GetCapacityImpl(backing_store)) { |
1356 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); | 1341 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
1357 } else { | 1342 } else { |
1358 return backing_store->GetIsolate()->factory()->undefined_value(); | 1343 return backing_store->GetIsolate()->factory()->undefined_value(); |
1359 } | 1344 } |
1360 } | 1345 } |
1361 | 1346 |
1362 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1347 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
1363 Object* receiver, | 1348 Handle<Object> receiver, |
1364 JSObject* obj, | 1349 Handle<JSObject> obj, |
1365 uint32_t key, | 1350 uint32_t key, |
1366 FixedArrayBase* backing_store) { | 1351 Handle<FixedArrayBase> backing_store) { |
1367 return | 1352 return |
1368 key < AccessorClass::GetCapacityImpl(backing_store) | 1353 key < AccessorClass::GetCapacityImpl(backing_store) |
1369 ? NONE : ABSENT; | 1354 ? NONE : ABSENT; |
1370 } | 1355 } |
1371 | 1356 |
1372 MUST_USE_RESULT static PropertyType GetTypeImpl( | 1357 MUST_USE_RESULT static PropertyType GetTypeImpl( |
1373 Object* receiver, | 1358 Handle<Object> receiver, |
1374 JSObject* obj, | 1359 Handle<JSObject> obj, |
1375 uint32_t key, | 1360 uint32_t key, |
1376 FixedArrayBase* backing_store) { | 1361 Handle<FixedArrayBase> backing_store) { |
1377 return | 1362 return |
1378 key < AccessorClass::GetCapacityImpl(backing_store) | 1363 key < AccessorClass::GetCapacityImpl(backing_store) |
1379 ? FIELD : NONEXISTENT; | 1364 ? FIELD : NONEXISTENT; |
1380 } | 1365 } |
1381 | 1366 |
1382 MUST_USE_RESULT static Handle<Object> SetLengthImpl( | 1367 MUST_USE_RESULT static Handle<Object> SetLengthImpl( |
1383 Handle<JSObject> obj, | 1368 Handle<JSObject> obj, |
1384 Handle<Object> length, | 1369 Handle<Object> length, |
1385 Handle<FixedArrayBase> backing_store) { | 1370 Handle<FixedArrayBase> backing_store) { |
1386 // External arrays do not support changing their length. | 1371 // External arrays do not support changing their length. |
1387 UNREACHABLE(); | 1372 UNREACHABLE(); |
1388 return obj; | 1373 return obj; |
1389 } | 1374 } |
1390 | 1375 |
1391 MUST_USE_RESULT virtual Handle<Object> Delete( | 1376 MUST_USE_RESULT virtual Handle<Object> Delete( |
1392 Handle<JSObject> obj, | 1377 Handle<JSObject> obj, |
1393 uint32_t key, | 1378 uint32_t key, |
1394 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { | 1379 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { |
1395 // External arrays always ignore deletes. | 1380 // External arrays always ignore deletes. |
1396 return obj->GetIsolate()->factory()->true_value(); | 1381 return obj->GetIsolate()->factory()->true_value(); |
1397 } | 1382 } |
1398 | 1383 |
1399 static bool HasElementImpl(Handle<Object> receiver, | 1384 static bool HasElementImpl(Handle<Object> receiver, |
1400 Handle<JSObject> holder, | 1385 Handle<JSObject> holder, |
1401 uint32_t key, | 1386 uint32_t key, |
1402 Handle<FixedArrayBase> backing_store) { | 1387 Handle<FixedArrayBase> backing_store) { |
1403 uint32_t capacity = | 1388 uint32_t capacity = |
1404 AccessorClass::GetCapacityImpl(*backing_store); | 1389 AccessorClass::GetCapacityImpl(backing_store); |
1405 return key < capacity; | 1390 return key < capacity; |
1406 } | 1391 } |
1407 }; | 1392 }; |
1408 | 1393 |
1409 | 1394 |
1410 | 1395 |
1411 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 1396 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
1412 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ | 1397 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ |
1413 External##Type##ElementsAccessor; | 1398 External##Type##ElementsAccessor; |
1414 | 1399 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 return JSObject::GetElementWithCallback( | 1581 return JSObject::GetElementWithCallback( |
1597 obj, receiver, element, key, obj); | 1582 obj, receiver, element, key, obj); |
1598 } else { | 1583 } else { |
1599 return element; | 1584 return element; |
1600 } | 1585 } |
1601 } | 1586 } |
1602 return isolate->factory()->the_hole_value(); | 1587 return isolate->factory()->the_hole_value(); |
1603 } | 1588 } |
1604 | 1589 |
1605 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1590 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
1606 Object* receiver, | 1591 Handle<Object> receiver, |
1607 JSObject* obj, | 1592 Handle<JSObject> obj, |
1608 uint32_t key, | 1593 uint32_t key, |
1609 FixedArrayBase* backing_store) { | 1594 Handle<FixedArrayBase> backing_store) { |
1610 SeededNumberDictionary* dictionary = | 1595 Handle<SeededNumberDictionary> dictionary = |
1611 SeededNumberDictionary::cast(backing_store); | 1596 Handle<SeededNumberDictionary>::cast(backing_store); |
1612 int entry = dictionary->FindEntry(key); | 1597 int entry = dictionary->FindEntry(key); |
1613 if (entry != SeededNumberDictionary::kNotFound) { | 1598 if (entry != SeededNumberDictionary::kNotFound) { |
1614 return dictionary->DetailsAt(entry).attributes(); | 1599 return dictionary->DetailsAt(entry).attributes(); |
1615 } | 1600 } |
1616 return ABSENT; | 1601 return ABSENT; |
1617 } | 1602 } |
1618 | 1603 |
1619 MUST_USE_RESULT static PropertyType GetTypeImpl( | 1604 MUST_USE_RESULT static PropertyType GetTypeImpl( |
1620 Object* receiver, | 1605 Handle<Object> receiver, |
1621 JSObject* obj, | 1606 Handle<JSObject> obj, |
1622 uint32_t key, | 1607 uint32_t key, |
1623 FixedArrayBase* store) { | 1608 Handle<FixedArrayBase> store) { |
1624 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); | 1609 Handle<SeededNumberDictionary> backing_store = |
| 1610 Handle<SeededNumberDictionary>::cast(store); |
1625 int entry = backing_store->FindEntry(key); | 1611 int entry = backing_store->FindEntry(key); |
1626 if (entry != SeededNumberDictionary::kNotFound) { | 1612 if (entry != SeededNumberDictionary::kNotFound) { |
1627 return backing_store->DetailsAt(entry).type(); | 1613 return backing_store->DetailsAt(entry).type(); |
1628 } | 1614 } |
1629 return NONEXISTENT; | 1615 return NONEXISTENT; |
1630 } | 1616 } |
1631 | 1617 |
1632 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( | 1618 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
1633 Handle<Object> receiver, | 1619 Handle<Object> receiver, |
1634 Handle<JSObject> obj, | 1620 Handle<JSObject> obj, |
(...skipping 12 matching lines...) Expand all Loading... |
1647 | 1633 |
1648 static bool HasElementImpl(Handle<Object> receiver, | 1634 static bool HasElementImpl(Handle<Object> receiver, |
1649 Handle<JSObject> holder, | 1635 Handle<JSObject> holder, |
1650 uint32_t key, | 1636 uint32_t key, |
1651 Handle<FixedArrayBase> store) { | 1637 Handle<FixedArrayBase> store) { |
1652 Handle<SeededNumberDictionary> backing_store = | 1638 Handle<SeededNumberDictionary> backing_store = |
1653 Handle<SeededNumberDictionary>::cast(store); | 1639 Handle<SeededNumberDictionary>::cast(store); |
1654 return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound; | 1640 return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound; |
1655 } | 1641 } |
1656 | 1642 |
1657 // TODO(ishell): Handlify when all callers are handlified. | 1643 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> store, |
1658 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, | |
1659 uint32_t index) { | 1644 uint32_t index) { |
1660 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1645 DisallowHeapAllocation no_gc; |
| 1646 Handle<SeededNumberDictionary> dict = |
| 1647 Handle<SeededNumberDictionary>::cast(store); |
1661 Object* key = dict->KeyAt(index); | 1648 Object* key = dict->KeyAt(index); |
1662 return Smi::cast(key)->value(); | 1649 return Smi::cast(key)->value(); |
1663 } | 1650 } |
1664 }; | 1651 }; |
1665 | 1652 |
1666 | 1653 |
1667 class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< | 1654 class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< |
1668 SloppyArgumentsElementsAccessor, | 1655 SloppyArgumentsElementsAccessor, |
1669 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > { | 1656 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > { |
1670 public: | 1657 public: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1705 int context_index = entry->aliased_context_slot(); | 1692 int context_index = entry->aliased_context_slot(); |
1706 ASSERT(!context->get(context_index)->IsTheHole()); | 1693 ASSERT(!context->get(context_index)->IsTheHole()); |
1707 return handle(context->get(context_index), isolate); | 1694 return handle(context->get(context_index), isolate); |
1708 } else { | 1695 } else { |
1709 return result; | 1696 return result; |
1710 } | 1697 } |
1711 } | 1698 } |
1712 } | 1699 } |
1713 | 1700 |
1714 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1701 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
1715 Object* receiver, | 1702 Handle<Object> receiver, |
1716 JSObject* obj, | 1703 Handle<JSObject> obj, |
1717 uint32_t key, | 1704 uint32_t key, |
1718 FixedArrayBase* backing_store) { | 1705 Handle<FixedArrayBase> backing_store) { |
1719 FixedArray* parameter_map = FixedArray::cast(backing_store); | 1706 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); |
1720 Object* probe = GetParameterMapArg(obj, parameter_map, key); | 1707 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); |
1721 if (!probe->IsTheHole()) { | 1708 if (!probe->IsTheHole()) { |
1722 return NONE; | 1709 return NONE; |
1723 } else { | 1710 } else { |
1724 // If not aliased, check the arguments. | 1711 // If not aliased, check the arguments. |
1725 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1712 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
1726 return ElementsAccessor::ForArray(arguments)->GetAttributes( | 1713 return ElementsAccessor::ForArray(arguments)->GetAttributes( |
1727 receiver, obj, key, arguments); | 1714 receiver, obj, key, arguments); |
1728 } | 1715 } |
1729 } | 1716 } |
1730 | 1717 |
1731 MUST_USE_RESULT static PropertyType GetTypeImpl( | 1718 MUST_USE_RESULT static PropertyType GetTypeImpl( |
1732 Object* receiver, | 1719 Handle<Object> receiver, |
1733 JSObject* obj, | 1720 Handle<JSObject> obj, |
1734 uint32_t key, | 1721 uint32_t key, |
1735 FixedArrayBase* parameters) { | 1722 Handle<FixedArrayBase> parameters) { |
1736 FixedArray* parameter_map = FixedArray::cast(parameters); | 1723 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |
1737 Object* probe = GetParameterMapArg(obj, parameter_map, key); | 1724 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); |
1738 if (!probe->IsTheHole()) { | 1725 if (!probe->IsTheHole()) { |
1739 return FIELD; | 1726 return FIELD; |
1740 } else { | 1727 } else { |
1741 // If not aliased, check the arguments. | 1728 // If not aliased, check the arguments. |
1742 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1729 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
1743 return ElementsAccessor::ForArray(arguments)->GetType( | 1730 return ElementsAccessor::ForArray(arguments)->GetType( |
1744 receiver, obj, key, arguments); | 1731 receiver, obj, key, arguments); |
1745 } | 1732 } |
1746 } | 1733 } |
1747 | 1734 |
1748 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( | 1735 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
1749 Handle<Object> receiver, | 1736 Handle<Object> receiver, |
1750 Handle<JSObject> obj, | 1737 Handle<JSObject> obj, |
1751 uint32_t key, | 1738 uint32_t key, |
1752 Handle<FixedArrayBase> parameters) { | 1739 Handle<FixedArrayBase> parameters) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1801 static void CopyElementsImpl(Handle<FixedArrayBase> from, | 1788 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
1802 uint32_t from_start, | 1789 uint32_t from_start, |
1803 Handle<FixedArrayBase> to, | 1790 Handle<FixedArrayBase> to, |
1804 ElementsKind from_kind, | 1791 ElementsKind from_kind, |
1805 uint32_t to_start, | 1792 uint32_t to_start, |
1806 int packed_size, | 1793 int packed_size, |
1807 int copy_size) { | 1794 int copy_size) { |
1808 UNREACHABLE(); | 1795 UNREACHABLE(); |
1809 } | 1796 } |
1810 | 1797 |
1811 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { | 1798 static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) { |
1812 FixedArray* parameter_map = FixedArray::cast(backing_store); | 1799 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); |
1813 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 1800 Handle<FixedArrayBase> arguments( |
| 1801 FixedArrayBase::cast(parameter_map->get(1))); |
1814 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 1802 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
1815 ForArray(arguments)->GetCapacity(arguments)); | 1803 ForArray(arguments)->GetCapacity(arguments)); |
1816 } | 1804 } |
1817 | 1805 |
1818 // TODO(ishell): Handlify when all callers are handlified. | 1806 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> dict, |
1819 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, | |
1820 uint32_t index) { | 1807 uint32_t index) { |
1821 return index; | 1808 return index; |
1822 } | 1809 } |
1823 | 1810 |
1824 static bool HasElementImpl(Handle<Object> receiver, | 1811 static bool HasElementImpl(Handle<Object> receiver, |
1825 Handle<JSObject> holder, | 1812 Handle<JSObject> holder, |
1826 uint32_t key, | 1813 uint32_t key, |
1827 Handle<FixedArrayBase> parameters) { | 1814 Handle<FixedArrayBase> parameters) { |
1828 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); | 1815 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |
1829 Handle<Object> probe = GetParameterMapArg(holder, parameter_map, key); | 1816 Handle<Object> probe = GetParameterMapArg(holder, parameter_map, key); |
1830 if (!probe->IsTheHole()) { | 1817 if (!probe->IsTheHole()) { |
1831 return true; | 1818 return true; |
1832 } else { | 1819 } else { |
1833 Handle<FixedArrayBase> arguments(FixedArrayBase::cast( | 1820 Handle<FixedArrayBase> arguments(FixedArrayBase::cast( |
1834 Handle<FixedArray>::cast(parameter_map)->get(1))); | 1821 Handle<FixedArray>::cast(parameter_map)->get(1))); |
1835 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); | 1822 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
1836 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); | 1823 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); |
1837 } | 1824 } |
1838 } | 1825 } |
1839 | 1826 |
1840 private: | 1827 private: |
1841 // TODO(ishell): remove when all usages are handlified. | |
1842 static Object* GetParameterMapArg(JSObject* holder, | |
1843 FixedArray* parameter_map, | |
1844 uint32_t key) { | |
1845 uint32_t length = holder->IsJSArray() | |
1846 ? Smi::cast(JSArray::cast(holder)->length())->value() | |
1847 : parameter_map->length(); | |
1848 return key < (length - 2) | |
1849 ? parameter_map->get(key + 2) | |
1850 : parameter_map->GetHeap()->the_hole_value(); | |
1851 } | |
1852 | |
1853 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, | 1828 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, |
1854 Handle<FixedArray> parameter_map, | 1829 Handle<FixedArray> parameter_map, |
1855 uint32_t key) { | 1830 uint32_t key) { |
1856 Isolate* isolate = holder->GetIsolate(); | 1831 Isolate* isolate = holder->GetIsolate(); |
1857 uint32_t length = holder->IsJSArray() | 1832 uint32_t length = holder->IsJSArray() |
1858 ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value() | 1833 ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value() |
1859 : parameter_map->length(); | 1834 : parameter_map->length(); |
1860 return key < (length - 2) | 1835 return key < (length - 2) |
1861 ? handle(parameter_map->get(key + 2), isolate) | 1836 ? handle(parameter_map->get(key + 2), isolate) |
1862 : Handle<Object>::cast(isolate->factory()->the_hole_value()); | 1837 : Handle<Object>::cast(isolate->factory()->the_hole_value()); |
1863 } | 1838 } |
1864 }; | 1839 }; |
1865 | 1840 |
1866 | 1841 |
1867 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { | 1842 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) { |
1868 return elements_accessors_[ElementsKindForArray(array)]; | 1843 return elements_accessors_[ElementsKindForArray(array)]; |
1869 } | 1844 } |
1870 | 1845 |
1871 | 1846 |
1872 void ElementsAccessor::InitializeOncePerProcess() { | 1847 void ElementsAccessor::InitializeOncePerProcess() { |
1873 static ElementsAccessor* accessor_array[] = { | 1848 static ElementsAccessor* accessor_array[] = { |
1874 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), | 1849 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), |
1875 ELEMENTS_LIST(ACCESSOR_ARRAY) | 1850 ELEMENTS_LIST(ACCESSOR_ARRAY) |
1876 #undef ACCESSOR_ARRAY | 1851 #undef ACCESSOR_ARRAY |
1877 }; | 1852 }; |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2044 UNREACHABLE(); | 2019 UNREACHABLE(); |
2045 break; | 2020 break; |
2046 } | 2021 } |
2047 | 2022 |
2048 array->set_elements(*elms); | 2023 array->set_elements(*elms); |
2049 array->set_length(Smi::FromInt(number_of_elements)); | 2024 array->set_length(Smi::FromInt(number_of_elements)); |
2050 return array; | 2025 return array; |
2051 } | 2026 } |
2052 | 2027 |
2053 } } // namespace v8::internal | 2028 } } // namespace v8::internal |
OLD | NEW |