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

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: Addressed comments. Created 6 years, 7 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 4300 matching lines...) Expand 10 before | Expand all | Expand 10 after
4311 return result; 4311 return result;
4312 } 4312 }
4313 4313
4314 4314
4315 // Set a real local property, even if it is READ_ONLY. If the property is not 4315 // Set a real local property, even if it is READ_ONLY. If the property is not
4316 // present, add it with attributes NONE. This code is an exact clone of 4316 // present, add it with attributes NONE. This code is an exact clone of
4317 // SetProperty, with the check for IsReadOnly and the check for a 4317 // SetProperty, with the check for IsReadOnly and the check for a
4318 // callback setter removed. The two lines looking up the LookupResult 4318 // callback setter removed. The two lines looking up the LookupResult
4319 // result are also added. If one of the functions is changed, the other 4319 // result are also added. If one of the functions is changed, the other
4320 // should be. 4320 // should be.
4321 // Note that this method cannot be used to set the prototype of a function
4322 // because ConvertDescriptorToField() which is called in "case CALLBACKS:"
4323 // doesn't handle function prototypes correctly.
4324 MaybeHandle<Object> JSObject::SetLocalPropertyIgnoreAttributes( 4321 MaybeHandle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
4325 Handle<JSObject> object, 4322 Handle<JSObject> object,
4326 Handle<Name> name, 4323 Handle<Name> name,
4327 Handle<Object> value, 4324 Handle<Object> value,
4328 PropertyAttributes attributes, 4325 PropertyAttributes attributes,
4329 ValueType value_type, 4326 ValueType value_type,
4330 StoreMode mode, 4327 StoreMode mode,
4331 ExtensibilityCheck extensibility_check, 4328 ExtensibilityCheck extensibility_check,
4332 StoreFromKeyed store_from_keyed) { 4329 StoreFromKeyed store_from_keyed,
4330 ExecutableAccessorInfoHandling handling) {
4333 Isolate* isolate = object->GetIsolate(); 4331 Isolate* isolate = object->GetIsolate();
4334 4332
4335 // Make sure that the top context does not change when doing callbacks or 4333 // Make sure that the top context does not change when doing callbacks or
4336 // interceptor calls. 4334 // interceptor calls.
4337 AssertNoContextChange ncc(isolate); 4335 AssertNoContextChange ncc(isolate);
4338 4336
4339 LookupResult lookup(isolate); 4337 LookupResult lookup(isolate);
4340 object->LocalLookup(name, &lookup, true); 4338 object->LocalLookup(name, &lookup, true);
4341 if (!lookup.IsFound()) { 4339 if (!lookup.IsFound()) {
4342 object->map()->LookupTransition(*object, *name, &lookup); 4340 object->map()->LookupTransition(*object, *name, &lookup);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4377 PropertyAttributes old_attributes = ABSENT; 4375 PropertyAttributes old_attributes = ABSENT;
4378 bool is_observed = object->map()->is_observed() && 4376 bool is_observed = object->map()->is_observed() &&
4379 *name != isolate->heap()->hidden_string(); 4377 *name != isolate->heap()->hidden_string();
4380 if (is_observed && lookup.IsProperty()) { 4378 if (is_observed && lookup.IsProperty()) {
4381 if (lookup.IsDataProperty()) { 4379 if (lookup.IsDataProperty()) {
4382 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked(); 4380 old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked();
4383 } 4381 }
4384 old_attributes = lookup.GetAttributes(); 4382 old_attributes = lookup.GetAttributes();
4385 } 4383 }
4386 4384
4385 bool dont_enqueue_records = false;
4386
4387 // Check of IsReadOnly removed from here in clone. 4387 // Check of IsReadOnly removed from here in clone.
4388 if (lookup.IsTransition()) { 4388 if (lookup.IsTransition()) {
4389 Handle<Object> result; 4389 Handle<Object> result;
4390 ASSIGN_RETURN_ON_EXCEPTION( 4390 ASSIGN_RETURN_ON_EXCEPTION(
4391 isolate, result, 4391 isolate, result,
4392 SetPropertyUsingTransition( 4392 SetPropertyUsingTransition(
4393 handle(lookup.holder()), &lookup, name, value, attributes), 4393 handle(lookup.holder()), &lookup, name, value, attributes),
4394 Object); 4394 Object);
4395 } else { 4395 } else {
4396 switch (lookup.type()) { 4396 switch (lookup.type()) {
4397 case NORMAL: 4397 case NORMAL:
4398 ReplaceSlowProperty(object, name, value, attributes); 4398 ReplaceSlowProperty(object, name, value, attributes);
4399 break; 4399 break;
4400 case FIELD: 4400 case FIELD:
4401 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); 4401 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
4402 break; 4402 break;
4403 case CONSTANT: 4403 case CONSTANT:
4404 // Only replace the constant if necessary. 4404 // Only replace the constant if necessary.
4405 if (lookup.GetAttributes() != attributes || 4405 if (lookup.GetAttributes() != attributes ||
4406 *value != lookup.GetConstant()) { 4406 *value != lookup.GetConstant()) {
4407 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); 4407 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
4408 } 4408 }
4409 break; 4409 break;
4410 case CALLBACKS: 4410 case CALLBACKS:
4411 ConvertAndSetLocalProperty(&lookup, name, value, attributes); 4411 {
4412 Handle<Object> callback(lookup.GetCallbackObject(), isolate);
4413 if (callback->IsExecutableAccessorInfo() &&
4414 handling == DONT_FORCE_FIELD) {
4415 Handle<Object> result;
4416 ASSIGN_RETURN_ON_EXCEPTION(
4417 isolate, result,
4418 JSObject::SetPropertyWithCallback(object,
4419 callback,
4420 name,
4421 value,
4422 handle(lookup.holder()),
4423 STRICT),
4424 Object);
4425
4426 if (attributes != lookup.GetAttributes()) {
4427 Handle<ExecutableAccessorInfo> new_data =
4428 Accessors::CloneAccessor(
4429 isolate, Handle<ExecutableAccessorInfo>::cast(callback));
4430 new_data->set_property_attributes(attributes);
4431 if (attributes & READ_ONLY) {
4432 // This way we don't have to introduce a lookup to the setter,
4433 // simply make it unavailable to reflect the attributes.
4434 new_data->clear_setter();
4435 }
4436
4437 SetPropertyCallback(object, name, new_data, attributes);
4438 } else if (is_observed) {
ulan 2014/05/23 10:14:48 Shouldn't we check is_observed independent of (att
mvstanton 2014/05/27 13:31:24 Good catch. And I renamed the variable from dont_e
4439 // If we are setting the prototype of a function and are observed,
4440 // don't send change records because the prototype handles that
4441 // itself.
4442 dont_enqueue_records = object->IsJSFunction() &&
4443 String::Equals(isolate->factory()->prototype_string(),
4444 Handle<String>::cast(name)) &&
4445 Handle<JSFunction>::cast(object)->should_have_prototype();
4446 }
4447 } else {
4448 ConvertAndSetLocalProperty(&lookup, name, value, attributes);
4449 }
4412 break; 4450 break;
4451 }
4413 case NONEXISTENT: 4452 case NONEXISTENT:
4414 case HANDLER: 4453 case HANDLER:
4415 case INTERCEPTOR: 4454 case INTERCEPTOR:
4416 UNREACHABLE(); 4455 UNREACHABLE();
4417 } 4456 }
4418 } 4457 }
4419 4458
4420 if (is_observed) { 4459 if (is_observed && !dont_enqueue_records) {
4421 if (lookup.IsTransition()) { 4460 if (lookup.IsTransition()) {
4422 EnqueueChangeRecord(object, "add", name, old_value); 4461 EnqueueChangeRecord(object, "add", name, old_value);
4423 } else if (old_value->IsTheHole()) { 4462 } else if (old_value->IsTheHole()) {
4424 EnqueueChangeRecord(object, "reconfigure", name, old_value); 4463 EnqueueChangeRecord(object, "reconfigure", name, old_value);
4425 } else { 4464 } else {
4426 LookupResult new_lookup(isolate); 4465 LookupResult new_lookup(isolate);
4427 object->LocalLookup(name, &new_lookup, true); 4466 object->LocalLookup(name, &new_lookup, true);
4428 bool value_changed = false; 4467 bool value_changed = false;
4429 if (new_lookup.IsDataProperty()) { 4468 if (new_lookup.IsDataProperty()) {
4430 Handle<Object> new_value = 4469 Handle<Object> new_value =
(...skipping 12845 matching lines...) Expand 10 before | Expand all | Expand 10 after
17276 #define ERROR_MESSAGES_TEXTS(C, T) T, 17315 #define ERROR_MESSAGES_TEXTS(C, T) T,
17277 static const char* error_messages_[] = { 17316 static const char* error_messages_[] = {
17278 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 17317 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
17279 }; 17318 };
17280 #undef ERROR_MESSAGES_TEXTS 17319 #undef ERROR_MESSAGES_TEXTS
17281 return error_messages_[reason]; 17320 return error_messages_[reason];
17282 } 17321 }
17283 17322
17284 17323
17285 } } // namespace v8::internal 17324 } } // 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