Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 02d8d3481f636d0b90702251b59684cde3eb8861..ac215cead6635b3c075de3ad10f96088ccac195a 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -6787,8 +6787,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); |
@@ -6846,33 +6847,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); |
+ 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())); |
} |
@@ -6915,7 +6929,7 @@ bool Map::DictionaryElementsInPrototypeChainOnly() { |
MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, |
- Handle<Name> name, |
+ Handle<Object> name, |
Handle<Object> getter, |
Handle<Object> setter, |
PropertyAttributes attributes) { |
@@ -6967,7 +6981,8 @@ MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, |
AssertNoContextChange ncc(isolate); |
const char* type = preexists ? "reconfigure" : "add"; |
RETURN_ON_EXCEPTION( |
- isolate, EnqueueChangeRecord(object, type, name, old_value), Object); |
+ isolate, EnqueueChangeRecord(object, type, it.GetName(), old_value), |
+ Object); |
} |
return isolate->factory()->undefined_value(); |
@@ -13775,13 +13790,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()) : |
@@ -13789,6 +13799,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)); |
} |