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

Side by Side Diff: src/objects.cc

Issue 11358234: Object.observe: Handle oldValue for elements with accessors properly. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments. Created 8 years, 1 month 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/runtime.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 4114 matching lines...) Expand 10 before | Expand all | Expand 10 after
4125 if (proto->IsNull()) return isolate->heap()->false_value(); 4125 if (proto->IsNull()) return isolate->heap()->false_value();
4126 ASSERT(proto->IsJSGlobalObject()); 4126 ASSERT(proto->IsJSGlobalObject());
4127 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); 4127 return JSGlobalObject::cast(proto)->DeleteElement(index, mode);
4128 } 4128 }
4129 4129
4130 // From this point on everything needs to be handlified. 4130 // From this point on everything needs to be handlified.
4131 HandleScope scope(isolate); 4131 HandleScope scope(isolate);
4132 Handle<JSObject> self(this); 4132 Handle<JSObject> self(this);
4133 4133
4134 Handle<String> name; 4134 Handle<String> name;
4135 Handle<Object> old_value(isolate->heap()->the_hole_value()); 4135 Handle<Object> old_value;
4136 bool preexists = false; 4136 bool preexists = false;
4137 if (FLAG_harmony_observation && map()->is_observed()) { 4137 if (FLAG_harmony_observation && map()->is_observed()) {
4138 name = isolate->factory()->Uint32ToString(index); 4138 name = isolate->factory()->Uint32ToString(index);
4139 preexists = self->HasLocalElement(index); 4139 preexists = self->HasLocalElement(index);
4140 if (preexists) { 4140 if (preexists) {
4141 // TODO(observe): only read & set old_value if it's not an accessor 4141 old_value = GetLocalElementAccessorPair(index) != NULL
4142 old_value = Object::GetElement(self, index); 4142 ? Handle<Object>::cast(isolate->factory()->the_hole_value())
4143 : Object::GetElement(self, index);
4143 } 4144 }
4144 } 4145 }
4145 4146
4146 MaybeObject* result; 4147 MaybeObject* result;
4147 // Skip interceptor if forcing deletion. 4148 // Skip interceptor if forcing deletion.
4148 if (self->HasIndexedInterceptor() && mode != FORCE_DELETION) { 4149 if (self->HasIndexedInterceptor() && mode != FORCE_DELETION) {
4149 result = self->DeleteElementWithInterceptor(index); 4150 result = self->DeleteElementWithInterceptor(index);
4150 } else { 4151 } else {
4151 result = self->GetElementsAccessor()->Delete(*self, index, mode); 4152 result = self->GetElementsAccessor()->Delete(*self, index, mode);
4152 } 4153 }
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after
4879 // From this point on everything needs to be handlified. 4880 // From this point on everything needs to be handlified.
4880 HandleScope scope(GetIsolate()); 4881 HandleScope scope(GetIsolate());
4881 Handle<JSObject> self(this); 4882 Handle<JSObject> self(this);
4882 Handle<String> name(name_raw); 4883 Handle<String> name(name_raw);
4883 Handle<Object> getter(getter_raw); 4884 Handle<Object> getter(getter_raw);
4884 Handle<Object> setter(setter_raw); 4885 Handle<Object> setter(setter_raw);
4885 4886
4886 uint32_t index = 0; 4887 uint32_t index = 0;
4887 bool is_element = name->AsArrayIndex(&index); 4888 bool is_element = name->AsArrayIndex(&index);
4888 4889
4889 Handle<Object> old_value(isolate->heap()->the_hole_value()); 4890 Handle<Object> old_value = isolate->factory()->the_hole_value();
4890 bool preexists = false; 4891 bool preexists = false;
4891 if (FLAG_harmony_observation && map()->is_observed()) { 4892 if (FLAG_harmony_observation && map()->is_observed()) {
4892 if (is_element) { 4893 if (is_element) {
4893 preexists = HasLocalElement(index); 4894 preexists = HasLocalElement(index);
4894 if (preexists) { 4895 if (preexists && GetLocalElementAccessorPair(index) == NULL) {
4895 // TODO(observe): distinguish the case where it's an accessor
4896 old_value = Object::GetElement(self, index); 4896 old_value = Object::GetElement(self, index);
4897 } 4897 }
4898 } else { 4898 } else {
4899 LookupResult lookup(isolate); 4899 LookupResult lookup(isolate);
4900 LocalLookup(*name, &lookup); 4900 LocalLookup(*name, &lookup);
4901 preexists = lookup.IsProperty(); 4901 preexists = lookup.IsProperty();
4902 if (preexists) old_value = handle(lookup.GetLazyValue()); 4902 if (preexists) old_value = handle(lookup.GetLazyValue());
4903 } 4903 }
4904 } 4904 }
4905 4905
(...skipping 4642 matching lines...) Expand 10 before | Expand all | Expand 10 after
9548 EnsureElementsMode mode) { 9548 EnsureElementsMode mode) {
9549 // Elements in |Arguments| are ordered backwards (because they're on the 9549 // Elements in |Arguments| are ordered backwards (because they're on the
9550 // stack), but the method that's called here iterates over them in forward 9550 // stack), but the method that's called here iterates over them in forward
9551 // direction. 9551 // direction.
9552 return EnsureCanContainElements( 9552 return EnsureCanContainElements(
9553 args->arguments() - first_arg - (arg_count - 1), 9553 args->arguments() - first_arg - (arg_count - 1),
9554 arg_count, mode); 9554 arg_count, mode);
9555 } 9555 }
9556 9556
9557 9557
9558 JSObject::LocalElementType JSObject::GetLocalElementType(uint32_t index) { 9558 PropertyType JSObject::GetLocalPropertyType(String* name) {
9559 uint32_t index = 0;
9560 if (name->AsArrayIndex(&index)) {
9561 return GetLocalElementType(index);
9562 }
9563 LookupResult lookup(GetIsolate());
9564 LocalLookup(name, &lookup);
9565 return lookup.type();
9566 }
9567
9568
9569 PropertyType JSObject::GetLocalElementType(uint32_t index) {
9570 return GetElementsAccessor()->GetType(this, this, index);
9571 }
9572
9573
9574 AccessorPair* JSObject::GetLocalPropertyAccessorPair(String* name) {
9575 uint32_t index = 0;
9576 if (name->AsArrayIndex(&index)) {
9577 return GetLocalElementAccessorPair(index);
9578 }
9579 LookupResult lookup(GetIsolate());
9580 LocalLookup(name, &lookup);
9581 if (lookup.IsPropertyCallbacks() &&
9582 lookup.GetCallbackObject()->IsAccessorPair()) {
9583 return AccessorPair::cast(lookup.GetCallbackObject());
9584 }
9585 return NULL;
9586 }
9587
9588
9589 AccessorPair* JSObject::GetLocalElementAccessorPair(uint32_t index) {
9590 return GetElementsAccessor()->GetAccessorPair(this, this, index);
9591 }
9592
9593
9594 JSObject::LocalElementKind JSObject::GetLocalElementKind(uint32_t index) {
9559 // Check access rights if needed. 9595 // Check access rights if needed.
9560 if (IsAccessCheckNeeded()) { 9596 if (IsAccessCheckNeeded()) {
9561 Heap* heap = GetHeap(); 9597 Heap* heap = GetHeap();
9562 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 9598 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
9563 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 9599 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
9564 return UNDEFINED_ELEMENT; 9600 return UNDEFINED_ELEMENT;
9565 } 9601 }
9566 } 9602 }
9567 9603
9568 if (IsJSGlobalProxy()) { 9604 if (IsJSGlobalProxy()) {
9569 Object* proto = GetPrototype(); 9605 Object* proto = GetPrototype();
9570 if (proto->IsNull()) return UNDEFINED_ELEMENT; 9606 if (proto->IsNull()) return UNDEFINED_ELEMENT;
9571 ASSERT(proto->IsJSGlobalObject()); 9607 ASSERT(proto->IsJSGlobalObject());
9572 return JSObject::cast(proto)->GetLocalElementType(index); 9608 return JSObject::cast(proto)->GetLocalElementKind(index);
9573 } 9609 }
9574 9610
9575 // Check for lookup interceptor 9611 // Check for lookup interceptor
9576 if (HasIndexedInterceptor()) { 9612 if (HasIndexedInterceptor()) {
9577 return GetElementAttributeWithInterceptor(this, index, false) != ABSENT 9613 return GetElementAttributeWithInterceptor(this, index, false) != ABSENT
9578 ? INTERCEPTED_ELEMENT : UNDEFINED_ELEMENT; 9614 ? INTERCEPTED_ELEMENT : UNDEFINED_ELEMENT;
9579 } 9615 }
9580 9616
9581 // Handle [] on String objects. 9617 // Handle [] on String objects.
9582 if (this->IsStringObjectWithCharacterAt(index)) { 9618 if (this->IsStringObjectWithCharacterAt(index)) {
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
10315 } 10351 }
10316 10352
10317 // From here on, everything has to be handlified. 10353 // From here on, everything has to be handlified.
10318 Handle<JSObject> self(this); 10354 Handle<JSObject> self(this);
10319 Handle<Object> value(value_raw); 10355 Handle<Object> value(value_raw);
10320 PropertyAttributes old_attributes = self->GetLocalElementAttribute(index); 10356 PropertyAttributes old_attributes = self->GetLocalElementAttribute(index);
10321 Handle<Object> old_value = isolate->factory()->the_hole_value(); 10357 Handle<Object> old_value = isolate->factory()->the_hole_value();
10322 Handle<Object> old_length; 10358 Handle<Object> old_length;
10323 10359
10324 if (old_attributes != ABSENT) { 10360 if (old_attributes != ABSENT) {
10325 // TODO(observe): only read & set old_value if we have a data property 10361 if (GetLocalElementAccessorPair(index) == NULL)
10326 old_value = Object::GetElement(self, index); 10362 old_value = Object::GetElement(self, index);
10327 } else if (self->IsJSArray()) { 10363 } else if (self->IsJSArray()) {
10328 // Store old array length in case adding an element grows the array. 10364 // Store old array length in case adding an element grows the array.
10329 old_length = handle(Handle<JSArray>::cast(self)->length()); 10365 old_length = handle(Handle<JSArray>::cast(self)->length());
10330 } 10366 }
10331 10367
10332 // Check for lookup interceptor 10368 // Check for lookup interceptor
10333 MaybeObject* result = self->HasIndexedInterceptor() 10369 MaybeObject* result = self->HasIndexedInterceptor()
10334 ? self->SetElementWithInterceptor( 10370 ? self->SetElementWithInterceptor(
10335 index, *value, attributes, strict_mode, check_prototype, set_mode) 10371 index, *value, attributes, strict_mode, check_prototype, set_mode)
10336 : self->SetElementWithoutInterceptor( 10372 : self->SetElementWithoutInterceptor(
(...skipping 3522 matching lines...) Expand 10 before | Expand all | Expand 10 after
13859 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13895 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13860 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13896 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13861 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13897 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13862 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13898 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13863 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13899 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13864 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13900 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13865 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13901 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13866 } 13902 }
13867 13903
13868 } } // namespace v8::internal 13904 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698