Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Unified Diff: src/objects.cc

Issue 1375003002: Teach JSReceiver::GetKeys() how to include symbols (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebased Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 4f9773cf7ce427947af6c23877ba4d72078dde6d..f192d9b6a56a20ed42131f18c5cfbabce2755350 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -6759,11 +6759,10 @@ void KeyAccumulator::AddKey(Handle<Object> key, int check_limit) {
}
-void KeyAccumulator::AddKeys(Handle<FixedArray> array,
- FixedArray::KeyFilter filter) {
+void KeyAccumulator::AddKeys(Handle<FixedArray> array, KeyFilter filter) {
int add_length = array->length();
if (add_length == 0) return;
- if (keys_.is_null() && filter == FixedArray::ALL_KEYS) {
+ if (keys_.is_null() && filter == INCLUDE_SYMBOLS) {
keys_ = array;
length_ = keys_->length();
return;
@@ -6772,14 +6771,13 @@ void KeyAccumulator::AddKeys(Handle<FixedArray> array,
int previous_key_count = length_;
for (int i = 0; i < add_length; i++) {
Handle<Object> current(array->get(i), isolate_);
- if (filter == FixedArray::NON_SYMBOL_KEYS && current->IsSymbol()) continue;
+ if (filter == SKIP_SYMBOLS && current->IsSymbol()) continue;
AddKey(current, previous_key_count);
}
}
-void KeyAccumulator::AddKeys(Handle<JSObject> array_like,
- FixedArray::KeyFilter filter) {
+void KeyAccumulator::AddKeys(Handle<JSObject> array_like, KeyFilter filter) {
DCHECK(array_like->IsJSArray() || array_like->HasSloppyArgumentsElements());
ElementsAccessor* accessor = array_like->GetElementsAccessor();
accessor->AddElementsToKeyAccumulator(array_like, this, filter);
@@ -6831,7 +6829,8 @@ void KeyAccumulator::Grow() {
MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
- KeyCollectionType type) {
+ KeyCollectionType type,
+ KeyFilter filter) {
USE(ContainsOnlyValidKeys);
Isolate* isolate = object->GetIsolate();
KeyAccumulator accumulator(isolate);
@@ -6857,7 +6856,7 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
arraysize(args),
args),
FixedArray);
- accumulator.AddKeys(Handle<JSObject>::cast(names), FixedArray::ALL_KEYS);
+ accumulator.AddKeys(Handle<JSObject>::cast(names), filter);
break;
}
@@ -6876,7 +6875,7 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
Handle<FixedArray> element_keys =
isolate->factory()->NewFixedArray(current->NumberOfEnumElements());
current->GetEnumElementKeys(*element_keys);
- accumulator.AddKeys(element_keys, FixedArray::ALL_KEYS);
+ accumulator.AddKeys(element_keys, filter);
DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
// Add the element keys from the interceptor.
@@ -6884,38 +6883,49 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
Handle<JSObject> result;
if (JSObject::GetKeysForIndexedInterceptor(
current, object).ToHandle(&result)) {
- accumulator.AddKeys(result, FixedArray::ALL_KEYS);
+ accumulator.AddKeys(result, filter);
}
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_length =
- ((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_length);
- accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS);
+ if (filter == 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_length =
+ ((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_length);
+ accumulator.AddKeys(enum_keys, filter);
+ } else {
+ DCHECK(filter == INCLUDE_SYMBOLS);
+ PropertyAttributes attr_filter =
+ static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL);
+ Handle<FixedArray> property_keys = isolate->factory()->NewFixedArray(
+ current->NumberOfOwnProperties(attr_filter));
+ current->GetOwnPropertyNames(*property_keys, 0, attr_filter);
+ accumulator.AddKeys(property_keys, filter);
+ }
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);
+ accumulator.AddKeys(result, filter);
}
DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
}
@@ -13833,13 +13843,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()) :
@@ -13847,6 +13852,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));
}
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698