| 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 4201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4212 // result are also added. If one of the functions is changed, the other | 4212 // result are also added. If one of the functions is changed, the other |
| 4213 // should be. | 4213 // should be. |
| 4214 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( | 4214 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( |
| 4215 Handle<JSObject> object, | 4215 Handle<JSObject> object, |
| 4216 Handle<Name> name, | 4216 Handle<Name> name, |
| 4217 Handle<Object> value, | 4217 Handle<Object> value, |
| 4218 PropertyAttributes attributes, | 4218 PropertyAttributes attributes, |
| 4219 ValueType value_type, | 4219 ValueType value_type, |
| 4220 StoreMode mode, | 4220 StoreMode mode, |
| 4221 ExtensibilityCheck extensibility_check, | 4221 ExtensibilityCheck extensibility_check, |
| 4222 StoreFromKeyed store_from_keyed) { | 4222 StoreFromKeyed store_from_keyed, |
| 4223 ExecutableAccessorInfoHandling handling) { |
| 4223 Isolate* isolate = object->GetIsolate(); | 4224 Isolate* isolate = object->GetIsolate(); |
| 4224 | 4225 |
| 4225 // Make sure that the top context does not change when doing callbacks or | 4226 // Make sure that the top context does not change when doing callbacks or |
| 4226 // interceptor calls. | 4227 // interceptor calls. |
| 4227 AssertNoContextChange ncc(isolate); | 4228 AssertNoContextChange ncc(isolate); |
| 4228 | 4229 |
| 4229 LookupResult lookup(isolate); | 4230 LookupResult lookup(isolate); |
| 4230 object->LookupOwn(name, &lookup, true); | 4231 object->LookupOwn(name, &lookup, true); |
| 4231 if (!lookup.IsFound()) { | 4232 if (!lookup.IsFound()) { |
| 4232 object->map()->LookupTransition(*object, *name, &lookup); | 4233 object->map()->LookupTransition(*object, *name, &lookup); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4267 PropertyAttributes old_attributes = ABSENT; | 4268 PropertyAttributes old_attributes = ABSENT; |
| 4268 bool is_observed = object->map()->is_observed() && | 4269 bool is_observed = object->map()->is_observed() && |
| 4269 *name != isolate->heap()->hidden_string(); | 4270 *name != isolate->heap()->hidden_string(); |
| 4270 if (is_observed && lookup.IsProperty()) { | 4271 if (is_observed && lookup.IsProperty()) { |
| 4271 if (lookup.IsDataProperty()) { | 4272 if (lookup.IsDataProperty()) { |
| 4272 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); | 4273 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); |
| 4273 } | 4274 } |
| 4274 old_attributes = lookup.GetAttributes(); | 4275 old_attributes = lookup.GetAttributes(); |
| 4275 } | 4276 } |
| 4276 | 4277 |
| 4278 bool executed_set_prototype = false; |
| 4279 |
| 4277 // Check of IsReadOnly removed from here in clone. | 4280 // Check of IsReadOnly removed from here in clone. |
| 4278 if (lookup.IsTransition()) { | 4281 if (lookup.IsTransition()) { |
| 4279 Handle<Object> result; | 4282 Handle<Object> result; |
| 4280 ASSIGN_RETURN_ON_EXCEPTION( | 4283 ASSIGN_RETURN_ON_EXCEPTION( |
| 4281 isolate, result, | 4284 isolate, result, |
| 4282 SetPropertyUsingTransition( | 4285 SetPropertyUsingTransition( |
| 4283 handle(lookup.holder()), &lookup, name, value, attributes), | 4286 handle(lookup.holder()), &lookup, name, value, attributes), |
| 4284 Object); | 4287 Object); |
| 4285 } else { | 4288 } else { |
| 4286 switch (lookup.type()) { | 4289 switch (lookup.type()) { |
| 4287 case NORMAL: | 4290 case NORMAL: |
| 4288 ReplaceSlowProperty(object, name, value, attributes); | 4291 ReplaceSlowProperty(object, name, value, attributes); |
| 4289 break; | 4292 break; |
| 4290 case FIELD: | 4293 case FIELD: |
| 4291 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); | 4294 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); |
| 4292 break; | 4295 break; |
| 4293 case CONSTANT: | 4296 case CONSTANT: |
| 4294 // Only replace the constant if necessary. | 4297 // Only replace the constant if necessary. |
| 4295 if (lookup.GetAttributes() != attributes || | 4298 if (lookup.GetAttributes() != attributes || |
| 4296 *value != lookup.GetConstant()) { | 4299 *value != lookup.GetConstant()) { |
| 4297 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); | 4300 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); |
| 4298 } | 4301 } |
| 4299 break; | 4302 break; |
| 4300 case CALLBACKS: { | 4303 case CALLBACKS: |
| 4304 { |
| 4301 Handle<Object> callback(lookup.GetCallbackObject(), isolate); | 4305 Handle<Object> callback(lookup.GetCallbackObject(), isolate); |
| 4302 if (callback->IsExecutableAccessorInfo()) { | 4306 if (callback->IsExecutableAccessorInfo() && |
| 4307 handling == DONT_FORCE_FIELD) { |
| 4303 Handle<Object> result; | 4308 Handle<Object> result; |
| 4304 ASSIGN_RETURN_ON_EXCEPTION( | 4309 ASSIGN_RETURN_ON_EXCEPTION( |
| 4305 isolate, result, | 4310 isolate, result, |
| 4306 JSObject::SetPropertyWithCallback(object, | 4311 JSObject::SetPropertyWithCallback(object, |
| 4307 name, | 4312 name, |
| 4308 value, | 4313 value, |
| 4309 handle(lookup.holder()), | 4314 handle(lookup.holder()), |
| 4310 callback, | 4315 callback, |
| 4311 STRICT), | 4316 STRICT), |
| 4312 Object); | 4317 Object); |
| 4313 | 4318 |
| 4314 if (attributes == lookup.GetAttributes()) return result; | 4319 if (attributes != lookup.GetAttributes()) { |
| 4320 Handle<ExecutableAccessorInfo> new_data = |
| 4321 Accessors::CloneAccessor( |
| 4322 isolate, Handle<ExecutableAccessorInfo>::cast(callback)); |
| 4323 new_data->set_property_attributes(attributes); |
| 4324 if (attributes & READ_ONLY) { |
| 4325 // This way we don't have to introduce a lookup to the setter, |
| 4326 // simply make it unavailable to reflect the attributes. |
| 4327 new_data->clear_setter(); |
| 4328 } |
| 4315 | 4329 |
| 4316 Handle<ExecutableAccessorInfo> new_data = | 4330 SetPropertyCallback(object, name, new_data, attributes); |
| 4317 Accessors::CloneAccessor( | 4331 } |
| 4318 isolate, Handle<ExecutableAccessorInfo>::cast(callback)); | |
| 4319 new_data->set_property_attributes(attributes); | |
| 4320 // This way we don't have to introduce a lookup to the setter, simply | |
| 4321 // make it unavailable to reflect the attributes. | |
| 4322 if (attributes & READ_ONLY) new_data->clear_setter(); | |
| 4323 SetPropertyCallback(object, name, new_data, attributes); | |
| 4324 | |
| 4325 if (is_observed) { | 4332 if (is_observed) { |
| 4326 Handle<Object> new_value = | 4333 // If we are setting the prototype of a function and are observed, |
| 4327 Object::GetPropertyOrElement(object, name).ToHandleChecked(); | 4334 // don't send change records because the prototype handles that |
| 4328 if (old_value->SameValue(*new_value)) { | 4335 // itself. |
| 4329 old_value = isolate->factory()->the_hole_value(); | 4336 executed_set_prototype = object->IsJSFunction() && |
| 4330 } | 4337 String::Equals(isolate->factory()->prototype_string(), |
| 4331 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 4338 Handle<String>::cast(name)) && |
| 4339 Handle<JSFunction>::cast(object)->should_have_prototype(); |
| 4332 } | 4340 } |
| 4333 | 4341 } else { |
| 4334 return result; | 4342 ConvertAndSetOwnProperty(&lookup, name, value, attributes); |
| 4335 } | 4343 } |
| 4336 ConvertAndSetOwnProperty(&lookup, name, value, attributes); | |
| 4337 break; | 4344 break; |
| 4338 } | 4345 } |
| 4339 case NONEXISTENT: | 4346 case NONEXISTENT: |
| 4340 case HANDLER: | 4347 case HANDLER: |
| 4341 case INTERCEPTOR: | 4348 case INTERCEPTOR: |
| 4342 UNREACHABLE(); | 4349 UNREACHABLE(); |
| 4343 } | 4350 } |
| 4344 } | 4351 } |
| 4345 | 4352 |
| 4346 if (is_observed) { | 4353 if (is_observed && !executed_set_prototype) { |
| 4347 if (lookup.IsTransition()) { | 4354 if (lookup.IsTransition()) { |
| 4348 EnqueueChangeRecord(object, "add", name, old_value); | 4355 EnqueueChangeRecord(object, "add", name, old_value); |
| 4349 } else if (old_value->IsTheHole()) { | 4356 } else if (old_value->IsTheHole()) { |
| 4350 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 4357 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 4351 } else { | 4358 } else { |
| 4352 LookupResult new_lookup(isolate); | 4359 LookupResult new_lookup(isolate); |
| 4353 object->LookupOwn(name, &new_lookup, true); | 4360 object->LookupOwn(name, &new_lookup, true); |
| 4354 bool value_changed = false; | 4361 bool value_changed = false; |
| 4355 if (new_lookup.IsDataProperty()) { | 4362 if (new_lookup.IsDataProperty()) { |
| 4356 Handle<Object> new_value = | 4363 Handle<Object> new_value = |
| (...skipping 12612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16969 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16976 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16970 static const char* error_messages_[] = { | 16977 static const char* error_messages_[] = { |
| 16971 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16978 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16972 }; | 16979 }; |
| 16973 #undef ERROR_MESSAGES_TEXTS | 16980 #undef ERROR_MESSAGES_TEXTS |
| 16974 return error_messages_[reason]; | 16981 return error_messages_[reason]; |
| 16975 } | 16982 } |
| 16976 | 16983 |
| 16977 | 16984 |
| 16978 } } // namespace v8::internal | 16985 } } // namespace v8::internal |
| OLD | NEW |