111
111
Object* receiver) {
112
return ElementsAccessorSubclass::Get(
112
return ElementsAccessorSubclass::GetImpl(
113
113
BackingStoreClass::cast(backing_store), key, obj, receiver);
116
static MaybeObject* Get(BackingStoreClass* backing_store,
120
if (key < ElementsAccessorSubclass::GetCapacity(backing_store)) {
121
return backing_store->get(key);
123
return backing_store->GetHeap()->the_hole_value();
116
static MaybeObject* GetImpl(BackingStoreClass* backing_store,
120
return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store))
121
? backing_store->get(key)
122
: backing_store->GetHeap()->the_hole_value();
126
125
virtual MaybeObject* SetLength(JSObject* obj,
127
126
Object* length) {
128
127
ASSERT(obj->IsJSArray());
129
return ElementsAccessorSubclass::SetLength(
128
return ElementsAccessorSubclass::SetLengthImpl(
130
129
BackingStoreClass::cast(obj->elements()), obj, length);
133
static MaybeObject* SetLength(BackingStoreClass* backing_store,
132
static MaybeObject* SetLengthImpl(BackingStoreClass* backing_store,
136
virtual MaybeObject* SetCapacityAndLength(JSArray* array,
139
return ElementsAccessorSubclass::SetFastElementsCapacityAndLength(
145
static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
137
152
virtual MaybeObject* Delete(JSObject* obj,
153
168
BackingStoreClass* backing_store = BackingStoreClass::cast(from);
154
uint32_t len1 = ElementsAccessorSubclass::GetCapacity(backing_store);
169
uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store);
156
171
// Optimize if 'other' is empty.
157
172
// We cannot optimize if 'this' is empty, as other may have holes.
160
175
// Compute how many elements are not in other.
162
177
for (uint32_t y = 0; y < len1; y++) {
163
if (ElementsAccessorSubclass::HasElementAtIndex(backing_store,
178
if (ElementsAccessorSubclass::HasElementAtIndexImpl(
179
backing_store, y, holder, receiver)) {
168
ElementsAccessorSubclass::GetKeyForIndex(backing_store, y);
181
ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
169
182
MaybeObject* maybe_value =
170
ElementsAccessorSubclass::Get(backing_store, key, holder, receiver);
183
ElementsAccessorSubclass::GetImpl(backing_store, key,
172
186
if (!maybe_value->ToObject(&value)) return maybe_value;
173
187
ASSERT(!value->IsTheHole());
198
212
// Fill in the extra values.
200
214
for (uint32_t y = 0; y < len1; y++) {
201
if (ElementsAccessorSubclass::HasElementAtIndex(backing_store,
215
if (ElementsAccessorSubclass::HasElementAtIndexImpl(
216
backing_store, y, holder, receiver)) {
206
ElementsAccessorSubclass::GetKeyForIndex(backing_store, y);
218
ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
207
219
MaybeObject* maybe_value =
208
ElementsAccessorSubclass::Get(backing_store, key, holder, receiver);
220
ElementsAccessorSubclass::GetImpl(backing_store, key,
210
223
if (!maybe_value->ToObject(&value)) return maybe_value;
211
224
if (!value->IsTheHole() && !HasKey(to, value)) {
222
static uint32_t GetCapacity(BackingStoreClass* backing_store) {
235
static uint32_t GetCapacityImpl(BackingStoreClass* backing_store) {
223
236
return backing_store->length();
226
239
virtual uint32_t GetCapacity(FixedArrayBase* backing_store) {
227
return ElementsAccessorSubclass::GetCapacity(
240
return ElementsAccessorSubclass::GetCapacityImpl(
228
241
BackingStoreClass::cast(backing_store));
231
static bool HasElementAtIndex(BackingStoreClass* backing_store,
244
static bool HasElementAtIndexImpl(BackingStoreClass* backing_store,
236
ElementsAccessorSubclass::GetKeyForIndex(backing_store, index);
237
MaybeObject* element = ElementsAccessorSubclass::Get(backing_store,
249
ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
250
MaybeObject* element =
251
ElementsAccessorSubclass::GetImpl(backing_store, key, holder, receiver);
241
252
return !element->IsTheHole();
246
257
JSObject* holder,
247
258
Object* receiver) {
248
return ElementsAccessorSubclass::HasElementAtIndex(
259
return ElementsAccessorSubclass::HasElementAtIndexImpl(
249
260
BackingStoreClass::cast(backing_store), index, holder, receiver);
252
static uint32_t GetKeyForIndex(BackingStoreClass* backing_store,
263
static uint32_t GetKeyForIndexImpl(BackingStoreClass* backing_store,
257
268
virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
258
269
uint32_t index) {
259
return ElementsAccessorSubclass::GetKeyForIndex(
270
return ElementsAccessorSubclass::GetKeyForIndexImpl(
260
271
BackingStoreClass::cast(backing_store), index);
405
416
: public FastElementsAccessor<FastDoubleElementsAccessor,
406
417
FixedDoubleArray,
419
static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
422
return obj->SetFastDoubleElementsCapacityAndLength(capacity, length);
409
426
friend class ElementsAccessorBase<FastDoubleElementsAccessor,
410
427
FixedDoubleArray>;
412
429
FixedDoubleArray,
415
static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
418
return obj->SetFastDoubleElementsCapacityAndLength(capacity, length);
421
432
virtual MaybeObject* Delete(JSObject* obj,
423
434
JSReceiver::DeleteMode mode) {
430
441
return obj->GetHeap()->true_value();
433
static bool HasElementAtIndex(FixedDoubleArray* backing_store,
444
static bool HasElementAtIndexImpl(FixedDoubleArray* backing_store,
437
448
return !backing_store->is_the_hole(index);
449
460
friend class ElementsAccessorBase<ExternalElementsAccessorSubclass,
452
static MaybeObject* Get(ExternalArray* backing_store,
456
if (key < ExternalElementsAccessorSubclass::GetCapacity(backing_store)) {
457
return backing_store->get(key);
459
return backing_store->GetHeap()->undefined_value();
463
static MaybeObject* GetImpl(ExternalArray* backing_store,
468
key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
469
? backing_store->get(key)
470
: backing_store->GetHeap()->undefined_value();
463
static MaybeObject* SetLength(ExternalArray* backing_store,
473
static MaybeObject* SetLengthImpl(ExternalArray* backing_store,
466
476
// External arrays do not support changing their length.
534
544
class DictionaryElementsAccessor
535
545
: public ElementsAccessorBase<DictionaryElementsAccessor,
546
SeededNumberDictionary> {
538
548
// Adjusts the length of the dictionary backing store and returns the new
539
549
// length according to ES5 section 15.4.5.2 behavior.
540
static MaybeObject* SetLengthWithoutNormalize(NumberDictionary* dict,
550
static MaybeObject* SetLengthWithoutNormalize(SeededNumberDictionary* dict,
542
552
Object* length_object,
543
553
uint32_t length) {
603
613
if (is_arguments) {
604
614
backing_store = FixedArray::cast(backing_store->get(1));
606
NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
616
SeededNumberDictionary* dictionary =
617
SeededNumberDictionary::cast(backing_store);
607
618
int entry = dictionary->FindEntry(key);
608
if (entry != NumberDictionary::kNotFound) {
619
if (entry != SeededNumberDictionary::kNotFound) {
609
620
Object* result = dictionary->DeleteProperty(entry, mode);
610
621
if (result == heap->true_value()) {
611
622
MaybeObject* maybe_elements = dictionary->Shrink(key);
646
657
return DeleteCommon(obj, key, mode);
649
static MaybeObject* Get(NumberDictionary* backing_store,
660
static MaybeObject* GetImpl(SeededNumberDictionary* backing_store,
653
664
int entry = backing_store->FindEntry(key);
654
if (entry != NumberDictionary::kNotFound) {
665
if (entry != SeededNumberDictionary::kNotFound) {
655
666
Object* element = backing_store->ValueAt(entry);
656
667
PropertyDetails details = backing_store->DetailsAt(entry);
657
668
if (details.type() == CALLBACKS) {
666
677
return obj->GetHeap()->the_hole_value();
669
static uint32_t GetKeyForIndex(NumberDictionary* dict,
680
static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict,
671
682
Object* key = dict->KeyAt(index);
672
683
return Smi::cast(key)->value();
681
692
friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor,
684
static MaybeObject* Get(FixedArray* parameter_map,
695
static MaybeObject* GetImpl(FixedArray* parameter_map,
688
699
Object* probe = GetParameterMapArg(parameter_map, key);
689
700
if (!probe->IsTheHole()) {
690
701
Context* context = Context::cast(parameter_map->get(0));
704
static MaybeObject* SetLength(FixedArray* parameter_map,
715
static MaybeObject* SetLengthImpl(FixedArray* parameter_map,
707
718
// TODO(mstarzinger): This was never implemented but will be used once we
708
719
// correctly implement [[DefineOwnProperty]] on arrays.
731
742
return obj->GetHeap()->true_value();
734
static uint32_t GetCapacity(FixedArray* parameter_map) {
745
static uint32_t GetCapacityImpl(FixedArray* parameter_map) {
735
746
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
736
747
return Max(static_cast<uint32_t>(parameter_map->length() - 2),
737
748
ForArray(arguments)->GetCapacity(arguments));
740
static uint32_t GetKeyForIndex(FixedArray* dict,
751
static uint32_t GetKeyForIndexImpl(FixedArray* dict,
745
static bool HasElementAtIndex(FixedArray* parameter_map,
756
static bool HasElementAtIndexImpl(FixedArray* parameter_map,
749
760
Object* probe = GetParameterMapArg(parameter_map, index);
750
761
if (!probe->IsTheHole()) {
850
861
template <typename ElementsAccessorSubclass, typename BackingStoreClass>
851
862
MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, BackingStoreClass>::
852
SetLength(BackingStoreClass* backing_store,
863
SetLengthImpl(BackingStoreClass* backing_store,
855
866
JSArray* array = JSArray::cast(obj);
857
868
// Fast case: The new length fits into a Smi.
879
890
if (length->IsNumber()) {
881
892
if (length->ToArrayIndex(&value)) {
882
NumberDictionary* dictionary;
893
SeededNumberDictionary* dictionary;
883
894
MaybeObject* maybe_object = array->NormalizeElements();
884
895
if (!maybe_object->To(&dictionary)) return maybe_object;
885
896
Object* new_length;