Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index b6c40d67fe8a64c13d4f7b44779e47281956a306..80d00f69e398cdc5b5fe8c16f4bc4bd4c3de8d78 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -6831,8 +6831,9 @@ void KeyAccumulator::Grow() { |
} |
-MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
- KeyCollectionType type) { |
+MaybeHandle<FixedArray> JSReceiver::GetKeys( |
+ Handle<JSReceiver> object, KeyCollectionType type, |
+ IncludeSymbolNamedProperties include_symbols) { |
USE(ContainsOnlyValidKeys); |
Isolate* isolate = object->GetIsolate(); |
KeyAccumulator accumulator(isolate); |
@@ -6890,33 +6891,46 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); |
} |
- // We can cache the computed property keys if access checks are |
- // not needed and no interceptors are involved. |
- // |
- // We do not use the cache if the object has elements and |
- // therefore it does not make sense to cache the property names |
- // for arguments objects. Arguments objects will always have |
- // elements. |
- // Wrapped strings have elements, but don't have an elements |
- // array or dictionary. So the fast inline test for whether to |
- // use the cache says yes, so we should not create a cache. |
- bool cache_enum_keys = |
- ((current->map()->GetConstructor() != *arguments_function) && |
- !current->IsJSValue() && !current->IsAccessCheckNeeded() && |
- !current->HasNamedInterceptor() && !current->HasIndexedInterceptor()); |
- // Compute the property keys and cache them if possible. |
- |
- Handle<FixedArray> enum_keys = |
- JSObject::GetEnumPropertyKeys(current, cache_enum_keys); |
- accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS); |
+ if (include_symbols == SKIP_SYMBOLS) { |
+ // We can cache the computed property keys if access checks are |
+ // not needed and no interceptors are involved. |
+ // |
+ // We do not use the cache if the object has elements and |
+ // therefore it does not make sense to cache the property names |
+ // for arguments objects. Arguments objects will always have |
+ // elements. |
+ // Wrapped strings have elements, but don't have an elements |
+ // array or dictionary. So the fast inline test for whether to |
+ // use the cache says yes, so we should not create a cache. |
+ bool cache_enum_keys = |
+ ((current->map()->GetConstructor() != *arguments_function) && |
+ !current->IsJSValue() && !current->IsAccessCheckNeeded() && |
+ !current->HasNamedInterceptor() && |
+ !current->HasIndexedInterceptor()); |
+ // Compute the property keys and cache them if possible. |
+ Handle<FixedArray> enum_keys = |
+ JSObject::GetEnumPropertyKeys(current, cache_enum_keys); |
+ accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS); |
+ } else { |
+ DCHECK(include_symbols == INCLUDE_SYMBOLS); |
+ PropertyAttributes filter = |
+ static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL); |
+ Handle<FixedArray> property_keys = isolate->factory()->NewFixedArray( |
+ current->NumberOfOwnProperties(filter)); |
+ current->GetOwnPropertyNames(*property_keys, 0, filter); |
Camillo Bruni
2015/09/29 16:27:20
Not sure how much work this would be, but essentia
Jakob Kummerow
2015/09/30 13:59:30
I'm leaving that to you :-)
|
+ accumulator.AddKeys(property_keys, FixedArray::ALL_KEYS); |
+ } |
DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); |
- // Add the non-symbol property keys from the interceptor. |
+ // Add the property keys from the interceptor. |
if (current->HasNamedInterceptor()) { |
Handle<JSObject> result; |
if (JSObject::GetKeysForNamedInterceptor( |
current, object).ToHandle(&result)) { |
- accumulator.AddKeys(result, FixedArray::NON_SYMBOL_KEYS); |
+ FixedArray::KeyFilter filter = include_symbols == SKIP_SYMBOLS |
+ ? FixedArray::NON_SYMBOL_KEYS |
+ : FixedArray::ALL_KEYS; |
+ accumulator.AddKeys(result, filter); |
} |
DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); |
} |
@@ -13832,13 +13846,8 @@ int JSObject::GetOwnPropertyNames(FixedArray* storage, int index, |
int JSObject::NumberOfOwnElements(PropertyAttributes filter) { |
- return GetOwnElementKeys(NULL, filter); |
-} |
- |
- |
-int JSObject::NumberOfEnumElements() { |
// Fast case for objects with no elements. |
- if (!IsJSValue() && HasFastObjectElements()) { |
+ if (!IsJSValue() && HasFastElements()) { |
uint32_t length = IsJSArray() ? |
static_cast<uint32_t>( |
Smi::cast(JSArray::cast(this)->length())->value()) : |
@@ -13846,6 +13855,11 @@ int JSObject::NumberOfEnumElements() { |
if (length == 0) return 0; |
} |
// Compute the number of enumerable elements. |
+ return GetOwnElementKeys(NULL, filter); |
+} |
+ |
+ |
+int JSObject::NumberOfEnumElements() { |
return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM)); |
} |