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(backing_store)) { | 623 if (key < ElementsAccessorSubclass::GetCapacityImpl(obj, 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(backing_store)) { | 641 if (key >= ElementsAccessorSubclass::GetCapacityImpl(obj, 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(from); | 754 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(holder, 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<FixedArrayBase> backing_store) { | 820 static uint32_t GetCapacityImpl(Handle<JSObject> holder, |
| 821 Handle<FixedArrayBase> backing_store) { |
821 return backing_store->length(); | 822 return backing_store->length(); |
822 } | 823 } |
823 | 824 |
824 uint32_t GetCapacity(Handle<FixedArrayBase> backing_store) final { | 825 uint32_t GetCapacity(Handle<JSObject> holder, |
825 return ElementsAccessorSubclass::GetCapacityImpl(backing_store); | 826 Handle<FixedArrayBase> backing_store) final { |
| 827 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); |
826 } | 828 } |
827 | 829 |
828 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> backing_store, | 830 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> backing_store, |
829 uint32_t index) { | 831 uint32_t index) { |
830 return index; | 832 return index; |
831 } | 833 } |
832 | 834 |
833 virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store, | 835 virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store, |
834 uint32_t index) final { | 836 uint32_t index) final { |
835 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); | 837 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1253 typedef TypedElementsAccessor<Kind> AccessorClass; | 1255 typedef TypedElementsAccessor<Kind> AccessorClass; |
1254 | 1256 |
1255 friend class ElementsAccessorBase<AccessorClass, | 1257 friend class ElementsAccessorBase<AccessorClass, |
1256 ElementsKindTraits<Kind> >; | 1258 ElementsKindTraits<Kind> >; |
1257 | 1259 |
1258 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( | 1260 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( |
1259 Handle<Object> receiver, | 1261 Handle<Object> receiver, |
1260 Handle<JSObject> obj, | 1262 Handle<JSObject> obj, |
1261 uint32_t key, | 1263 uint32_t key, |
1262 Handle<FixedArrayBase> backing_store) { | 1264 Handle<FixedArrayBase> backing_store) { |
1263 if (key < AccessorClass::GetCapacityImpl(backing_store)) { | 1265 if (key < AccessorClass::GetCapacityImpl(obj, backing_store)) { |
1264 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); | 1266 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
1265 } else { | 1267 } else { |
1266 return backing_store->GetIsolate()->factory()->undefined_value(); | 1268 return backing_store->GetIsolate()->factory()->undefined_value(); |
1267 } | 1269 } |
1268 } | 1270 } |
1269 | 1271 |
1270 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1272 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
1271 Handle<JSObject> obj, | 1273 Handle<JSObject> obj, |
1272 uint32_t key, | 1274 uint32_t key, |
1273 Handle<FixedArrayBase> backing_store) { | 1275 Handle<FixedArrayBase> backing_store) { |
1274 return | 1276 return key < AccessorClass::GetCapacityImpl(obj, backing_store) ? NONE |
1275 key < AccessorClass::GetCapacityImpl(backing_store) | 1277 : ABSENT; |
1276 ? NONE : ABSENT; | |
1277 } | 1278 } |
1278 | 1279 |
1279 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( | 1280 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( |
1280 Handle<JSObject> obj, | 1281 Handle<JSObject> obj, |
1281 Handle<Object> length, | 1282 Handle<Object> length, |
1282 Handle<FixedArrayBase> backing_store) { | 1283 Handle<FixedArrayBase> backing_store) { |
1283 // External arrays do not support changing their length. | 1284 // External arrays do not support changing their length. |
1284 UNREACHABLE(); | 1285 UNREACHABLE(); |
1285 return obj; | 1286 return obj; |
1286 } | 1287 } |
1287 | 1288 |
1288 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( | 1289 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( |
1289 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { | 1290 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { |
1290 // External arrays always ignore deletes. | 1291 // External arrays always ignore deletes. |
1291 return obj->GetIsolate()->factory()->true_value(); | 1292 return obj->GetIsolate()->factory()->true_value(); |
1292 } | 1293 } |
1293 | 1294 |
1294 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, | 1295 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, |
1295 Handle<FixedArrayBase> backing_store) { | 1296 Handle<FixedArrayBase> backing_store) { |
1296 uint32_t capacity = | 1297 uint32_t capacity = AccessorClass::GetCapacityImpl(holder, backing_store); |
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 } |
1300 }; | 1307 }; |
1301 | 1308 |
1302 | 1309 |
1303 | 1310 |
1304 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 1311 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
1305 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ | 1312 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ |
1306 External##Type##ElementsAccessor; | 1313 External##Type##ElementsAccessor; |
1307 | 1314 |
1308 TYPED_ARRAYS(EXTERNAL_ELEMENTS_ACCESSOR) | 1315 TYPED_ARRAYS(EXTERNAL_ELEMENTS_ACCESSOR) |
1309 #undef EXTERNAL_ELEMENTS_ACCESSOR | 1316 #undef EXTERNAL_ELEMENTS_ACCESSOR |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1625 return isolate->factory()->true_value(); | 1632 return isolate->factory()->true_value(); |
1626 } | 1633 } |
1627 | 1634 |
1628 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 1635 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
1629 FixedArrayBase* to, ElementsKind from_kind, | 1636 FixedArrayBase* to, ElementsKind from_kind, |
1630 uint32_t to_start, int packed_size, | 1637 uint32_t to_start, int packed_size, |
1631 int copy_size) { | 1638 int copy_size) { |
1632 UNREACHABLE(); | 1639 UNREACHABLE(); |
1633 } | 1640 } |
1634 | 1641 |
1635 static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) { | 1642 static uint32_t GetCapacityImpl(Handle<JSObject> holder, |
| 1643 Handle<FixedArrayBase> backing_store) { |
1636 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); | 1644 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); |
1637 Handle<FixedArrayBase> arguments( | 1645 Handle<FixedArrayBase> arguments( |
1638 FixedArrayBase::cast(parameter_map->get(1))); | 1646 FixedArrayBase::cast(parameter_map->get(1))); |
1639 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 1647 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
1640 ForArray(arguments)->GetCapacity(arguments)); | 1648 ForArray(arguments)->GetCapacity(holder, arguments)); |
1641 } | 1649 } |
1642 | 1650 |
1643 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> dict, | 1651 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> dict, |
1644 uint32_t index) { | 1652 uint32_t index) { |
1645 return index; | 1653 return index; |
1646 } | 1654 } |
1647 | 1655 |
1648 private: | 1656 private: |
1649 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, | 1657 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, |
1650 Handle<FixedArray> parameter_map, | 1658 Handle<FixedArray> parameter_map, |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1843 UNREACHABLE(); | 1851 UNREACHABLE(); |
1844 break; | 1852 break; |
1845 } | 1853 } |
1846 | 1854 |
1847 array->set_elements(*elms); | 1855 array->set_elements(*elms); |
1848 array->set_length(Smi::FromInt(number_of_elements)); | 1856 array->set_length(Smi::FromInt(number_of_elements)); |
1849 return array; | 1857 return array; |
1850 } | 1858 } |
1851 | 1859 |
1852 } } // namespace v8::internal | 1860 } } // namespace v8::internal |
OLD | NEW |