Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index 1cc5c8ba299c4a8a350388d5f437e5cd967ed239..4d9a55635bc8694caaf502b98e249609827755e4 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -7,6 +7,7 @@ |
#include "src/arguments.h" |
#include "src/conversions.h" |
#include "src/factory.h" |
+#include "src/isolate-inl.h" |
#include "src/messages.h" |
#include "src/objects-inl.h" |
#include "src/utils.h" |
@@ -856,6 +857,56 @@ class ElementsAccessorBase : public ElementsAccessor { |
return Handle<SeededNumberDictionary>(); |
} |
+ Maybe<bool> CollectValuesOrEntries(Isolate* isolate, Handle<JSObject> object, |
+ Handle<FixedArray> values_or_entries, |
+ bool get_entries, int* nof_items, |
+ PropertyFilter filter) { |
+ return ElementsAccessorSubclass::CollectValuesOrEntriesImpl( |
+ isolate, object, values_or_entries, get_entries, nof_items, filter); |
+ } |
+ |
+ static Maybe<bool> CollectValuesOrEntriesImpl( |
+ Isolate* isolate, Handle<JSObject> object, |
+ Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
+ PropertyFilter filter) { |
+ int count = 0; |
+ KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES); |
+ accumulator.NextPrototype(); |
+ ElementsAccessorSubclass::CollectElementIndicesImpl( |
+ object, handle(object->elements(), isolate), &accumulator, kMaxUInt32, |
+ ALL_PROPERTIES, 0); |
+ Handle<FixedArray> keys = accumulator.GetKeys(); |
+ |
+ for (int i = 0; i < keys->length(); ++i) { |
+ Handle<Object> key(keys->get(i), isolate); |
+ Handle<Object> value; |
+ uint32_t index; |
+ if (!key->ToUint32(&index)) continue; |
+ |
+ uint32_t entry = ElementsAccessorSubclass::GetEntryForIndexImpl( |
+ *object, object->elements(), index, filter); |
+ if (entry == kMaxUInt32) continue; |
+ |
+ PropertyDetails details = |
+ ElementsAccessorSubclass::GetDetailsImpl(*object, entry); |
+ |
+ if (details.kind() == kData) { |
+ value = ElementsAccessorSubclass::GetImpl(object, entry); |
+ } else { |
+ LookupIterator it(isolate, object, index, LookupIterator::OWN); |
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
+ isolate, value, Object::GetProperty(&it), Nothing<bool>()); |
+ } |
+ if (get_entries) { |
+ value = MakeEntryPair(isolate, index, value); |
+ } |
+ values_or_entries->set(count++, *value); |
+ } |
+ |
+ *nof_items = count; |
+ return Just(true); |
+ } |
+ |
void CollectElementIndices(Handle<JSObject> object, |
Handle<FixedArrayBase> backing_store, |
KeyAccumulator* keys, uint32_t range, |
@@ -1604,6 +1655,25 @@ class FastElementsAccessor |
return deleted_elements; |
} |
+ static Maybe<bool> CollectValuesOrEntriesImpl( |
+ Isolate* isolate, Handle<JSObject> object, |
+ Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
+ PropertyFilter filter) { |
+ int count = 0; |
+ uint32_t length = object->elements()->length(); |
+ for (uint32_t index = 0; index < length; ++index) { |
+ if (!HasEntryImpl(object->elements(), index)) continue; |
+ Handle<Object> value = |
+ FastElementsAccessorSubclass::GetImpl(object->elements(), index); |
+ if (get_entries) { |
+ value = MakeEntryPair(isolate, index, value); |
+ } |
+ values_or_entries->set(count++, *value); |
+ } |
+ *nof_items = count; |
+ return Just(true); |
+ } |
+ |
private: |
// SpliceShrinkStep might modify the backing_store. |
static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, |
@@ -2104,6 +2174,26 @@ class TypedElementsAccessor |
accumulator->AddKey(value, convert); |
} |
} |
+ |
+ static Maybe<bool> CollectValuesOrEntriesImpl( |
+ Isolate* isolate, Handle<JSObject> object, |
+ Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
+ PropertyFilter filter) { |
+ int count = 0; |
+ if ((filter & ONLY_CONFIGURABLE) == 0) { |
+ Handle<FixedArrayBase> elements(object->elements()); |
+ uint32_t length = AccessorClass::GetCapacityImpl(*object, *elements); |
+ for (uint32_t index = 0; index < length; ++index) { |
+ Handle<Object> value = AccessorClass::GetImpl(*elements, index); |
+ if (get_entries) { |
+ value = MakeEntryPair(isolate, index, value); |
+ } |
+ values_or_entries->set(count++, *value); |
+ } |
+ } |
+ *nof_items = count; |
+ return Just(true); |
+ } |
}; |