@@ -636,16 +636,13 @@ class ElementsAccessorBase : public ElementsAccessor {
636636 return MaybeHandle<AccessorPair>();
637637 }
638638
639- MUST_USE_RESULT virtual MaybeHandle<Object> SetLength (
640- Handle<JSArray> array, Handle<Object> length) final {
641- return ElementsAccessorSubclass::SetLengthImpl (
642- array, length, handle (array->elements ()));
639+ virtual void SetLength (Handle<JSArray> array, uint32_t length) final {
640+ ElementsAccessorSubclass::SetLengthImpl (array, length,
641+ handle (array->elements ()));
643642 }
644643
645- MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl (
646- Handle<JSObject> obj,
647- Handle<Object> length,
648- Handle<FixedArrayBase> backing_store);
644+ static void SetLengthImpl (Handle<JSArray> array, uint32_t length,
645+ Handle<FixedArrayBase> backing_store);
649646
650647 virtual void SetCapacityAndLength (Handle<JSArray> array, int capacity,
651648 int length) final {
@@ -866,10 +863,8 @@ class FastElementsAccessor
866863 typedef typename KindTraits::BackingStore BackingStore;
867864
868865 // Adjusts the length of the fast backing store.
869- static Handle<Object> SetLengthWithoutNormalize (
870- Handle<FixedArrayBase> backing_store,
871- Handle<JSArray> array,
872- Handle<Object> length_object,
866+ static uint32_t SetLengthWithoutNormalize (
867+ Handle<FixedArrayBase> backing_store, Handle<JSArray> array,
873868 uint32_t length) {
874869 Isolate* isolate = array->GetIsolate ();
875870 uint32_t old_capacity = backing_store->length ();
@@ -904,7 +899,7 @@ class FastElementsAccessor
904899 Handle<BackingStore>::cast (backing_store)->set_the_hole (i);
905900 }
906901 }
907- return length_object ;
902+ return length ;
908903 }
909904
910905 // Check whether the backing store should be expanded.
@@ -913,7 +908,7 @@ class FastElementsAccessor
913908 FastElementsAccessorSubclass::SetFastElementsCapacityAndLength (
914909 array, new_capacity, length);
915910 JSObject::ValidateElements (array);
916- return length_object ;
911+ return length ;
917912 }
918913
919914 static void DeleteCommon (Handle<JSObject> obj, uint32_t key,
@@ -1271,13 +1266,10 @@ class TypedElementsAccessor
12711266 return PropertyDetails (DONT_DELETE , DATA , 0 , PropertyCellType::kNoCell );
12721267 }
12731268
1274- MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl (
1275- Handle<JSObject> obj,
1276- Handle<Object> length,
1277- Handle<FixedArrayBase> backing_store) {
1269+ static void SetLengthImpl (Handle<JSArray> array, uint32_t length,
1270+ Handle<FixedArrayBase> backing_store) {
12781271 // External arrays do not support changing their length.
12791272 UNREACHABLE ();
1280- return obj;
12811273 }
12821274
12831275 virtual void Delete (Handle<JSObject> obj, uint32_t key,
@@ -1327,39 +1319,51 @@ class DictionaryElementsAccessor
13271319 : ElementsAccessorBase<DictionaryElementsAccessor,
13281320 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
13291321
1322+ static void SetLengthImpl (Handle<JSArray> array, uint32_t length,
1323+ Handle<FixedArrayBase> backing_store) {
1324+ uint32_t new_length =
1325+ SetLengthWithoutNormalize (backing_store, array, length);
1326+ // SetLengthWithoutNormalize does not allow length to drop below the last
1327+ // non-deletable element.
1328+ DCHECK_GE (new_length, length);
1329+ if (new_length <= Smi::kMaxValue ) {
1330+ array->set_length (Smi::FromInt (new_length));
1331+ } else {
1332+ Isolate* isolate = array->GetIsolate ();
1333+ Handle<Object> length_obj =
1334+ isolate->factory ()->NewNumberFromUint (new_length);
1335+ array->set_length (*length_obj);
1336+ }
1337+ }
1338+
13301339 // Adjusts the length of the dictionary backing store and returns the new
13311340 // length according to ES5 section 15.4.5.2 behavior.
1332- static Handle<Object> SetLengthWithoutNormalize (
1333- Handle<FixedArrayBase> store,
1334- Handle<JSArray> array,
1335- Handle<Object> length_object,
1336- uint32_t length) {
1341+ static uint32_t SetLengthWithoutNormalize (Handle<FixedArrayBase> store,
1342+ Handle<JSArray> array,
1343+ uint32_t length) {
13371344 Handle<SeededNumberDictionary> dict =
13381345 Handle<SeededNumberDictionary>::cast (store);
13391346 Isolate* isolate = array->GetIsolate ();
13401347 int capacity = dict->Capacity ();
1341- uint32_t new_length = length ;
1342- uint32_t old_length = static_cast < uint32_t > (array->length ()->Number ( ));
1343- if (new_length < old_length) {
1348+ uint32_t old_length = 0 ;
1349+ CHECK (array->length ()->ToArrayLength (&old_length ));
1350+ if (length < old_length) {
13441351 // Find last non-deletable element in range of elements to be
13451352 // deleted and adjust range accordingly.
13461353 for (int i = 0 ; i < capacity; i++) {
13471354 DisallowHeapAllocation no_gc;
13481355 Object* key = dict->KeyAt (i);
13491356 if (key->IsNumber ()) {
13501357 uint32_t number = static_cast <uint32_t >(key->Number ());
1351- if (new_length <= number && number < old_length) {
1358+ if (length <= number && number < old_length) {
13521359 PropertyDetails details = dict->DetailsAt (i);
1353- if (!details.IsConfigurable ()) new_length = number + 1 ;
1360+ if (!details.IsConfigurable ()) length = number + 1 ;
13541361 }
13551362 }
13561363 }
1357- if (new_length != length) {
1358- length_object = isolate->factory ()->NewNumberFromUint (new_length);
1359- }
13601364 }
13611365
1362- if (new_length == 0 ) {
1366+ if (length == 0 ) {
13631367 // Flush the backing store.
13641368 JSObject::ResetElements (array);
13651369 } else {
@@ -1371,7 +1375,7 @@ class DictionaryElementsAccessor
13711375 Object* key = dict->KeyAt (i);
13721376 if (key->IsNumber ()) {
13731377 uint32_t number = static_cast <uint32_t >(key->Number ());
1374- if (new_length <= number && number < old_length) {
1378+ if (length <= number && number < old_length) {
13751379 dict->SetEntry (i, the_hole_value, the_hole_value);
13761380 removed_entries++;
13771381 }
@@ -1381,7 +1385,7 @@ class DictionaryElementsAccessor
13811385 // Update the number of elements.
13821386 dict->ElementsRemoved (removed_entries);
13831387 }
1384- return length_object ;
1388+ return length ;
13851389 }
13861390
13871391 static void DeleteCommon (Handle<JSObject> obj, uint32_t key,
@@ -1566,14 +1570,10 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
15661570 }
15671571 }
15681572
1569- MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl (
1570- Handle<JSObject> obj,
1571- Handle<Object> length,
1572- Handle<FixedArrayBase> parameter_map) {
1573- // TODO(mstarzinger): This was never implemented but will be used once we
1574- // correctly implement [[DefineOwnProperty]] on arrays.
1575- UNIMPLEMENTED ();
1576- return obj;
1573+ static void SetLengthImpl (Handle<JSArray> array, uint32_t length,
1574+ Handle<FixedArrayBase> parameter_map) {
1575+ // Sloppy arguments objects are not arrays.
1576+ UNREACHABLE ();
15771577 }
15781578
15791579 virtual void Delete (Handle<JSObject> obj, uint32_t key,
@@ -1704,52 +1704,26 @@ void ElementsAccessor::TearDown() {
17041704
17051705
17061706template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
1707- MUST_USE_RESULT MaybeHandle<Object> ElementsAccessorBase<
1708- ElementsAccessorSubclass,
1709- ElementsKindTraits>::SetLengthImpl(Handle<JSObject> obj,
1710- Handle<Object> length_obj,
1711- Handle<FixedArrayBase> backing_store) {
1712- Handle<JSArray> array = Handle<JSArray>::cast (obj);
1713-
1714- uint32_t length = 0 ;
1715- CHECK (length_obj->ToArrayLength (&length));
1716- // Fast case: length fits in a smi.
1717- if (length <= Smi::kMaxValue ) {
1718- Handle<Smi> smi (Smi::FromInt (length), obj->GetIsolate ());
1719- Handle<Object> new_length =
1720- ElementsAccessorSubclass::SetLengthWithoutNormalize (backing_store,
1721- array, smi, length);
1722- DCHECK (!new_length.is_null ());
1723-
1724- // Even though the proposed length was a smi, new_length could
1725- // still be a heap number because SetLengthWithoutNormalize doesn't
1726- // allow the array length property to drop below the index of
1727- // non-deletable elements.
1728- DCHECK (new_length->IsSmi () || new_length->IsHeapNumber () ||
1729- new_length->IsUndefined ());
1730- if (new_length->IsSmi ()) {
1731- array->set_length (*Handle<Smi>::cast (new_length));
1732- return array;
1733- } else if (new_length->IsHeapNumber ()) {
1734- array->set_length (*new_length);
1735- return array;
1736- }
1707+ void ElementsAccessorBase<ElementsAccessorSubclass, ElementsKindTraits>::
1708+ SetLengthImpl (Handle<JSArray> array, uint32_t length,
1709+ Handle<FixedArrayBase> backing_store) {
1710+ // Normalize if the length does not fit in a smi. Fast mode arrays only
1711+ // support smi length.
1712+ if (JSArray::SetLengthWouldNormalize (array->GetHeap (), length)) {
1713+ Handle<SeededNumberDictionary> dictionary =
1714+ JSObject::NormalizeElements (array);
1715+ DCHECK (!dictionary.is_null ());
1716+ DictionaryElementsAccessor::SetLengthImpl (array, length, dictionary);
1717+ } else {
1718+ #ifdef DEBUG
1719+ uint32_t max = Smi::kMaxValue ;
1720+ DCHECK_LE (length, max);
1721+ #endif
1722+ uint32_t new_length = ElementsAccessorSubclass::SetLengthWithoutNormalize (
1723+ backing_store, array, length);
1724+ DCHECK_EQ (length, new_length);
1725+ array->set_length (Smi::FromInt (new_length));
17371726 }
1738-
1739- // Slow case: The new length does not fit into a Smi or conversion
1740- // to slow elements is needed for other reasons.
1741- Handle<SeededNumberDictionary> dictionary =
1742- JSObject::NormalizeElements (array);
1743- DCHECK (!dictionary.is_null ());
1744-
1745- Handle<Object> new_length =
1746- DictionaryElementsAccessor::SetLengthWithoutNormalize (dictionary, array,
1747- length_obj, length);
1748- DCHECK (!new_length.is_null ());
1749-
1750- DCHECK (new_length->IsNumber ());
1751- array->set_length (*new_length);
1752- return array;
17531727}
17541728
17551729
@@ -1776,15 +1750,14 @@ MaybeHandle<Object> ArrayConstructInitializeElements(Handle<JSArray> array,
17761750 elements_kind = GetHoleyElementsKind (elements_kind);
17771751 JSObject::TransitionElementsKind (array, elements_kind);
17781752 }
1779- return array;
17801753 } else if (length == 0 ) {
17811754 JSArray::Initialize (array, JSArray::kPreallocatedArrayElements );
1782- return array;
1755+ } else {
1756+ // Take the argument as the length.
1757+ JSArray::Initialize (array, 0 );
1758+ JSArray::SetLength (array, length);
17831759 }
1784-
1785- // Take the argument as the length.
1786- JSArray::Initialize (array, 0 );
1787- return JSArray::SetElementsLength (array, args->at <Object>(0 ));
1760+ return array;
17881761 }
17891762
17901763 Factory* factory = array->GetIsolate ()->factory ();
0 commit comments