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/objects.h" | 10 #include "src/objects.h" |
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 | 613 |
614 return ElementsAccessorSubclass::GetImpl( | 614 return ElementsAccessorSubclass::GetImpl( |
615 receiver, holder, key, backing_store); | 615 receiver, holder, key, backing_store); |
616 } | 616 } |
617 | 617 |
618 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( | 618 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( |
619 Handle<Object> receiver, | 619 Handle<Object> receiver, |
620 Handle<JSObject> obj, | 620 Handle<JSObject> obj, |
621 uint32_t key, | 621 uint32_t key, |
622 Handle<FixedArrayBase> backing_store) { | 622 Handle<FixedArrayBase> backing_store) { |
623 if (key < ElementsAccessorSubclass::GetCapacityImpl(obj, backing_store)) { | 623 if (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { |
624 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); | 624 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
625 } else { | 625 } else { |
626 return backing_store->GetIsolate()->factory()->the_hole_value(); | 626 return backing_store->GetIsolate()->factory()->the_hole_value(); |
627 } | 627 } |
628 } | 628 } |
629 | 629 |
630 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( | 630 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( |
631 Handle<JSObject> holder, uint32_t key, | 631 Handle<JSObject> holder, uint32_t key, |
632 Handle<FixedArrayBase> backing_store) final { | 632 Handle<FixedArrayBase> backing_store) final { |
633 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, | 633 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, |
634 backing_store); | 634 backing_store); |
635 } | 635 } |
636 | 636 |
637 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 637 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
638 Handle<JSObject> obj, | 638 Handle<JSObject> obj, |
639 uint32_t key, | 639 uint32_t key, |
640 Handle<FixedArrayBase> backing_store) { | 640 Handle<FixedArrayBase> backing_store) { |
641 if (key >= ElementsAccessorSubclass::GetCapacityImpl(obj, backing_store)) { | 641 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { |
642 return ABSENT; | 642 return ABSENT; |
643 } | 643 } |
644 return | 644 return |
645 Handle<BackingStore>::cast(backing_store)->is_the_hole(key) | 645 Handle<BackingStore>::cast(backing_store)->is_the_hole(key) |
646 ? ABSENT : NONE; | 646 ? ABSENT : NONE; |
647 } | 647 } |
648 | 648 |
649 MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( | 649 MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( |
650 Handle<JSObject> holder, uint32_t key, | 650 Handle<JSObject> holder, uint32_t key, |
651 Handle<FixedArrayBase> backing_store) final { | 651 Handle<FixedArrayBase> backing_store) final { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 #ifdef ENABLE_SLOW_DCHECKS | 744 #ifdef ENABLE_SLOW_DCHECKS |
745 if (FLAG_enable_slow_asserts) { | 745 if (FLAG_enable_slow_asserts) { |
746 for (int i = 0; i < len0; i++) { | 746 for (int i = 0; i < len0; i++) { |
747 DCHECK(!to->get(i)->IsTheHole()); | 747 DCHECK(!to->get(i)->IsTheHole()); |
748 } | 748 } |
749 } | 749 } |
750 #endif | 750 #endif |
751 | 751 |
752 // Optimize if 'other' is empty. | 752 // Optimize if 'other' is empty. |
753 // We cannot optimize if 'this' is empty, as other may have holes. | 753 // We cannot optimize if 'this' is empty, as other may have holes. |
754 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(holder, from); | 754 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from); |
755 if (len1 == 0) return to; | 755 if (len1 == 0) return to; |
756 | 756 |
757 Isolate* isolate = from->GetIsolate(); | 757 Isolate* isolate = from->GetIsolate(); |
758 | 758 |
759 // Compute how many elements are not in other. | 759 // Compute how many elements are not in other. |
760 uint32_t extra = 0; | 760 uint32_t extra = 0; |
761 for (uint32_t y = 0; y < len1; y++) { | 761 for (uint32_t y = 0; y < len1; y++) { |
762 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); | 762 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); |
763 if (ElementsAccessorSubclass::HasElementImpl(holder, key, from)) { | 763 if (ElementsAccessorSubclass::HasElementImpl(holder, key, from)) { |
764 Handle<Object> value; | 764 Handle<Object> value; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 result->set(len0 + index, *value); | 810 result->set(len0 + index, *value); |
811 index++; | 811 index++; |
812 } | 812 } |
813 } | 813 } |
814 } | 814 } |
815 DCHECK(extra == index); | 815 DCHECK(extra == index); |
816 return result; | 816 return result; |
817 } | 817 } |
818 | 818 |
819 protected: | 819 protected: |
820 static uint32_t GetCapacityImpl(Handle<JSObject> holder, | 820 static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) { |
821 Handle<FixedArrayBase> backing_store) { | |
822 return backing_store->length(); | 821 return backing_store->length(); |
823 } | 822 } |
824 | 823 |
825 uint32_t GetCapacity(Handle<JSObject> holder, | 824 uint32_t GetCapacity(Handle<FixedArrayBase> backing_store) final { |
826 Handle<FixedArrayBase> backing_store) final { | 825 return ElementsAccessorSubclass::GetCapacityImpl(backing_store); |
827 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); | |
828 } | 826 } |
829 | 827 |
830 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> backing_store, | 828 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> backing_store, |
831 uint32_t index) { | 829 uint32_t index) { |
832 return index; | 830 return index; |
833 } | 831 } |
834 | 832 |
835 virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store, | 833 virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store, |
836 uint32_t index) final { | 834 uint32_t index) final { |
837 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); | 835 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1255 typedef TypedElementsAccessor<Kind> AccessorClass; | 1253 typedef TypedElementsAccessor<Kind> AccessorClass; |
1256 | 1254 |
1257 friend class ElementsAccessorBase<AccessorClass, | 1255 friend class ElementsAccessorBase<AccessorClass, |
1258 ElementsKindTraits<Kind> >; | 1256 ElementsKindTraits<Kind> >; |
1259 | 1257 |
1260 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( | 1258 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( |
1261 Handle<Object> receiver, | 1259 Handle<Object> receiver, |
1262 Handle<JSObject> obj, | 1260 Handle<JSObject> obj, |
1263 uint32_t key, | 1261 uint32_t key, |
1264 Handle<FixedArrayBase> backing_store) { | 1262 Handle<FixedArrayBase> backing_store) { |
1265 if (key < AccessorClass::GetCapacityImpl(obj, backing_store)) { | 1263 if (key < AccessorClass::GetCapacityImpl(backing_store)) { |
1266 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); | 1264 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
1267 } else { | 1265 } else { |
1268 return backing_store->GetIsolate()->factory()->undefined_value(); | 1266 return backing_store->GetIsolate()->factory()->undefined_value(); |
1269 } | 1267 } |
1270 } | 1268 } |
1271 | 1269 |
1272 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1270 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
1273 Handle<JSObject> obj, | 1271 Handle<JSObject> obj, |
1274 uint32_t key, | 1272 uint32_t key, |
1275 Handle<FixedArrayBase> backing_store) { | 1273 Handle<FixedArrayBase> backing_store) { |
1276 return key < AccessorClass::GetCapacityImpl(obj, backing_store) ? NONE | 1274 return |
1277 : ABSENT; | 1275 key < AccessorClass::GetCapacityImpl(backing_store) |
| 1276 ? NONE : ABSENT; |
1278 } | 1277 } |
1279 | 1278 |
1280 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( | 1279 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( |
1281 Handle<JSObject> obj, | 1280 Handle<JSObject> obj, |
1282 Handle<Object> length, | 1281 Handle<Object> length, |
1283 Handle<FixedArrayBase> backing_store) { | 1282 Handle<FixedArrayBase> backing_store) { |
1284 // External arrays do not support changing their length. | 1283 // External arrays do not support changing their length. |
1285 UNREACHABLE(); | 1284 UNREACHABLE(); |
1286 return obj; | 1285 return obj; |
1287 } | 1286 } |
1288 | 1287 |
1289 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( | 1288 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( |
1290 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { | 1289 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { |
1291 // External arrays always ignore deletes. | 1290 // External arrays always ignore deletes. |
1292 return obj->GetIsolate()->factory()->true_value(); | 1291 return obj->GetIsolate()->factory()->true_value(); |
1293 } | 1292 } |
1294 | 1293 |
1295 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, | 1294 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, |
1296 Handle<FixedArrayBase> backing_store) { | 1295 Handle<FixedArrayBase> backing_store) { |
1297 uint32_t capacity = AccessorClass::GetCapacityImpl(holder, backing_store); | 1296 uint32_t capacity = |
| 1297 AccessorClass::GetCapacityImpl(backing_store); |
1298 return key < capacity; | 1298 return key < capacity; |
1299 } | 1299 } |
1300 | |
1301 static uint32_t GetCapacityImpl(Handle<JSObject> holder, | |
1302 Handle<FixedArrayBase> backing_store) { | |
1303 Handle<JSArrayBufferView> view = Handle<JSArrayBufferView>::cast(holder); | |
1304 if (view->WasNeutered()) return 0; | |
1305 return backing_store->length(); | |
1306 } | |
1307 }; | 1300 }; |
1308 | 1301 |
1309 | 1302 |
1310 | 1303 |
1311 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 1304 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
1312 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ | 1305 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ |
1313 External##Type##ElementsAccessor; | 1306 External##Type##ElementsAccessor; |
1314 | 1307 |
1315 TYPED_ARRAYS(EXTERNAL_ELEMENTS_ACCESSOR) | 1308 TYPED_ARRAYS(EXTERNAL_ELEMENTS_ACCESSOR) |
1316 #undef EXTERNAL_ELEMENTS_ACCESSOR | 1309 #undef EXTERNAL_ELEMENTS_ACCESSOR |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1632 return isolate->factory()->true_value(); | 1625 return isolate->factory()->true_value(); |
1633 } | 1626 } |
1634 | 1627 |
1635 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 1628 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
1636 FixedArrayBase* to, ElementsKind from_kind, | 1629 FixedArrayBase* to, ElementsKind from_kind, |
1637 uint32_t to_start, int packed_size, | 1630 uint32_t to_start, int packed_size, |
1638 int copy_size) { | 1631 int copy_size) { |
1639 UNREACHABLE(); | 1632 UNREACHABLE(); |
1640 } | 1633 } |
1641 | 1634 |
1642 static uint32_t GetCapacityImpl(Handle<JSObject> holder, | 1635 static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) { |
1643 Handle<FixedArrayBase> backing_store) { | |
1644 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); | 1636 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); |
1645 Handle<FixedArrayBase> arguments( | 1637 Handle<FixedArrayBase> arguments( |
1646 FixedArrayBase::cast(parameter_map->get(1))); | 1638 FixedArrayBase::cast(parameter_map->get(1))); |
1647 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 1639 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
1648 ForArray(arguments)->GetCapacity(holder, arguments)); | 1640 ForArray(arguments)->GetCapacity(arguments)); |
1649 } | 1641 } |
1650 | 1642 |
1651 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> dict, | 1643 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> dict, |
1652 uint32_t index) { | 1644 uint32_t index) { |
1653 return index; | 1645 return index; |
1654 } | 1646 } |
1655 | 1647 |
1656 private: | 1648 private: |
1657 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, | 1649 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, |
1658 Handle<FixedArray> parameter_map, | 1650 Handle<FixedArray> parameter_map, |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1851 UNREACHABLE(); | 1843 UNREACHABLE(); |
1852 break; | 1844 break; |
1853 } | 1845 } |
1854 | 1846 |
1855 array->set_elements(*elms); | 1847 array->set_elements(*elms); |
1856 array->set_length(Smi::FromInt(number_of_elements)); | 1848 array->set_length(Smi::FromInt(number_of_elements)); |
1857 return array; | 1849 return array; |
1858 } | 1850 } |
1859 | 1851 |
1860 } } // namespace v8::internal | 1852 } } // namespace v8::internal |
OLD | NEW |