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

Side by Side Diff: src/objects.cc

Issue 11338048: Handle Object.observe notifications for setting Array.length (Closed) Base URL: git@github.com:rafaelw/v8@master
Patch Set: Clarify test todo 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
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/harmony/object-observe.js » ('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 1699 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 result = AddSlowProperty(name, value, attributes); 1710 result = AddSlowProperty(name, value, attributes);
1711 } 1711 }
1712 } else { 1712 } else {
1713 result = AddSlowProperty(name, value, attributes); 1713 result = AddSlowProperty(name, value, attributes);
1714 } 1714 }
1715 1715
1716 Handle<Object> hresult; 1716 Handle<Object> hresult;
1717 if (!result->ToHandle(&hresult)) return result; 1717 if (!result->ToHandle(&hresult)) return result;
1718 1718
1719 if (FLAG_harmony_observation && map()->is_observed()) { 1719 if (FLAG_harmony_observation && map()->is_observed()) {
1720 this->EnqueueChangeRecord( 1720 EnqueueChangeRecord(handle(this), "new", handle(name),
1721 "new", handle(name), handle(heap->the_hole_value())); 1721 handle(heap->the_hole_value()));
1722 } 1722 }
1723 1723
1724 return *hresult; 1724 return *hresult;
1725 } 1725 }
1726 1726
1727 1727
1728 void JSObject::EnqueueChangeRecord( 1728 void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
1729 const char* type_str, Handle<String> name, Handle<Object> old_value) { 1729 const char* type_str,
1730 Isolate* isolate = GetIsolate(); 1730 Handle<String> name,
1731 Handle<Object> old_value) {
1732 Isolate* isolate = object->GetIsolate();
1731 HandleScope scope; 1733 HandleScope scope;
1732 Handle<String> type = isolate->factory()->LookupAsciiSymbol(type_str); 1734 Handle<String> type = isolate->factory()->LookupAsciiSymbol(type_str);
1733 Handle<JSObject> object(this);
1734 Handle<Object> args[] = { type, object, name, old_value }; 1735 Handle<Object> args[] = { type, object, name, old_value };
1735 bool threw; 1736 bool threw;
1736 Execution::Call(Handle<JSFunction>(isolate->observers_notify_change()), 1737 Execution::Call(Handle<JSFunction>(isolate->observers_notify_change()),
1737 Handle<Object>(isolate->heap()->undefined_value()), 1738 Handle<Object>(isolate->heap()->undefined_value()),
1738 old_value->IsTheHole() ? 3 : 4, args, 1739 old_value->IsTheHole() ? 3 : 4, args,
1739 &threw); 1740 &threw);
1740 ASSERT(!threw); 1741 ASSERT(!threw);
1741 } 1742 }
1742 1743
1743 1744
(...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after
2991 case HANDLER: 2992 case HANDLER:
2992 case NONEXISTENT: 2993 case NONEXISTENT:
2993 UNREACHABLE(); 2994 UNREACHABLE();
2994 } 2995 }
2995 2996
2996 Handle<Object> hresult; 2997 Handle<Object> hresult;
2997 if (!result->ToHandle(&hresult)) return result; 2998 if (!result->ToHandle(&hresult)) return result;
2998 2999
2999 if (FLAG_harmony_observation && map()->is_observed()) { 3000 if (FLAG_harmony_observation && map()->is_observed()) {
3000 if (lookup->IsTransition()) { 3001 if (lookup->IsTransition()) {
3001 self->EnqueueChangeRecord("new", name, old_value); 3002 EnqueueChangeRecord(self, "new", name, old_value);
3002 } else { 3003 } else {
3003 LookupResult new_lookup(self->GetIsolate()); 3004 LookupResult new_lookup(self->GetIsolate());
3004 self->LocalLookup(*name, &new_lookup); 3005 self->LocalLookup(*name, &new_lookup);
3005 ASSERT(!new_lookup.GetLazyValue()->IsTheHole()); 3006 ASSERT(!new_lookup.GetLazyValue()->IsTheHole());
3006 if (!new_lookup.GetLazyValue()->SameValue(*old_value)) { 3007 if (!new_lookup.GetLazyValue()->SameValue(*old_value)) {
3007 self->EnqueueChangeRecord("updated", name, old_value); 3008 EnqueueChangeRecord(self, "updated", name, old_value);
3008 } 3009 }
3009 } 3010 }
3010 } 3011 }
3011 3012
3012 return *hresult; 3013 return *hresult;
3013 } 3014 }
3014 3015
3015 3016
3016 // Set a real local property, even if it is READ_ONLY. If the property is not 3017 // Set a real local property, even if it is READ_ONLY. If the property is not
3017 // present, add it with attributes NONE. This code is an exact clone of 3018 // present, add it with attributes NONE. This code is an exact clone of
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
3139 case HANDLER: 3140 case HANDLER:
3140 case NONEXISTENT: 3141 case NONEXISTENT:
3141 UNREACHABLE(); 3142 UNREACHABLE();
3142 } 3143 }
3143 3144
3144 Handle<Object> hresult; 3145 Handle<Object> hresult;
3145 if (!result->ToHandle(&hresult)) return result; 3146 if (!result->ToHandle(&hresult)) return result;
3146 3147
3147 if (FLAG_harmony_observation && map()->is_observed()) { 3148 if (FLAG_harmony_observation && map()->is_observed()) {
3148 if (lookup.IsTransition()) { 3149 if (lookup.IsTransition()) {
3149 self->EnqueueChangeRecord("new", name, old_value); 3150 EnqueueChangeRecord(self, "new", name, old_value);
3150 } else { 3151 } else {
3151 LookupResult new_lookup(isolate); 3152 LookupResult new_lookup(isolate);
3152 self->LocalLookup(*name, &new_lookup); 3153 self->LocalLookup(*name, &new_lookup);
3153 ASSERT(!new_lookup.GetLazyValue()->IsTheHole()); 3154 ASSERT(!new_lookup.GetLazyValue()->IsTheHole());
3154 if (old_value->IsTheHole() || 3155 if (old_value->IsTheHole() ||
3155 new_lookup.GetAttributes() != old_attributes) { 3156 new_lookup.GetAttributes() != old_attributes) {
3156 self->EnqueueChangeRecord("reconfigured", name, old_value); 3157 EnqueueChangeRecord(self, "reconfigured", name, old_value);
3157 } else if (!new_lookup.GetLazyValue()->SameValue(*old_value)) { 3158 } else if (!new_lookup.GetLazyValue()->SameValue(*old_value)) {
3158 self->EnqueueChangeRecord("updated", name, old_value); 3159 EnqueueChangeRecord(self, "updated", name, old_value);
3159 } 3160 }
3160 } 3161 }
3161 } 3162 }
3162 3163
3163 return *hresult; 3164 return *hresult;
3164 } 3165 }
3165 3166
3166 3167
3167 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( 3168 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
3168 JSObject* receiver, 3169 JSObject* receiver,
(...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after
4145 result = self->DeleteElementWithInterceptor(index); 4146 result = self->DeleteElementWithInterceptor(index);
4146 } else { 4147 } else {
4147 result = self->GetElementsAccessor()->Delete(*self, index, mode); 4148 result = self->GetElementsAccessor()->Delete(*self, index, mode);
4148 } 4149 }
4149 4150
4150 Handle<Object> hresult; 4151 Handle<Object> hresult;
4151 if (!result->ToHandle(&hresult)) return result; 4152 if (!result->ToHandle(&hresult)) return result;
4152 4153
4153 if (FLAG_harmony_observation && map()->is_observed()) { 4154 if (FLAG_harmony_observation && map()->is_observed()) {
4154 if (preexists && !self->HasLocalElement(index)) 4155 if (preexists && !self->HasLocalElement(index))
4155 self->EnqueueChangeRecord("deleted", name, old_value); 4156 EnqueueChangeRecord(self, "deleted", name, old_value);
4156 } 4157 }
4157 4158
4158 return *hresult; 4159 return *hresult;
4159 } 4160 }
4160 4161
4161 4162
4162 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> obj, 4163 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> obj,
4163 Handle<String> prop) { 4164 Handle<String> prop) {
4164 CALL_HEAP_FUNCTION(obj->GetIsolate(), 4165 CALL_HEAP_FUNCTION(obj->GetIsolate(),
4165 obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION), 4166 obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION),
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
4232 if (!result->To(&obj)) return result; 4233 if (!result->To(&obj)) return result;
4233 // Make sure the properties are normalized before removing the entry. 4234 // Make sure the properties are normalized before removing the entry.
4234 result = self->DeleteNormalizedProperty(*hname, mode); 4235 result = self->DeleteNormalizedProperty(*hname, mode);
4235 } 4236 }
4236 4237
4237 Handle<Object> hresult; 4238 Handle<Object> hresult;
4238 if (!result->ToHandle(&hresult)) return result; 4239 if (!result->ToHandle(&hresult)) return result;
4239 4240
4240 if (FLAG_harmony_observation && map()->is_observed()) { 4241 if (FLAG_harmony_observation && map()->is_observed()) {
4241 if (!self->HasLocalProperty(*hname)) 4242 if (!self->HasLocalProperty(*hname))
4242 self->EnqueueChangeRecord("deleted", hname, old_value); 4243 EnqueueChangeRecord(self, "deleted", hname, old_value);
4243 } 4244 }
4244 4245
4245 return *hresult; 4246 return *hresult;
4246 } 4247 }
4247 4248
4248 4249
4249 MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) { 4250 MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) {
4250 if (IsJSProxy()) { 4251 if (IsJSProxy()) {
4251 return JSProxy::cast(this)->DeleteElementWithHandler(index, mode); 4252 return JSProxy::cast(this)->DeleteElementWithHandler(index, mode);
4252 } 4253 }
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
4899 4900
4900 MaybeObject* result = is_element ? 4901 MaybeObject* result = is_element ?
4901 self->DefineElementAccessor(index, *getter, *setter, attributes) : 4902 self->DefineElementAccessor(index, *getter, *setter, attributes) :
4902 self->DefinePropertyAccessor(*name, *getter, *setter, attributes); 4903 self->DefinePropertyAccessor(*name, *getter, *setter, attributes);
4903 4904
4904 Handle<Object> hresult; 4905 Handle<Object> hresult;
4905 if (!result->ToHandle(&hresult)) return result; 4906 if (!result->ToHandle(&hresult)) return result;
4906 4907
4907 if (FLAG_harmony_observation && map()->is_observed()) { 4908 if (FLAG_harmony_observation && map()->is_observed()) {
4908 const char* type = preexists ? "reconfigured" : "new"; 4909 const char* type = preexists ? "reconfigured" : "new";
4909 self->EnqueueChangeRecord(type, name, old_value); 4910 EnqueueChangeRecord(self, type, name, old_value);
4910 } 4911 }
4911 4912
4912 return *hresult; 4913 return *hresult;
4913 } 4914 }
4914 4915
4915 4916
4916 static MaybeObject* TryAccessorTransition(JSObject* self, 4917 static MaybeObject* TryAccessorTransition(JSObject* self,
4917 Map* transitioned_map, 4918 Map* transitioned_map,
4918 int target_descriptor, 4919 int target_descriptor,
4919 AccessorComponent component, 4920 AccessorComponent component,
(...skipping 5404 matching lines...) Expand 10 before | Expand all | Expand 10 after
10324 index, *value, attributes, strict_mode, check_prototype, set_mode) 10325 index, *value, attributes, strict_mode, check_prototype, set_mode)
10325 : self->SetElementWithoutInterceptor( 10326 : self->SetElementWithoutInterceptor(
10326 index, *value, attributes, strict_mode, check_prototype, set_mode); 10327 index, *value, attributes, strict_mode, check_prototype, set_mode);
10327 10328
10328 Handle<Object> hresult; 10329 Handle<Object> hresult;
10329 if (!result->ToHandle(&hresult)) return result; 10330 if (!result->ToHandle(&hresult)) return result;
10330 10331
10331 if (FLAG_harmony_observation && map()->is_observed()) { 10332 if (FLAG_harmony_observation && map()->is_observed()) {
10332 PropertyAttributes new_attributes = self->GetLocalPropertyAttribute(*name); 10333 PropertyAttributes new_attributes = self->GetLocalPropertyAttribute(*name);
10333 if (!preexists) { 10334 if (!preexists) {
10334 self->EnqueueChangeRecord("new", name, old_value); 10335 EnqueueChangeRecord(self, "new", name, old_value);
10335 } else if (new_attributes != old_attributes || old_value->IsTheHole()) { 10336 } else if (new_attributes != old_attributes || old_value->IsTheHole()) {
10336 self->EnqueueChangeRecord("reconfigured", name, old_value); 10337 EnqueueChangeRecord(self, "reconfigured", name, old_value);
10337 } else { 10338 } else {
10338 Handle<Object> newValue = Object::GetElement(self, index); 10339 Handle<Object> newValue = Object::GetElement(self, index);
10339 if (!newValue->SameValue(*old_value)) 10340 if (!newValue->SameValue(*old_value))
10340 self->EnqueueChangeRecord("updated", name, old_value); 10341 EnqueueChangeRecord(self, "updated", name, old_value);
10341 } 10342 }
10342 } 10343 }
10343 10344
10344 return *hresult; 10345 return *hresult;
10345 } 10346 }
10346 10347
10347 10348
10348 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, 10349 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index,
10349 Object* value, 10350 Object* value,
10350 PropertyAttributes attr, 10351 PropertyAttributes attr,
(...skipping 3495 matching lines...) Expand 10 before | Expand all | Expand 10 after
13846 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13847 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13847 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13848 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13848 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13849 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13849 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13850 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13850 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13851 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13851 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13852 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13852 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13853 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13853 } 13854 }
13854 13855
13855 } } // namespace v8::internal 13856 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/harmony/object-observe.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698