| 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 "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "accessors.h" | 7 #include "accessors.h" |
| 8 #include "allocation-site-scopes.h" | 8 #include "allocation-site-scopes.h" |
| 9 #include "api.h" | 9 #include "api.h" |
| 10 #include "arguments.h" | 10 #include "arguments.h" |
| (...skipping 4317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4328 return result; | 4328 return result; |
| 4329 } | 4329 } |
| 4330 | 4330 |
| 4331 | 4331 |
| 4332 // Set a real own property, even if it is READ_ONLY. If the property is not | 4332 // Set a real own property, even if it is READ_ONLY. If the property is not |
| 4333 // present, add it with attributes NONE. This code is an exact clone of | 4333 // present, add it with attributes NONE. This code is an exact clone of |
| 4334 // SetProperty, with the check for IsReadOnly and the check for a | 4334 // SetProperty, with the check for IsReadOnly and the check for a |
| 4335 // callback setter removed. The two lines looking up the LookupResult | 4335 // callback setter removed. The two lines looking up the LookupResult |
| 4336 // result are also added. If one of the functions is changed, the other | 4336 // result are also added. If one of the functions is changed, the other |
| 4337 // should be. | 4337 // should be. |
| 4338 // Note that this method cannot be used to set the prototype of a function | |
| 4339 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" | |
| 4340 // doesn't handle function prototypes correctly. | |
| 4341 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( | 4338 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( |
| 4342 Handle<JSObject> object, | 4339 Handle<JSObject> object, |
| 4343 Handle<Name> name, | 4340 Handle<Name> name, |
| 4344 Handle<Object> value, | 4341 Handle<Object> value, |
| 4345 PropertyAttributes attributes, | 4342 PropertyAttributes attributes, |
| 4346 ValueType value_type, | 4343 ValueType value_type, |
| 4347 StoreMode mode, | 4344 StoreMode mode, |
| 4348 ExtensibilityCheck extensibility_check, | 4345 ExtensibilityCheck extensibility_check, |
| 4349 StoreFromKeyed store_from_keyed) { | 4346 StoreFromKeyed store_from_keyed, |
| 4347 ExecutableAccessorInfoHandling handling) { |
| 4350 Isolate* isolate = object->GetIsolate(); | 4348 Isolate* isolate = object->GetIsolate(); |
| 4351 | 4349 |
| 4352 // Make sure that the top context does not change when doing callbacks or | 4350 // Make sure that the top context does not change when doing callbacks or |
| 4353 // interceptor calls. | 4351 // interceptor calls. |
| 4354 AssertNoContextChange ncc(isolate); | 4352 AssertNoContextChange ncc(isolate); |
| 4355 | 4353 |
| 4356 LookupResult lookup(isolate); | 4354 LookupResult lookup(isolate); |
| 4357 object->LookupOwn(name, &lookup, true); | 4355 object->LookupOwn(name, &lookup, true); |
| 4358 if (!lookup.IsFound()) { | 4356 if (!lookup.IsFound()) { |
| 4359 object->map()->LookupTransition(*object, *name, &lookup); | 4357 object->map()->LookupTransition(*object, *name, &lookup); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4394 PropertyAttributes old_attributes = ABSENT; | 4392 PropertyAttributes old_attributes = ABSENT; |
| 4395 bool is_observed = object->map()->is_observed() && | 4393 bool is_observed = object->map()->is_observed() && |
| 4396 *name != isolate->heap()->hidden_string(); | 4394 *name != isolate->heap()->hidden_string(); |
| 4397 if (is_observed && lookup.IsProperty()) { | 4395 if (is_observed && lookup.IsProperty()) { |
| 4398 if (lookup.IsDataProperty()) { | 4396 if (lookup.IsDataProperty()) { |
| 4399 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); | 4397 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); |
| 4400 } | 4398 } |
| 4401 old_attributes = lookup.GetAttributes(); | 4399 old_attributes = lookup.GetAttributes(); |
| 4402 } | 4400 } |
| 4403 | 4401 |
| 4402 bool executed_set_prototype = false; |
| 4403 |
| 4404 // Check of IsReadOnly removed from here in clone. | 4404 // Check of IsReadOnly removed from here in clone. |
| 4405 if (lookup.IsTransition()) { | 4405 if (lookup.IsTransition()) { |
| 4406 Handle<Object> result; | 4406 Handle<Object> result; |
| 4407 ASSIGN_RETURN_ON_EXCEPTION( | 4407 ASSIGN_RETURN_ON_EXCEPTION( |
| 4408 isolate, result, | 4408 isolate, result, |
| 4409 SetPropertyUsingTransition( | 4409 SetPropertyUsingTransition( |
| 4410 handle(lookup.holder()), &lookup, name, value, attributes), | 4410 handle(lookup.holder()), &lookup, name, value, attributes), |
| 4411 Object); | 4411 Object); |
| 4412 } else { | 4412 } else { |
| 4413 switch (lookup.type()) { | 4413 switch (lookup.type()) { |
| 4414 case NORMAL: | 4414 case NORMAL: |
| 4415 ReplaceSlowProperty(object, name, value, attributes); | 4415 ReplaceSlowProperty(object, name, value, attributes); |
| 4416 break; | 4416 break; |
| 4417 case FIELD: | 4417 case FIELD: |
| 4418 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); | 4418 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); |
| 4419 break; | 4419 break; |
| 4420 case CONSTANT: | 4420 case CONSTANT: |
| 4421 // Only replace the constant if necessary. | 4421 // Only replace the constant if necessary. |
| 4422 if (lookup.GetAttributes() != attributes || | 4422 if (lookup.GetAttributes() != attributes || |
| 4423 *value != lookup.GetConstant()) { | 4423 *value != lookup.GetConstant()) { |
| 4424 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); | 4424 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); |
| 4425 } | 4425 } |
| 4426 break; | 4426 break; |
| 4427 case CALLBACKS: | 4427 case CALLBACKS: |
| 4428 ConvertAndSetOwnProperty(&lookup, name, value, attributes); | 4428 { |
| 4429 Handle<Object> callback(lookup.GetCallbackObject(), isolate); |
| 4430 if (callback->IsExecutableAccessorInfo() && |
| 4431 handling == DONT_FORCE_FIELD) { |
| 4432 Handle<Object> result; |
| 4433 ASSIGN_RETURN_ON_EXCEPTION( |
| 4434 isolate, result, |
| 4435 JSObject::SetPropertyWithCallback(object, |
| 4436 name, |
| 4437 value, |
| 4438 handle(lookup.holder()), |
| 4439 callback, |
| 4440 STRICT), |
| 4441 Object); |
| 4442 |
| 4443 if (attributes != lookup.GetAttributes()) { |
| 4444 Handle<ExecutableAccessorInfo> new_data = |
| 4445 Accessors::CloneAccessor( |
| 4446 isolate, Handle<ExecutableAccessorInfo>::cast(callback)); |
| 4447 new_data->set_property_attributes(attributes); |
| 4448 if (attributes & READ_ONLY) { |
| 4449 // This way we don't have to introduce a lookup to the setter, |
| 4450 // simply make it unavailable to reflect the attributes. |
| 4451 new_data->clear_setter(); |
| 4452 } |
| 4453 |
| 4454 SetPropertyCallback(object, name, new_data, attributes); |
| 4455 } |
| 4456 if (is_observed) { |
| 4457 // If we are setting the prototype of a function and are observed, |
| 4458 // don't send change records because the prototype handles that |
| 4459 // itself. |
| 4460 executed_set_prototype = object->IsJSFunction() && |
| 4461 String::Equals(isolate->factory()->prototype_string(), |
| 4462 Handle<String>::cast(name)) && |
| 4463 Handle<JSFunction>::cast(object)->should_have_prototype(); |
| 4464 } |
| 4465 } else { |
| 4466 ConvertAndSetOwnProperty(&lookup, name, value, attributes); |
| 4467 } |
| 4429 break; | 4468 break; |
| 4469 } |
| 4430 case NONEXISTENT: | 4470 case NONEXISTENT: |
| 4431 case HANDLER: | 4471 case HANDLER: |
| 4432 case INTERCEPTOR: | 4472 case INTERCEPTOR: |
| 4433 UNREACHABLE(); | 4473 UNREACHABLE(); |
| 4434 } | 4474 } |
| 4435 } | 4475 } |
| 4436 | 4476 |
| 4437 if (is_observed) { | 4477 if (is_observed && !executed_set_prototype) { |
| 4438 if (lookup.IsTransition()) { | 4478 if (lookup.IsTransition()) { |
| 4439 EnqueueChangeRecord(object, "add", name, old_value); | 4479 EnqueueChangeRecord(object, "add", name, old_value); |
| 4440 } else if (old_value->IsTheHole()) { | 4480 } else if (old_value->IsTheHole()) { |
| 4441 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 4481 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 4442 } else { | 4482 } else { |
| 4443 LookupResult new_lookup(isolate); | 4483 LookupResult new_lookup(isolate); |
| 4444 object->LookupOwn(name, &new_lookup, true); | 4484 object->LookupOwn(name, &new_lookup, true); |
| 4445 bool value_changed = false; | 4485 bool value_changed = false; |
| 4446 if (new_lookup.IsDataProperty()) { | 4486 if (new_lookup.IsDataProperty()) { |
| 4447 Handle<Object> new_value = | 4487 Handle<Object> new_value = |
| (...skipping 12807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17255 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17295 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 17256 static const char* error_messages_[] = { | 17296 static const char* error_messages_[] = { |
| 17257 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17297 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 17258 }; | 17298 }; |
| 17259 #undef ERROR_MESSAGES_TEXTS | 17299 #undef ERROR_MESSAGES_TEXTS |
| 17260 return error_messages_[reason]; | 17300 return error_messages_[reason]; |
| 17261 } | 17301 } |
| 17262 | 17302 |
| 17263 | 17303 |
| 17264 } } // namespace v8::internal | 17304 } } // namespace v8::internal |
| OLD | NEW |