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 |