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/messages.h" | 10 #include "src/messages.h" |
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 SetFastElementsCapacityAndLength(array, capacity, length); | 662 SetFastElementsCapacityAndLength(array, capacity, length); |
663 } | 663 } |
664 | 664 |
665 static void SetFastElementsCapacityAndLength( | 665 static void SetFastElementsCapacityAndLength( |
666 Handle<JSObject> obj, | 666 Handle<JSObject> obj, |
667 int capacity, | 667 int capacity, |
668 int length) { | 668 int length) { |
669 UNIMPLEMENTED(); | 669 UNIMPLEMENTED(); |
670 } | 670 } |
671 | 671 |
672 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( | 672 virtual void Delete(Handle<JSObject> obj, uint32_t key, |
673 Handle<JSObject> obj, uint32_t key, | 673 LanguageMode language_mode) override = 0; |
674 LanguageMode language_mode) override = 0; | |
675 | 674 |
676 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 675 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
677 FixedArrayBase* to, ElementsKind from_kind, | 676 FixedArrayBase* to, ElementsKind from_kind, |
678 uint32_t to_start, int packed_size, | 677 uint32_t to_start, int packed_size, |
679 int copy_size) { | 678 int copy_size) { |
680 UNREACHABLE(); | 679 UNREACHABLE(); |
681 } | 680 } |
682 | 681 |
683 virtual void CopyElements(Handle<FixedArrayBase> from, uint32_t from_start, | 682 virtual void CopyElements(Handle<FixedArrayBase> from, uint32_t from_start, |
684 ElementsKind from_kind, Handle<FixedArrayBase> to, | 683 ElementsKind from_kind, Handle<FixedArrayBase> to, |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
912 | 911 |
913 // Check whether the backing store should be expanded. | 912 // Check whether the backing store should be expanded. |
914 uint32_t min = JSObject::NewElementsCapacity(old_capacity); | 913 uint32_t min = JSObject::NewElementsCapacity(old_capacity); |
915 uint32_t new_capacity = length > min ? length : min; | 914 uint32_t new_capacity = length > min ? length : min; |
916 FastElementsAccessorSubclass::SetFastElementsCapacityAndLength( | 915 FastElementsAccessorSubclass::SetFastElementsCapacityAndLength( |
917 array, new_capacity, length); | 916 array, new_capacity, length); |
918 JSObject::ValidateElements(array); | 917 JSObject::ValidateElements(array); |
919 return length_object; | 918 return length_object; |
920 } | 919 } |
921 | 920 |
922 static MaybeHandle<Object> DeleteCommon(Handle<JSObject> obj, uint32_t key, | 921 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, |
923 LanguageMode language_mode) { | 922 LanguageMode language_mode) { |
924 DCHECK(obj->HasFastSmiOrObjectElements() || | 923 DCHECK(obj->HasFastSmiOrObjectElements() || |
925 obj->HasFastDoubleElements() || | 924 obj->HasFastDoubleElements() || |
926 obj->HasFastArgumentsElements()); | 925 obj->HasFastArgumentsElements()); |
927 Isolate* isolate = obj->GetIsolate(); | 926 Isolate* isolate = obj->GetIsolate(); |
928 Heap* heap = obj->GetHeap(); | 927 Heap* heap = obj->GetHeap(); |
929 Handle<FixedArrayBase> elements(obj->elements()); | 928 Handle<FixedArrayBase> elements(obj->elements()); |
930 if (*elements == heap->empty_fixed_array()) { | 929 if (*elements == heap->empty_fixed_array()) return; |
931 return isolate->factory()->true_value(); | 930 |
932 } | |
933 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); | 931 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); |
934 bool is_sloppy_arguments_elements_map = | 932 bool is_sloppy_arguments_elements_map = |
935 backing_store->map() == heap->sloppy_arguments_elements_map(); | 933 backing_store->map() == heap->sloppy_arguments_elements_map(); |
936 if (is_sloppy_arguments_elements_map) { | 934 if (is_sloppy_arguments_elements_map) { |
937 backing_store = handle( | 935 backing_store = handle( |
938 BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1)), | 936 BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1)), |
939 isolate); | 937 isolate); |
940 } | 938 } |
941 uint32_t length = static_cast<uint32_t>( | 939 uint32_t length = static_cast<uint32_t>( |
942 obj->IsJSArray() | 940 obj->IsJSArray() |
943 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value() | 941 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value() |
944 : backing_store->length()); | 942 : backing_store->length()); |
945 if (key < length) { | 943 if (key < length) { |
946 if (obj->map()->is_strong() && !backing_store->is_the_hole(key)) { | |
947 if (is_strict(language_mode)) { | |
948 Handle<Object> name = isolate->factory()->NewNumberFromUint(key); | |
949 THROW_NEW_ERROR( | |
950 isolate, | |
951 NewTypeError(MessageTemplate::kStrongDeleteProperty, obj, name), | |
952 Object); | |
953 } | |
954 return isolate->factory()->false_value(); | |
955 } | |
956 if (!is_sloppy_arguments_elements_map) { | 944 if (!is_sloppy_arguments_elements_map) { |
957 ElementsKind kind = KindTraits::Kind; | 945 ElementsKind kind = KindTraits::Kind; |
958 if (IsFastPackedElementsKind(kind)) { | 946 if (IsFastPackedElementsKind(kind)) { |
959 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); | 947 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); |
960 } | 948 } |
961 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { | 949 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { |
962 Handle<Object> writable = JSObject::EnsureWritableFastElements(obj); | 950 Handle<Object> writable = JSObject::EnsureWritableFastElements(obj); |
963 backing_store = Handle<BackingStore>::cast(writable); | 951 backing_store = Handle<BackingStore>::cast(writable); |
964 } | 952 } |
965 } | 953 } |
(...skipping 11 matching lines...) Expand all Loading... |
977 for (int i = 0; i < backing_store->length(); ++i) { | 965 for (int i = 0; i < backing_store->length(); ++i) { |
978 if (!backing_store->is_the_hole(i)) ++num_used; | 966 if (!backing_store->is_the_hole(i)) ++num_used; |
979 // Bail out early if more than 1/4 is used. | 967 // Bail out early if more than 1/4 is used. |
980 if (4 * num_used > backing_store->length()) break; | 968 if (4 * num_used > backing_store->length()) break; |
981 } | 969 } |
982 if (4 * num_used <= backing_store->length()) { | 970 if (4 * num_used <= backing_store->length()) { |
983 JSObject::NormalizeElements(obj); | 971 JSObject::NormalizeElements(obj); |
984 } | 972 } |
985 } | 973 } |
986 } | 974 } |
987 return isolate->factory()->true_value(); | |
988 } | 975 } |
989 | 976 |
990 virtual MaybeHandle<Object> Delete(Handle<JSObject> obj, uint32_t key, | 977 virtual void Delete(Handle<JSObject> obj, uint32_t key, |
991 LanguageMode language_mode) final { | 978 LanguageMode language_mode) final { |
992 return DeleteCommon(obj, key, language_mode); | 979 DeleteCommon(obj, key, language_mode); |
993 } | 980 } |
994 | 981 |
995 static bool HasElementImpl( | 982 static bool HasElementImpl( |
996 Handle<JSObject> holder, | 983 Handle<JSObject> holder, |
997 uint32_t key, | 984 uint32_t key, |
998 Handle<FixedArrayBase> backing_store) { | 985 Handle<FixedArrayBase> backing_store) { |
999 if (key >= static_cast<uint32_t>(backing_store->length())) { | 986 if (key >= static_cast<uint32_t>(backing_store->length())) { |
1000 return false; | 987 return false; |
1001 } | 988 } |
1002 return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key); | 989 return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1299 | 1286 |
1300 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( | 1287 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( |
1301 Handle<JSObject> obj, | 1288 Handle<JSObject> obj, |
1302 Handle<Object> length, | 1289 Handle<Object> length, |
1303 Handle<FixedArrayBase> backing_store) { | 1290 Handle<FixedArrayBase> backing_store) { |
1304 // External arrays do not support changing their length. | 1291 // External arrays do not support changing their length. |
1305 UNREACHABLE(); | 1292 UNREACHABLE(); |
1306 return obj; | 1293 return obj; |
1307 } | 1294 } |
1308 | 1295 |
1309 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( | 1296 virtual void Delete(Handle<JSObject> obj, uint32_t key, |
1310 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { | 1297 LanguageMode language_mode) final { |
1311 // External arrays always ignore deletes. | 1298 // External arrays always ignore deletes. |
1312 return obj->GetIsolate()->factory()->true_value(); | |
1313 } | 1299 } |
1314 | 1300 |
1315 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, | 1301 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, |
1316 Handle<FixedArrayBase> backing_store) { | 1302 Handle<FixedArrayBase> backing_store) { |
1317 uint32_t capacity = AccessorClass::GetCapacityImpl(*holder, *backing_store); | 1303 uint32_t capacity = AccessorClass::GetCapacityImpl(*holder, *backing_store); |
1318 return key < capacity; | 1304 return key < capacity; |
1319 } | 1305 } |
1320 | 1306 |
1321 static uint32_t GetCapacityImpl(JSObject* holder, | 1307 static uint32_t GetCapacityImpl(JSObject* holder, |
1322 FixedArrayBase* backing_store) { | 1308 FixedArrayBase* backing_store) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1402 } | 1388 } |
1403 } | 1389 } |
1404 } | 1390 } |
1405 | 1391 |
1406 // Update the number of elements. | 1392 // Update the number of elements. |
1407 dict->ElementsRemoved(removed_entries); | 1393 dict->ElementsRemoved(removed_entries); |
1408 } | 1394 } |
1409 return length_object; | 1395 return length_object; |
1410 } | 1396 } |
1411 | 1397 |
1412 MUST_USE_RESULT static MaybeHandle<Object> DeleteCommon( | 1398 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, |
1413 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) { | 1399 LanguageMode language_mode) { |
1414 Isolate* isolate = obj->GetIsolate(); | 1400 Isolate* isolate = obj->GetIsolate(); |
1415 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()), | 1401 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()), |
1416 isolate); | 1402 isolate); |
1417 bool is_arguments = | 1403 bool is_arguments = |
1418 (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS); | 1404 (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS); |
1419 if (is_arguments) { | 1405 if (is_arguments) { |
1420 backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate); | 1406 backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate); |
1421 } | 1407 } |
1422 Handle<SeededNumberDictionary> dictionary = | 1408 Handle<SeededNumberDictionary> dictionary = |
1423 Handle<SeededNumberDictionary>::cast(backing_store); | 1409 Handle<SeededNumberDictionary>::cast(backing_store); |
1424 int entry = dictionary->FindEntry(key); | 1410 int entry = dictionary->FindEntry(key); |
1425 if (entry != SeededNumberDictionary::kNotFound) { | 1411 if (entry != SeededNumberDictionary::kNotFound) { |
1426 Handle<Object> result; | 1412 Handle<Object> result = |
1427 bool strong = obj->map()->is_strong(); | 1413 SeededNumberDictionary::DeleteProperty(dictionary, entry); |
1428 if (!strong) { | 1414 USE(result); |
1429 result = SeededNumberDictionary::DeleteProperty(dictionary, entry); | 1415 DCHECK(result->IsTrue()); |
1430 } | |
1431 if (strong || *result == *isolate->factory()->false_value()) { | |
1432 // Fail if the property is not configurable, or on a strong object. | |
1433 if (is_strict(language_mode)) { | |
1434 Handle<Object> name = isolate->factory()->NewNumberFromUint(key); | |
1435 if (strong) { | |
1436 THROW_NEW_ERROR( | |
1437 isolate, | |
1438 NewTypeError(MessageTemplate::kStrongDeleteProperty, obj, name), | |
1439 Object); | |
1440 } | |
1441 THROW_NEW_ERROR( | |
1442 isolate, | |
1443 NewTypeError(MessageTemplate::kStrictDeleteProperty, name, obj), | |
1444 Object); | |
1445 } | |
1446 return isolate->factory()->false_value(); | |
1447 } | |
1448 Handle<FixedArray> new_elements = | 1416 Handle<FixedArray> new_elements = |
1449 SeededNumberDictionary::Shrink(dictionary, key); | 1417 SeededNumberDictionary::Shrink(dictionary, key); |
1450 | 1418 |
1451 if (is_arguments) { | 1419 if (is_arguments) { |
1452 FixedArray::cast(obj->elements())->set(1, *new_elements); | 1420 FixedArray::cast(obj->elements())->set(1, *new_elements); |
1453 } else { | 1421 } else { |
1454 obj->set_elements(*new_elements); | 1422 obj->set_elements(*new_elements); |
1455 } | 1423 } |
1456 } | 1424 } |
1457 return isolate->factory()->true_value(); | |
1458 } | 1425 } |
1459 | 1426 |
1460 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 1427 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
1461 FixedArrayBase* to, ElementsKind from_kind, | 1428 FixedArrayBase* to, ElementsKind from_kind, |
1462 uint32_t to_start, int packed_size, | 1429 uint32_t to_start, int packed_size, |
1463 int copy_size) { | 1430 int copy_size) { |
1464 UNREACHABLE(); | 1431 UNREACHABLE(); |
1465 } | 1432 } |
1466 | 1433 |
1467 | 1434 |
1468 protected: | 1435 protected: |
1469 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 1436 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
1470 ElementsKindTraits<DICTIONARY_ELEMENTS> >; | 1437 ElementsKindTraits<DICTIONARY_ELEMENTS> >; |
1471 | 1438 |
1472 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( | 1439 virtual void Delete(Handle<JSObject> obj, uint32_t key, |
1473 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { | 1440 LanguageMode language_mode) final { |
1474 return DeleteCommon(obj, key, language_mode); | 1441 DeleteCommon(obj, key, language_mode); |
1475 } | 1442 } |
1476 | 1443 |
1477 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, | 1444 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, |
1478 Handle<FixedArrayBase> store) { | 1445 Handle<FixedArrayBase> store) { |
1479 Handle<SeededNumberDictionary> backing_store = | 1446 Handle<SeededNumberDictionary> backing_store = |
1480 Handle<SeededNumberDictionary>::cast(store); | 1447 Handle<SeededNumberDictionary>::cast(store); |
1481 Isolate* isolate = backing_store->GetIsolate(); | 1448 Isolate* isolate = backing_store->GetIsolate(); |
1482 int entry = backing_store->FindEntry(key); | 1449 int entry = backing_store->FindEntry(key); |
1483 if (entry != SeededNumberDictionary::kNotFound) { | 1450 if (entry != SeededNumberDictionary::kNotFound) { |
1484 return handle(backing_store->ValueAt(entry), isolate); | 1451 return handle(backing_store->ValueAt(entry), isolate); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( | 1591 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( |
1625 Handle<JSObject> obj, | 1592 Handle<JSObject> obj, |
1626 Handle<Object> length, | 1593 Handle<Object> length, |
1627 Handle<FixedArrayBase> parameter_map) { | 1594 Handle<FixedArrayBase> parameter_map) { |
1628 // TODO(mstarzinger): This was never implemented but will be used once we | 1595 // TODO(mstarzinger): This was never implemented but will be used once we |
1629 // correctly implement [[DefineOwnProperty]] on arrays. | 1596 // correctly implement [[DefineOwnProperty]] on arrays. |
1630 UNIMPLEMENTED(); | 1597 UNIMPLEMENTED(); |
1631 return obj; | 1598 return obj; |
1632 } | 1599 } |
1633 | 1600 |
1634 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( | 1601 virtual void Delete(Handle<JSObject> obj, uint32_t key, |
1635 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { | 1602 LanguageMode language_mode) final { |
1636 Isolate* isolate = obj->GetIsolate(); | 1603 Isolate* isolate = obj->GetIsolate(); |
1637 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); | 1604 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); |
1638 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); | 1605 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); |
1639 if (!probe->IsTheHole()) { | 1606 if (!probe->IsTheHole()) { |
1640 // TODO(kmillikin): We could check if this was the last aliased | 1607 // TODO(kmillikin): We could check if this was the last aliased |
1641 // parameter, and revert to normal elements in that case. That | 1608 // parameter, and revert to normal elements in that case. That |
1642 // would enable GC of the context. | 1609 // would enable GC of the context. |
1643 parameter_map->set_the_hole(key + 2); | 1610 parameter_map->set_the_hole(key + 2); |
1644 } else { | 1611 } else { |
1645 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); | 1612 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
1646 if (arguments->IsDictionary()) { | 1613 if (arguments->IsDictionary()) { |
1647 return DictionaryElementsAccessor::DeleteCommon(obj, key, | 1614 DictionaryElementsAccessor::DeleteCommon(obj, key, language_mode); |
1648 language_mode); | |
1649 } else { | 1615 } else { |
1650 // It's difficult to access the version of DeleteCommon that is declared | 1616 // It's difficult to access the version of DeleteCommon that is declared |
1651 // in the templatized super class, call the concrete implementation in | 1617 // in the templatized super class, call the concrete implementation in |
1652 // the class for the most generalized ElementsKind subclass. | 1618 // the class for the most generalized ElementsKind subclass. |
1653 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, | 1619 FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, language_mode); |
1654 language_mode); | |
1655 } | 1620 } |
1656 } | 1621 } |
1657 return isolate->factory()->true_value(); | |
1658 } | 1622 } |
1659 | 1623 |
1660 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 1624 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
1661 FixedArrayBase* to, ElementsKind from_kind, | 1625 FixedArrayBase* to, ElementsKind from_kind, |
1662 uint32_t to_start, int packed_size, | 1626 uint32_t to_start, int packed_size, |
1663 int copy_size) { | 1627 int copy_size) { |
1664 UNREACHABLE(); | 1628 UNREACHABLE(); |
1665 } | 1629 } |
1666 | 1630 |
1667 static uint32_t GetCapacityImpl(JSObject* holder, | 1631 static uint32_t GetCapacityImpl(JSObject* holder, |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1916 break; | 1880 break; |
1917 } | 1881 } |
1918 | 1882 |
1919 array->set_elements(*elms); | 1883 array->set_elements(*elms); |
1920 array->set_length(Smi::FromInt(number_of_elements)); | 1884 array->set_length(Smi::FromInt(number_of_elements)); |
1921 return array; | 1885 return array; |
1922 } | 1886 } |
1923 | 1887 |
1924 } // namespace internal | 1888 } // namespace internal |
1925 } // namespace v8 | 1889 } // namespace v8 |
OLD | NEW |