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/elements.h" | 5 #include "src/elements.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/factory.h" | 9 #include "src/factory.h" |
| 10 #include "src/isolate-inl.h" |
10 #include "src/messages.h" | 11 #include "src/messages.h" |
11 #include "src/objects-inl.h" | 12 #include "src/objects-inl.h" |
12 #include "src/utils.h" | 13 #include "src/utils.h" |
13 | 14 |
14 // Each concrete ElementsAccessor can handle exactly one ElementsKind, | 15 // Each concrete ElementsAccessor can handle exactly one ElementsKind, |
15 // several abstract ElementsAccessor classes are used to allow sharing | 16 // several abstract ElementsAccessor classes are used to allow sharing |
16 // common code. | 17 // common code. |
17 // | 18 // |
18 // Inheritance hierarchy: | 19 // Inheritance hierarchy: |
19 // - ElementsAccessorBase (abstract) | 20 // - ElementsAccessorBase (abstract) |
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 return ElementsAccessorSubclass::NormalizeImpl(object, | 850 return ElementsAccessorSubclass::NormalizeImpl(object, |
850 handle(object->elements())); | 851 handle(object->elements())); |
851 } | 852 } |
852 | 853 |
853 static Handle<SeededNumberDictionary> NormalizeImpl( | 854 static Handle<SeededNumberDictionary> NormalizeImpl( |
854 Handle<JSObject> object, Handle<FixedArrayBase> elements) { | 855 Handle<JSObject> object, Handle<FixedArrayBase> elements) { |
855 UNREACHABLE(); | 856 UNREACHABLE(); |
856 return Handle<SeededNumberDictionary>(); | 857 return Handle<SeededNumberDictionary>(); |
857 } | 858 } |
858 | 859 |
| 860 Maybe<bool> CollectValuesOrEntries(Isolate* isolate, Handle<JSObject> object, |
| 861 Handle<FixedArray> values_or_entries, |
| 862 bool get_entries, int* nof_items, |
| 863 PropertyFilter filter) { |
| 864 return ElementsAccessorSubclass::CollectValuesOrEntriesImpl( |
| 865 isolate, object, values_or_entries, get_entries, nof_items, filter); |
| 866 } |
| 867 |
| 868 static Maybe<bool> CollectValuesOrEntriesImpl( |
| 869 Isolate* isolate, Handle<JSObject> object, |
| 870 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
| 871 PropertyFilter filter) { |
| 872 int count = 0; |
| 873 KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES); |
| 874 accumulator.NextPrototype(); |
| 875 ElementsAccessorSubclass::CollectElementIndicesImpl( |
| 876 object, handle(object->elements(), isolate), &accumulator, kMaxUInt32, |
| 877 ALL_PROPERTIES, 0); |
| 878 Handle<FixedArray> keys = accumulator.GetKeys(); |
| 879 |
| 880 for (int i = 0; i < keys->length(); ++i) { |
| 881 Handle<Object> key(keys->get(i), isolate); |
| 882 Handle<Object> value; |
| 883 uint32_t index; |
| 884 if (!key->ToUint32(&index)) continue; |
| 885 |
| 886 uint32_t entry = ElementsAccessorSubclass::GetEntryForIndexImpl( |
| 887 *object, object->elements(), index, filter); |
| 888 if (entry == kMaxUInt32) continue; |
| 889 |
| 890 PropertyDetails details = |
| 891 ElementsAccessorSubclass::GetDetailsImpl(*object, entry); |
| 892 |
| 893 if (details.kind() == kData) { |
| 894 value = ElementsAccessorSubclass::GetImpl(object, entry); |
| 895 } else { |
| 896 LookupIterator it(isolate, object, index, LookupIterator::OWN); |
| 897 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 898 isolate, value, Object::GetProperty(&it), Nothing<bool>()); |
| 899 } |
| 900 if (get_entries) { |
| 901 value = MakeEntryPair(isolate, index, value); |
| 902 } |
| 903 values_or_entries->set(count++, *value); |
| 904 } |
| 905 |
| 906 *nof_items = count; |
| 907 return Just(true); |
| 908 } |
| 909 |
859 void CollectElementIndices(Handle<JSObject> object, | 910 void CollectElementIndices(Handle<JSObject> object, |
860 Handle<FixedArrayBase> backing_store, | 911 Handle<FixedArrayBase> backing_store, |
861 KeyAccumulator* keys, uint32_t range, | 912 KeyAccumulator* keys, uint32_t range, |
862 PropertyFilter filter, uint32_t offset) final { | 913 PropertyFilter filter, uint32_t offset) final { |
863 if (filter & ONLY_ALL_CAN_READ) return; | 914 if (filter & ONLY_ALL_CAN_READ) return; |
864 ElementsAccessorSubclass::CollectElementIndicesImpl( | 915 ElementsAccessorSubclass::CollectElementIndicesImpl( |
865 object, backing_store, keys, range, filter, offset); | 916 object, backing_store, keys, range, filter, offset); |
866 } | 917 } |
867 | 918 |
868 static void CollectElementIndicesImpl(Handle<JSObject> object, | 919 static void CollectElementIndicesImpl(Handle<JSObject> object, |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1597 // Copy over the arguments. | 1648 // Copy over the arguments. |
1598 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_count, | 1649 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_count, |
1599 3, start); | 1650 3, start); |
1600 | 1651 |
1601 receiver->set_length(Smi::FromInt(new_length)); | 1652 receiver->set_length(Smi::FromInt(new_length)); |
1602 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( | 1653 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( |
1603 deleted_elements); | 1654 deleted_elements); |
1604 return deleted_elements; | 1655 return deleted_elements; |
1605 } | 1656 } |
1606 | 1657 |
| 1658 static Maybe<bool> CollectValuesOrEntriesImpl( |
| 1659 Isolate* isolate, Handle<JSObject> object, |
| 1660 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
| 1661 PropertyFilter filter) { |
| 1662 int count = 0; |
| 1663 uint32_t length = object->elements()->length(); |
| 1664 for (uint32_t index = 0; index < length; ++index) { |
| 1665 if (!HasEntryImpl(object->elements(), index)) continue; |
| 1666 Handle<Object> value = |
| 1667 FastElementsAccessorSubclass::GetImpl(object->elements(), index); |
| 1668 if (get_entries) { |
| 1669 value = MakeEntryPair(isolate, index, value); |
| 1670 } |
| 1671 values_or_entries->set(count++, *value); |
| 1672 } |
| 1673 *nof_items = count; |
| 1674 return Just(true); |
| 1675 } |
| 1676 |
1607 private: | 1677 private: |
1608 // SpliceShrinkStep might modify the backing_store. | 1678 // SpliceShrinkStep might modify the backing_store. |
1609 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, | 1679 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, |
1610 Handle<FixedArrayBase> backing_store, | 1680 Handle<FixedArrayBase> backing_store, |
1611 uint32_t start, uint32_t delete_count, | 1681 uint32_t start, uint32_t delete_count, |
1612 uint32_t add_count, uint32_t len, | 1682 uint32_t add_count, uint32_t len, |
1613 uint32_t new_length) { | 1683 uint32_t new_length) { |
1614 const int move_left_count = len - delete_count - start; | 1684 const int move_left_count = len - delete_count - start; |
1615 const int move_left_dst_index = start + add_count; | 1685 const int move_left_dst_index = start + add_count; |
1616 FastElementsAccessorSubclass::MoveElements( | 1686 FastElementsAccessorSubclass::MoveElements( |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2097 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 2167 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
2098 KeyAccumulator* accumulator, | 2168 KeyAccumulator* accumulator, |
2099 AddKeyConversion convert) { | 2169 AddKeyConversion convert) { |
2100 Handle<FixedArrayBase> elements(receiver->elements()); | 2170 Handle<FixedArrayBase> elements(receiver->elements()); |
2101 uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements); | 2171 uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements); |
2102 for (uint32_t i = 0; i < length; i++) { | 2172 for (uint32_t i = 0; i < length; i++) { |
2103 Handle<Object> value = AccessorClass::GetImpl(*elements, i); | 2173 Handle<Object> value = AccessorClass::GetImpl(*elements, i); |
2104 accumulator->AddKey(value, convert); | 2174 accumulator->AddKey(value, convert); |
2105 } | 2175 } |
2106 } | 2176 } |
| 2177 |
| 2178 static Maybe<bool> CollectValuesOrEntriesImpl( |
| 2179 Isolate* isolate, Handle<JSObject> object, |
| 2180 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
| 2181 PropertyFilter filter) { |
| 2182 int count = 0; |
| 2183 if ((filter & ONLY_CONFIGURABLE) == 0) { |
| 2184 Handle<FixedArrayBase> elements(object->elements()); |
| 2185 uint32_t length = AccessorClass::GetCapacityImpl(*object, *elements); |
| 2186 for (uint32_t index = 0; index < length; ++index) { |
| 2187 Handle<Object> value = AccessorClass::GetImpl(*elements, index); |
| 2188 if (get_entries) { |
| 2189 value = MakeEntryPair(isolate, index, value); |
| 2190 } |
| 2191 values_or_entries->set(count++, *value); |
| 2192 } |
| 2193 } |
| 2194 *nof_items = count; |
| 2195 return Just(true); |
| 2196 } |
2107 }; | 2197 }; |
2108 | 2198 |
2109 | 2199 |
2110 | 2200 |
2111 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 2201 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
2112 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \ | 2202 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \ |
2113 Fixed##Type##ElementsAccessor; | 2203 Fixed##Type##ElementsAccessor; |
2114 | 2204 |
2115 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) | 2205 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) |
2116 #undef FIXED_ELEMENTS_ACCESSOR | 2206 #undef FIXED_ELEMENTS_ACCESSOR |
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2909 } | 2999 } |
2910 } | 3000 } |
2911 | 3001 |
2912 DCHECK(j == result_len); | 3002 DCHECK(j == result_len); |
2913 return result_array; | 3003 return result_array; |
2914 } | 3004 } |
2915 | 3005 |
2916 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3006 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2917 } // namespace internal | 3007 } // namespace internal |
2918 } // namespace v8 | 3008 } // namespace v8 |
OLD | NEW |