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 4186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4197 // callback setter removed. The two lines looking up the LookupResult | 4197 // callback setter removed. The two lines looking up the LookupResult |
4198 // result are also added. If one of the functions is changed, the other | 4198 // result are also added. If one of the functions is changed, the other |
4199 // should be. | 4199 // should be. |
4200 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( | 4200 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( |
4201 Handle<JSObject> object, | 4201 Handle<JSObject> object, |
4202 Handle<Name> name, | 4202 Handle<Name> name, |
4203 Handle<Object> value, | 4203 Handle<Object> value, |
4204 PropertyAttributes attributes, | 4204 PropertyAttributes attributes, |
4205 StoreMode mode, | 4205 StoreMode mode, |
4206 ExtensibilityCheck extensibility_check, | 4206 ExtensibilityCheck extensibility_check, |
4207 StoreFromKeyed store_from_keyed, | 4207 StoreFromKeyed store_from_keyed) { |
4208 ExecutableAccessorInfoHandling handling) { | |
4209 Isolate* isolate = object->GetIsolate(); | 4208 Isolate* isolate = object->GetIsolate(); |
4210 | 4209 |
4211 // Make sure that the top context does not change when doing callbacks or | 4210 // Make sure that the top context does not change when doing callbacks or |
4212 // interceptor calls. | 4211 // interceptor calls. |
4213 AssertNoContextChange ncc(isolate); | 4212 AssertNoContextChange ncc(isolate); |
4214 | 4213 |
4215 LookupResult lookup(isolate); | 4214 LookupResult lookup(isolate); |
4216 object->LookupOwn(name, &lookup, true); | 4215 object->LookupOwn(name, &lookup, true); |
4217 if (!lookup.IsFound()) { | 4216 if (!lookup.IsFound()) { |
4218 object->map()->LookupTransition(*object, *name, &lookup); | 4217 object->map()->LookupTransition(*object, *name, &lookup); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4253 PropertyAttributes old_attributes = ABSENT; | 4252 PropertyAttributes old_attributes = ABSENT; |
4254 bool is_observed = object->map()->is_observed() && | 4253 bool is_observed = object->map()->is_observed() && |
4255 *name != isolate->heap()->hidden_string(); | 4254 *name != isolate->heap()->hidden_string(); |
4256 if (is_observed && lookup.IsProperty()) { | 4255 if (is_observed && lookup.IsProperty()) { |
4257 if (lookup.IsDataProperty()) { | 4256 if (lookup.IsDataProperty()) { |
4258 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); | 4257 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); |
4259 } | 4258 } |
4260 old_attributes = lookup.GetAttributes(); | 4259 old_attributes = lookup.GetAttributes(); |
4261 } | 4260 } |
4262 | 4261 |
4263 bool executed_set_prototype = false; | |
4264 | |
4265 // Check of IsReadOnly removed from here in clone. | 4262 // Check of IsReadOnly removed from here in clone. |
4266 if (lookup.IsTransition()) { | 4263 if (lookup.IsTransition()) { |
4267 Handle<Object> result; | 4264 Handle<Object> result; |
4268 ASSIGN_RETURN_ON_EXCEPTION( | 4265 ASSIGN_RETURN_ON_EXCEPTION( |
4269 isolate, result, | 4266 isolate, result, |
4270 SetPropertyUsingTransition( | 4267 SetPropertyUsingTransition( |
4271 handle(lookup.holder()), &lookup, name, value, attributes), | 4268 handle(lookup.holder()), &lookup, name, value, attributes), |
4272 Object); | 4269 Object); |
4273 } else { | 4270 } else { |
4274 switch (lookup.type()) { | 4271 switch (lookup.type()) { |
4275 case NORMAL: | 4272 case NORMAL: |
4276 ReplaceSlowProperty(object, name, value, attributes); | 4273 ReplaceSlowProperty(object, name, value, attributes); |
4277 break; | 4274 break; |
4278 case FIELD: | 4275 case FIELD: |
4279 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); | 4276 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); |
4280 break; | 4277 break; |
4281 case CONSTANT: | 4278 case CONSTANT: |
4282 // Only replace the constant if necessary. | 4279 // Only replace the constant if necessary. |
4283 if (lookup.GetAttributes() != attributes || | 4280 if (lookup.GetAttributes() != attributes || |
4284 *value != lookup.GetConstant()) { | 4281 *value != lookup.GetConstant()) { |
4285 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); | 4282 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); |
4286 } | 4283 } |
4287 break; | 4284 break; |
4288 case CALLBACKS: | 4285 case CALLBACKS: { |
4289 { | |
4290 Handle<Object> callback(lookup.GetCallbackObject(), isolate); | 4286 Handle<Object> callback(lookup.GetCallbackObject(), isolate); |
4291 if (callback->IsExecutableAccessorInfo() && | 4287 if (callback->IsExecutableAccessorInfo()) { |
4292 handling == DONT_FORCE_FIELD) { | |
4293 Handle<Object> result; | 4288 Handle<Object> result; |
4294 ASSIGN_RETURN_ON_EXCEPTION( | 4289 ASSIGN_RETURN_ON_EXCEPTION( |
4295 isolate, result, | 4290 isolate, result, |
4296 JSObject::SetPropertyWithCallback(object, | 4291 JSObject::SetPropertyWithCallback(object, |
4297 name, | 4292 name, |
4298 value, | 4293 value, |
4299 handle(lookup.holder()), | 4294 handle(lookup.holder()), |
4300 callback, | 4295 callback, |
4301 STRICT), | 4296 STRICT), |
4302 Object); | 4297 Object); |
4303 | 4298 |
4304 if (attributes != lookup.GetAttributes()) { | 4299 if (attributes == lookup.GetAttributes()) return result; |
4305 Handle<ExecutableAccessorInfo> new_data = | 4300 |
4306 Accessors::CloneAccessor( | 4301 Handle<ExecutableAccessorInfo> new_data = |
4307 isolate, Handle<ExecutableAccessorInfo>::cast(callback)); | 4302 Accessors::CloneAccessor( |
4308 new_data->set_property_attributes(attributes); | 4303 isolate, Handle<ExecutableAccessorInfo>::cast(callback)); |
4309 if (attributes & READ_ONLY) { | 4304 new_data->set_property_attributes(attributes); |
4310 // This way we don't have to introduce a lookup to the setter, | 4305 // This way we don't have to introduce a lookup to the setter, simply |
4311 // simply make it unavailable to reflect the attributes. | 4306 // make it unavailable to reflect the attributes. |
4312 new_data->clear_setter(); | 4307 if (attributes & READ_ONLY) new_data->clear_setter(); |
| 4308 SetPropertyCallback(object, name, new_data, attributes); |
| 4309 |
| 4310 if (is_observed) { |
| 4311 Handle<Object> new_value = |
| 4312 Object::GetPropertyOrElement(object, name).ToHandleChecked(); |
| 4313 if (old_value->SameValue(*new_value)) { |
| 4314 old_value = isolate->factory()->the_hole_value(); |
4313 } | 4315 } |
| 4316 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 4317 } |
4314 | 4318 |
4315 SetPropertyCallback(object, name, new_data, attributes); | 4319 return result; |
4316 } | |
4317 if (is_observed) { | |
4318 // If we are setting the prototype of a function and are observed, | |
4319 // don't send change records because the prototype handles that | |
4320 // itself. | |
4321 executed_set_prototype = object->IsJSFunction() && | |
4322 String::Equals(isolate->factory()->prototype_string(), | |
4323 Handle<String>::cast(name)) && | |
4324 Handle<JSFunction>::cast(object)->should_have_prototype(); | |
4325 } | |
4326 } else { | |
4327 ConvertAndSetOwnProperty(&lookup, name, value, attributes); | |
4328 } | 4320 } |
| 4321 ConvertAndSetOwnProperty(&lookup, name, value, attributes); |
4329 break; | 4322 break; |
4330 } | 4323 } |
4331 case NONEXISTENT: | 4324 case NONEXISTENT: |
4332 case HANDLER: | 4325 case HANDLER: |
4333 case INTERCEPTOR: | 4326 case INTERCEPTOR: |
4334 UNREACHABLE(); | 4327 UNREACHABLE(); |
4335 } | 4328 } |
4336 } | 4329 } |
4337 | 4330 |
4338 if (is_observed && !executed_set_prototype) { | 4331 if (is_observed) { |
4339 if (lookup.IsTransition()) { | 4332 if (lookup.IsTransition()) { |
4340 EnqueueChangeRecord(object, "add", name, old_value); | 4333 EnqueueChangeRecord(object, "add", name, old_value); |
4341 } else if (old_value->IsTheHole()) { | 4334 } else if (old_value->IsTheHole()) { |
4342 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 4335 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
4343 } else { | 4336 } else { |
4344 LookupResult new_lookup(isolate); | 4337 LookupResult new_lookup(isolate); |
4345 object->LookupOwn(name, &new_lookup, true); | 4338 object->LookupOwn(name, &new_lookup, true); |
4346 bool value_changed = false; | 4339 bool value_changed = false; |
4347 if (new_lookup.IsDataProperty()) { | 4340 if (new_lookup.IsDataProperty()) { |
4348 Handle<Object> new_value = | 4341 Handle<Object> new_value = |
(...skipping 12594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16943 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16936 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16944 static const char* error_messages_[] = { | 16937 static const char* error_messages_[] = { |
16945 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16938 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16946 }; | 16939 }; |
16947 #undef ERROR_MESSAGES_TEXTS | 16940 #undef ERROR_MESSAGES_TEXTS |
16948 return error_messages_[reason]; | 16941 return error_messages_[reason]; |
16949 } | 16942 } |
16950 | 16943 |
16951 | 16944 |
16952 } } // namespace v8::internal | 16945 } } // namespace v8::internal |
OLD | NEW |