| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |