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 |