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

Side by Side Diff: src/objects.cc

Issue 11554019: Object.observe: Make array length and other magic data properties work correctly. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressing Michael's comments Created 8 years 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/object-observe.js ('k') | src/property.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 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 2925 matching lines...) Expand 10 before | Expand all | Expand 10 after
2936 if (strict_mode == kStrictMode) { 2936 if (strict_mode == kStrictMode) {
2937 Handle<Object> args[] = { name, self }; 2937 Handle<Object> args[] = { name, self };
2938 return isolate->Throw(*isolate->factory()->NewTypeError( 2938 return isolate->Throw(*isolate->factory()->NewTypeError(
2939 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); 2939 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))));
2940 } else { 2940 } else {
2941 return *value; 2941 return *value;
2942 } 2942 }
2943 } 2943 }
2944 2944
2945 Handle<Object> old_value(heap->the_hole_value(), isolate); 2945 Handle<Object> old_value(heap->the_hole_value(), isolate);
2946 if (FLAG_harmony_observation && map()->is_observed()) { 2946 if (FLAG_harmony_observation &&
2947 old_value = handle(lookup->GetLazyValue(), isolate); 2947 map()->is_observed() && lookup->IsDataProperty()) {
2948 old_value = Object::GetProperty(self, name);
2948 } 2949 }
2949 2950
2950 // This is a real property that is not read-only, or it is a 2951 // This is a real property that is not read-only, or it is a
2951 // transition or null descriptor and there are no setters in the prototypes. 2952 // transition or null descriptor and there are no setters in the prototypes.
2952 MaybeObject* result = *value; 2953 MaybeObject* result = *value;
2953 switch (lookup->type()) { 2954 switch (lookup->type()) {
2954 case NORMAL: 2955 case NORMAL:
2955 result = self->SetNormalizedProperty(lookup, *value); 2956 result = self->SetNormalizedProperty(lookup, *value);
2956 break; 2957 break;
2957 case FIELD: 2958 case FIELD:
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3023 3024
3024 Handle<Object> hresult; 3025 Handle<Object> hresult;
3025 if (!result->ToHandle(&hresult, isolate)) return result; 3026 if (!result->ToHandle(&hresult, isolate)) return result;
3026 3027
3027 if (FLAG_harmony_observation && map()->is_observed()) { 3028 if (FLAG_harmony_observation && map()->is_observed()) {
3028 if (lookup->IsTransition()) { 3029 if (lookup->IsTransition()) {
3029 EnqueueChangeRecord(self, "new", name, old_value); 3030 EnqueueChangeRecord(self, "new", name, old_value);
3030 } else { 3031 } else {
3031 LookupResult new_lookup(isolate); 3032 LookupResult new_lookup(isolate);
3032 self->LocalLookup(*name, &new_lookup, true); 3033 self->LocalLookup(*name, &new_lookup, true);
3033 ASSERT(!new_lookup.GetLazyValue()->IsTheHole()); 3034 if (new_lookup.IsDataProperty() &&
3034 if (!new_lookup.GetLazyValue()->SameValue(*old_value)) { 3035 !Object::GetProperty(self, name)->SameValue(*old_value)) {
3035 EnqueueChangeRecord(self, "updated", name, old_value); 3036 EnqueueChangeRecord(self, "updated", name, old_value);
3036 } 3037 }
3037 } 3038 }
3038 } 3039 }
3039 3040
3040 return *hresult; 3041 return *hresult;
3041 } 3042 }
3042 3043
3043 3044
3044 // Set a real local property, even if it is READ_ONLY. If the property is not 3045 // Set a real local property, even if it is READ_ONLY. If the property is not
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3103 // From this point on everything needs to be handlified. 3104 // From this point on everything needs to be handlified.
3104 HandleScope scope(isolate); 3105 HandleScope scope(isolate);
3105 Handle<JSObject> self(this); 3106 Handle<JSObject> self(this);
3106 Handle<String> name(name_raw); 3107 Handle<String> name(name_raw);
3107 Handle<Object> value(value_raw, isolate); 3108 Handle<Object> value(value_raw, isolate);
3108 3109
3109 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); 3110 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate);
3110 PropertyAttributes old_attributes = ABSENT; 3111 PropertyAttributes old_attributes = ABSENT;
3111 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); 3112 bool is_observed = FLAG_harmony_observation && self->map()->is_observed();
3112 if (is_observed) { 3113 if (is_observed) {
3113 // Function prototypes are stored specially 3114 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name);
3114 if (self->IsJSFunction() &&
3115 JSFunction::cast(*self)->should_have_prototype() &&
3116 name->Equals(isolate->heap()->prototype_symbol())) {
3117 MaybeObject* maybe = Accessors::FunctionGetPrototype(*self, NULL);
3118 if (!maybe->ToHandle(&old_value, isolate)) return maybe;
3119 } else {
3120 old_value = handle(lookup.GetLazyValue(), isolate);
3121 }
3122 old_attributes = lookup.GetAttributes(); 3115 old_attributes = lookup.GetAttributes();
3123 } 3116 }
3124 3117
3125 // Check of IsReadOnly removed from here in clone. 3118 // Check of IsReadOnly removed from here in clone.
3126 MaybeObject* result = *value; 3119 MaybeObject* result = *value;
3127 switch (lookup.type()) { 3120 switch (lookup.type()) {
3128 case NORMAL: { 3121 case NORMAL: {
3129 PropertyDetails details = PropertyDetails(attributes, NORMAL); 3122 PropertyDetails details = PropertyDetails(attributes, NORMAL);
3130 result = self->SetNormalizedProperty(*name, *value, details); 3123 result = self->SetNormalizedProperty(*name, *value, details);
3131 break; 3124 break;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3181 3174
3182 Handle<Object> hresult; 3175 Handle<Object> hresult;
3183 if (!result->ToHandle(&hresult, isolate)) return result; 3176 if (!result->ToHandle(&hresult, isolate)) return result;
3184 3177
3185 if (is_observed) { 3178 if (is_observed) {
3186 if (lookup.IsTransition()) { 3179 if (lookup.IsTransition()) {
3187 EnqueueChangeRecord(self, "new", name, old_value); 3180 EnqueueChangeRecord(self, "new", name, old_value);
3188 } else { 3181 } else {
3189 LookupResult new_lookup(isolate); 3182 LookupResult new_lookup(isolate);
3190 self->LocalLookup(*name, &new_lookup, true); 3183 self->LocalLookup(*name, &new_lookup, true);
3191 ASSERT(!new_lookup.GetLazyValue()->IsTheHole());
3192 if (old_value->IsTheHole() || 3184 if (old_value->IsTheHole() ||
3193 new_lookup.GetAttributes() != old_attributes) { 3185 new_lookup.GetAttributes() != old_attributes) {
3194 EnqueueChangeRecord(self, "reconfigured", name, old_value); 3186 EnqueueChangeRecord(self, "reconfigured", name, old_value);
3195 } else if (!new_lookup.GetLazyValue()->SameValue(*old_value)) { 3187 } else if (new_lookup.IsDataProperty() &&
3188 !Object::GetProperty(self, name)->SameValue(*old_value)) {
3196 EnqueueChangeRecord(self, "updated", name, old_value); 3189 EnqueueChangeRecord(self, "updated", name, old_value);
3197 } 3190 }
3198 } 3191 }
3199 } 3192 }
3200 3193
3201 return *hresult; 3194 return *hresult;
3202 } 3195 }
3203 3196
3204 3197
3205 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( 3198 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
(...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after
4248 return isolate->heap()->false_value(); 4241 return isolate->heap()->false_value();
4249 } 4242 }
4250 4243
4251 // From this point on everything needs to be handlified. 4244 // From this point on everything needs to be handlified.
4252 HandleScope scope(isolate); 4245 HandleScope scope(isolate);
4253 Handle<JSObject> self(this); 4246 Handle<JSObject> self(this);
4254 Handle<String> hname(name); 4247 Handle<String> hname(name);
4255 4248
4256 Handle<Object> old_value(isolate->heap()->the_hole_value()); 4249 Handle<Object> old_value(isolate->heap()->the_hole_value());
4257 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); 4250 bool is_observed = FLAG_harmony_observation && self->map()->is_observed();
4258 if (is_observed) { 4251 if (is_observed && lookup.IsDataProperty()) {
4259 old_value = handle(lookup.GetLazyValue(), isolate); 4252 old_value = Object::GetProperty(self, hname);
4260 } 4253 }
4261 MaybeObject* result; 4254 MaybeObject* result;
4262 4255
4263 // Check for interceptor. 4256 // Check for interceptor.
4264 if (lookup.IsInterceptor()) { 4257 if (lookup.IsInterceptor()) {
4265 // Skip interceptor if forcing a deletion. 4258 // Skip interceptor if forcing a deletion.
4266 if (mode == FORCE_DELETION) { 4259 if (mode == FORCE_DELETION) {
4267 result = self->DeletePropertyPostInterceptor(*hname, mode); 4260 result = self->DeletePropertyPostInterceptor(*hname, mode);
4268 } else { 4261 } else {
4269 result = self->DeletePropertyWithInterceptor(*hname); 4262 result = self->DeletePropertyWithInterceptor(*hname);
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
4940 if (is_observed) { 4933 if (is_observed) {
4941 if (is_element) { 4934 if (is_element) {
4942 preexists = HasLocalElement(index); 4935 preexists = HasLocalElement(index);
4943 if (preexists && self->GetLocalElementAccessorPair(index) == NULL) { 4936 if (preexists && self->GetLocalElementAccessorPair(index) == NULL) {
4944 old_value = Object::GetElement(self, index); 4937 old_value = Object::GetElement(self, index);
4945 } 4938 }
4946 } else { 4939 } else {
4947 LookupResult lookup(isolate); 4940 LookupResult lookup(isolate);
4948 LocalLookup(*name, &lookup, true); 4941 LocalLookup(*name, &lookup, true);
4949 preexists = lookup.IsProperty(); 4942 preexists = lookup.IsProperty();
4950 if (preexists) old_value = handle(lookup.GetLazyValue(), isolate); 4943 if (preexists && lookup.IsDataProperty()) {
4944 old_value = Object::GetProperty(self, name);
4945 }
4951 } 4946 }
4952 } 4947 }
4953 4948
4954 MaybeObject* result = is_element ? 4949 MaybeObject* result = is_element ?
4955 self->DefineElementAccessor(index, *getter, *setter, attributes) : 4950 self->DefineElementAccessor(index, *getter, *setter, attributes) :
4956 self->DefinePropertyAccessor(*name, *getter, *setter, attributes); 4951 self->DefinePropertyAccessor(*name, *getter, *setter, attributes);
4957 4952
4958 Handle<Object> hresult; 4953 Handle<Object> hresult;
4959 if (!result->ToHandle(&hresult, isolate)) return result; 4954 if (!result->ToHandle(&hresult, isolate)) return result;
4960 4955
(...skipping 9071 matching lines...) Expand 10 before | Expand all | Expand 10 after
14032 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 14027 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
14033 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 14028 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
14034 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 14029 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
14035 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 14030 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
14036 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 14031 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
14037 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 14032 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
14038 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 14033 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
14039 } 14034 }
14040 14035
14041 } } // namespace v8::internal 14036 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/object-observe.js ('k') | src/property.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698