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 |