| 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));
|
| }
|
|
|
|
|