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 1851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1862 value = cell; | 1862 value = cell; |
1863 } | 1863 } |
1864 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); | 1864 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
1865 Handle<NameDictionary> result = | 1865 Handle<NameDictionary> result = |
1866 NameDictionary::Add(dict, name, value, details); | 1866 NameDictionary::Add(dict, name, value, details); |
1867 if (*dict != *result) object->set_properties(*result); | 1867 if (*dict != *result) object->set_properties(*result); |
1868 } | 1868 } |
1869 | 1869 |
1870 | 1870 |
1871 MaybeHandle<Object> JSObject::AddPropertyInternal( | 1871 MaybeHandle<Object> JSObject::AddPropertyInternal( |
1872 Handle<JSObject> object, | 1872 Handle<JSObject> object, Handle<Name> name, Handle<Object> value, |
1873 Handle<Name> name, | 1873 PropertyAttributes attributes, JSReceiver::StoreFromKeyed store_mode, |
1874 Handle<Object> value, | 1874 ExtensibilityCheck extensibility_check, TransitionFlag transition_flag) { |
1875 PropertyAttributes attributes, | |
1876 StrictMode strict_mode, | |
1877 JSReceiver::StoreFromKeyed store_mode, | |
1878 ExtensibilityCheck extensibility_check, | |
1879 StoreMode mode, | |
1880 TransitionFlag transition_flag) { | |
1881 ASSERT(!object->IsJSGlobalProxy()); | 1875 ASSERT(!object->IsJSGlobalProxy()); |
1882 Isolate* isolate = object->GetIsolate(); | 1876 Isolate* isolate = object->GetIsolate(); |
1883 | 1877 |
1884 if (!name->IsUniqueName()) { | 1878 if (!name->IsUniqueName()) { |
1885 name = isolate->factory()->InternalizeString( | 1879 name = isolate->factory()->InternalizeString( |
1886 Handle<String>::cast(name)); | 1880 Handle<String>::cast(name)); |
1887 } | 1881 } |
1888 | 1882 |
1889 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | 1883 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && |
1890 !object->map()->is_extensible()) { | 1884 !object->map()->is_extensible()) { |
1891 if (strict_mode == SLOPPY) { | 1885 Handle<Object> args[1] = {name}; |
1892 return value; | 1886 Handle<Object> error = isolate->factory()->NewTypeError( |
1893 } else { | 1887 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); |
1894 Handle<Object> args[1] = { name }; | 1888 return isolate->Throw<Object>(error); |
1895 Handle<Object> error = isolate->factory()->NewTypeError( | |
1896 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); | |
1897 return isolate->Throw<Object>(error); | |
1898 } | |
1899 } | 1889 } |
1900 | 1890 |
1901 if (object->HasFastProperties()) { | 1891 if (object->HasFastProperties()) { |
1902 AddFastProperty(object, name, value, attributes, store_mode, | 1892 AddFastProperty(object, name, value, attributes, store_mode, |
1903 transition_flag); | 1893 transition_flag); |
1904 } | 1894 } |
1905 | 1895 |
1906 if (!object->HasFastProperties()) { | 1896 if (!object->HasFastProperties()) { |
1907 AddSlowProperty(object, name, value, attributes); | 1897 AddSlowProperty(object, name, value, attributes); |
1908 } | 1898 } |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2252 | 2242 |
2253 // We are storing the new map using release store after creating a filler for | 2243 // We are storing the new map using release store after creating a filler for |
2254 // the left-over space to avoid races with the sweeper thread. | 2244 // the left-over space to avoid races with the sweeper thread. |
2255 object->synchronized_set_map(*new_map); | 2245 object->synchronized_set_map(*new_map); |
2256 } | 2246 } |
2257 | 2247 |
2258 | 2248 |
2259 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, | 2249 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, |
2260 int modify_index, | 2250 int modify_index, |
2261 Representation new_representation, | 2251 Representation new_representation, |
2262 Handle<HeapType> new_field_type, | 2252 Handle<HeapType> new_field_type) { |
2263 StoreMode store_mode) { | |
2264 Handle<Map> new_map = Map::GeneralizeRepresentation( | 2253 Handle<Map> new_map = Map::GeneralizeRepresentation( |
2265 handle(object->map()), modify_index, new_representation, | 2254 handle(object->map()), modify_index, new_representation, new_field_type, |
2266 new_field_type, store_mode); | 2255 FORCE_FIELD); |
2267 MigrateToMap(object, new_map); | 2256 MigrateToMap(object, new_map); |
2268 } | 2257 } |
2269 | 2258 |
2270 | 2259 |
2271 int Map::NumberOfFields() { | 2260 int Map::NumberOfFields() { |
2272 DescriptorArray* descriptors = instance_descriptors(); | 2261 DescriptorArray* descriptors = instance_descriptors(); |
2273 int result = 0; | 2262 int result = 0; |
2274 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { | 2263 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { |
2275 if (descriptors->GetDetails(i).type() == FIELD) result++; | 2264 if (descriptors->GetDetails(i).type() == FIELD) result++; |
2276 } | 2265 } |
(...skipping 1708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3985 int descriptor = transition_map->LastAdded(); | 3974 int descriptor = transition_map->LastAdded(); |
3986 | 3975 |
3987 Handle<DescriptorArray> descriptors(transition_map->instance_descriptors()); | 3976 Handle<DescriptorArray> descriptors(transition_map->instance_descriptors()); |
3988 PropertyDetails details = descriptors->GetDetails(descriptor); | 3977 PropertyDetails details = descriptors->GetDetails(descriptor); |
3989 | 3978 |
3990 if (details.type() == CALLBACKS || attributes != details.attributes()) { | 3979 if (details.type() == CALLBACKS || attributes != details.attributes()) { |
3991 // AddPropertyInternal will either normalize the object, or create a new | 3980 // AddPropertyInternal will either normalize the object, or create a new |
3992 // fast copy of the map. If we get a fast copy of the map, all field | 3981 // fast copy of the map. If we get a fast copy of the map, all field |
3993 // representations will be tagged since the transition is omitted. | 3982 // representations will be tagged since the transition is omitted. |
3994 return JSObject::AddPropertyInternal( | 3983 return JSObject::AddPropertyInternal( |
3995 object, name, value, attributes, SLOPPY, | 3984 object, name, value, attributes, |
3996 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, | 3985 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, |
3997 JSReceiver::OMIT_EXTENSIBILITY_CHECK, FORCE_FIELD, OMIT_TRANSITION); | 3986 JSReceiver::OMIT_EXTENSIBILITY_CHECK, OMIT_TRANSITION); |
3998 } | 3987 } |
3999 | 3988 |
4000 // Keep the target CONSTANT if the same value is stored. | 3989 // Keep the target CONSTANT if the same value is stored. |
4001 // TODO(verwaest): Also support keeping the placeholder | 3990 // TODO(verwaest): Also support keeping the placeholder |
4002 // (value->IsUninitialized) as constant. | 3991 // (value->IsUninitialized) as constant. |
4003 if (!lookup->CanHoldValue(value)) { | 3992 if (!lookup->CanHoldValue(value)) { |
4004 Representation field_representation = value->OptimalRepresentation(); | 3993 Representation field_representation = value->OptimalRepresentation(); |
4005 Handle<HeapType> field_type = value->OptimalType( | 3994 Handle<HeapType> field_type = value->OptimalType( |
4006 lookup->isolate(), field_representation); | 3995 lookup->isolate(), field_representation); |
4007 transition_map = Map::GeneralizeRepresentation( | 3996 transition_map = Map::GeneralizeRepresentation( |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4044 } | 4033 } |
4045 | 4034 |
4046 | 4035 |
4047 void JSObject::SetPropertyToField(LookupResult* lookup, Handle<Object> value) { | 4036 void JSObject::SetPropertyToField(LookupResult* lookup, Handle<Object> value) { |
4048 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { | 4037 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { |
4049 Representation field_representation = value->OptimalRepresentation(); | 4038 Representation field_representation = value->OptimalRepresentation(); |
4050 Handle<HeapType> field_type = value->OptimalType( | 4039 Handle<HeapType> field_type = value->OptimalType( |
4051 lookup->isolate(), field_representation); | 4040 lookup->isolate(), field_representation); |
4052 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), | 4041 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), |
4053 lookup->GetDescriptorIndex(), | 4042 lookup->GetDescriptorIndex(), |
4054 field_representation, field_type, | 4043 field_representation, field_type); |
4055 FORCE_FIELD); | |
4056 } | 4044 } |
4057 lookup->holder()->WriteToField(lookup->GetDescriptorIndex(), *value); | 4045 lookup->holder()->WriteToField(lookup->GetDescriptorIndex(), *value); |
4058 } | 4046 } |
4059 | 4047 |
4060 | 4048 |
4061 void JSObject::ConvertAndSetOwnProperty(LookupResult* lookup, | 4049 void JSObject::ConvertAndSetOwnProperty(LookupResult* lookup, |
4062 Handle<Name> name, | 4050 Handle<Name> name, |
4063 Handle<Object> value, | 4051 Handle<Object> value, |
4064 PropertyAttributes attributes) { | 4052 PropertyAttributes attributes) { |
4065 Handle<JSObject> object(lookup->holder()); | 4053 Handle<JSObject> object(lookup->holder()); |
4066 if (object->map()->TooManyFastProperties(Object::MAY_BE_STORE_FROM_KEYED)) { | 4054 if (object->map()->TooManyFastProperties(Object::MAY_BE_STORE_FROM_KEYED)) { |
4067 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 4055 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
4068 } | 4056 } |
4069 | 4057 |
4070 if (!object->HasFastProperties()) { | 4058 if (!object->HasFastProperties()) { |
4071 ReplaceSlowProperty(object, name, value, attributes); | 4059 ReplaceSlowProperty(object, name, value, attributes); |
4072 return; | 4060 return; |
4073 } | 4061 } |
4074 | 4062 |
4075 int descriptor_index = lookup->GetDescriptorIndex(); | 4063 int descriptor_index = lookup->GetDescriptorIndex(); |
4076 if (lookup->GetAttributes() == attributes) { | 4064 if (lookup->GetAttributes() == attributes) { |
4077 JSObject::GeneralizeFieldRepresentation( | 4065 JSObject::GeneralizeFieldRepresentation(object, descriptor_index, |
4078 object, descriptor_index, Representation::Tagged(), | 4066 Representation::Tagged(), |
4079 HeapType::Any(lookup->isolate()), FORCE_FIELD); | 4067 HeapType::Any(lookup->isolate())); |
4080 } else { | 4068 } else { |
4081 Handle<Map> old_map(object->map()); | 4069 Handle<Map> old_map(object->map()); |
4082 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, | 4070 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, |
4083 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); | 4071 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); |
4084 JSObject::MigrateToMap(object, new_map); | 4072 JSObject::MigrateToMap(object, new_map); |
4085 } | 4073 } |
4086 | 4074 |
4087 object->WriteToField(descriptor_index, *value); | 4075 object->WriteToField(descriptor_index, *value); |
4088 } | 4076 } |
4089 | 4077 |
4090 | 4078 |
4091 void JSObject::SetPropertyToFieldWithAttributes(LookupResult* lookup, | 4079 void JSObject::SetPropertyToFieldWithAttributes(LookupResult* lookup, |
4092 Handle<Name> name, | 4080 Handle<Name> name, |
4093 Handle<Object> value, | 4081 Handle<Object> value, |
4094 PropertyAttributes attributes) { | 4082 PropertyAttributes attributes) { |
4095 if (lookup->GetAttributes() == attributes) { | 4083 if (lookup->GetAttributes() == attributes) { |
4096 if (value->IsUninitialized()) return; | 4084 if (value->IsUninitialized()) return; |
4097 SetPropertyToField(lookup, value); | 4085 SetPropertyToField(lookup, value); |
4098 } else { | 4086 } else { |
4099 ConvertAndSetOwnProperty(lookup, name, value, attributes); | 4087 ConvertAndSetOwnProperty(lookup, name, value, attributes); |
4100 } | 4088 } |
4101 } | 4089 } |
4102 | 4090 |
4103 | 4091 |
4104 void JSObject::AddProperty( | 4092 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, |
4105 Handle<JSObject> object, | 4093 Handle<Object> value, |
4106 Handle<Name> name, | 4094 PropertyAttributes attributes) { |
4107 Handle<Object> value, | |
4108 PropertyAttributes attributes, | |
4109 StoreMode store_mode) { | |
4110 #ifdef DEBUG | 4095 #ifdef DEBUG |
4111 uint32_t index; | 4096 uint32_t index; |
4112 ASSERT(!object->IsJSProxy()); | 4097 ASSERT(!object->IsJSProxy()); |
4113 ASSERT(!name->AsArrayIndex(&index)); | 4098 ASSERT(!name->AsArrayIndex(&index)); |
4114 LookupIterator it(object, name, LookupIterator::CHECK_OWN_REAL); | 4099 LookupIterator it(object, name, LookupIterator::CHECK_OWN_REAL); |
4115 GetPropertyAttributes(&it); | 4100 GetPropertyAttributes(&it); |
4116 ASSERT(!it.IsFound()); | 4101 ASSERT(!it.IsFound()); |
4117 ASSERT(object->map()->is_extensible()); | 4102 ASSERT(object->map()->is_extensible()); |
4118 #endif | 4103 #endif |
4119 SetOwnPropertyIgnoreAttributes(object, name, value, attributes, store_mode, | 4104 SetOwnPropertyIgnoreAttributes(object, name, value, attributes, |
4120 OMIT_EXTENSIBILITY_CHECK).Check(); | 4105 OMIT_EXTENSIBILITY_CHECK).Check(); |
4121 } | 4106 } |
4122 | 4107 |
4123 | 4108 |
4124 // Reconfigures a property to a data property with attributes, even if it is not | 4109 // Reconfigures a property to a data property with attributes, even if it is not |
4125 // reconfigurable. | 4110 // reconfigurable. |
4126 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( | 4111 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( |
4127 Handle<JSObject> object, | 4112 Handle<JSObject> object, |
4128 Handle<Name> name, | 4113 Handle<Name> name, |
4129 Handle<Object> value, | 4114 Handle<Object> value, |
4130 PropertyAttributes attributes, | 4115 PropertyAttributes attributes, |
4131 StoreMode mode, | |
4132 ExtensibilityCheck extensibility_check, | 4116 ExtensibilityCheck extensibility_check, |
4133 StoreFromKeyed store_from_keyed, | 4117 StoreFromKeyed store_from_keyed, |
4134 ExecutableAccessorInfoHandling handling) { | 4118 ExecutableAccessorInfoHandling handling) { |
4135 ASSERT(!value->IsTheHole()); | 4119 ASSERT(!value->IsTheHole()); |
4136 Isolate* isolate = object->GetIsolate(); | 4120 Isolate* isolate = object->GetIsolate(); |
4137 | 4121 |
4138 // Make sure that the top context does not change when doing callbacks or | 4122 // Make sure that the top context does not change when doing callbacks or |
4139 // interceptor calls. | 4123 // interceptor calls. |
4140 AssertNoContextChange ncc(isolate); | 4124 AssertNoContextChange ncc(isolate); |
4141 | 4125 |
(...skipping 10 matching lines...) Expand all Loading... |
4152 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); | 4136 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); |
4153 } | 4137 } |
4154 } | 4138 } |
4155 | 4139 |
4156 if (object->IsJSGlobalProxy()) { | 4140 if (object->IsJSGlobalProxy()) { |
4157 PrototypeIterator iter(isolate, object); | 4141 PrototypeIterator iter(isolate, object); |
4158 if (iter.IsAtEnd()) return value; | 4142 if (iter.IsAtEnd()) return value; |
4159 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 4143 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
4160 return SetOwnPropertyIgnoreAttributes( | 4144 return SetOwnPropertyIgnoreAttributes( |
4161 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), name, | 4145 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), name, |
4162 value, attributes, mode, extensibility_check); | 4146 value, attributes, extensibility_check); |
4163 } | 4147 } |
4164 | 4148 |
4165 if (lookup.IsInterceptor() || | 4149 if (lookup.IsInterceptor() || |
4166 (lookup.IsDescriptorOrDictionary() && lookup.type() == CALLBACKS)) { | 4150 (lookup.IsDescriptorOrDictionary() && lookup.type() == CALLBACKS)) { |
4167 object->LookupOwnRealNamedProperty(name, &lookup); | 4151 object->LookupOwnRealNamedProperty(name, &lookup); |
4168 } | 4152 } |
4169 | 4153 |
4170 // Check for accessor in prototype chain removed here in clone. | 4154 // Check for accessor in prototype chain removed here in clone. |
4171 if (!lookup.IsFound()) { | 4155 if (!lookup.IsFound()) { |
4172 object->map()->LookupTransition(*object, *name, &lookup); | 4156 object->map()->LookupTransition(*object, *name, &lookup); |
4173 TransitionFlag flag = lookup.IsFound() | 4157 TransitionFlag flag = lookup.IsFound() |
4174 ? OMIT_TRANSITION : INSERT_TRANSITION; | 4158 ? OMIT_TRANSITION : INSERT_TRANSITION; |
4175 // Neither properties nor transitions found. | 4159 // Neither properties nor transitions found. |
4176 return AddPropertyInternal(object, name, value, attributes, SLOPPY, | 4160 return AddPropertyInternal(object, name, value, attributes, |
4177 store_from_keyed, extensibility_check, mode, | 4161 store_from_keyed, extensibility_check, flag); |
4178 flag); | |
4179 } | 4162 } |
4180 | 4163 |
4181 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 4164 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
4182 PropertyAttributes old_attributes = ABSENT; | 4165 PropertyAttributes old_attributes = ABSENT; |
4183 bool is_observed = object->map()->is_observed() && | 4166 bool is_observed = object->map()->is_observed() && |
4184 *name != isolate->heap()->hidden_string(); | 4167 *name != isolate->heap()->hidden_string(); |
4185 if (is_observed && lookup.IsProperty()) { | 4168 if (is_observed && lookup.IsProperty()) { |
4186 if (lookup.IsDataProperty()) { | 4169 if (lookup.IsDataProperty()) { |
4187 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); | 4170 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); |
4188 } | 4171 } |
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5134 int sorted_index = descriptors->GetSortedKeyIndex(0); | 5117 int sorted_index = descriptors->GetSortedKeyIndex(0); |
5135 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string() | 5118 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string() |
5136 && sorted_index < object->map()->NumberOfOwnDescriptors()) { | 5119 && sorted_index < object->map()->NumberOfOwnDescriptors()) { |
5137 object->WriteToField(sorted_index, *value); | 5120 object->WriteToField(sorted_index, *value); |
5138 return object; | 5121 return object; |
5139 } | 5122 } |
5140 } | 5123 } |
5141 } | 5124 } |
5142 | 5125 |
5143 SetOwnPropertyIgnoreAttributes(object, isolate->factory()->hidden_string(), | 5126 SetOwnPropertyIgnoreAttributes(object, isolate->factory()->hidden_string(), |
5144 value, DONT_ENUM, ALLOW_AS_CONSTANT, | 5127 value, DONT_ENUM, |
5145 OMIT_EXTENSIBILITY_CHECK).Assert(); | 5128 OMIT_EXTENSIBILITY_CHECK).Assert(); |
5146 return object; | 5129 return object; |
5147 } | 5130 } |
5148 | 5131 |
5149 | 5132 |
5150 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, | 5133 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, |
5151 Handle<Name> name, | 5134 Handle<Name> name, |
5152 DeleteMode mode) { | 5135 DeleteMode mode) { |
5153 // Check own property, ignore interceptor. | 5136 // Check own property, ignore interceptor. |
5154 Isolate* isolate = object->GetIsolate(); | 5137 Isolate* isolate = object->GetIsolate(); |
(...skipping 11800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16955 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16938 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16956 static const char* error_messages_[] = { | 16939 static const char* error_messages_[] = { |
16957 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16940 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16958 }; | 16941 }; |
16959 #undef ERROR_MESSAGES_TEXTS | 16942 #undef ERROR_MESSAGES_TEXTS |
16960 return error_messages_[reason]; | 16943 return error_messages_[reason]; |
16961 } | 16944 } |
16962 | 16945 |
16963 | 16946 |
16964 } } // namespace v8::internal | 16947 } } // namespace v8::internal |
OLD | NEW |