| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 11383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11394 | 11394 |
| 11395 bool threw; | 11395 bool threw; |
| 11396 Execution::Call(isolate, | 11396 Execution::Call(isolate, |
| 11397 Handle<JSFunction>(isolate->observers_end_perform_splice()), | 11397 Handle<JSFunction>(isolate->observers_end_perform_splice()), |
| 11398 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args, | 11398 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args, |
| 11399 &threw); | 11399 &threw); |
| 11400 ASSERT(!threw); | 11400 ASSERT(!threw); |
| 11401 } | 11401 } |
| 11402 | 11402 |
| 11403 | 11403 |
| 11404 // TODO(ishell): Temporary wrapper until handlified. | |
| 11405 // static | |
| 11406 Handle<Object> JSArray::SetElementsLength(Handle<JSArray> array, | 11404 Handle<Object> JSArray::SetElementsLength(Handle<JSArray> array, |
| 11407 Handle<Object> length) { | 11405 Handle<Object> new_length_handle) { |
| 11408 CALL_HEAP_FUNCTION(array->GetIsolate(), | 11406 // We should never end in here with a pixel or external array. |
| 11409 array->SetElementsLength(*length), | 11407 ASSERT(array->AllowsSetElementsLength()); |
| 11410 Object); | 11408 if (!array->map()->is_observed()) { |
| 11411 } | 11409 return array->GetElementsAccessor()->SetLength(array, new_length_handle); |
| 11410 } |
| 11412 | 11411 |
| 11413 | 11412 Isolate* isolate = array->GetIsolate(); |
| 11414 MaybeObject* JSArray::SetElementsLength(Object* len) { | |
| 11415 // We should never end in here with a pixel or external array. | |
| 11416 ASSERT(AllowsSetElementsLength()); | |
| 11417 if (!map()->is_observed()) | |
| 11418 return GetElementsAccessor()->SetLength(this, len); | |
| 11419 | |
| 11420 Isolate* isolate = GetIsolate(); | |
| 11421 HandleScope scope(isolate); | |
| 11422 Handle<JSArray> self(this); | |
| 11423 List<uint32_t> indices; | 11413 List<uint32_t> indices; |
| 11424 List<Handle<Object> > old_values; | 11414 List<Handle<Object> > old_values; |
| 11425 Handle<Object> old_length_handle(self->length(), isolate); | 11415 Handle<Object> old_length_handle(array->length(), isolate); |
| 11426 Handle<Object> new_length_handle(len, isolate); | |
| 11427 uint32_t old_length = 0; | 11416 uint32_t old_length = 0; |
| 11428 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 11417 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
| 11429 uint32_t new_length = 0; | 11418 uint32_t new_length = 0; |
| 11430 if (!new_length_handle->ToArrayIndex(&new_length)) | 11419 CHECK(new_length_handle->ToArrayIndex(&new_length)); |
| 11431 return Failure::InternalError(); | |
| 11432 | 11420 |
| 11433 static const PropertyAttributes kNoAttrFilter = NONE; | 11421 static const PropertyAttributes kNoAttrFilter = NONE; |
| 11434 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); | 11422 int num_elements = array->NumberOfLocalElements(kNoAttrFilter); |
| 11435 if (num_elements > 0) { | 11423 if (num_elements > 0) { |
| 11436 if (old_length == static_cast<uint32_t>(num_elements)) { | 11424 if (old_length == static_cast<uint32_t>(num_elements)) { |
| 11437 // Simple case for arrays without holes. | 11425 // Simple case for arrays without holes. |
| 11438 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { | 11426 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { |
| 11439 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; | 11427 if (!GetOldValue(isolate, array, i, &old_values, &indices)) break; |
| 11440 } | 11428 } |
| 11441 } else { | 11429 } else { |
| 11442 // For sparse arrays, only iterate over existing elements. | 11430 // For sparse arrays, only iterate over existing elements. |
| 11443 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over | 11431 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over |
| 11444 // the to-be-removed indices twice. | 11432 // the to-be-removed indices twice. |
| 11445 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); | 11433 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); |
| 11446 self->GetLocalElementKeys(*keys, kNoAttrFilter); | 11434 array->GetLocalElementKeys(*keys, kNoAttrFilter); |
| 11447 while (num_elements-- > 0) { | 11435 while (num_elements-- > 0) { |
| 11448 uint32_t index = NumberToUint32(keys->get(num_elements)); | 11436 uint32_t index = NumberToUint32(keys->get(num_elements)); |
| 11449 if (index < new_length) break; | 11437 if (index < new_length) break; |
| 11450 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; | 11438 if (!GetOldValue(isolate, array, index, &old_values, &indices)) break; |
| 11451 } | 11439 } |
| 11452 } | 11440 } |
| 11453 } | 11441 } |
| 11454 | 11442 |
| 11455 MaybeObject* result = | 11443 Handle<Object> hresult = |
| 11456 self->GetElementsAccessor()->SetLength(*self, *new_length_handle); | 11444 array->GetElementsAccessor()->SetLength(array, new_length_handle); |
| 11457 Handle<Object> hresult; | 11445 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, hresult, hresult); |
| 11458 if (!result->ToHandle(&hresult, isolate)) return result; | |
| 11459 | 11446 |
| 11460 CHECK(self->length()->ToArrayIndex(&new_length)); | 11447 CHECK(array->length()->ToArrayIndex(&new_length)); |
| 11461 if (old_length == new_length) return *hresult; | 11448 if (old_length == new_length) return hresult; |
| 11462 | 11449 |
| 11463 BeginPerformSplice(self); | 11450 BeginPerformSplice(array); |
| 11464 | 11451 |
| 11465 for (int i = 0; i < indices.length(); ++i) { | 11452 for (int i = 0; i < indices.length(); ++i) { |
| 11466 JSObject::EnqueueChangeRecord( | 11453 JSObject::EnqueueChangeRecord( |
| 11467 self, "delete", isolate->factory()->Uint32ToString(indices[i]), | 11454 array, "delete", isolate->factory()->Uint32ToString(indices[i]), |
| 11468 old_values[i]); | 11455 old_values[i]); |
| 11469 } | 11456 } |
| 11470 JSObject::EnqueueChangeRecord( | 11457 JSObject::EnqueueChangeRecord( |
| 11471 self, "update", isolate->factory()->length_string(), | 11458 array, "update", isolate->factory()->length_string(), |
| 11472 old_length_handle); | 11459 old_length_handle); |
| 11473 | 11460 |
| 11474 EndPerformSplice(self); | 11461 EndPerformSplice(array); |
| 11475 | 11462 |
| 11476 uint32_t index = Min(old_length, new_length); | 11463 uint32_t index = Min(old_length, new_length); |
| 11477 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; | 11464 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; |
| 11478 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; | 11465 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; |
| 11479 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 11466 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
| 11480 if (delete_count > 0) { | 11467 if (delete_count > 0) { |
| 11481 for (int i = indices.length() - 1; i >= 0; i--) { | 11468 for (int i = indices.length() - 1; i >= 0; i--) { |
| 11482 JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE, | 11469 JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE, |
| 11483 SLOPPY); | 11470 SLOPPY); |
| 11484 } | 11471 } |
| 11485 | 11472 |
| 11486 SetProperty(deleted, isolate->factory()->length_string(), | 11473 SetProperty(deleted, isolate->factory()->length_string(), |
| 11487 isolate->factory()->NewNumberFromUint(delete_count), | 11474 isolate->factory()->NewNumberFromUint(delete_count), |
| 11488 NONE, SLOPPY); | 11475 NONE, SLOPPY); |
| 11489 } | 11476 } |
| 11490 | 11477 |
| 11491 EnqueueSpliceRecord(self, index, deleted, add_count); | 11478 EnqueueSpliceRecord(array, index, deleted, add_count); |
| 11492 | 11479 |
| 11493 return *hresult; | 11480 return hresult; |
| 11494 } | 11481 } |
| 11495 | 11482 |
| 11496 | 11483 |
| 11497 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map, | 11484 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map, |
| 11498 Handle<Object> prototype) { | 11485 Handle<Object> prototype) { |
| 11499 FixedArray* cache = map->GetPrototypeTransitions(); | 11486 FixedArray* cache = map->GetPrototypeTransitions(); |
| 11500 int number_of_transitions = map->NumberOfProtoTransitions(); | 11487 int number_of_transitions = map->NumberOfProtoTransitions(); |
| 11501 const int proto_offset = | 11488 const int proto_offset = |
| 11502 kProtoTransitionHeaderSize + kProtoTransitionPrototypeOffset; | 11489 kProtoTransitionHeaderSize + kProtoTransitionPrototypeOffset; |
| 11503 const int map_offset = kProtoTransitionHeaderSize + kProtoTransitionMapOffset; | 11490 const int map_offset = kProtoTransitionHeaderSize + kProtoTransitionMapOffset; |
| (...skipping 4987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16491 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16478 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16492 static const char* error_messages_[] = { | 16479 static const char* error_messages_[] = { |
| 16493 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16480 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16494 }; | 16481 }; |
| 16495 #undef ERROR_MESSAGES_TEXTS | 16482 #undef ERROR_MESSAGES_TEXTS |
| 16496 return error_messages_[reason]; | 16483 return error_messages_[reason]; |
| 16497 } | 16484 } |
| 16498 | 16485 |
| 16499 | 16486 |
| 16500 } } // namespace v8::internal | 16487 } } // namespace v8::internal |
| OLD | NEW |