Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 10249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10260 } | 10260 } |
| 10261 | 10261 |
| 10262 | 10262 |
| 10263 MaybeObject* JSObject::SetElement(uint32_t index, | 10263 MaybeObject* JSObject::SetElement(uint32_t index, |
| 10264 Object* value_raw, | 10264 Object* value_raw, |
| 10265 PropertyAttributes attributes, | 10265 PropertyAttributes attributes, |
| 10266 StrictModeFlag strict_mode, | 10266 StrictModeFlag strict_mode, |
| 10267 bool check_prototype, | 10267 bool check_prototype, |
| 10268 SetPropertyMode set_mode) { | 10268 SetPropertyMode set_mode) { |
| 10269 Isolate* isolate = GetIsolate(); | 10269 Isolate* isolate = GetIsolate(); |
| 10270 HandleScope scope(isolate); | |
| 10271 Handle<JSObject> self(this); | |
| 10272 Handle<Object> value(value_raw); | |
| 10273 | 10270 |
| 10274 // Check access rights if needed. | 10271 // Check access rights if needed. |
| 10275 if (IsAccessCheckNeeded()) { | 10272 if (IsAccessCheckNeeded()) { |
| 10276 Heap* heap = GetHeap(); | 10273 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
| 10277 if (!heap->isolate()->MayIndexedAccess(*self, index, v8::ACCESS_SET)) { | 10274 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 10278 heap->isolate()->ReportFailedAccessCheck(*self, v8::ACCESS_SET); | 10275 return value_raw; |
| 10279 return *value; | |
| 10280 } | 10276 } |
| 10281 } | 10277 } |
| 10282 | 10278 |
| 10283 if (IsJSGlobalProxy()) { | 10279 if (IsJSGlobalProxy()) { |
| 10284 Object* proto = GetPrototype(); | 10280 Object* proto = GetPrototype(); |
| 10285 if (proto->IsNull()) return *value; | 10281 if (proto->IsNull()) return value_raw; |
| 10286 ASSERT(proto->IsJSGlobalObject()); | 10282 ASSERT(proto->IsJSGlobalObject()); |
| 10287 return JSObject::cast(proto)->SetElement(index, | 10283 return JSObject::cast(proto)->SetElement(index, |
| 10288 *value, | 10284 value_raw, |
| 10289 attributes, | 10285 attributes, |
| 10290 strict_mode, | 10286 strict_mode, |
| 10291 check_prototype, | 10287 check_prototype, |
| 10292 set_mode); | 10288 set_mode); |
| 10293 } | 10289 } |
| 10294 | 10290 |
| 10295 // Don't allow element properties to be redefined for external arrays. | 10291 // Don't allow element properties to be redefined for external arrays. |
| 10296 if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { | 10292 if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { |
| 10297 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 10293 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 10298 Handle<Object> args[] = { self, number }; | 10294 Handle<Object> args[] = { handle(this), number }; |
| 10299 Handle<Object> error = isolate->factory()->NewTypeError( | 10295 Handle<Object> error = isolate->factory()->NewTypeError( |
| 10300 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 10296 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
| 10301 return isolate->Throw(*error); | 10297 return isolate->Throw(*error); |
| 10302 } | 10298 } |
| 10303 | 10299 |
| 10304 // Normalize the elements to enable attributes on the property. | 10300 // Normalize the elements to enable attributes on the property. |
| 10305 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 10301 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
| 10306 SeededNumberDictionary* dictionary; | 10302 SeededNumberDictionary* dictionary; |
| 10307 MaybeObject* maybe_object = NormalizeElements(); | 10303 MaybeObject* maybe_object = NormalizeElements(); |
| 10308 if (!maybe_object->To(&dictionary)) return maybe_object; | 10304 if (!maybe_object->To(&dictionary)) return maybe_object; |
| 10309 // Make sure that we never go back to fast case. | 10305 // Make sure that we never go back to fast case. |
| 10310 dictionary->set_requires_slow_elements(); | 10306 dictionary->set_requires_slow_elements(); |
| 10311 } | 10307 } |
| 10312 | 10308 |
| 10309 if (!(FLAG_harmony_observation && map()->is_observed())) { | |
| 10310 return HasIndexedInterceptor() | |
|
rafaelw
2012/11/13 13:18:44
consider factoring out into inline static?
Toon Verwaest
2012/11/13 13:38:08
+1
On 2012/11/13 13:18:44, rafaelw wrote:
rossberg
2012/11/13 13:47:44
Note that one version is handlified while the othe
rafaelw
2012/11/13 14:53:01
I'm not understanding why it wouldn't work, but I
rossberg
2012/11/13 15:33:13
Thing is, I could only factor it out in form of a
| |
| 10311 ? SetElementWithInterceptor( | |
| 10312 index, value_raw, attributes, strict_mode, check_prototype, set_mode) | |
| 10313 : SetElementWithoutInterceptor( | |
| 10314 index, value_raw, attributes, strict_mode, check_prototype, set_mode); | |
| 10315 } | |
| 10316 | |
| 10313 // From here on, everything has to be handlified. | 10317 // From here on, everything has to be handlified. |
| 10314 Handle<String> name; | 10318 Handle<JSObject> self(this); |
| 10315 Handle<Object> old_value(isolate->heap()->the_hole_value()); | 10319 Handle<Object> value(value_raw); |
| 10316 Handle<Object> old_array_length; | 10320 PropertyAttributes old_attributes = self->GetLocalElementAttribute(index); |
| 10317 PropertyAttributes old_attributes = ABSENT; | 10321 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 10318 bool preexists = false; | 10322 Handle<Object> old_length; |
| 10319 if (FLAG_harmony_observation && map()->is_observed()) { | 10323 |
| 10320 name = isolate->factory()->Uint32ToString(index); | 10324 if (old_attributes != ABSENT) { |
| 10321 preexists = self->HasLocalElement(index); | 10325 // TODO(observe): only read & set old_value if we have a data property |
| 10322 if (preexists) { | 10326 old_value = Object::GetElement(self, index); |
| 10323 old_attributes = self->GetLocalPropertyAttribute(*name); | 10327 } else if (self->IsJSArray()) { |
| 10324 // TODO(observe): only read & set old_value if we have a data property | 10328 // Store old array length in case adding an element grows the array. |
| 10325 old_value = Object::GetElement(self, index); | 10329 old_length = handle(Handle<JSArray>::cast(self)->length()); |
| 10326 } else if (self->IsJSArray()) { | |
| 10327 // Store old array length in case adding an element grows the array. | |
| 10328 old_array_length = handle(Handle<JSArray>::cast(self)->length()); | |
| 10329 } | |
| 10330 } | 10330 } |
| 10331 | 10331 |
| 10332 // Check for lookup interceptor | 10332 // Check for lookup interceptor |
| 10333 MaybeObject* result = self->HasIndexedInterceptor() | 10333 MaybeObject* result = self->HasIndexedInterceptor() |
| 10334 ? self->SetElementWithInterceptor( | 10334 ? self->SetElementWithInterceptor( |
| 10335 index, *value, attributes, strict_mode, check_prototype, set_mode) | 10335 index, *value, attributes, strict_mode, check_prototype, set_mode) |
| 10336 : self->SetElementWithoutInterceptor( | 10336 : self->SetElementWithoutInterceptor( |
| 10337 index, *value, attributes, strict_mode, check_prototype, set_mode); | 10337 index, *value, attributes, strict_mode, check_prototype, set_mode); |
| 10338 | 10338 |
| 10339 Handle<Object> hresult; | 10339 Handle<Object> hresult; |
| 10340 if (!result->ToHandle(&hresult)) return result; | 10340 if (!result->ToHandle(&hresult)) return result; |
| 10341 | 10341 |
| 10342 if (FLAG_harmony_observation && map()->is_observed()) { | 10342 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 10343 PropertyAttributes new_attributes = self->GetLocalPropertyAttribute(*name); | 10343 PropertyAttributes new_attributes = self->GetLocalElementAttribute(index); |
| 10344 if (!preexists) { | 10344 if (old_attributes == ABSENT) { |
|
rafaelw
2012/11/13 13:18:44
nit: return early here. e.g.
if (old_attributes !
Toon Verwaest
2012/11/13 13:38:08
This doesn't seem possible, given that the value i
rafaelw
2012/11/13 13:41:25
You are correct. Sorry. Misread the code.
On 2012
| |
| 10345 EnqueueChangeRecord(self, "new", name, old_value); | 10345 EnqueueChangeRecord(self, "new", name, old_value); |
| 10346 if (self->IsJSArray() && | 10346 if (self->IsJSArray() && |
| 10347 !old_array_length->SameValue(Handle<JSArray>::cast(self)->length())) { | 10347 !old_length->SameValue(Handle<JSArray>::cast(self)->length())) { |
| 10348 EnqueueChangeRecord(self, "updated", | 10348 EnqueueChangeRecord( |
| 10349 isolate->factory()->length_symbol(), | 10349 self, "updated", isolate->factory()->length_symbol(), old_length); |
| 10350 old_array_length); | |
| 10351 } | |
| 10352 } else if (new_attributes != old_attributes || old_value->IsTheHole()) { | |
| 10353 EnqueueChangeRecord(self, "reconfigured", name, old_value); | |
| 10354 } else { | |
| 10355 Handle<Object> new_value = Object::GetElement(self, index); | |
| 10356 if (!new_value->SameValue(*old_value)) | |
| 10357 EnqueueChangeRecord(self, "updated", name, old_value); | |
| 10358 } | 10350 } |
| 10351 } else if (old_attributes != new_attributes || old_value->IsTheHole()) { | |
| 10352 EnqueueChangeRecord(self, "reconfigured", name, old_value); | |
| 10353 } else if (!old_value->SameValue(*Object::GetElement(self, index))) { | |
| 10354 EnqueueChangeRecord(self, "updated", name, old_value); | |
| 10359 } | 10355 } |
| 10360 | 10356 |
| 10361 return *hresult; | 10357 return *hresult; |
| 10362 } | 10358 } |
| 10363 | 10359 |
| 10364 | 10360 |
| 10365 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 10361 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, |
| 10366 Object* value, | 10362 Object* value, |
| 10367 PropertyAttributes attr, | 10363 PropertyAttributes attr, |
| 10368 StrictModeFlag strict_mode, | 10364 StrictModeFlag strict_mode, |
| (...skipping 3494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13863 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13859 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 13864 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13860 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 13865 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13861 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 13866 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13862 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 13867 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13863 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 13868 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13864 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 13869 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13865 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 13870 } | 13866 } |
| 13871 | 13867 |
| 13872 } } // namespace v8::internal | 13868 } } // namespace v8::internal |
| OLD | NEW |