Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(688)

Side by Side Diff: src/objects.cc

Issue 262053011: Confusion on changing data property callback attributes (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698