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 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 length = fixed_array_base->length(); | 580 length = fixed_array_base->length(); |
581 } | 581 } |
582 ElementsAccessorSubclass::ValidateContents(holder, length); | 582 ElementsAccessorSubclass::ValidateContents(holder, length); |
583 } | 583 } |
584 | 584 |
585 void Validate(Handle<JSObject> holder) FINAL { | 585 void Validate(Handle<JSObject> holder) FINAL { |
586 DisallowHeapAllocation no_gc; | 586 DisallowHeapAllocation no_gc; |
587 ElementsAccessorSubclass::ValidateImpl(holder); | 587 ElementsAccessorSubclass::ValidateImpl(holder); |
588 } | 588 } |
589 | 589 |
590 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, | 590 static bool HasElementImpl(JSObject* holder, uint32_t key, |
591 Handle<FixedArrayBase> backing_store) { | 591 FixedArrayBase* backing_store) { |
592 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, | 592 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, |
593 backing_store) != ABSENT; | 593 backing_store) != ABSENT; |
594 } | 594 } |
595 | 595 |
596 virtual bool HasElement(Handle<JSObject> holder, uint32_t key, | 596 virtual bool HasElement(JSObject* holder, uint32_t key, |
597 Handle<FixedArrayBase> backing_store) FINAL { | 597 FixedArrayBase* backing_store) FINAL { |
598 return ElementsAccessorSubclass::HasElementImpl(holder, key, backing_store); | 598 return ElementsAccessorSubclass::HasElementImpl(holder, key, backing_store); |
599 } | 599 } |
600 | 600 |
601 MUST_USE_RESULT virtual MaybeHandle<Object> Get( | 601 MUST_USE_RESULT virtual MaybeHandle<Object> Get( |
602 Handle<Object> receiver, Handle<JSObject> holder, uint32_t key, | 602 Handle<Object> receiver, Handle<JSObject> holder, uint32_t key, |
603 Handle<FixedArrayBase> backing_store) FINAL { | 603 Handle<FixedArrayBase> backing_store) FINAL { |
604 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) && | 604 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) && |
605 FLAG_trace_js_array_abuse) { | 605 FLAG_trace_js_array_abuse) { |
606 CheckArrayAbuse(holder, "elements read", key); | 606 CheckArrayAbuse(holder, "elements read", key); |
607 } | 607 } |
608 | 608 |
609 if (IsExternalArrayElementsKind(ElementsTraits::Kind) && | 609 if (IsExternalArrayElementsKind(ElementsTraits::Kind) && |
610 FLAG_trace_external_array_abuse) { | 610 FLAG_trace_external_array_abuse) { |
611 CheckArrayAbuse(holder, "external elements read", key); | 611 CheckArrayAbuse(holder, "external elements read", key); |
612 } | 612 } |
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(*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 JSObject* holder, uint32_t key, FixedArrayBase* backing_store) FINAL { |
632 Handle<FixedArrayBase> backing_store) FINAL { | |
633 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, | 632 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, |
634 backing_store); | 633 backing_store); |
635 } | 634 } |
636 | 635 |
637 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 636 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
638 Handle<JSObject> obj, | 637 JSObject* obj, uint32_t key, FixedArrayBase* backing_store) { |
639 uint32_t key, | |
640 Handle<FixedArrayBase> backing_store) { | |
641 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { | 638 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { |
642 return ABSENT; | 639 return ABSENT; |
643 } | 640 } |
644 return | 641 return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE; |
645 Handle<BackingStore>::cast(backing_store)->is_the_hole(key) | |
646 ? ABSENT : NONE; | |
647 } | 642 } |
648 | 643 |
649 MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( | 644 MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( |
650 Handle<JSObject> holder, uint32_t key, | 645 Handle<JSObject> holder, uint32_t key, |
651 Handle<FixedArrayBase> backing_store) FINAL { | 646 Handle<FixedArrayBase> backing_store) FINAL { |
652 return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key, | 647 return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key, |
653 backing_store); | 648 backing_store); |
654 } | 649 } |
655 | 650 |
656 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( | 651 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 #ifdef ENABLE_SLOW_DCHECKS | 739 #ifdef ENABLE_SLOW_DCHECKS |
745 if (FLAG_enable_slow_asserts) { | 740 if (FLAG_enable_slow_asserts) { |
746 for (int i = 0; i < len0; i++) { | 741 for (int i = 0; i < len0; i++) { |
747 DCHECK(!to->get(i)->IsTheHole()); | 742 DCHECK(!to->get(i)->IsTheHole()); |
748 } | 743 } |
749 } | 744 } |
750 #endif | 745 #endif |
751 | 746 |
752 // Optimize if 'other' is empty. | 747 // Optimize if 'other' is empty. |
753 // We cannot optimize if 'this' is empty, as other may have holes. | 748 // We cannot optimize if 'this' is empty, as other may have holes. |
754 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from); | 749 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*from); |
755 if (len1 == 0) return to; | 750 if (len1 == 0) return to; |
756 | 751 |
757 Isolate* isolate = from->GetIsolate(); | 752 Isolate* isolate = from->GetIsolate(); |
758 | 753 |
759 // Compute how many elements are not in other. | 754 // Compute how many elements are not in other. |
760 uint32_t extra = 0; | 755 uint32_t extra = 0; |
761 for (uint32_t y = 0; y < len1; y++) { | 756 for (uint32_t y = 0; y < len1; y++) { |
762 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); | 757 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); |
763 if (ElementsAccessorSubclass::HasElementImpl(holder, key, from)) { | 758 if (ElementsAccessorSubclass::HasElementImpl(*holder, key, *from)) { |
764 Handle<Object> value; | 759 Handle<Object> value; |
765 ASSIGN_RETURN_ON_EXCEPTION( | 760 ASSIGN_RETURN_ON_EXCEPTION( |
766 isolate, value, | 761 isolate, value, |
767 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from), | 762 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from), |
768 FixedArray); | 763 FixedArray); |
769 | 764 |
770 DCHECK(!value->IsTheHole()); | 765 DCHECK(!value->IsTheHole()); |
771 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { | 766 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { |
772 continue; | 767 continue; |
773 } | 768 } |
(...skipping 16 matching lines...) Expand all Loading... |
790 Object* e = to->get(i); | 785 Object* e = to->get(i); |
791 DCHECK(e->IsString() || e->IsNumber()); | 786 DCHECK(e->IsString() || e->IsNumber()); |
792 result->set(i, e, mode); | 787 result->set(i, e, mode); |
793 } | 788 } |
794 } | 789 } |
795 // Fill in the extra values. | 790 // Fill in the extra values. |
796 uint32_t index = 0; | 791 uint32_t index = 0; |
797 for (uint32_t y = 0; y < len1; y++) { | 792 for (uint32_t y = 0; y < len1; y++) { |
798 uint32_t key = | 793 uint32_t key = |
799 ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); | 794 ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); |
800 if (ElementsAccessorSubclass::HasElementImpl(holder, key, from)) { | 795 if (ElementsAccessorSubclass::HasElementImpl(*holder, key, *from)) { |
801 Handle<Object> value; | 796 Handle<Object> value; |
802 ASSIGN_RETURN_ON_EXCEPTION( | 797 ASSIGN_RETURN_ON_EXCEPTION( |
803 isolate, value, | 798 isolate, value, |
804 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from), | 799 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from), |
805 FixedArray); | 800 FixedArray); |
806 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { | 801 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { |
807 continue; | 802 continue; |
808 } | 803 } |
809 if (!value->IsTheHole() && !HasKey(to, value)) { | 804 if (!value->IsTheHole() && !HasKey(to, value)) { |
810 result->set(len0 + index, *value); | 805 result->set(len0 + index, *value); |
811 index++; | 806 index++; |
812 } | 807 } |
813 } | 808 } |
814 } | 809 } |
815 DCHECK(extra == index); | 810 DCHECK(extra == index); |
816 return result; | 811 return result; |
817 } | 812 } |
818 | 813 |
819 protected: | 814 protected: |
820 static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) { | 815 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { |
821 return backing_store->length(); | 816 return backing_store->length(); |
822 } | 817 } |
823 | 818 |
824 uint32_t GetCapacity(Handle<FixedArrayBase> backing_store) FINAL { | 819 uint32_t GetCapacity(FixedArrayBase* backing_store) FINAL { |
825 return ElementsAccessorSubclass::GetCapacityImpl(backing_store); | 820 return ElementsAccessorSubclass::GetCapacityImpl(backing_store); |
826 } | 821 } |
827 | 822 |
828 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> backing_store, | 823 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> backing_store, |
829 uint32_t index) { | 824 uint32_t index) { |
830 return index; | 825 return index; |
831 } | 826 } |
832 | 827 |
833 virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store, | 828 virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store, |
834 uint32_t index) FINAL { | 829 uint32_t index) FINAL { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 } | 957 } |
963 } | 958 } |
964 return isolate->factory()->true_value(); | 959 return isolate->factory()->true_value(); |
965 } | 960 } |
966 | 961 |
967 virtual MaybeHandle<Object> Delete(Handle<JSObject> obj, uint32_t key, | 962 virtual MaybeHandle<Object> Delete(Handle<JSObject> obj, uint32_t key, |
968 LanguageMode language_mode) FINAL { | 963 LanguageMode language_mode) FINAL { |
969 return DeleteCommon(obj, key, language_mode); | 964 return DeleteCommon(obj, key, language_mode); |
970 } | 965 } |
971 | 966 |
972 static bool HasElementImpl( | 967 static bool HasElementImpl(JSObject* holder, uint32_t key, |
973 Handle<JSObject> holder, | 968 FixedArrayBase* backing_store) { |
974 uint32_t key, | |
975 Handle<FixedArrayBase> backing_store) { | |
976 if (key >= static_cast<uint32_t>(backing_store->length())) { | 969 if (key >= static_cast<uint32_t>(backing_store->length())) { |
977 return false; | 970 return false; |
978 } | 971 } |
979 return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key); | 972 return !BackingStore::cast(backing_store)->is_the_hole(key); |
980 } | 973 } |
981 | 974 |
982 static void ValidateContents(Handle<JSObject> holder, int length) { | 975 static void ValidateContents(Handle<JSObject> holder, int length) { |
983 #if DEBUG | 976 #if DEBUG |
984 Isolate* isolate = holder->GetIsolate(); | 977 Isolate* isolate = holder->GetIsolate(); |
985 HandleScope scope(isolate); | 978 HandleScope scope(isolate); |
986 Handle<FixedArrayBase> elements(holder->elements(), isolate); | 979 Handle<FixedArrayBase> elements(holder->elements(), isolate); |
987 Map* map = elements->map(); | 980 Map* map = elements->map(); |
988 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && | 981 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && |
989 (map == isolate->heap()->fixed_array_map() || | 982 (map == isolate->heap()->fixed_array_map() || |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1253 typedef TypedElementsAccessor<Kind> AccessorClass; | 1246 typedef TypedElementsAccessor<Kind> AccessorClass; |
1254 | 1247 |
1255 friend class ElementsAccessorBase<AccessorClass, | 1248 friend class ElementsAccessorBase<AccessorClass, |
1256 ElementsKindTraits<Kind> >; | 1249 ElementsKindTraits<Kind> >; |
1257 | 1250 |
1258 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( | 1251 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( |
1259 Handle<Object> receiver, | 1252 Handle<Object> receiver, |
1260 Handle<JSObject> obj, | 1253 Handle<JSObject> obj, |
1261 uint32_t key, | 1254 uint32_t key, |
1262 Handle<FixedArrayBase> backing_store) { | 1255 Handle<FixedArrayBase> backing_store) { |
1263 if (key < AccessorClass::GetCapacityImpl(backing_store)) { | 1256 if (key < AccessorClass::GetCapacityImpl(*backing_store)) { |
1264 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); | 1257 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
1265 } else { | 1258 } else { |
1266 return backing_store->GetIsolate()->factory()->undefined_value(); | 1259 return backing_store->GetIsolate()->factory()->undefined_value(); |
1267 } | 1260 } |
1268 } | 1261 } |
1269 | 1262 |
1270 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1263 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
1271 Handle<JSObject> obj, | 1264 JSObject* obj, uint32_t key, FixedArrayBase* backing_store) { |
1272 uint32_t key, | |
1273 Handle<FixedArrayBase> backing_store) { | |
1274 return | 1265 return |
1275 key < AccessorClass::GetCapacityImpl(backing_store) | 1266 key < AccessorClass::GetCapacityImpl(backing_store) |
1276 ? NONE : ABSENT; | 1267 ? NONE : ABSENT; |
1277 } | 1268 } |
1278 | 1269 |
1279 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( | 1270 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( |
1280 Handle<JSObject> obj, | 1271 Handle<JSObject> obj, |
1281 Handle<Object> length, | 1272 Handle<Object> length, |
1282 Handle<FixedArrayBase> backing_store) { | 1273 Handle<FixedArrayBase> backing_store) { |
1283 // External arrays do not support changing their length. | 1274 // External arrays do not support changing their length. |
1284 UNREACHABLE(); | 1275 UNREACHABLE(); |
1285 return obj; | 1276 return obj; |
1286 } | 1277 } |
1287 | 1278 |
1288 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( | 1279 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( |
1289 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) FINAL { | 1280 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) FINAL { |
1290 // External arrays always ignore deletes. | 1281 // External arrays always ignore deletes. |
1291 return obj->GetIsolate()->factory()->true_value(); | 1282 return obj->GetIsolate()->factory()->true_value(); |
1292 } | 1283 } |
1293 | 1284 |
1294 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, | 1285 static bool HasElementImpl(JSObject* holder, uint32_t key, |
1295 Handle<FixedArrayBase> backing_store) { | 1286 FixedArrayBase* backing_store) { |
1296 uint32_t capacity = | 1287 uint32_t capacity = |
1297 AccessorClass::GetCapacityImpl(backing_store); | 1288 AccessorClass::GetCapacityImpl(backing_store); |
1298 return key < capacity; | 1289 return key < capacity; |
1299 } | 1290 } |
1300 }; | 1291 }; |
1301 | 1292 |
1302 | 1293 |
1303 | 1294 |
1304 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 1295 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
1305 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ | 1296 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 return JSObject::GetElementWithCallback( | 1445 return JSObject::GetElementWithCallback( |
1455 obj, receiver, element, key, obj); | 1446 obj, receiver, element, key, obj); |
1456 } else { | 1447 } else { |
1457 return element; | 1448 return element; |
1458 } | 1449 } |
1459 } | 1450 } |
1460 return isolate->factory()->the_hole_value(); | 1451 return isolate->factory()->the_hole_value(); |
1461 } | 1452 } |
1462 | 1453 |
1463 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1454 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
1464 Handle<JSObject> obj, | 1455 JSObject* obj, uint32_t key, FixedArrayBase* backing_store) { |
1465 uint32_t key, | 1456 SeededNumberDictionary* dictionary = |
1466 Handle<FixedArrayBase> backing_store) { | 1457 SeededNumberDictionary::cast(backing_store); |
1467 Handle<SeededNumberDictionary> dictionary = | |
1468 Handle<SeededNumberDictionary>::cast(backing_store); | |
1469 int entry = dictionary->FindEntry(key); | 1458 int entry = dictionary->FindEntry(key); |
1470 if (entry != SeededNumberDictionary::kNotFound) { | 1459 if (entry != SeededNumberDictionary::kNotFound) { |
1471 return dictionary->DetailsAt(entry).attributes(); | 1460 return dictionary->DetailsAt(entry).attributes(); |
1472 } | 1461 } |
1473 return ABSENT; | 1462 return ABSENT; |
1474 } | 1463 } |
1475 | 1464 |
1476 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( | 1465 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
1477 Handle<JSObject> obj, | 1466 Handle<JSObject> obj, |
1478 uint32_t key, | 1467 uint32_t key, |
1479 Handle<FixedArrayBase> store) { | 1468 Handle<FixedArrayBase> store) { |
1480 Handle<SeededNumberDictionary> backing_store = | 1469 Handle<SeededNumberDictionary> backing_store = |
1481 Handle<SeededNumberDictionary>::cast(store); | 1470 Handle<SeededNumberDictionary>::cast(store); |
1482 int entry = backing_store->FindEntry(key); | 1471 int entry = backing_store->FindEntry(key); |
1483 if (entry != SeededNumberDictionary::kNotFound && | 1472 if (entry != SeededNumberDictionary::kNotFound && |
1484 backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT && | 1473 backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT && |
1485 backing_store->ValueAt(entry)->IsAccessorPair()) { | 1474 backing_store->ValueAt(entry)->IsAccessorPair()) { |
1486 return handle(AccessorPair::cast(backing_store->ValueAt(entry))); | 1475 return handle(AccessorPair::cast(backing_store->ValueAt(entry))); |
1487 } | 1476 } |
1488 return MaybeHandle<AccessorPair>(); | 1477 return MaybeHandle<AccessorPair>(); |
1489 } | 1478 } |
1490 | 1479 |
1491 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, | 1480 static bool HasElementImpl(JSObject* holder, uint32_t key, |
1492 Handle<FixedArrayBase> store) { | 1481 FixedArrayBase* store) { |
1493 Handle<SeededNumberDictionary> backing_store = | 1482 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); |
1494 Handle<SeededNumberDictionary>::cast(store); | |
1495 return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound; | 1483 return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound; |
1496 } | 1484 } |
1497 | 1485 |
1498 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> store, | 1486 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> store, |
1499 uint32_t index) { | 1487 uint32_t index) { |
1500 DisallowHeapAllocation no_gc; | 1488 DisallowHeapAllocation no_gc; |
1501 Handle<SeededNumberDictionary> dict = | 1489 Handle<SeededNumberDictionary> dict = |
1502 Handle<SeededNumberDictionary>::cast(store); | 1490 Handle<SeededNumberDictionary>::cast(store); |
1503 Object* key = dict->KeyAt(index); | 1491 Object* key = dict->KeyAt(index); |
1504 return Smi::cast(key)->value(); | 1492 return Smi::cast(key)->value(); |
(...skipping 14 matching lines...) Expand all Loading... |
1519 SloppyArgumentsElementsAccessor, | 1507 SloppyArgumentsElementsAccessor, |
1520 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >; | 1508 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >; |
1521 | 1509 |
1522 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( | 1510 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( |
1523 Handle<Object> receiver, | 1511 Handle<Object> receiver, |
1524 Handle<JSObject> obj, | 1512 Handle<JSObject> obj, |
1525 uint32_t key, | 1513 uint32_t key, |
1526 Handle<FixedArrayBase> parameters) { | 1514 Handle<FixedArrayBase> parameters) { |
1527 Isolate* isolate = obj->GetIsolate(); | 1515 Isolate* isolate = obj->GetIsolate(); |
1528 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); | 1516 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |
1529 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | 1517 Object* probe = GetParameterMapArg(*obj, *parameter_map, key); |
1530 if (!probe->IsTheHole()) { | 1518 if (!probe->IsTheHole()) { |
1531 DisallowHeapAllocation no_gc; | 1519 DisallowHeapAllocation no_gc; |
1532 Context* context = Context::cast(parameter_map->get(0)); | 1520 Context* context = Context::cast(parameter_map->get(0)); |
1533 int context_index = Handle<Smi>::cast(probe)->value(); | 1521 int context_index = Smi::cast(probe)->value(); |
1534 DCHECK(!context->get(context_index)->IsTheHole()); | 1522 DCHECK(!context->get(context_index)->IsTheHole()); |
1535 return handle(context->get(context_index), isolate); | 1523 return handle(context->get(context_index), isolate); |
1536 } else { | 1524 } else { |
1537 // Object is not mapped, defer to the arguments. | 1525 // Object is not mapped, defer to the arguments. |
1538 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), | 1526 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), |
1539 isolate); | 1527 isolate); |
1540 Handle<Object> result; | 1528 Handle<Object> result; |
1541 ASSIGN_RETURN_ON_EXCEPTION( | 1529 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, |
1542 isolate, result, | 1530 ElementsAccessor::ForArray(*arguments) |
1543 ElementsAccessor::ForArray(arguments)->Get( | 1531 ->Get(receiver, obj, key, arguments), |
1544 receiver, obj, key, arguments), | 1532 Object); |
1545 Object); | |
1546 // Elements of the arguments object in slow mode might be slow aliases. | 1533 // Elements of the arguments object in slow mode might be slow aliases. |
1547 if (result->IsAliasedArgumentsEntry()) { | 1534 if (result->IsAliasedArgumentsEntry()) { |
1548 DisallowHeapAllocation no_gc; | 1535 DisallowHeapAllocation no_gc; |
1549 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); | 1536 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); |
1550 Context* context = Context::cast(parameter_map->get(0)); | 1537 Context* context = Context::cast(parameter_map->get(0)); |
1551 int context_index = entry->aliased_context_slot(); | 1538 int context_index = entry->aliased_context_slot(); |
1552 DCHECK(!context->get(context_index)->IsTheHole()); | 1539 DCHECK(!context->get(context_index)->IsTheHole()); |
1553 return handle(context->get(context_index), isolate); | 1540 return handle(context->get(context_index), isolate); |
1554 } else { | 1541 } else { |
1555 return result; | 1542 return result; |
1556 } | 1543 } |
1557 } | 1544 } |
1558 } | 1545 } |
1559 | 1546 |
1560 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1547 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
1561 Handle<JSObject> obj, | 1548 JSObject* obj, uint32_t key, FixedArrayBase* backing_store) { |
1562 uint32_t key, | 1549 FixedArray* parameter_map = FixedArray::cast(backing_store); |
1563 Handle<FixedArrayBase> backing_store) { | 1550 Object* probe = GetParameterMapArg(obj, parameter_map, key); |
1564 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); | |
1565 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | |
1566 if (!probe->IsTheHole()) { | 1551 if (!probe->IsTheHole()) { |
1567 return NONE; | 1552 return NONE; |
1568 } else { | 1553 } else { |
1569 // If not aliased, check the arguments. | 1554 // If not aliased, check the arguments. |
1570 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); | 1555 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
1571 return ElementsAccessor::ForArray(arguments) | 1556 return ElementsAccessor::ForArray(arguments) |
1572 ->GetAttributes(obj, key, arguments); | 1557 ->GetAttributes(obj, key, arguments); |
1573 } | 1558 } |
1574 } | 1559 } |
1575 | 1560 |
1576 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( | 1561 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
1577 Handle<JSObject> obj, | 1562 Handle<JSObject> obj, |
1578 uint32_t key, | 1563 uint32_t key, |
1579 Handle<FixedArrayBase> parameters) { | 1564 Handle<FixedArrayBase> parameters) { |
1580 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); | 1565 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |
1581 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | 1566 Object* probe = GetParameterMapArg(*obj, *parameter_map, key); |
1582 if (!probe->IsTheHole()) { | 1567 if (!probe->IsTheHole()) { |
1583 return MaybeHandle<AccessorPair>(); | 1568 return MaybeHandle<AccessorPair>(); |
1584 } else { | 1569 } else { |
1585 // If not aliased, check the arguments. | 1570 // If not aliased, check the arguments. |
1586 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); | 1571 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
1587 return ElementsAccessor::ForArray(arguments) | 1572 return ElementsAccessor::ForArray(*arguments) |
1588 ->GetAccessorPair(obj, key, arguments); | 1573 ->GetAccessorPair(obj, key, arguments); |
1589 } | 1574 } |
1590 } | 1575 } |
1591 | 1576 |
1592 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( | 1577 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( |
1593 Handle<JSObject> obj, | 1578 Handle<JSObject> obj, |
1594 Handle<Object> length, | 1579 Handle<Object> length, |
1595 Handle<FixedArrayBase> parameter_map) { | 1580 Handle<FixedArrayBase> parameter_map) { |
1596 // TODO(mstarzinger): This was never implemented but will be used once we | 1581 // TODO(mstarzinger): This was never implemented but will be used once we |
1597 // correctly implement [[DefineOwnProperty]] on arrays. | 1582 // correctly implement [[DefineOwnProperty]] on arrays. |
1598 UNIMPLEMENTED(); | 1583 UNIMPLEMENTED(); |
1599 return obj; | 1584 return obj; |
1600 } | 1585 } |
1601 | 1586 |
1602 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( | 1587 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( |
1603 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) FINAL { | 1588 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) FINAL { |
1604 Isolate* isolate = obj->GetIsolate(); | 1589 Isolate* isolate = obj->GetIsolate(); |
1605 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); | 1590 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); |
1606 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | 1591 Handle<Object> probe(GetParameterMapArg(*obj, *parameter_map, key), |
| 1592 isolate); |
1607 if (!probe->IsTheHole()) { | 1593 if (!probe->IsTheHole()) { |
1608 // TODO(kmillikin): We could check if this was the last aliased | 1594 // TODO(kmillikin): We could check if this was the last aliased |
1609 // parameter, and revert to normal elements in that case. That | 1595 // parameter, and revert to normal elements in that case. That |
1610 // would enable GC of the context. | 1596 // would enable GC of the context. |
1611 parameter_map->set_the_hole(key + 2); | 1597 parameter_map->set_the_hole(key + 2); |
1612 } else { | 1598 } else { |
1613 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); | 1599 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
1614 if (arguments->IsDictionary()) { | 1600 if (arguments->IsDictionary()) { |
1615 return DictionaryElementsAccessor::DeleteCommon(obj, key, | 1601 return DictionaryElementsAccessor::DeleteCommon(obj, key, |
1616 language_mode); | 1602 language_mode); |
1617 } else { | 1603 } else { |
1618 // It's difficult to access the version of DeleteCommon that is declared | 1604 // It's difficult to access the version of DeleteCommon that is declared |
1619 // in the templatized super class, call the concrete implementation in | 1605 // in the templatized super class, call the concrete implementation in |
1620 // the class for the most generalized ElementsKind subclass. | 1606 // the class for the most generalized ElementsKind subclass. |
1621 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, | 1607 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, |
1622 language_mode); | 1608 language_mode); |
1623 } | 1609 } |
1624 } | 1610 } |
1625 return isolate->factory()->true_value(); | 1611 return isolate->factory()->true_value(); |
1626 } | 1612 } |
1627 | 1613 |
1628 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 1614 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
1629 FixedArrayBase* to, ElementsKind from_kind, | 1615 FixedArrayBase* to, ElementsKind from_kind, |
1630 uint32_t to_start, int packed_size, | 1616 uint32_t to_start, int packed_size, |
1631 int copy_size) { | 1617 int copy_size) { |
1632 UNREACHABLE(); | 1618 UNREACHABLE(); |
1633 } | 1619 } |
1634 | 1620 |
1635 static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) { | 1621 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { |
1636 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); | 1622 FixedArray* parameter_map = FixedArray::cast(backing_store); |
1637 Handle<FixedArrayBase> arguments( | 1623 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
1638 FixedArrayBase::cast(parameter_map->get(1))); | |
1639 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 1624 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
1640 ForArray(arguments)->GetCapacity(arguments)); | 1625 ForArray(arguments)->GetCapacity(arguments)); |
1641 } | 1626 } |
1642 | 1627 |
1643 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> dict, | 1628 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> dict, |
1644 uint32_t index) { | 1629 uint32_t index) { |
1645 return index; | 1630 return index; |
1646 } | 1631 } |
1647 | 1632 |
1648 private: | 1633 private: |
1649 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, | 1634 static Object* GetParameterMapArg(JSObject* holder, FixedArray* parameter_map, |
1650 Handle<FixedArray> parameter_map, | 1635 uint32_t key) { |
1651 uint32_t key) { | |
1652 Isolate* isolate = holder->GetIsolate(); | 1636 Isolate* isolate = holder->GetIsolate(); |
1653 uint32_t length = holder->IsJSArray() | 1637 uint32_t length = holder->IsJSArray() |
1654 ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value() | 1638 ? Smi::cast(JSArray::cast(holder)->length())->value() |
1655 : parameter_map->length(); | 1639 : parameter_map->length(); |
1656 return key < (length - 2) | 1640 return key < (length - 2) ? parameter_map->get(key + 2) |
1657 ? handle(parameter_map->get(key + 2), isolate) | 1641 : isolate->heap()->the_hole_value(); |
1658 : Handle<Object>::cast(isolate->factory()->the_hole_value()); | |
1659 } | 1642 } |
1660 }; | 1643 }; |
1661 | 1644 |
1662 | 1645 |
1663 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) { | 1646 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { |
1664 return elements_accessors_[ElementsKindForArray(*array)]; | 1647 return elements_accessors_[ElementsKindForArray(array)]; |
1665 } | 1648 } |
1666 | 1649 |
1667 | 1650 |
1668 void ElementsAccessor::InitializeOncePerProcess() { | 1651 void ElementsAccessor::InitializeOncePerProcess() { |
1669 static ElementsAccessor* accessor_array[] = { | 1652 static ElementsAccessor* accessor_array[] = { |
1670 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), | 1653 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), |
1671 ELEMENTS_LIST(ACCESSOR_ARRAY) | 1654 ELEMENTS_LIST(ACCESSOR_ARRAY) |
1672 #undef ACCESSOR_ARRAY | 1655 #undef ACCESSOR_ARRAY |
1673 }; | 1656 }; |
1674 | 1657 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1843 UNREACHABLE(); | 1826 UNREACHABLE(); |
1844 break; | 1827 break; |
1845 } | 1828 } |
1846 | 1829 |
1847 array->set_elements(*elms); | 1830 array->set_elements(*elms); |
1848 array->set_length(Smi::FromInt(number_of_elements)); | 1831 array->set_length(Smi::FromInt(number_of_elements)); |
1849 return array; | 1832 return array; |
1850 } | 1833 } |
1851 | 1834 |
1852 } } // namespace v8::internal | 1835 } } // namespace v8::internal |
OLD | NEW |