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 |