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

Side by Side Diff: src/objects.cc

Issue 1492653004: [cleanup] Introduce PropertyFilter (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: windows ♥ Created 5 years 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 unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 6100 matching lines...) Expand 10 before | Expand all | Expand 10 after
6111 Handle<JSReceiver> props; 6111 Handle<JSReceiver> props;
6112 if (!Object::ToObject(isolate, properties).ToHandle(&props)) { 6112 if (!Object::ToObject(isolate, properties).ToHandle(&props)) {
6113 THROW_NEW_ERROR_RETURN_FAILURE( 6113 THROW_NEW_ERROR_RETURN_FAILURE(
6114 isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject)); 6114 isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
6115 } 6115 }
6116 // 4. Let keys be props.[[OwnPropertyKeys]](). 6116 // 4. Let keys be props.[[OwnPropertyKeys]]().
6117 // 5. ReturnIfAbrupt(keys). 6117 // 5. ReturnIfAbrupt(keys).
6118 Handle<FixedArray> keys; 6118 Handle<FixedArray> keys;
6119 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 6119 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6120 isolate, keys, 6120 isolate, keys,
6121 JSReceiver::GetKeys(props, JSReceiver::OWN_ONLY, INCLUDE_SYMBOLS)); 6121 JSReceiver::GetKeys(props, JSReceiver::OWN_ONLY, ALL_PROPERTIES));
6122 // 6. Let descriptors be an empty List. 6122 // 6. Let descriptors be an empty List.
6123 int capacity = keys->length(); 6123 int capacity = keys->length();
6124 std::vector<PropertyDescriptor> descriptors(capacity); 6124 std::vector<PropertyDescriptor> descriptors(capacity);
6125 size_t descriptors_index = 0;
6125 // 7. Repeat for each element nextKey of keys in List order, 6126 // 7. Repeat for each element nextKey of keys in List order,
6126 for (int i = 0; i < keys->length(); ++i) { 6127 for (int i = 0; i < keys->length(); ++i) {
6127 Handle<Object> next_key(keys->get(i), isolate); 6128 Handle<Object> next_key(keys->get(i), isolate);
6128 // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey). 6129 // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey).
6129 // 7b. ReturnIfAbrupt(propDesc). 6130 // 7b. ReturnIfAbrupt(propDesc).
6130 bool success = false; 6131 bool success = false;
6131 LookupIterator it = LookupIterator::PropertyOrElement( 6132 LookupIterator it = LookupIterator::PropertyOrElement(
6132 isolate, props, next_key, &success, LookupIterator::HIDDEN); 6133 isolate, props, next_key, &success, LookupIterator::HIDDEN);
6133 DCHECK(success); 6134 DCHECK(success);
6134 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); 6135 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
6135 if (!maybe.IsJust()) return isolate->heap()->exception(); 6136 if (!maybe.IsJust()) return isolate->heap()->exception();
6136 PropertyAttributes attrs = maybe.FromJust(); 6137 PropertyAttributes attrs = maybe.FromJust();
6137 // 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true: 6138 // 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true:
6138 if (attrs == ABSENT) continue; 6139 if (attrs == ABSENT) continue;
6139 // GetKeys() only returns enumerable keys. 6140 if (attrs & DONT_ENUM) continue;
6140 DCHECK((attrs & DONT_ENUM) == 0);
6141 // 7c i. Let descObj be Get(props, nextKey). 6141 // 7c i. Let descObj be Get(props, nextKey).
6142 // 7c ii. ReturnIfAbrupt(descObj). 6142 // 7c ii. ReturnIfAbrupt(descObj).
6143 Handle<Object> desc_obj; 6143 Handle<Object> desc_obj;
6144 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, desc_obj, 6144 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, desc_obj,
6145 Object::GetProperty(&it)); 6145 Object::GetProperty(&it));
6146 // 7c iii. Let desc be ToPropertyDescriptor(descObj). 6146 // 7c iii. Let desc be ToPropertyDescriptor(descObj).
6147 success = PropertyDescriptor::ToPropertyDescriptor(isolate, desc_obj, 6147 success = PropertyDescriptor::ToPropertyDescriptor(
6148 &descriptors[i]); 6148 isolate, desc_obj, &descriptors[descriptors_index]);
6149 // 7c iv. ReturnIfAbrupt(desc). 6149 // 7c iv. ReturnIfAbrupt(desc).
6150 if (!success) return isolate->heap()->exception(); 6150 if (!success) return isolate->heap()->exception();
6151 // 7c v. Append the pair (a two element List) consisting of nextKey and 6151 // 7c v. Append the pair (a two element List) consisting of nextKey and
6152 // desc to the end of descriptors. 6152 // desc to the end of descriptors.
6153 descriptors[i].set_name(next_key); 6153 descriptors[descriptors_index].set_name(next_key);
6154 descriptors_index++;
6154 } 6155 }
6155 // 8. For each pair from descriptors in list order, 6156 // 8. For each pair from descriptors in list order,
6156 for (size_t i = 0; i < descriptors.size(); ++i) { 6157 for (size_t i = 0; i < descriptors_index; ++i) {
6157 PropertyDescriptor* desc = &descriptors[i]; 6158 PropertyDescriptor* desc = &descriptors[i];
6158 // 8a. Let P be the first element of pair. 6159 // 8a. Let P be the first element of pair.
6159 // 8b. Let desc be the second element of pair. 6160 // 8b. Let desc be the second element of pair.
6160 // 8c. Let status be DefinePropertyOrThrow(O, P, desc). 6161 // 8c. Let status be DefinePropertyOrThrow(O, P, desc).
6161 bool status = DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object), 6162 bool status = DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object),
6162 desc->name(), desc, THROW_ON_ERROR); 6163 desc->name(), desc, THROW_ON_ERROR);
6163 // 8d. ReturnIfAbrupt(status). 6164 // 8d. ReturnIfAbrupt(status).
6164 if (isolate->has_pending_exception()) return isolate->heap()->exception(); 6165 if (isolate->has_pending_exception()) return isolate->heap()->exception();
6165 CHECK(status == true); 6166 CHECK(status == true);
6166 } 6167 }
(...skipping 1543 matching lines...) Expand 10 before | Expand all | Expand 10 after
7710 copy->FastPropertyAtPut(index, *value); 7711 copy->FastPropertyAtPut(index, *value);
7711 } 7712 }
7712 } 7713 }
7713 } 7714 }
7714 } 7715 }
7715 } else { 7716 } else {
7716 Handle<FixedArray> names = 7717 Handle<FixedArray> names =
7717 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties()); 7718 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties());
7718 copy->GetOwnPropertyNames(*names, 0); 7719 copy->GetOwnPropertyNames(*names, 0);
7719 for (int i = 0; i < names->length(); i++) { 7720 for (int i = 0; i < names->length(); i++) {
7720 DCHECK(names->get(i)->IsString()); 7721 DCHECK(names->get(i)->IsName());
7721 Handle<String> key_string(String::cast(names->get(i))); 7722 Handle<Name> name(Name::cast(names->get(i)));
7722 Maybe<PropertyAttributes> maybe = 7723 Maybe<PropertyAttributes> maybe =
7723 JSReceiver::GetOwnPropertyAttributes(copy, key_string); 7724 JSReceiver::GetOwnPropertyAttributes(copy, name);
7724 DCHECK(maybe.IsJust()); 7725 DCHECK(maybe.IsJust());
7725 PropertyAttributes attributes = maybe.FromJust(); 7726 PropertyAttributes attributes = maybe.FromJust();
7726 // Only deep copy fields from the object literal expression. 7727 // Only deep copy fields from the object literal expression.
7727 // In particular, don't try to copy the length attribute of 7728 // In particular, don't try to copy the length attribute of
7728 // an array. 7729 // an array.
7729 if (attributes != NONE) continue; 7730 if (attributes != NONE) continue;
7730 Handle<Object> value = 7731 Handle<Object> value =
7731 Object::GetProperty(copy, key_string).ToHandleChecked(); 7732 Object::GetProperty(copy, name).ToHandleChecked();
7732 if (value->IsJSObject()) { 7733 if (value->IsJSObject()) {
7733 Handle<JSObject> result; 7734 Handle<JSObject> result;
7734 ASSIGN_RETURN_ON_EXCEPTION( 7735 ASSIGN_RETURN_ON_EXCEPTION(
7735 isolate, result, 7736 isolate, result,
7736 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), 7737 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
7737 JSObject); 7738 JSObject);
7738 if (copying) { 7739 if (copying) {
7739 // Creating object copy for literals. No strict mode needed. 7740 // Creating object copy for literals. No strict mode needed.
7740 JSObject::SetProperty(copy, key_string, result, SLOPPY).Assert(); 7741 JSObject::SetProperty(copy, name, result, SLOPPY).Assert();
7741 } 7742 }
7742 } 7743 }
7743 } 7744 }
7744 } 7745 }
7745 7746
7746 // Deep copy own elements. 7747 // Deep copy own elements.
7747 // Pixel elements cannot be created using an object literal. 7748 // Pixel elements cannot be created using an object literal.
7748 DCHECK(!copy->HasFixedTypedArrayElements()); 7749 DCHECK(!copy->HasFixedTypedArrayElements());
7749 switch (kind) { 7750 switch (kind) {
7750 case FAST_SMI_ELEMENTS: 7751 case FAST_SMI_ELEMENTS:
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
7934 DCHECK(!current->HasNamedInterceptor()); 7935 DCHECK(!current->HasNamedInterceptor());
7935 DCHECK(!current->HasIndexedInterceptor()); 7936 DCHECK(!current->HasIndexedInterceptor());
7936 if (current->NumberOfEnumElements() > 0) return false; 7937 if (current->NumberOfEnumElements() > 0) return false;
7937 if (current != this && enum_length != 0) return false; 7938 if (current != this && enum_length != 0) return false;
7938 } 7939 }
7939 return true; 7940 return true;
7940 } 7941 }
7941 7942
7942 7943
7943 int Map::NumberOfDescribedProperties(DescriptorFlag which, 7944 int Map::NumberOfDescribedProperties(DescriptorFlag which,
7944 PropertyAttributes filter) { 7945 PropertyFilter filter) {
7945 int result = 0; 7946 int result = 0;
7946 DescriptorArray* descs = instance_descriptors(); 7947 DescriptorArray* descs = instance_descriptors();
7947 int limit = which == ALL_DESCRIPTORS 7948 int limit = which == ALL_DESCRIPTORS
7948 ? descs->number_of_descriptors() 7949 ? descs->number_of_descriptors()
7949 : NumberOfOwnDescriptors(); 7950 : NumberOfOwnDescriptors();
7950 for (int i = 0; i < limit; i++) { 7951 for (int i = 0; i < limit; i++) {
7951 if ((descs->GetDetails(i).attributes() & filter) == 0 && 7952 if ((descs->GetDetails(i).attributes() & filter) == 0 &&
7952 !descs->GetKey(i)->FilterKey(filter)) { 7953 !descs->GetKey(i)->FilterKey(filter)) {
7953 result++; 7954 result++;
7954 } 7955 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
7999 Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate, 8000 Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate,
8000 Handle<JSObject> object, 8001 Handle<JSObject> object,
8001 bool cache_enum_length) { 8002 bool cache_enum_length) {
8002 Handle<Map> map(object->map()); 8003 Handle<Map> map(object->map());
8003 Handle<DescriptorArray> descs = 8004 Handle<DescriptorArray> descs =
8004 Handle<DescriptorArray>(map->instance_descriptors(), isolate); 8005 Handle<DescriptorArray>(map->instance_descriptors(), isolate);
8005 int own_property_count = map->EnumLength(); 8006 int own_property_count = map->EnumLength();
8006 // If the enum length of the given map is set to kInvalidEnumCache, this 8007 // If the enum length of the given map is set to kInvalidEnumCache, this
8007 // means that the map itself has never used the present enum cache. The 8008 // means that the map itself has never used the present enum cache. The
8008 // first step to using the cache is to set the enum length of the map by 8009 // first step to using the cache is to set the enum length of the map by
8009 // counting the number of own descriptors that are not DONT_ENUM or 8010 // counting the number of own descriptors that are ENUMERABLE_STRINGS.
8010 // SYMBOLIC.
8011 if (own_property_count == kInvalidEnumCacheSentinel) { 8011 if (own_property_count == kInvalidEnumCacheSentinel) {
8012 own_property_count = 8012 own_property_count =
8013 map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_SHOW); 8013 map->NumberOfDescribedProperties(OWN_DESCRIPTORS, ENUMERABLE_STRINGS);
8014 } else { 8014 } else {
8015 DCHECK(own_property_count == 8015 DCHECK(
8016 map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_SHOW)); 8016 own_property_count ==
8017 map->NumberOfDescribedProperties(OWN_DESCRIPTORS, ENUMERABLE_STRINGS));
8017 } 8018 }
8018 8019
8019 if (descs->HasEnumCache()) { 8020 if (descs->HasEnumCache()) {
8020 Handle<FixedArray> keys(descs->GetEnumCache(), isolate); 8021 Handle<FixedArray> keys(descs->GetEnumCache(), isolate);
8021 // In case the number of properties required in the enum are actually 8022 // In case the number of properties required in the enum are actually
8022 // present, we can reuse the enum cache. Otherwise, this means that the 8023 // present, we can reuse the enum cache. Otherwise, this means that the
8023 // enum cache was generated for a previous (smaller) version of the 8024 // enum cache was generated for a previous (smaller) version of the
8024 // Descriptor Array. In that case we regenerate the enum cache. 8025 // Descriptor Array. In that case we regenerate the enum cache.
8025 if (own_property_count <= keys->length()) { 8026 if (own_property_count <= keys->length()) {
8026 isolate->counters()->enum_cache_hits()->Increment(); 8027 isolate->counters()->enum_cache_hits()->Increment();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
8094 return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); 8095 return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
8095 } 8096 }
8096 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); 8097 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
8097 dictionary->CopyEnumKeysTo(*storage); 8098 dictionary->CopyEnumKeysTo(*storage);
8098 return storage; 8099 return storage;
8099 } 8100 }
8100 } 8101 }
8101 8102
8102 8103
8103 static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver, 8104 static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver,
8104 Handle<JSObject> object, KeyFilter filter, 8105 Handle<JSObject> object, PropertyFilter filter,
8105 Enumerability enum_policy,
8106 KeyAccumulator* accumulator) { 8106 KeyAccumulator* accumulator) {
8107 accumulator->NextPrototype(); 8107 accumulator->NextPrototype();
8108 // Check access rights if required. 8108 // Check access rights if required.
8109 if (object->IsAccessCheckNeeded() && 8109 if (object->IsAccessCheckNeeded() &&
8110 !isolate->MayAccess(handle(isolate->context()), object)) { 8110 !isolate->MayAccess(handle(isolate->context()), object)) {
8111 // TODO(jkummerow): Get whitelisted (all-can-read) keys. 8111 // TODO(jkummerow): Get whitelisted (all-can-read) keys.
8112 // It's probably best to implement a "GetKeysWithFailedAccessCheck" 8112 // It's probably best to implement a "GetKeysWithFailedAccessCheck"
8113 // helper, which will need to look at both interceptors and accessors. 8113 // helper, which will need to look at both interceptors and accessors.
8114 return false; 8114 return false;
8115 } 8115 }
8116 8116
8117 PropertyAttributes attr_filter = static_cast<PropertyAttributes>( 8117 JSObject::CollectOwnElementKeys(object, accumulator, filter);
8118 (enum_policy == RESPECT_ENUMERABILITY ? DONT_ENUM : NONE) |
8119 PRIVATE_SYMBOL);
8120
8121 JSObject::CollectOwnElementKeys(object, accumulator, attr_filter);
8122 8118
8123 // Add the element keys from the interceptor. 8119 // Add the element keys from the interceptor.
8124 if (object->HasIndexedInterceptor()) { 8120 if (object->HasIndexedInterceptor()) {
8125 Handle<JSObject> result; 8121 Handle<JSObject> result;
8126 if (JSObject::GetKeysForIndexedInterceptor(object, receiver) 8122 if (JSObject::GetKeysForIndexedInterceptor(object, receiver)
8127 .ToHandle(&result)) { 8123 .ToHandle(&result)) {
8128 accumulator->AddElementKeysFromInterceptor(result); 8124 accumulator->AddElementKeysFromInterceptor(result);
8129 } 8125 }
8130 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false); 8126 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false);
8131 } 8127 }
8132 8128
8133 if (filter == SKIP_SYMBOLS) { 8129 if (filter == ENUMERABLE_STRINGS) {
8134 if (enum_policy == IGNORE_ENUMERABILITY) UNIMPLEMENTED();
8135
8136 // We can cache the computed property keys if access checks are 8130 // We can cache the computed property keys if access checks are
8137 // not needed and no interceptors are involved. 8131 // not needed and no interceptors are involved.
8138 // 8132 //
8139 // We do not use the cache if the object has elements and 8133 // We do not use the cache if the object has elements and
8140 // therefore it does not make sense to cache the property names 8134 // therefore it does not make sense to cache the property names
8141 // for arguments objects. Arguments objects will always have 8135 // for arguments objects. Arguments objects will always have
8142 // elements. 8136 // elements.
8143 // Wrapped strings have elements, but don't have an elements 8137 // Wrapped strings have elements, but don't have an elements
8144 // array or dictionary. So the fast inline test for whether to 8138 // array or dictionary. So the fast inline test for whether to
8145 // use the cache says yes, so we should not create a cache. 8139 // use the cache says yes, so we should not create a cache.
8146 Handle<JSFunction> arguments_function( 8140 Handle<JSFunction> arguments_function(
8147 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); 8141 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor()));
8148 bool cache_enum_length = 8142 bool cache_enum_length =
8149 ((object->map()->GetConstructor() != *arguments_function) && 8143 ((object->map()->GetConstructor() != *arguments_function) &&
8150 !object->IsJSValue() && !object->IsAccessCheckNeeded() && 8144 !object->IsJSValue() && !object->IsAccessCheckNeeded() &&
8151 !object->HasNamedInterceptor() && !object->HasIndexedInterceptor()); 8145 !object->HasNamedInterceptor() && !object->HasIndexedInterceptor());
8152 // Compute the property keys and cache them if possible. 8146 // Compute the property keys and cache them if possible.
8153 Handle<FixedArray> enum_keys = 8147 Handle<FixedArray> enum_keys =
8154 JSObject::GetEnumPropertyKeys(object, cache_enum_length); 8148 JSObject::GetEnumPropertyKeys(object, cache_enum_length);
8155 accumulator->AddKeys(enum_keys); 8149 accumulator->AddKeys(enum_keys);
8156 } else { 8150 } else {
8157 DCHECK(filter == INCLUDE_SYMBOLS); 8151 object->CollectOwnPropertyNames(accumulator, filter);
8158 object->CollectOwnPropertyNames(accumulator, attr_filter);
8159 } 8152 }
8160 8153
8161 // Add the property keys from the interceptor. 8154 // Add the property keys from the interceptor.
8162 if (object->HasNamedInterceptor()) { 8155 if (object->HasNamedInterceptor()) {
8163 Handle<JSObject> result; 8156 Handle<JSObject> result;
8164 if (JSObject::GetKeysForNamedInterceptor(object, receiver) 8157 if (JSObject::GetKeysForNamedInterceptor(object, receiver)
8165 .ToHandle(&result)) { 8158 .ToHandle(&result)) {
8166 accumulator->AddKeys(result); 8159 accumulator->AddKeys(result);
8167 } 8160 }
8168 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false); 8161 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false);
8169 } 8162 }
8170 return true; 8163 return true;
8171 } 8164 }
8172 8165
8173 8166
8174 // Helper function for JSReceiver::GetKeys() below. Can be called recursively. 8167 // Helper function for JSReceiver::GetKeys() below. Can be called recursively.
8175 // Returns false iff an exception was thrown. 8168 // Returns false iff an exception was thrown.
8176 static bool GetKeys_Internal(Isolate* isolate, Handle<JSReceiver> receiver, 8169 static bool GetKeys_Internal(Isolate* isolate, Handle<JSReceiver> receiver,
8177 Handle<JSReceiver> object, 8170 Handle<JSReceiver> object,
8178 JSReceiver::KeyCollectionType type, 8171 JSReceiver::KeyCollectionType type,
8179 KeyFilter filter, Enumerability enum_policy, 8172 PropertyFilter filter,
8180 KeyAccumulator* accumulator) { 8173 KeyAccumulator* accumulator) {
8181 PrototypeIterator::WhereToEnd end = type == JSReceiver::OWN_ONLY 8174 PrototypeIterator::WhereToEnd end = type == JSReceiver::OWN_ONLY
8182 ? PrototypeIterator::END_AT_NON_HIDDEN 8175 ? PrototypeIterator::END_AT_NON_HIDDEN
8183 : PrototypeIterator::END_AT_NULL; 8176 : PrototypeIterator::END_AT_NULL;
8184 for (PrototypeIterator iter(isolate, object, 8177 for (PrototypeIterator iter(isolate, object,
8185 PrototypeIterator::START_AT_RECEIVER); 8178 PrototypeIterator::START_AT_RECEIVER);
8186 !iter.IsAtEnd(end); iter.Advance()) { 8179 !iter.IsAtEnd(end); iter.Advance()) {
8187 Handle<JSReceiver> current = 8180 Handle<JSReceiver> current =
8188 PrototypeIterator::GetCurrent<JSReceiver>(iter); 8181 PrototypeIterator::GetCurrent<JSReceiver>(iter);
8189 bool result = false; 8182 bool result = false;
8190 if (current->IsJSProxy()) { 8183 if (current->IsJSProxy()) {
8191 if (type == JSReceiver::OWN_ONLY) { 8184 if (type == JSReceiver::OWN_ONLY) {
8192 result = JSProxy::OwnPropertyKeys(isolate, receiver, 8185 result = JSProxy::OwnPropertyKeys(isolate, receiver,
8193 Handle<JSProxy>::cast(current), 8186 Handle<JSProxy>::cast(current),
8194 filter, enum_policy, accumulator); 8187 filter, accumulator);
8195 } else { 8188 } else {
8196 DCHECK(type == JSReceiver::INCLUDE_PROTOS); 8189 DCHECK(type == JSReceiver::INCLUDE_PROTOS);
8197 result = JSProxy::Enumerate( 8190 result = JSProxy::Enumerate(
8198 isolate, receiver, Handle<JSProxy>::cast(current), accumulator); 8191 isolate, receiver, Handle<JSProxy>::cast(current), accumulator);
8199 } 8192 }
8200 } else { 8193 } else {
8201 DCHECK(current->IsJSObject()); 8194 DCHECK(current->IsJSObject());
8202 result = GetKeysFromJSObject(isolate, receiver, 8195 result = GetKeysFromJSObject(isolate, receiver,
8203 Handle<JSObject>::cast(current), filter, 8196 Handle<JSObject>::cast(current), filter,
8204 enum_policy, accumulator); 8197 accumulator);
8205 } 8198 }
8206 if (!result) { 8199 if (!result) {
8207 if (isolate->has_pending_exception()) { 8200 if (isolate->has_pending_exception()) {
8208 return false; 8201 return false;
8209 } 8202 }
8210 // If there was no exception, then "false" means "stop iterating". 8203 // If there was no exception, then "false" means "stop iterating".
8211 break; 8204 break;
8212 } 8205 }
8213 } 8206 }
8214 return true; 8207 return true;
(...skipping 21 matching lines...) Expand all
8236 // 5. Let trap be ? GetMethod(handler, "enumerate"). 8229 // 5. Let trap be ? GetMethod(handler, "enumerate").
8237 Handle<Object> trap; 8230 Handle<Object> trap;
8238 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 8231 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
8239 isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler), 8232 isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler),
8240 isolate->factory()->enumerate_string()), 8233 isolate->factory()->enumerate_string()),
8241 false); 8234 false);
8242 // 6. If trap is undefined, then 8235 // 6. If trap is undefined, then
8243 if (trap->IsUndefined()) { 8236 if (trap->IsUndefined()) {
8244 // 6a. Return target.[[Enumerate]](). 8237 // 6a. Return target.[[Enumerate]]().
8245 return GetKeys_Internal(isolate, receiver, target, INCLUDE_PROTOS, 8238 return GetKeys_Internal(isolate, receiver, target, INCLUDE_PROTOS,
8246 SKIP_SYMBOLS, RESPECT_ENUMERABILITY, accumulator); 8239 ENUMERABLE_STRINGS, accumulator);
8247 } 8240 }
8248 // The "proxy_enumerate" helper calls the trap (steps 7 - 9), which returns 8241 // The "proxy_enumerate" helper calls the trap (steps 7 - 9), which returns
8249 // a generator; it then iterates over that generator until it's exhausted 8242 // a generator; it then iterates over that generator until it's exhausted
8250 // and returns an array containing the generated values. 8243 // and returns an array containing the generated values.
8251 Handle<Object> trap_result_array; 8244 Handle<Object> trap_result_array;
8252 Handle<Object> args[] = {trap, handler, target}; 8245 Handle<Object> args[] = {trap, handler, target};
8253 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 8246 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
8254 isolate, trap_result_array, 8247 isolate, trap_result_array,
8255 Execution::Call(isolate, isolate->proxy_enumerate(), 8248 Execution::Call(isolate, isolate->proxy_enumerate(),
8256 isolate->factory()->undefined_value(), arraysize(args), 8249 isolate->factory()->undefined_value(), arraysize(args),
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
8317 } 8310 }
8318 // 8. Return list. 8311 // 8. Return list.
8319 return list; 8312 return list;
8320 } 8313 }
8321 8314
8322 8315
8323 // ES6 9.5.12 8316 // ES6 9.5.12
8324 // Returns "false" in case of exception. 8317 // Returns "false" in case of exception.
8325 // static 8318 // static
8326 bool JSProxy::OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver, 8319 bool JSProxy::OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver,
8327 Handle<JSProxy> proxy, KeyFilter filter, 8320 Handle<JSProxy> proxy, PropertyFilter filter,
8328 Enumerability enum_policy,
8329 KeyAccumulator* accumulator) { 8321 KeyAccumulator* accumulator) {
8330 // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. 8322 // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O.
8331 Handle<Object> handler(proxy->handler(), isolate); 8323 Handle<Object> handler(proxy->handler(), isolate);
8332 // 2. If handler is null, throw a TypeError exception. 8324 // 2. If handler is null, throw a TypeError exception.
8333 if (proxy->IsRevoked()) { 8325 if (proxy->IsRevoked()) {
8334 isolate->Throw(*isolate->factory()->NewTypeError( 8326 isolate->Throw(*isolate->factory()->NewTypeError(
8335 MessageTemplate::kProxyRevoked, isolate->factory()->ownKeys_string())); 8327 MessageTemplate::kProxyRevoked, isolate->factory()->ownKeys_string()));
8336 return false; 8328 return false;
8337 } 8329 }
8338 // 3. Assert: Type(handler) is Object. 8330 // 3. Assert: Type(handler) is Object.
8339 DCHECK(handler->IsJSReceiver()); 8331 DCHECK(handler->IsJSReceiver());
8340 // 4. Let target be the value of the [[ProxyTarget]] internal slot of O. 8332 // 4. Let target be the value of the [[ProxyTarget]] internal slot of O.
8341 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); 8333 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
8342 // 5. Let trap be ? GetMethod(handler, "ownKeys"). 8334 // 5. Let trap be ? GetMethod(handler, "ownKeys").
8343 Handle<Object> trap; 8335 Handle<Object> trap;
8344 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 8336 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
8345 isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler), 8337 isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler),
8346 isolate->factory()->ownKeys_string()), 8338 isolate->factory()->ownKeys_string()),
8347 false); 8339 false);
8348 // 6. If trap is undefined, then 8340 // 6. If trap is undefined, then
8349 if (trap->IsUndefined()) { 8341 if (trap->IsUndefined()) {
8350 // 6a. Return target.[[OwnPropertyKeys]](). 8342 // 6a. Return target.[[OwnPropertyKeys]]().
8351 return GetKeys_Internal(isolate, receiver, target, OWN_ONLY, filter, 8343 return GetKeys_Internal(isolate, receiver, target, OWN_ONLY, filter,
8352 enum_policy, accumulator); 8344 accumulator);
8353 } 8345 }
8354 // 7. Let trapResultArray be Call(trap, handler, «target»). 8346 // 7. Let trapResultArray be Call(trap, handler, «target»).
8355 Handle<Object> trap_result_array; 8347 Handle<Object> trap_result_array;
8356 Handle<Object> args[] = {target}; 8348 Handle<Object> args[] = {target};
8357 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 8349 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
8358 isolate, trap_result_array, 8350 isolate, trap_result_array,
8359 Execution::Call(isolate, trap, handler, arraysize(args), args), false); 8351 Execution::Call(isolate, trap, handler, arraysize(args), args), false);
8360 // 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, 8352 // 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray,
8361 // «String, Symbol»). 8353 // «String, Symbol»).
8362 Handle<FixedArray> trap_result; 8354 Handle<FixedArray> trap_result;
8363 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 8355 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
8364 isolate, trap_result, 8356 isolate, trap_result,
8365 CreateListFromArrayLike_StringSymbol(isolate, trap_result_array), false); 8357 CreateListFromArrayLike_StringSymbol(isolate, trap_result_array), false);
8366 // 9. Let extensibleTarget be ? IsExtensible(target). 8358 // 9. Let extensibleTarget be ? IsExtensible(target).
8367 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target); 8359 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target);
8368 if (maybe_extensible.IsNothing()) return false; 8360 if (maybe_extensible.IsNothing()) return false;
8369 bool extensible_target = maybe_extensible.FromJust(); 8361 bool extensible_target = maybe_extensible.FromJust();
8370 // 10. Let targetKeys be ? target.[[OwnPropertyKeys]](). 8362 // 10. Let targetKeys be ? target.[[OwnPropertyKeys]]().
8371 Handle<FixedArray> target_keys; 8363 Handle<FixedArray> target_keys;
8372 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 8364 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
8373 isolate, target_keys, 8365 isolate, target_keys,
8374 JSReceiver::GetKeys(target, JSReceiver::OWN_ONLY, INCLUDE_SYMBOLS, 8366 JSReceiver::GetKeys(target, JSReceiver::OWN_ONLY, ALL_PROPERTIES,
8375 CONVERT_TO_STRING, IGNORE_ENUMERABILITY), 8367 CONVERT_TO_STRING),
8376 false); 8368 false);
8377 // 11. (Assert) 8369 // 11. (Assert)
8378 // 12. Let targetConfigurableKeys be an empty List. 8370 // 12. Let targetConfigurableKeys be an empty List.
8379 // To save memory, we're re-using target_keys and will modify it in-place. 8371 // To save memory, we're re-using target_keys and will modify it in-place.
8380 Handle<FixedArray> target_configurable_keys = target_keys; 8372 Handle<FixedArray> target_configurable_keys = target_keys;
8381 // 13. Let targetNonconfigurableKeys be an empty List. 8373 // 13. Let targetNonconfigurableKeys be an empty List.
8382 Handle<FixedArray> target_nonconfigurable_keys = 8374 Handle<FixedArray> target_nonconfigurable_keys =
8383 isolate->factory()->NewFixedArray(target_keys->length()); 8375 isolate->factory()->NewFixedArray(target_keys->length());
8384 int nonconfigurable_keys_length = 0; 8376 int nonconfigurable_keys_length = 0;
8385 // 14. Repeat, for each element key of targetKeys: 8377 // 14. Repeat, for each element key of targetKeys:
(...skipping 15 matching lines...) Expand all
8401 // 14c. Else, 8393 // 14c. Else,
8402 // 14c i. Append key as an element of targetConfigurableKeys. 8394 // 14c i. Append key as an element of targetConfigurableKeys.
8403 // (No-op, just keep it in |target_keys|.) 8395 // (No-op, just keep it in |target_keys|.)
8404 } 8396 }
8405 } 8397 }
8406 accumulator->NextPrototype(); // Prepare for accumulating keys. 8398 accumulator->NextPrototype(); // Prepare for accumulating keys.
8407 // 15. If extensibleTarget is true and targetNonconfigurableKeys is empty, 8399 // 15. If extensibleTarget is true and targetNonconfigurableKeys is empty,
8408 // then: 8400 // then:
8409 if (extensible_target && nonconfigurable_keys_length == 0) { 8401 if (extensible_target && nonconfigurable_keys_length == 0) {
8410 // 15a. Return trapResult. 8402 // 15a. Return trapResult.
8411 return accumulator->AddKeysFromProxy(proxy, trap_result, filter, 8403 return accumulator->AddKeysFromProxy(proxy, trap_result);
8412 enum_policy);
8413 } 8404 }
8414 // 16. Let uncheckedResultKeys be a new List which is a copy of trapResult. 8405 // 16. Let uncheckedResultKeys be a new List which is a copy of trapResult.
8415 Zone set_zone; 8406 Zone set_zone;
8416 const int kPresent = 1; 8407 const int kPresent = 1;
8417 const int kGone = 0; 8408 const int kGone = 0;
8418 IdentityMap<int> unchecked_result_keys(isolate->heap(), &set_zone); 8409 IdentityMap<int> unchecked_result_keys(isolate->heap(), &set_zone);
8419 int unchecked_result_keys_size = trap_result->length(); 8410 int unchecked_result_keys_size = trap_result->length();
8420 for (int i = 0; i < trap_result->length(); ++i) { 8411 for (int i = 0; i < trap_result->length(); ++i) {
8421 DCHECK(trap_result->get(i)->IsUniqueName()); 8412 DCHECK(trap_result->get(i)->IsUniqueName());
8422 unchecked_result_keys.Set(trap_result->get(i), kPresent); 8413 unchecked_result_keys.Set(trap_result->get(i), kPresent);
8423 } 8414 }
8424 // 17. Repeat, for each key that is an element of targetNonconfigurableKeys: 8415 // 17. Repeat, for each key that is an element of targetNonconfigurableKeys:
8425 for (int i = 0; i < nonconfigurable_keys_length; ++i) { 8416 for (int i = 0; i < nonconfigurable_keys_length; ++i) {
8426 Object* key = target_nonconfigurable_keys->get(i); 8417 Object* key = target_nonconfigurable_keys->get(i);
8427 // 17a. If key is not an element of uncheckedResultKeys, throw a 8418 // 17a. If key is not an element of uncheckedResultKeys, throw a
8428 // TypeError exception. 8419 // TypeError exception.
8429 int* found = unchecked_result_keys.Find(key); 8420 int* found = unchecked_result_keys.Find(key);
8430 if (found == nullptr || *found == kGone) { 8421 if (found == nullptr || *found == kGone) {
8431 isolate->Throw(*isolate->factory()->NewTypeError( 8422 isolate->Throw(*isolate->factory()->NewTypeError(
8432 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate))); 8423 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate)));
8433 return false; 8424 return false;
8434 } 8425 }
8435 // 17b. Remove key from uncheckedResultKeys. 8426 // 17b. Remove key from uncheckedResultKeys.
8436 *found = kGone; 8427 *found = kGone;
8437 unchecked_result_keys_size--; 8428 unchecked_result_keys_size--;
8438 } 8429 }
8439 // 18. If extensibleTarget is true, return trapResult. 8430 // 18. If extensibleTarget is true, return trapResult.
8440 if (extensible_target) { 8431 if (extensible_target) {
8441 return accumulator->AddKeysFromProxy(proxy, trap_result, filter, 8432 return accumulator->AddKeysFromProxy(proxy, trap_result);
8442 enum_policy);
8443 } 8433 }
8444 // 19. Repeat, for each key that is an element of targetConfigurableKeys: 8434 // 19. Repeat, for each key that is an element of targetConfigurableKeys:
8445 for (int i = 0; i < target_configurable_keys->length(); ++i) { 8435 for (int i = 0; i < target_configurable_keys->length(); ++i) {
8446 Object* key = target_configurable_keys->get(i); 8436 Object* key = target_configurable_keys->get(i);
8447 if (key->IsSmi()) continue; // Zapped entry, was nonconfigurable. 8437 if (key->IsSmi()) continue; // Zapped entry, was nonconfigurable.
8448 // 19a. If key is not an element of uncheckedResultKeys, throw a 8438 // 19a. If key is not an element of uncheckedResultKeys, throw a
8449 // TypeError exception. 8439 // TypeError exception.
8450 int* found = unchecked_result_keys.Find(key); 8440 int* found = unchecked_result_keys.Find(key);
8451 if (found == nullptr || *found == kGone) { 8441 if (found == nullptr || *found == kGone) {
8452 isolate->Throw(*isolate->factory()->NewTypeError( 8442 isolate->Throw(*isolate->factory()->NewTypeError(
8453 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate))); 8443 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate)));
8454 return false; 8444 return false;
8455 } 8445 }
8456 // 19b. Remove key from uncheckedResultKeys. 8446 // 19b. Remove key from uncheckedResultKeys.
8457 *found = kGone; 8447 *found = kGone;
8458 unchecked_result_keys_size--; 8448 unchecked_result_keys_size--;
8459 } 8449 }
8460 // 20. If uncheckedResultKeys is not empty, throw a TypeError exception. 8450 // 20. If uncheckedResultKeys is not empty, throw a TypeError exception.
8461 if (unchecked_result_keys_size != 0) { 8451 if (unchecked_result_keys_size != 0) {
8462 DCHECK_GT(unchecked_result_keys_size, 0); 8452 DCHECK_GT(unchecked_result_keys_size, 0);
8463 isolate->Throw(*isolate->factory()->NewTypeError( 8453 isolate->Throw(*isolate->factory()->NewTypeError(
8464 MessageTemplate::kProxyTargetNotExtensible)); 8454 MessageTemplate::kProxyTargetNotExtensible));
8465 return false; 8455 return false;
8466 } 8456 }
8467 // 21. Return trapResult. 8457 // 21. Return trapResult.
8468 return accumulator->AddKeysFromProxy(proxy, trap_result, filter, enum_policy); 8458 return accumulator->AddKeysFromProxy(proxy, trap_result);
8469 } 8459 }
8470 8460
8471 8461
8472 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, 8462 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
8473 KeyCollectionType type, 8463 KeyCollectionType type,
8474 KeyFilter filter, 8464 PropertyFilter filter,
8475 GetKeysConversion keys_conversion, 8465 GetKeysConversion keys_conversion) {
8476 Enumerability enum_policy) {
8477 USE(ContainsOnlyValidKeys); 8466 USE(ContainsOnlyValidKeys);
8478 Isolate* isolate = object->GetIsolate(); 8467 Isolate* isolate = object->GetIsolate();
8479 KeyAccumulator accumulator(isolate, filter); 8468 KeyAccumulator accumulator(isolate, filter);
8480 if (!GetKeys_Internal(isolate, object, object, type, filter, enum_policy, 8469 if (!GetKeys_Internal(isolate, object, object, type, filter, &accumulator)) {
8481 &accumulator)) {
8482 DCHECK(isolate->has_pending_exception()); 8470 DCHECK(isolate->has_pending_exception());
8483 return MaybeHandle<FixedArray>(); 8471 return MaybeHandle<FixedArray>();
8484 } 8472 }
8485 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); 8473 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion);
8486 DCHECK(ContainsOnlyValidKeys(keys)); 8474 DCHECK(ContainsOnlyValidKeys(keys));
8487 return keys; 8475 return keys;
8488 } 8476 }
8489 8477
8490 8478
8491 bool Map::DictionaryElementsInPrototypeChainOnly() { 8479 bool Map::DictionaryElementsInPrototypeChainOnly() {
(...skipping 5947 matching lines...) Expand 10 before | Expand all | Expand 10 after
14439 return array; 14427 return array;
14440 } 14428 }
14441 14429
14442 Isolate* isolate = array->GetIsolate(); 14430 Isolate* isolate = array->GetIsolate();
14443 List<uint32_t> indices; 14431 List<uint32_t> indices;
14444 List<Handle<Object> > old_values; 14432 List<Handle<Object> > old_values;
14445 Handle<Object> old_length_handle(array->length(), isolate); 14433 Handle<Object> old_length_handle(array->length(), isolate);
14446 uint32_t old_length = 0; 14434 uint32_t old_length = 0;
14447 CHECK(old_length_handle->ToArrayLength(&old_length)); 14435 CHECK(old_length_handle->ToArrayLength(&old_length));
14448 14436
14449 static const PropertyAttributes kNoAttrFilter = NONE; 14437 int num_elements = array->NumberOfOwnElements(ALL_PROPERTIES);
14450 int num_elements = array->NumberOfOwnElements(kNoAttrFilter);
14451 if (num_elements > 0) { 14438 if (num_elements > 0) {
14452 if (old_length == static_cast<uint32_t>(num_elements)) { 14439 if (old_length == static_cast<uint32_t>(num_elements)) {
14453 // Simple case for arrays without holes. 14440 // Simple case for arrays without holes.
14454 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { 14441 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) {
14455 if (!GetOldValue(isolate, array, i, &old_values, &indices)) break; 14442 if (!GetOldValue(isolate, array, i, &old_values, &indices)) break;
14456 } 14443 }
14457 } else { 14444 } else {
14458 // For sparse arrays, only iterate over existing elements. 14445 // For sparse arrays, only iterate over existing elements.
14459 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over 14446 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over
14460 // the to-be-removed indices twice. 14447 // the to-be-removed indices twice.
14461 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); 14448 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements);
14462 array->GetOwnElementKeys(*keys, kNoAttrFilter); 14449 array->GetOwnElementKeys(*keys, ALL_PROPERTIES);
14463 while (num_elements-- > 0) { 14450 while (num_elements-- > 0) {
14464 uint32_t index = NumberToUint32(keys->get(num_elements)); 14451 uint32_t index = NumberToUint32(keys->get(num_elements));
14465 if (index < new_length) break; 14452 if (index < new_length) break;
14466 if (!GetOldValue(isolate, array, index, &old_values, &indices)) break; 14453 if (!GetOldValue(isolate, array, index, &old_values, &indices)) break;
14467 } 14454 }
14468 } 14455 }
14469 } 14456 }
14470 14457
14471 SetLength(array, new_length); 14458 SetLength(array, new_length);
14472 14459
(...skipping 1205 matching lines...) Expand 10 before | Expand all | Expand 10 after
15678 Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object, 15665 Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
15679 Handle<Name> name) { 15666 Handle<Name> name) {
15680 LookupIterator it = LookupIterator::PropertyOrElement( 15667 LookupIterator it = LookupIterator::PropertyOrElement(
15681 name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); 15668 name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
15682 Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it); 15669 Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
15683 return maybe_result.IsJust() ? Just(it.state() == LookupIterator::ACCESSOR) 15670 return maybe_result.IsJust() ? Just(it.state() == LookupIterator::ACCESSOR)
15684 : Nothing<bool>(); 15671 : Nothing<bool>();
15685 } 15672 }
15686 15673
15687 15674
15688 int JSObject::NumberOfOwnProperties(PropertyAttributes filter) { 15675 // Private symbols are always filtered out.
15676 int JSObject::NumberOfOwnProperties(PropertyFilter filter) {
15689 if (HasFastProperties()) { 15677 if (HasFastProperties()) {
15690 Map* map = this->map(); 15678 Map* map = this->map();
15691 if (filter == NONE) return map->NumberOfOwnDescriptors(); 15679 if (filter == ENUMERABLE_STRINGS) {
15692 if (filter == DONT_SHOW) { 15680 // The cached enum length was computed with filter == ENUMERABLE_STRING,
15693 // The cached enum length was computed with filter == DONT_SHOW, so 15681 // so that's the only filter for which it's valid to retrieve it.
15694 // that's the only filter for which it's valid to retrieve it.
15695 int result = map->EnumLength(); 15682 int result = map->EnumLength();
15696 if (result != kInvalidEnumCacheSentinel) return result; 15683 if (result != kInvalidEnumCacheSentinel) return result;
15697 } 15684 }
15698 return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter); 15685 return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter);
15699 } else if (IsJSGlobalObject()) { 15686 } else if (IsJSGlobalObject()) {
15700 return global_dictionary()->NumberOfElementsFilterAttributes(filter); 15687 return global_dictionary()->NumberOfElementsFilterAttributes(filter);
15701 } else { 15688 } else {
15702 return property_dictionary()->NumberOfElementsFilterAttributes(filter); 15689 return property_dictionary()->NumberOfElementsFilterAttributes(filter);
15703 } 15690 }
15704 } 15691 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
15814 HeapSortPairs(this, numbers, len); 15801 HeapSortPairs(this, numbers, len);
15815 return; 15802 return;
15816 } 15803 }
15817 } 15804 }
15818 15805
15819 15806
15820 // Fill in the names of own properties into the supplied storage. The main 15807 // Fill in the names of own properties into the supplied storage. The main
15821 // purpose of this function is to provide reflection information for the object 15808 // purpose of this function is to provide reflection information for the object
15822 // mirrors. 15809 // mirrors.
15823 int JSObject::GetOwnPropertyNames(FixedArray* storage, int index, 15810 int JSObject::GetOwnPropertyNames(FixedArray* storage, int index,
15824 PropertyAttributes filter) { 15811 PropertyFilter filter) {
15825 DCHECK(storage->length() >= (NumberOfOwnProperties(filter) - index)); 15812 DCHECK(storage->length() >= (NumberOfOwnProperties(filter) - index));
15826 if (HasFastProperties()) { 15813 if (HasFastProperties()) {
15827 int start_index = index; 15814 int start_index = index;
15828 int real_size = map()->NumberOfOwnDescriptors(); 15815 int real_size = map()->NumberOfOwnDescriptors();
15829 DescriptorArray* descs = map()->instance_descriptors(); 15816 DescriptorArray* descs = map()->instance_descriptors();
15830 for (int i = 0; i < real_size; i++) { 15817 for (int i = 0; i < real_size; i++) {
15831 if ((descs->GetDetails(i).attributes() & filter) == 0 && 15818 if ((descs->GetDetails(i).attributes() & filter) == 0 &&
15832 !descs->GetKey(i)->FilterKey(filter)) { 15819 !descs->GetKey(i)->FilterKey(filter)) {
15833 storage->set(index++, descs->GetKey(i)); 15820 storage->set(index++, descs->GetKey(i));
15834 } 15821 }
15835 } 15822 }
15836 return index - start_index; 15823 return index - start_index;
15837 } else if (IsJSGlobalObject()) { 15824 } else if (IsJSGlobalObject()) {
15838 return global_dictionary()->CopyKeysTo(storage, index, filter, 15825 return global_dictionary()->CopyKeysTo(storage, index, filter,
15839 GlobalDictionary::UNSORTED); 15826 GlobalDictionary::UNSORTED);
15840 } else { 15827 } else {
15841 return property_dictionary()->CopyKeysTo(storage, index, filter, 15828 return property_dictionary()->CopyKeysTo(storage, index, filter,
15842 NameDictionary::UNSORTED); 15829 NameDictionary::UNSORTED);
15843 } 15830 }
15844 } 15831 }
15845 15832
15846 15833
15847 void JSObject::CollectOwnPropertyNames(KeyAccumulator* keys, 15834 void JSObject::CollectOwnPropertyNames(KeyAccumulator* keys,
15848 PropertyAttributes filter) { 15835 PropertyFilter filter) {
15849 if (HasFastProperties()) { 15836 if (HasFastProperties()) {
15850 int real_size = map()->NumberOfOwnDescriptors(); 15837 int real_size = map()->NumberOfOwnDescriptors();
15851 Handle<DescriptorArray> descs(map()->instance_descriptors()); 15838 Handle<DescriptorArray> descs(map()->instance_descriptors());
15852 for (int i = 0; i < real_size; i++) { 15839 for (int i = 0; i < real_size; i++) {
15853 if ((descs->GetDetails(i).attributes() & filter) != 0) continue; 15840 if ((descs->GetDetails(i).attributes() & filter) != 0) continue;
15854 Name* key = descs->GetKey(i); 15841 Name* key = descs->GetKey(i);
15855 if (key->FilterKey(filter)) continue; 15842 if (key->FilterKey(filter)) continue;
15856 keys->AddKey(key); 15843 keys->AddKey(key);
15857 } 15844 }
15858 } else if (IsJSGlobalObject()) { 15845 } else if (IsJSGlobalObject()) {
15859 GlobalDictionary::CollectKeysTo(handle(global_dictionary()), keys, filter); 15846 GlobalDictionary::CollectKeysTo(handle(global_dictionary()), keys, filter);
15860 } else { 15847 } else {
15861 NameDictionary::CollectKeysTo(handle(property_dictionary()), keys, filter); 15848 NameDictionary::CollectKeysTo(handle(property_dictionary()), keys, filter);
15862 } 15849 }
15863 } 15850 }
15864 15851
15865 15852
15866 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { 15853 int JSObject::NumberOfOwnElements(PropertyFilter filter) {
15867 // Fast case for objects with no elements. 15854 // Fast case for objects with no elements.
15868 if (!IsJSValue() && HasFastElements()) { 15855 if (!IsJSValue() && HasFastElements()) {
15869 uint32_t length = 15856 uint32_t length =
15870 IsJSArray() 15857 IsJSArray()
15871 ? static_cast<uint32_t>( 15858 ? static_cast<uint32_t>(
15872 Smi::cast(JSArray::cast(this)->length())->value()) 15859 Smi::cast(JSArray::cast(this)->length())->value())
15873 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length()); 15860 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length());
15874 if (length == 0) return 0; 15861 if (length == 0) return 0;
15875 } 15862 }
15876 // Compute the number of enumerable elements. 15863 // Compute the number of enumerable elements.
15877 return GetOwnElementKeys(NULL, filter); 15864 return GetOwnElementKeys(NULL, filter);
15878 } 15865 }
15879 15866
15880 15867
15881 int JSObject::NumberOfEnumElements() { 15868 int JSObject::NumberOfEnumElements() {
15882 return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM)); 15869 return NumberOfOwnElements(ONLY_ENUMERABLE);
15883 } 15870 }
15884 15871
15885 15872
15886 void JSObject::CollectOwnElementKeys(Handle<JSObject> object, 15873 void JSObject::CollectOwnElementKeys(Handle<JSObject> object,
15887 KeyAccumulator* keys, 15874 KeyAccumulator* keys,
15888 PropertyAttributes filter) { 15875 PropertyFilter filter) {
15889 uint32_t string_keys = 0; 15876 uint32_t string_keys = 0;
15890 15877
15891 // If this is a String wrapper, add the string indices first, 15878 // If this is a String wrapper, add the string indices first,
15892 // as they're guaranteed to precede the elements in numerical order 15879 // as they're guaranteed to precede the elements in numerical order
15893 // and ascending order is required by ECMA-262, 6th, 9.1.12. 15880 // and ascending order is required by ECMA-262, 6th, 9.1.12.
15894 if (object->IsJSValue()) { 15881 if (object->IsJSValue()) {
15895 Object* val = JSValue::cast(*object)->value(); 15882 Object* val = JSValue::cast(*object)->value();
15896 if (val->IsString()) { 15883 if (val->IsString()) {
15897 String* str = String::cast(val); 15884 String* str = String::cast(val);
15898 string_keys = str->length(); 15885 string_keys = str->length();
15899 for (uint32_t i = 0; i < string_keys; i++) { 15886 for (uint32_t i = 0; i < string_keys; i++) {
15900 keys->AddKey(i); 15887 keys->AddKey(i);
15901 } 15888 }
15902 } 15889 }
15903 } 15890 }
15904 ElementsAccessor* accessor = object->GetElementsAccessor(); 15891 ElementsAccessor* accessor = object->GetElementsAccessor();
15905 accessor->CollectElementIndices(object, keys, kMaxUInt32, filter, 0); 15892 accessor->CollectElementIndices(object, keys, kMaxUInt32, filter, 0);
15906 } 15893 }
15907 15894
15908 15895
15909 int JSObject::GetOwnElementKeys(FixedArray* storage, 15896 int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) {
15910 PropertyAttributes filter) {
15911 int counter = 0; 15897 int counter = 0;
15912 15898
15913 // If this is a String wrapper, add the string indices first, 15899 // If this is a String wrapper, add the string indices first,
15914 // as they're guaranteed to precede the elements in numerical order 15900 // as they're guaranteed to precede the elements in numerical order
15915 // and ascending order is required by ECMA-262, 6th, 9.1.12. 15901 // and ascending order is required by ECMA-262, 6th, 9.1.12.
15916 if (IsJSValue()) { 15902 if (IsJSValue()) {
15917 Object* val = JSValue::cast(this)->value(); 15903 Object* val = JSValue::cast(this)->value();
15918 if (val->IsString()) { 15904 if (val->IsString()) {
15919 String* str = String::cast(val); 15905 String* str = String::cast(val);
15920 if (storage) { 15906 if (storage) {
(...skipping 1810 matching lines...) Expand 10 before | Expand all | Expand 10 after
17731 if (entry == kNotFound) return AddNumberEntry(dictionary, key, value); 17717 if (entry == kNotFound) return AddNumberEntry(dictionary, key, value);
17732 Handle<Object> object_key = 17718 Handle<Object> object_key =
17733 UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key); 17719 UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
17734 dictionary->SetEntry(entry, object_key, value); 17720 dictionary->SetEntry(entry, object_key, value);
17735 return dictionary; 17721 return dictionary;
17736 } 17722 }
17737 17723
17738 17724
17739 template <typename Derived, typename Shape, typename Key> 17725 template <typename Derived, typename Shape, typename Key>
17740 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( 17726 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes(
17741 PropertyAttributes filter) { 17727 PropertyFilter filter) {
17742 int capacity = this->Capacity(); 17728 int capacity = this->Capacity();
17743 int result = 0; 17729 int result = 0;
17744 for (int i = 0; i < capacity; i++) { 17730 for (int i = 0; i < capacity; i++) {
17745 Object* k = this->KeyAt(i); 17731 Object* k = this->KeyAt(i);
17746 if (this->IsKey(k) && !k->FilterKey(filter)) { 17732 if (this->IsKey(k) && !k->FilterKey(filter)) {
17747 if (this->IsDeleted(i)) continue; 17733 if (this->IsDeleted(i)) continue;
17748 PropertyDetails details = this->DetailsAt(i); 17734 PropertyDetails details = this->DetailsAt(i);
17749 PropertyAttributes attr = details.attributes(); 17735 PropertyAttributes attr = details.attributes();
17750 if ((attr & filter) == 0) result++; 17736 if ((attr & filter) == 0) result++;
17751 } 17737 }
17752 } 17738 }
17753 return result; 17739 return result;
17754 } 17740 }
17755 17741
17756 17742
17757 template <typename Derived, typename Shape, typename Key> 17743 template <typename Derived, typename Shape, typename Key>
17758 bool Dictionary<Derived, Shape, Key>::HasComplexElements() { 17744 bool Dictionary<Derived, Shape, Key>::HasComplexElements() {
17759 int capacity = this->Capacity(); 17745 int capacity = this->Capacity();
17760 for (int i = 0; i < capacity; i++) { 17746 for (int i = 0; i < capacity; i++) {
17761 Object* k = this->KeyAt(i); 17747 Object* k = this->KeyAt(i);
17762 if (this->IsKey(k) && !k->FilterKey(NONE)) { 17748 if (this->IsKey(k) && !k->FilterKey(ALL_PROPERTIES)) {
17763 if (this->IsDeleted(i)) continue; 17749 if (this->IsDeleted(i)) continue;
17764 PropertyDetails details = this->DetailsAt(i); 17750 PropertyDetails details = this->DetailsAt(i);
17765 if (details.type() == ACCESSOR_CONSTANT) return true; 17751 if (details.type() == ACCESSOR_CONSTANT) return true;
17766 PropertyAttributes attr = details.attributes(); 17752 PropertyAttributes attr = details.attributes();
17767 if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true; 17753 if (attr & ALL_ATTRIBUTES_MASK) return true;
17768 } 17754 }
17769 } 17755 }
17770 return false; 17756 return false;
17771 } 17757 }
17772 17758
17773 17759
17774 template <typename Dictionary> 17760 template <typename Dictionary>
17775 struct EnumIndexComparator { 17761 struct EnumIndexComparator {
17776 explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {} 17762 explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {}
17777 bool operator() (Smi* a, Smi* b) { 17763 bool operator() (Smi* a, Smi* b) {
(...skipping 26 matching lines...) Expand all
17804 std::sort(start, start + length, cmp); 17790 std::sort(start, start + length, cmp);
17805 for (int i = 0; i < length; i++) { 17791 for (int i = 0; i < length; i++) {
17806 int index = Smi::cast(storage->get(i))->value(); 17792 int index = Smi::cast(storage->get(i))->value();
17807 storage->set(i, this->KeyAt(index)); 17793 storage->set(i, this->KeyAt(index));
17808 } 17794 }
17809 } 17795 }
17810 17796
17811 17797
17812 template <typename Derived, typename Shape, typename Key> 17798 template <typename Derived, typename Shape, typename Key>
17813 int Dictionary<Derived, Shape, Key>::CopyKeysTo( 17799 int Dictionary<Derived, Shape, Key>::CopyKeysTo(
17814 FixedArray* storage, int index, PropertyAttributes filter, 17800 FixedArray* storage, int index, PropertyFilter filter,
17815 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { 17801 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
17816 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter)); 17802 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
17817 int start_index = index; 17803 int start_index = index;
17818 int capacity = this->Capacity(); 17804 int capacity = this->Capacity();
17819 for (int i = 0; i < capacity; i++) { 17805 for (int i = 0; i < capacity; i++) {
17820 Object* k = this->KeyAt(i); 17806 Object* k = this->KeyAt(i);
17821 if (!this->IsKey(k) || k->FilterKey(filter)) continue; 17807 if (!this->IsKey(k) || k->FilterKey(filter)) continue;
17822 if (this->IsDeleted(i)) continue; 17808 if (this->IsDeleted(i)) continue;
17823 PropertyDetails details = this->DetailsAt(i); 17809 PropertyDetails details = this->DetailsAt(i);
17824 PropertyAttributes attr = details.attributes(); 17810 PropertyAttributes attr = details.attributes();
17825 if ((attr & filter) != 0) continue; 17811 if ((attr & filter) != 0) continue;
17826 storage->set(index++, k); 17812 storage->set(index++, k);
17827 } 17813 }
17828 if (sort_mode == Dictionary::SORTED) { 17814 if (sort_mode == Dictionary::SORTED) {
17829 storage->SortPairs(storage, index); 17815 storage->SortPairs(storage, index);
17830 } 17816 }
17831 DCHECK(storage->length() >= index); 17817 DCHECK(storage->length() >= index);
17832 return index - start_index; 17818 return index - start_index;
17833 } 17819 }
17834 17820
17835 17821
17836 template <typename Derived, typename Shape, typename Key> 17822 template <typename Derived, typename Shape, typename Key>
17837 void Dictionary<Derived, Shape, Key>::CollectKeysTo( 17823 void Dictionary<Derived, Shape, Key>::CollectKeysTo(
17838 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys, 17824 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys,
17839 PropertyAttributes filter) { 17825 PropertyFilter filter) {
17840 int capacity = dictionary->Capacity(); 17826 int capacity = dictionary->Capacity();
17841 Handle<FixedArray> array = 17827 Handle<FixedArray> array =
17842 keys->isolate()->factory()->NewFixedArray(dictionary->NumberOfElements()); 17828 keys->isolate()->factory()->NewFixedArray(dictionary->NumberOfElements());
17843 int array_size = 0; 17829 int array_size = 0;
17844 17830
17845 { 17831 {
17846 DisallowHeapAllocation no_gc; 17832 DisallowHeapAllocation no_gc;
17847 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary; 17833 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary;
17848 for (int i = 0; i < capacity; i++) { 17834 for (int i = 0; i < capacity; i++) {
17849 Object* k = raw_dict->KeyAt(i); 17835 Object* k = raw_dict->KeyAt(i);
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after
19069 if (cell->value() != *new_value) { 19055 if (cell->value() != *new_value) {
19070 cell->set_value(*new_value); 19056 cell->set_value(*new_value);
19071 Isolate* isolate = cell->GetIsolate(); 19057 Isolate* isolate = cell->GetIsolate();
19072 cell->dependent_code()->DeoptimizeDependentCodeGroup( 19058 cell->dependent_code()->DeoptimizeDependentCodeGroup(
19073 isolate, DependentCode::kPropertyCellChangedGroup); 19059 isolate, DependentCode::kPropertyCellChangedGroup);
19074 } 19060 }
19075 } 19061 }
19076 19062
19077 } // namespace internal 19063 } // namespace internal
19078 } // namespace v8 19064 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698