Chromium Code Reviews| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 2905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2916 return SetDataProperty(it, value); | 2916 return SetDataProperty(it, value); |
| 2917 } | 2917 } |
| 2918 } | 2918 } |
| 2919 done = true; | 2919 done = true; |
| 2920 break; | 2920 break; |
| 2921 } | 2921 } |
| 2922 | 2922 |
| 2923 if (done) break; | 2923 if (done) break; |
| 2924 } | 2924 } |
| 2925 | 2925 |
| 2926 return AddDataProperty(it, value, NONE, strict_mode, store_mode, | 2926 return AddDataProperty(it, value, NONE, strict_mode, store_mode); |
| 2927 PERFORM_EXTENSIBILITY_CHECK); | |
| 2928 } | 2927 } |
| 2929 | 2928 |
| 2930 | 2929 |
| 2931 MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it, | 2930 MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it, |
| 2932 Handle<Object> value, | 2931 Handle<Object> value, |
| 2933 StrictMode strict_mode) { | 2932 StrictMode strict_mode) { |
| 2934 if (strict_mode != STRICT) return value; | 2933 if (strict_mode != STRICT) return value; |
| 2935 | 2934 |
| 2936 Handle<Object> args[] = {it->name(), it->GetReceiver()}; | 2935 Handle<Object> args[] = {it->name(), it->GetReceiver()}; |
| 2937 Handle<Object> error = it->factory()->NewTypeError( | 2936 Handle<Object> error = it->factory()->NewTypeError( |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2972 } | 2971 } |
| 2973 | 2972 |
| 2974 return value; | 2973 return value; |
| 2975 } | 2974 } |
| 2976 | 2975 |
| 2977 | 2976 |
| 2978 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, | 2977 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, |
| 2979 Handle<Object> value, | 2978 Handle<Object> value, |
| 2980 PropertyAttributes attributes, | 2979 PropertyAttributes attributes, |
| 2981 StrictMode strict_mode, | 2980 StrictMode strict_mode, |
| 2982 StoreFromKeyed store_mode, | 2981 StoreFromKeyed store_mode) { |
| 2983 ExtensibilityCheck check) { | |
| 2984 DCHECK(!it->GetReceiver()->IsJSProxy()); | 2982 DCHECK(!it->GetReceiver()->IsJSProxy()); |
| 2985 if (!it->GetReceiver()->IsJSObject()) { | 2983 if (!it->GetReceiver()->IsJSObject()) { |
| 2986 // TODO(verwaest): Throw a TypeError with a more specific message. | 2984 // TODO(verwaest): Throw a TypeError with a more specific message. |
| 2987 return WriteToReadOnlyProperty(it, value, strict_mode); | 2985 return WriteToReadOnlyProperty(it, value, strict_mode); |
| 2988 } | 2986 } |
| 2989 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); | 2987 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); |
| 2990 | 2988 |
| 2991 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) | 2989 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) |
| 2992 // instead. If the prototype is Null, the proxy is detached. | 2990 // instead. If the prototype is Null, the proxy is detached. |
| 2993 if (receiver->IsJSGlobalProxy()) { | 2991 if (receiver->IsJSGlobalProxy()) { |
| 2994 // Trying to assign to a detached proxy. | 2992 // Trying to assign to a detached proxy. |
| 2995 PrototypeIterator iter(it->isolate(), receiver); | 2993 PrototypeIterator iter(it->isolate(), receiver); |
| 2996 if (iter.IsAtEnd()) return value; | 2994 if (iter.IsAtEnd()) return value; |
| 2997 receiver = | 2995 receiver = |
| 2998 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); | 2996 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| 2999 } | 2997 } |
| 3000 | 2998 |
| 3001 if (check == PERFORM_EXTENSIBILITY_CHECK && | 2999 if (!it->name().is_identical_to(it->isolate()->factory()->hidden_string()) && |
| 3002 !receiver->map()->is_extensible()) { | 3000 !receiver->map()->is_extensible()) { |
| 3003 if (strict_mode == SLOPPY) return value; | 3001 if (strict_mode == SLOPPY) return value; |
| 3004 | 3002 |
| 3005 Handle<Object> args[1] = {it->name()}; | 3003 Handle<Object> args[1] = {it->name()}; |
| 3006 Handle<Object> error = it->factory()->NewTypeError( | 3004 Handle<Object> error = it->factory()->NewTypeError( |
| 3007 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); | 3005 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); |
| 3008 return it->isolate()->Throw<Object>(error); | 3006 return it->isolate()->Throw<Object>(error); |
| 3009 } | 3007 } |
| 3010 | 3008 |
| 3011 // Possibly migrate to the most up-to-date map that will be able to store | 3009 // Possibly migrate to the most up-to-date map that will be able to store |
| (...skipping 854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3866 box->set_value(value->Number()); | 3864 box->set_value(value->Number()); |
| 3867 } else { | 3865 } else { |
| 3868 FastPropertyAtPut(index, value); | 3866 FastPropertyAtPut(index, value); |
| 3869 } | 3867 } |
| 3870 } | 3868 } |
| 3871 | 3869 |
| 3872 | 3870 |
| 3873 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, | 3871 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, |
| 3874 Handle<Object> value, | 3872 Handle<Object> value, |
| 3875 PropertyAttributes attributes) { | 3873 PropertyAttributes attributes) { |
| 3874 LookupIterator it(object, name, LookupIterator::CHECK_OWN_REAL); | |
| 3876 #ifdef DEBUG | 3875 #ifdef DEBUG |
| 3877 uint32_t index; | 3876 uint32_t index; |
| 3878 DCHECK(!object->IsJSProxy()); | 3877 DCHECK(!object->IsJSProxy()); |
| 3879 DCHECK(!name->AsArrayIndex(&index)); | 3878 DCHECK(!name->AsArrayIndex(&index)); |
| 3880 LookupIterator it(object, name, LookupIterator::CHECK_OWN_REAL); | |
| 3881 Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it); | 3879 Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it); |
| 3882 DCHECK(maybe.has_value); | 3880 DCHECK(maybe.has_value); |
| 3883 DCHECK(!it.IsFound()); | 3881 DCHECK(!it.IsFound()); |
| 3884 DCHECK(object->map()->is_extensible()); | 3882 DCHECK(object->map()->is_extensible() || |
| 3883 name.is_identical_to(it.isolate()->factory()->hidden_string())); | |
| 3885 #endif | 3884 #endif |
| 3886 SetOwnPropertyIgnoreAttributes(object, name, value, attributes, | 3885 AddDataProperty(&it, value, attributes, STRICT, |
| 3887 OMIT_EXTENSIBILITY_CHECK).Check(); | 3886 CERTAINLY_NOT_STORE_FROM_KEYED).Check(); |
| 3888 } | 3887 } |
| 3889 | 3888 |
| 3890 | 3889 |
| 3891 // Reconfigures a property to a data property with attributes, even if it is not | 3890 // Reconfigures a property to a data property with attributes, even if it is not |
| 3892 // reconfigurable. | 3891 // reconfigurable. |
| 3893 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( | 3892 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( |
| 3894 Handle<JSObject> object, | 3893 Handle<JSObject> object, |
| 3895 Handle<Name> name, | 3894 Handle<Name> name, |
| 3896 Handle<Object> value, | 3895 Handle<Object> value, |
| 3897 PropertyAttributes attributes, | 3896 PropertyAttributes attributes, |
| 3898 ExtensibilityCheck extensibility_check, | |
| 3899 StoreFromKeyed store_from_keyed, | 3897 StoreFromKeyed store_from_keyed, |
| 3900 ExecutableAccessorInfoHandling handling) { | 3898 ExecutableAccessorInfoHandling handling) { |
| 3901 DCHECK(!value->IsTheHole()); | 3899 DCHECK(!value->IsTheHole()); |
| 3902 LookupIterator it(object, name, LookupIterator::CHECK_HIDDEN_ACCESS); | 3900 LookupIterator it(object, name, LookupIterator::CHECK_HIDDEN_ACCESS); |
| 3903 bool is_observed = object->map()->is_observed() && | 3901 bool is_observed = object->map()->is_observed() && |
| 3904 *name != it.isolate()->heap()->hidden_string(); | 3902 *name != it.isolate()->heap()->hidden_string(); |
| 3905 for (; it.IsFound(); it.Next()) { | 3903 for (; it.IsFound(); it.Next()) { |
| 3906 switch (it.state()) { | 3904 switch (it.state()) { |
| 3907 case LookupIterator::NOT_FOUND: | 3905 case LookupIterator::NOT_FOUND: |
| 3908 case LookupIterator::JSPROXY: | 3906 case LookupIterator::JSPROXY: |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4007 old_value = it.isolate()->factory()->the_hole_value(); | 4005 old_value = it.isolate()->factory()->the_hole_value(); |
| 4008 } | 4006 } |
| 4009 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 4007 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 4010 } | 4008 } |
| 4011 | 4009 |
| 4012 return value; | 4010 return value; |
| 4013 } | 4011 } |
| 4014 } | 4012 } |
| 4015 } | 4013 } |
| 4016 | 4014 |
| 4017 return AddDataProperty(&it, value, attributes, STRICT, store_from_keyed, | 4015 return AddDataProperty(&it, value, attributes, STRICT, store_from_keyed); |
| 4018 extensibility_check); | |
| 4019 } | 4016 } |
| 4020 | 4017 |
| 4021 | 4018 |
| 4022 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( | 4019 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( |
| 4023 Handle<JSObject> holder, | 4020 Handle<JSObject> holder, |
| 4024 Handle<Object> receiver, | 4021 Handle<Object> receiver, |
| 4025 Handle<Name> name) { | 4022 Handle<Name> name) { |
| 4026 // TODO(rossberg): Support symbols in the API. | 4023 // TODO(rossberg): Support symbols in the API. |
| 4027 if (name->IsSymbol()) return maybe(ABSENT); | 4024 if (name->IsSymbol()) return maybe(ABSENT); |
| 4028 | 4025 |
| (...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4836 isolate, kInitialCapacity, USE_CUSTOM_MINIMUM_CAPACITY); | 4833 isolate, kInitialCapacity, USE_CUSTOM_MINIMUM_CAPACITY); |
| 4837 | 4834 |
| 4838 if (inline_value->IsSmi()) { | 4835 if (inline_value->IsSmi()) { |
| 4839 // We were storing the identity hash inline and now allocated an actual | 4836 // We were storing the identity hash inline and now allocated an actual |
| 4840 // dictionary. Put the identity hash into the new dictionary. | 4837 // dictionary. Put the identity hash into the new dictionary. |
| 4841 hashtable = ObjectHashTable::Put(hashtable, | 4838 hashtable = ObjectHashTable::Put(hashtable, |
| 4842 isolate->factory()->identity_hash_string(), | 4839 isolate->factory()->identity_hash_string(), |
| 4843 inline_value); | 4840 inline_value); |
| 4844 } | 4841 } |
| 4845 | 4842 |
| 4846 JSObject::SetOwnPropertyIgnoreAttributes( | 4843 SetHiddenPropertiesHashTable(object, hashtable); |
| 4847 object, isolate->factory()->hidden_string(), | |
| 4848 hashtable, DONT_ENUM).Assert(); | |
| 4849 | |
| 4850 return hashtable; | 4844 return hashtable; |
| 4851 } | 4845 } |
| 4852 | 4846 |
| 4853 | 4847 |
| 4854 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, | 4848 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, |
| 4855 Handle<Object> value) { | 4849 Handle<Object> value) { |
| 4856 DCHECK(!object->IsJSGlobalProxy()); | 4850 DCHECK(!object->IsJSGlobalProxy()); |
| 4857 | |
| 4858 Isolate* isolate = object->GetIsolate(); | 4851 Isolate* isolate = object->GetIsolate(); |
| 4859 | 4852 Handle<Name> name = isolate->factory()->hidden_string(); |
| 4860 // We can store the identity hash inline iff there is no backing store | 4853 SetOwnPropertyIgnoreAttributes(object, name, value, DONT_ENUM); |
|
Jakob Kummerow
2014/08/13 10:31:10
MUST_USE_RESULT, so you'll need to keep the .Asser
| |
| 4861 // for hidden properties yet. | |
| 4862 DCHECK(JSObject::HasHiddenProperties(object) != value->IsSmi()); | |
| 4863 if (object->HasFastProperties()) { | |
| 4864 // If the object has fast properties, check whether the first slot | |
| 4865 // in the descriptor array matches the hidden string. Since the | |
| 4866 // hidden strings hash code is zero (and no other name has hash | |
| 4867 // code zero) it will always occupy the first entry if present. | |
| 4868 DescriptorArray* descriptors = object->map()->instance_descriptors(); | |
| 4869 if (descriptors->number_of_descriptors() > 0) { | |
| 4870 int sorted_index = descriptors->GetSortedKeyIndex(0); | |
| 4871 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string() | |
| 4872 && sorted_index < object->map()->NumberOfOwnDescriptors()) { | |
| 4873 object->WriteToField(sorted_index, *value); | |
| 4874 return object; | |
| 4875 } | |
| 4876 } | |
| 4877 } | |
| 4878 | |
| 4879 SetOwnPropertyIgnoreAttributes(object, isolate->factory()->hidden_string(), | |
| 4880 value, DONT_ENUM, | |
| 4881 OMIT_EXTENSIBILITY_CHECK).Assert(); | |
| 4882 return object; | 4854 return object; |
| 4883 } | 4855 } |
| 4884 | 4856 |
| 4885 | 4857 |
| 4886 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, | 4858 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, |
| 4887 Handle<Name> name, | 4859 Handle<Name> name, |
| 4888 DeleteMode delete_mode) { | 4860 DeleteMode delete_mode) { |
| 4889 // Check own property, ignore interceptor. | 4861 // Check own property, ignore interceptor. |
| 4890 Isolate* isolate = object->GetIsolate(); | 4862 Isolate* isolate = object->GetIsolate(); |
| 4891 LookupResult lookup(isolate); | 4863 LookupResult lookup(isolate); |
| (...skipping 11815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16707 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16679 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16708 static const char* error_messages_[] = { | 16680 static const char* error_messages_[] = { |
| 16709 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16681 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16710 }; | 16682 }; |
| 16711 #undef ERROR_MESSAGES_TEXTS | 16683 #undef ERROR_MESSAGES_TEXTS |
| 16712 return error_messages_[reason]; | 16684 return error_messages_[reason]; |
| 16713 } | 16685 } |
| 16714 | 16686 |
| 16715 | 16687 |
| 16716 } } // namespace v8::internal | 16688 } } // namespace v8::internal |
| OLD | NEW |