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 6813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6824 DisallowHeapAllocation no_gc; | 6824 DisallowHeapAllocation no_gc; |
6825 WriteBarrierMode mode = new_keys->GetWriteBarrierMode(no_gc); | 6825 WriteBarrierMode mode = new_keys->GetWriteBarrierMode(no_gc); |
6826 for (int i = 0; i < buffer_length; i++) { | 6826 for (int i = 0; i < buffer_length; i++) { |
6827 new_keys->set(i, keys_->get(i), mode); | 6827 new_keys->set(i, keys_->get(i), mode); |
6828 } | 6828 } |
6829 } | 6829 } |
6830 keys_ = new_keys; | 6830 keys_ = new_keys; |
6831 } | 6831 } |
6832 | 6832 |
6833 | 6833 |
6834 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, | 6834 MaybeHandle<FixedArray> JSReceiver::GetKeys( |
6835 KeyCollectionType type) { | 6835 Handle<JSReceiver> object, KeyCollectionType type, |
6836 IncludeSymbolNamedProperties include_symbols) { | |
6836 USE(ContainsOnlyValidKeys); | 6837 USE(ContainsOnlyValidKeys); |
6837 Isolate* isolate = object->GetIsolate(); | 6838 Isolate* isolate = object->GetIsolate(); |
6838 KeyAccumulator accumulator(isolate); | 6839 KeyAccumulator accumulator(isolate); |
6839 Handle<JSFunction> arguments_function( | 6840 Handle<JSFunction> arguments_function( |
6840 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); | 6841 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); |
6841 | 6842 |
6842 PrototypeIterator::WhereToEnd end = type == OWN_ONLY | 6843 PrototypeIterator::WhereToEnd end = type == OWN_ONLY |
6843 ? PrototypeIterator::END_AT_NON_HIDDEN | 6844 ? PrototypeIterator::END_AT_NON_HIDDEN |
6844 : PrototypeIterator::END_AT_NULL; | 6845 : PrototypeIterator::END_AT_NULL; |
6845 // Only collect keys if access is permitted. | 6846 // Only collect keys if access is permitted. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6883 // Add the element keys from the interceptor. | 6884 // Add the element keys from the interceptor. |
6884 if (current->HasIndexedInterceptor()) { | 6885 if (current->HasIndexedInterceptor()) { |
6885 Handle<JSObject> result; | 6886 Handle<JSObject> result; |
6886 if (JSObject::GetKeysForIndexedInterceptor( | 6887 if (JSObject::GetKeysForIndexedInterceptor( |
6887 current, object).ToHandle(&result)) { | 6888 current, object).ToHandle(&result)) { |
6888 accumulator.AddKeys(result, FixedArray::ALL_KEYS); | 6889 accumulator.AddKeys(result, FixedArray::ALL_KEYS); |
6889 } | 6890 } |
6890 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); | 6891 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); |
6891 } | 6892 } |
6892 | 6893 |
6893 // We can cache the computed property keys if access checks are | 6894 if (include_symbols == SKIP_SYMBOLS) { |
6894 // not needed and no interceptors are involved. | 6895 // We can cache the computed property keys if access checks are |
6895 // | 6896 // not needed and no interceptors are involved. |
6896 // We do not use the cache if the object has elements and | 6897 // |
6897 // therefore it does not make sense to cache the property names | 6898 // We do not use the cache if the object has elements and |
6898 // for arguments objects. Arguments objects will always have | 6899 // therefore it does not make sense to cache the property names |
6899 // elements. | 6900 // for arguments objects. Arguments objects will always have |
6900 // Wrapped strings have elements, but don't have an elements | 6901 // elements. |
6901 // array or dictionary. So the fast inline test for whether to | 6902 // Wrapped strings have elements, but don't have an elements |
6902 // use the cache says yes, so we should not create a cache. | 6903 // array or dictionary. So the fast inline test for whether to |
6903 bool cache_enum_keys = | 6904 // use the cache says yes, so we should not create a cache. |
6904 ((current->map()->GetConstructor() != *arguments_function) && | 6905 bool cache_enum_keys = |
6905 !current->IsJSValue() && !current->IsAccessCheckNeeded() && | 6906 ((current->map()->GetConstructor() != *arguments_function) && |
6906 !current->HasNamedInterceptor() && !current->HasIndexedInterceptor()); | 6907 !current->IsJSValue() && !current->IsAccessCheckNeeded() && |
6907 // Compute the property keys and cache them if possible. | 6908 !current->HasNamedInterceptor() && |
6908 | 6909 !current->HasIndexedInterceptor()); |
6909 Handle<FixedArray> enum_keys = | 6910 // Compute the property keys and cache them if possible. |
6910 JSObject::GetEnumPropertyKeys(current, cache_enum_keys); | 6911 Handle<FixedArray> enum_keys = |
6911 accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS); | 6912 JSObject::GetEnumPropertyKeys(current, cache_enum_keys); |
6913 accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS); | |
6914 } else { | |
6915 DCHECK(include_symbols == INCLUDE_SYMBOLS); | |
6916 PropertyAttributes filter = | |
6917 static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL); | |
6918 Handle<FixedArray> property_keys = isolate->factory()->NewFixedArray( | |
6919 current->NumberOfOwnProperties(filter)); | |
6920 current->GetOwnPropertyNames(*property_keys, 0, filter); | |
Camillo Bruni
2015/09/29 16:27:20
Not sure how much work this would be, but essentia
Jakob Kummerow
2015/09/30 13:59:30
I'm leaving that to you :-)
| |
6921 accumulator.AddKeys(property_keys, FixedArray::ALL_KEYS); | |
6922 } | |
6912 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); | 6923 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); |
6913 | 6924 |
6914 // Add the non-symbol property keys from the interceptor. | 6925 // Add the property keys from the interceptor. |
6915 if (current->HasNamedInterceptor()) { | 6926 if (current->HasNamedInterceptor()) { |
6916 Handle<JSObject> result; | 6927 Handle<JSObject> result; |
6917 if (JSObject::GetKeysForNamedInterceptor( | 6928 if (JSObject::GetKeysForNamedInterceptor( |
6918 current, object).ToHandle(&result)) { | 6929 current, object).ToHandle(&result)) { |
6919 accumulator.AddKeys(result, FixedArray::NON_SYMBOL_KEYS); | 6930 FixedArray::KeyFilter filter = include_symbols == SKIP_SYMBOLS |
6931 ? FixedArray::NON_SYMBOL_KEYS | |
6932 : FixedArray::ALL_KEYS; | |
6933 accumulator.AddKeys(result, filter); | |
6920 } | 6934 } |
6921 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); | 6935 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); |
6922 } | 6936 } |
6923 } | 6937 } |
6924 | 6938 |
6925 Handle<FixedArray> keys = accumulator.GetKeys(); | 6939 Handle<FixedArray> keys = accumulator.GetKeys(); |
6926 DCHECK(ContainsOnlyValidKeys(keys)); | 6940 DCHECK(ContainsOnlyValidKeys(keys)); |
6927 return keys; | 6941 return keys; |
6928 } | 6942 } |
6929 | 6943 |
(...skipping 6895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13825 return global_dictionary()->CopyKeysTo(storage, index, filter, | 13839 return global_dictionary()->CopyKeysTo(storage, index, filter, |
13826 GlobalDictionary::UNSORTED); | 13840 GlobalDictionary::UNSORTED); |
13827 } else { | 13841 } else { |
13828 return property_dictionary()->CopyKeysTo(storage, index, filter, | 13842 return property_dictionary()->CopyKeysTo(storage, index, filter, |
13829 NameDictionary::UNSORTED); | 13843 NameDictionary::UNSORTED); |
13830 } | 13844 } |
13831 } | 13845 } |
13832 | 13846 |
13833 | 13847 |
13834 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { | 13848 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { |
13835 return GetOwnElementKeys(NULL, filter); | |
13836 } | |
13837 | |
13838 | |
13839 int JSObject::NumberOfEnumElements() { | |
13840 // Fast case for objects with no elements. | 13849 // Fast case for objects with no elements. |
13841 if (!IsJSValue() && HasFastObjectElements()) { | 13850 if (!IsJSValue() && HasFastElements()) { |
13842 uint32_t length = IsJSArray() ? | 13851 uint32_t length = IsJSArray() ? |
13843 static_cast<uint32_t>( | 13852 static_cast<uint32_t>( |
13844 Smi::cast(JSArray::cast(this)->length())->value()) : | 13853 Smi::cast(JSArray::cast(this)->length())->value()) : |
13845 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 13854 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
13846 if (length == 0) return 0; | 13855 if (length == 0) return 0; |
13847 } | 13856 } |
13848 // Compute the number of enumerable elements. | 13857 // Compute the number of enumerable elements. |
13858 return GetOwnElementKeys(NULL, filter); | |
13859 } | |
13860 | |
13861 | |
13862 int JSObject::NumberOfEnumElements() { | |
13849 return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM)); | 13863 return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM)); |
13850 } | 13864 } |
13851 | 13865 |
13852 | 13866 |
13853 int JSObject::GetOwnElementKeys(FixedArray* storage, | 13867 int JSObject::GetOwnElementKeys(FixedArray* storage, |
13854 PropertyAttributes filter) { | 13868 PropertyAttributes filter) { |
13855 int counter = 0; | 13869 int counter = 0; |
13856 | 13870 |
13857 // If this is a String wrapper, add the string indices first, | 13871 // If this is a String wrapper, add the string indices first, |
13858 // as they're guaranteed to preced the elements in numerical order | 13872 // as they're guaranteed to preced the elements in numerical order |
(...skipping 2942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16801 if (cell->value() != *new_value) { | 16815 if (cell->value() != *new_value) { |
16802 cell->set_value(*new_value); | 16816 cell->set_value(*new_value); |
16803 Isolate* isolate = cell->GetIsolate(); | 16817 Isolate* isolate = cell->GetIsolate(); |
16804 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16818 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
16805 isolate, DependentCode::kPropertyCellChangedGroup); | 16819 isolate, DependentCode::kPropertyCellChangedGroup); |
16806 } | 16820 } |
16807 } | 16821 } |
16808 | 16822 |
16809 } // namespace internal | 16823 } // namespace internal |
16810 } // namespace v8 | 16824 } // namespace v8 |
OLD | NEW |