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

Side by Side Diff: src/objects.cc

Issue 1368753003: Add C++ implementation of Object.defineProperties (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: preview -- needs refactoring Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime.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 6769 matching lines...) Expand 10 before | Expand all | Expand 10 after
6780 DisallowHeapAllocation no_gc; 6780 DisallowHeapAllocation no_gc;
6781 WriteBarrierMode mode = new_keys->GetWriteBarrierMode(no_gc); 6781 WriteBarrierMode mode = new_keys->GetWriteBarrierMode(no_gc);
6782 for (int i = 0; i < buffer_length; i++) { 6782 for (int i = 0; i < buffer_length; i++) {
6783 new_keys->set(i, keys_->get(i), mode); 6783 new_keys->set(i, keys_->get(i), mode);
6784 } 6784 }
6785 } 6785 }
6786 keys_ = new_keys; 6786 keys_ = new_keys;
6787 } 6787 }
6788 6788
6789 6789
6790 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, 6790 MaybeHandle<FixedArray> JSReceiver::GetKeys(
6791 KeyCollectionType type) { 6791 Handle<JSReceiver> object, KeyCollectionType type,
6792 IncludeSymbolNamedProperties include_symbols) {
6792 USE(ContainsOnlyValidKeys); 6793 USE(ContainsOnlyValidKeys);
6793 Isolate* isolate = object->GetIsolate(); 6794 Isolate* isolate = object->GetIsolate();
6794 KeyAccumulator accumulator(isolate); 6795 KeyAccumulator accumulator(isolate);
6795 Handle<JSFunction> arguments_function( 6796 Handle<JSFunction> arguments_function(
6796 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); 6797 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor()));
6797 6798
6798 PrototypeIterator::WhereToEnd end = type == OWN_ONLY 6799 PrototypeIterator::WhereToEnd end = type == OWN_ONLY
6799 ? PrototypeIterator::END_AT_NON_HIDDEN 6800 ? PrototypeIterator::END_AT_NON_HIDDEN
6800 : PrototypeIterator::END_AT_NULL; 6801 : PrototypeIterator::END_AT_NULL;
6801 // Only collect keys if access is permitted. 6802 // Only collect keys if access is permitted.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
6839 // Add the element keys from the interceptor. 6840 // Add the element keys from the interceptor.
6840 if (current->HasIndexedInterceptor()) { 6841 if (current->HasIndexedInterceptor()) {
6841 Handle<JSObject> result; 6842 Handle<JSObject> result;
6842 if (JSObject::GetKeysForIndexedInterceptor( 6843 if (JSObject::GetKeysForIndexedInterceptor(
6843 current, object).ToHandle(&result)) { 6844 current, object).ToHandle(&result)) {
6844 accumulator.AddKeys(result, FixedArray::ALL_KEYS); 6845 accumulator.AddKeys(result, FixedArray::ALL_KEYS);
6845 } 6846 }
6846 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); 6847 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6847 } 6848 }
6848 6849
6849 // We can cache the computed property keys if access checks are 6850 if (include_symbols == SKIP_SYMBOLS) {
6850 // not needed and no interceptors are involved. 6851 // We can cache the computed property keys if access checks are
6851 // 6852 // not needed and no interceptors are involved.
6852 // We do not use the cache if the object has elements and 6853 //
6853 // therefore it does not make sense to cache the property names 6854 // We do not use the cache if the object has elements and
6854 // for arguments objects. Arguments objects will always have 6855 // therefore it does not make sense to cache the property names
6855 // elements. 6856 // for arguments objects. Arguments objects will always have
6856 // Wrapped strings have elements, but don't have an elements 6857 // elements.
6857 // array or dictionary. So the fast inline test for whether to 6858 // Wrapped strings have elements, but don't have an elements
6858 // use the cache says yes, so we should not create a cache. 6859 // array or dictionary. So the fast inline test for whether to
6859 bool cache_enum_keys = 6860 // use the cache says yes, so we should not create a cache.
6860 ((current->map()->GetConstructor() != *arguments_function) && 6861 bool cache_enum_keys =
6861 !current->IsJSValue() && !current->IsAccessCheckNeeded() && 6862 ((current->map()->GetConstructor() != *arguments_function) &&
6862 !current->HasNamedInterceptor() && !current->HasIndexedInterceptor()); 6863 !current->IsJSValue() && !current->IsAccessCheckNeeded() &&
6863 // Compute the property keys and cache them if possible. 6864 !current->HasNamedInterceptor() &&
6864 6865 !current->HasIndexedInterceptor());
6865 Handle<FixedArray> enum_keys = 6866 // Compute the property keys and cache them if possible.
6866 JSObject::GetEnumPropertyKeys(current, cache_enum_keys); 6867 Handle<FixedArray> enum_keys =
6867 accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS); 6868 JSObject::GetEnumPropertyKeys(current, cache_enum_keys);
6869 accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS);
6870 } else {
6871 DCHECK(include_symbols == INCLUDE_SYMBOLS);
6872 PropertyAttributes filter =
6873 static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL);
6874 Handle<FixedArray> property_keys = isolate->factory()->NewFixedArray(
6875 current->NumberOfOwnProperties(filter));
6876 current->GetOwnPropertyNames(*property_keys, 0, filter);
6877 accumulator.AddKeys(property_keys, FixedArray::ALL_KEYS);
6878 }
6868 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); 6879 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6869 6880
6870 // Add the non-symbol property keys from the interceptor. 6881 // Add the property keys from the interceptor.
6871 if (current->HasNamedInterceptor()) { 6882 if (current->HasNamedInterceptor()) {
6872 Handle<JSObject> result; 6883 Handle<JSObject> result;
6873 if (JSObject::GetKeysForNamedInterceptor( 6884 if (JSObject::GetKeysForNamedInterceptor(
6874 current, object).ToHandle(&result)) { 6885 current, object).ToHandle(&result)) {
6875 accumulator.AddKeys(result, FixedArray::NON_SYMBOL_KEYS); 6886 FixedArray::KeyFilter filter = include_symbols == SKIP_SYMBOLS
6887 ? FixedArray::NON_SYMBOL_KEYS
6888 : FixedArray::ALL_KEYS;
6889 accumulator.AddKeys(result, filter);
6876 } 6890 }
6877 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); 6891 DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys()));
6878 } 6892 }
6879 } 6893 }
6880 6894
6881 Handle<FixedArray> keys = accumulator.GetKeys(); 6895 Handle<FixedArray> keys = accumulator.GetKeys();
6882 DCHECK(ContainsOnlyValidKeys(keys)); 6896 DCHECK(ContainsOnlyValidKeys(keys));
6883 return keys; 6897 return keys;
6884 } 6898 }
6885 6899
(...skipping 22 matching lines...) Expand all
6908 return true; 6922 return true;
6909 } 6923 }
6910 } 6924 }
6911 } 6925 }
6912 6926
6913 return false; 6927 return false;
6914 } 6928 }
6915 6929
6916 6930
6917 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, 6931 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
6918 Handle<Name> name, 6932 Handle<Object> name,
6919 Handle<Object> getter, 6933 Handle<Object> getter,
6920 Handle<Object> setter, 6934 Handle<Object> setter,
6921 PropertyAttributes attributes) { 6935 PropertyAttributes attributes) {
6922 Isolate* isolate = object->GetIsolate(); 6936 Isolate* isolate = object->GetIsolate();
6923 6937
6924 LookupIterator it = LookupIterator::PropertyOrElement( 6938 LookupIterator it = LookupIterator::PropertyOrElement(
6925 isolate, object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); 6939 isolate, object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
6926 6940
6927 if (it.state() == LookupIterator::ACCESS_CHECK) { 6941 if (it.state() == LookupIterator::ACCESS_CHECK) {
6928 if (!it.HasAccess()) { 6942 if (!it.HasAccess()) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
6960 } 6974 }
6961 if (!setter->IsNull()) { 6975 if (!setter->IsNull()) {
6962 it.TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes); 6976 it.TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes);
6963 } 6977 }
6964 6978
6965 if (is_observed) { 6979 if (is_observed) {
6966 // Make sure the top context isn't changed. 6980 // Make sure the top context isn't changed.
6967 AssertNoContextChange ncc(isolate); 6981 AssertNoContextChange ncc(isolate);
6968 const char* type = preexists ? "reconfigure" : "add"; 6982 const char* type = preexists ? "reconfigure" : "add";
6969 RETURN_ON_EXCEPTION( 6983 RETURN_ON_EXCEPTION(
6970 isolate, EnqueueChangeRecord(object, type, name, old_value), Object); 6984 isolate, EnqueueChangeRecord(object, type, it.GetName(), old_value),
6985 Object);
6971 } 6986 }
6972 6987
6973 return isolate->factory()->undefined_value(); 6988 return isolate->factory()->undefined_value();
6974 } 6989 }
6975 6990
6976 6991
6977 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, 6992 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
6978 Handle<AccessorInfo> info) { 6993 Handle<AccessorInfo> info) {
6979 Isolate* isolate = object->GetIsolate(); 6994 Isolate* isolate = object->GetIsolate();
6980 Handle<Name> name(Name::cast(info->name()), isolate); 6995 Handle<Name> name(Name::cast(info->name()), isolate);
(...skipping 6787 matching lines...) Expand 10 before | Expand all | Expand 10 after
13768 return global_dictionary()->CopyKeysTo(storage, index, filter, 13783 return global_dictionary()->CopyKeysTo(storage, index, filter,
13769 GlobalDictionary::UNSORTED); 13784 GlobalDictionary::UNSORTED);
13770 } else { 13785 } else {
13771 return property_dictionary()->CopyKeysTo(storage, index, filter, 13786 return property_dictionary()->CopyKeysTo(storage, index, filter,
13772 NameDictionary::UNSORTED); 13787 NameDictionary::UNSORTED);
13773 } 13788 }
13774 } 13789 }
13775 13790
13776 13791
13777 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { 13792 int JSObject::NumberOfOwnElements(PropertyAttributes filter) {
13778 return GetOwnElementKeys(NULL, filter);
13779 }
13780
13781
13782 int JSObject::NumberOfEnumElements() {
13783 // Fast case for objects with no elements. 13793 // Fast case for objects with no elements.
13784 if (!IsJSValue() && HasFastObjectElements()) { 13794 if (!IsJSValue() && HasFastElements()) {
13785 uint32_t length = IsJSArray() ? 13795 uint32_t length = IsJSArray() ?
13786 static_cast<uint32_t>( 13796 static_cast<uint32_t>(
13787 Smi::cast(JSArray::cast(this)->length())->value()) : 13797 Smi::cast(JSArray::cast(this)->length())->value()) :
13788 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 13798 static_cast<uint32_t>(FixedArray::cast(elements())->length());
13789 if (length == 0) return 0; 13799 if (length == 0) return 0;
13790 } 13800 }
13791 // Compute the number of enumerable elements. 13801 // Compute the number of enumerable elements.
13802 return GetOwnElementKeys(NULL, filter);
13803 }
13804
13805
13806 int JSObject::NumberOfEnumElements() {
13792 return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM)); 13807 return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM));
13793 } 13808 }
13794 13809
13795 13810
13796 int JSObject::GetOwnElementKeys(FixedArray* storage, 13811 int JSObject::GetOwnElementKeys(FixedArray* storage,
13797 PropertyAttributes filter) { 13812 PropertyAttributes filter) {
13798 int counter = 0; 13813 int counter = 0;
13799 13814
13800 // If this is a String wrapper, add the string indices first, 13815 // If this is a String wrapper, add the string indices first,
13801 // as they're guaranteed to preced the elements in numerical order 13816 // as they're guaranteed to preced the elements in numerical order
(...skipping 2943 matching lines...) Expand 10 before | Expand all | Expand 10 after
16745 if (cell->value() != *new_value) { 16760 if (cell->value() != *new_value) {
16746 cell->set_value(*new_value); 16761 cell->set_value(*new_value);
16747 Isolate* isolate = cell->GetIsolate(); 16762 Isolate* isolate = cell->GetIsolate();
16748 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16763 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16749 isolate, DependentCode::kPropertyCellChangedGroup); 16764 isolate, DependentCode::kPropertyCellChangedGroup);
16750 } 16765 }
16751 } 16766 }
16752 16767
16753 } // namespace internal 16768 } // namespace internal
16754 } // namespace v8 16769 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698