Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/elements.h" | 8 #include "src/elements.h" |
| 9 #include "src/messages.h" | 9 #include "src/messages.h" |
| 10 #include "src/runtime/runtime-utils.h" | 10 #include "src/runtime/runtime-utils.h" |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 355 | 355 |
| 356 | 356 |
| 357 // Used for sorting indices in a List<uint32_t>. | 357 // Used for sorting indices in a List<uint32_t>. |
| 358 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) { | 358 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) { |
| 359 uint32_t a = *ap; | 359 uint32_t a = *ap; |
| 360 uint32_t b = *bp; | 360 uint32_t b = *bp; |
| 361 return (a == b) ? 0 : (a < b) ? -1 : 1; | 361 return (a == b) ? 0 : (a < b) ? -1 : 1; |
| 362 } | 362 } |
| 363 | 363 |
| 364 | 364 |
| 365 static void CollectElementIndices(Handle<JSObject> object, uint32_t range, | 365 // Return false on exception. |
| 366 static bool CollectElementIndices(Handle<JSObject> object, uint32_t range, | |
| 366 List<uint32_t>* indices) { | 367 List<uint32_t>* indices) { |
| 367 Isolate* isolate = object->GetIsolate(); | 368 Isolate* isolate = object->GetIsolate(); |
| 368 ElementsKind kind = object->GetElementsKind(); | 369 ElementsKind kind = object->GetElementsKind(); |
| 369 switch (kind) { | 370 switch (kind) { |
| 370 case FAST_SMI_ELEMENTS: | 371 case FAST_SMI_ELEMENTS: |
| 371 case FAST_ELEMENTS: | 372 case FAST_ELEMENTS: |
| 372 case FAST_HOLEY_SMI_ELEMENTS: | 373 case FAST_HOLEY_SMI_ELEMENTS: |
| 373 case FAST_HOLEY_ELEMENTS: { | 374 case FAST_HOLEY_ELEMENTS: { |
| 374 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 375 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
| 375 uint32_t length = static_cast<uint32_t>(elements->length()); | 376 uint32_t length = static_cast<uint32_t>(elements->length()); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 FixedArrayBase::cast(object->elements())->length()); | 426 FixedArrayBase::cast(object->elements())->length()); |
| 426 if (range <= length) { | 427 if (range <= length) { |
| 427 length = range; | 428 length = range; |
| 428 // We will add all indices, so we might as well clear it first | 429 // We will add all indices, so we might as well clear it first |
| 429 // and avoid duplicates. | 430 // and avoid duplicates. |
| 430 indices->Clear(); | 431 indices->Clear(); |
| 431 } | 432 } |
| 432 for (uint32_t i = 0; i < length; i++) { | 433 for (uint32_t i = 0; i < length; i++) { |
| 433 indices->Add(i); | 434 indices->Add(i); |
| 434 } | 435 } |
| 435 if (length == range) return; // All indices accounted for already. | 436 if (length == range) return true; // All indices accounted for already. |
| 436 break; | 437 break; |
| 437 } | 438 } |
| 438 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 439 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 439 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { | 440 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { |
| 440 MaybeHandle<Object> length_obj = | 441 Handle<Object> length_obj; |
| 441 Object::GetProperty(object, isolate->factory()->length_string()); | 442 // See ES6 22.1.3.1 step 7-a-ii |
|
adamk
2015/08/05 18:05:53
I think you mean 7-d-ii?
| |
| 442 double length_num = length_obj.ToHandleChecked()->Number(); | 443 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 444 isolate, length_obj, | |
| 445 Object::GetProperty(object, isolate->factory()->length_string()), | |
| 446 false); | |
| 447 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 448 isolate, length_obj, Execution::ToLength(isolate, length_obj), false); | |
| 449 double length_num = length_obj->Number(); | |
| 443 uint32_t length = static_cast<uint32_t>(DoubleToInt32(length_num)); | 450 uint32_t length = static_cast<uint32_t>(DoubleToInt32(length_num)); |
| 444 ElementsAccessor* accessor = object->GetElementsAccessor(); | 451 ElementsAccessor* accessor = object->GetElementsAccessor(); |
| 445 for (uint32_t i = 0; i < length; i++) { | 452 for (uint32_t i = 0; i < length; i++) { |
| 446 if (accessor->HasElement(object, i)) { | 453 if (accessor->HasElement(object, i)) { |
| 447 indices->Add(i); | 454 indices->Add(i); |
| 448 } | 455 } |
| 449 } | 456 } |
| 450 break; | 457 break; |
| 451 } | 458 } |
| 452 } | 459 } |
| 453 | 460 |
| 454 PrototypeIterator iter(isolate, object); | 461 PrototypeIterator iter(isolate, object); |
| 455 if (!iter.IsAtEnd()) { | 462 if (!iter.IsAtEnd()) { |
| 456 // The prototype will usually have no inherited element indices, | 463 // The prototype will usually have no inherited element indices, |
| 457 // but we have to check. | 464 // but we have to check. |
| 458 CollectElementIndices( | 465 return CollectElementIndices( |
| 459 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range, | 466 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range, |
| 460 indices); | 467 indices); |
| 461 } | 468 } |
| 469 return true; | |
| 462 } | 470 } |
| 463 | 471 |
| 464 | 472 |
| 465 static bool IterateElementsSlow(Isolate* isolate, Handle<JSObject> receiver, | 473 static bool IterateElementsSlow(Isolate* isolate, Handle<JSObject> receiver, |
| 466 uint32_t length, ArrayConcatVisitor* visitor) { | 474 uint32_t length, ArrayConcatVisitor* visitor) { |
| 467 for (uint32_t i = 0; i < length; ++i) { | 475 for (uint32_t i = 0; i < length; ++i) { |
| 468 HandleScope loop_scope(isolate); | 476 HandleScope loop_scope(isolate); |
| 469 Maybe<bool> maybe = JSReceiver::HasElement(receiver, i); | 477 Maybe<bool> maybe = JSReceiver::HasElement(receiver, i); |
| 470 if (!maybe.IsJust()) return false; | 478 if (!maybe.IsJust()) return false; |
| 471 if (maybe.FromJust()) { | 479 if (maybe.FromJust()) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 582 } | 590 } |
| 583 } | 591 } |
| 584 } | 592 } |
| 585 break; | 593 break; |
| 586 } | 594 } |
| 587 case DICTIONARY_ELEMENTS: { | 595 case DICTIONARY_ELEMENTS: { |
| 588 Handle<SeededNumberDictionary> dict(receiver->element_dictionary()); | 596 Handle<SeededNumberDictionary> dict(receiver->element_dictionary()); |
| 589 List<uint32_t> indices(dict->Capacity() / 2); | 597 List<uint32_t> indices(dict->Capacity() / 2); |
| 590 // Collect all indices in the object and the prototypes less | 598 // Collect all indices in the object and the prototypes less |
| 591 // than length. This might introduce duplicates in the indices list. | 599 // than length. This might introduce duplicates in the indices list. |
| 592 CollectElementIndices(receiver, length, &indices); | 600 if (!CollectElementIndices(receiver, length, &indices)) return false; |
| 593 indices.Sort(&compareUInt32); | 601 indices.Sort(&compareUInt32); |
| 594 int j = 0; | 602 int j = 0; |
| 595 int n = indices.length(); | 603 int n = indices.length(); |
| 596 while (j < n) { | 604 while (j < n) { |
| 597 HandleScope loop_scope(isolate); | 605 HandleScope loop_scope(isolate); |
| 598 uint32_t index = indices[j]; | 606 uint32_t index = indices[j]; |
| 599 Handle<Object> element; | 607 Handle<Object> element; |
| 600 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 608 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 601 isolate, element, Object::GetElement(isolate, receiver, index), | 609 isolate, element, Object::GetElement(isolate, receiver, index), |
| 602 false); | 610 false); |
| (...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1268 | 1276 |
| 1269 RUNTIME_FUNCTION(Runtime_FastOneByteArrayJoin) { | 1277 RUNTIME_FUNCTION(Runtime_FastOneByteArrayJoin) { |
| 1270 SealHandleScope shs(isolate); | 1278 SealHandleScope shs(isolate); |
| 1271 DCHECK(args.length() == 2); | 1279 DCHECK(args.length() == 2); |
| 1272 // Returning undefined means that this fast path fails and one has to resort | 1280 // Returning undefined means that this fast path fails and one has to resort |
| 1273 // to a slow path. | 1281 // to a slow path. |
| 1274 return isolate->heap()->undefined_value(); | 1282 return isolate->heap()->undefined_value(); |
| 1275 } | 1283 } |
| 1276 } // namespace internal | 1284 } // namespace internal |
| 1277 } // namespace v8 | 1285 } // namespace v8 |
| OLD | NEW |