OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 (function(global, utils) { | 5 (function(global, utils) { |
6 | 6 |
7 "use strict"; | 7 "use strict"; |
8 | 8 |
9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
10 | 10 |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 func = array.join; | 388 func = array.join; |
389 } | 389 } |
390 if (!IS_CALLABLE(func)) { | 390 if (!IS_CALLABLE(func)) { |
391 return %_CallFunction(array, ObjectToString); | 391 return %_CallFunction(array, ObjectToString); |
392 } | 392 } |
393 return %_Call(func, array); | 393 return %_Call(func, array); |
394 } | 394 } |
395 | 395 |
396 | 396 |
397 function InnerArrayToLocaleString(array, length) { | 397 function InnerArrayToLocaleString(array, length) { |
398 var len = TO_UINT32(length); | 398 var len = TO_LENGTH_OR_UINT32(length); |
399 if (len === 0) return ""; | 399 if (len === 0) return ""; |
400 return Join(array, len, ',', ConvertToLocaleString); | 400 return Join(array, len, ',', ConvertToLocaleString); |
401 } | 401 } |
402 | 402 |
403 | 403 |
404 function ArrayToLocaleString() { | 404 function ArrayToLocaleString() { |
405 var array = TO_OBJECT(this); | 405 var array = TO_OBJECT(this); |
406 var arrayLen = array.length; | 406 var arrayLen = array.length; |
407 return InnerArrayToLocaleString(array, arrayLen); | 407 return InnerArrayToLocaleString(array, arrayLen); |
408 } | 408 } |
(...skipping 18 matching lines...) Expand all Loading... |
427 } | 427 } |
428 | 428 |
429 return Join(array, length, separator, ConvertToString); | 429 return Join(array, length, separator, ConvertToString); |
430 } | 430 } |
431 | 431 |
432 | 432 |
433 function ArrayJoin(separator) { | 433 function ArrayJoin(separator) { |
434 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join"); | 434 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join"); |
435 | 435 |
436 var array = TO_OBJECT(this); | 436 var array = TO_OBJECT(this); |
437 var length = TO_UINT32(array.length); | 437 var length = TO_LENGTH_OR_UINT32(array.length); |
438 | 438 |
439 return InnerArrayJoin(separator, array, length); | 439 return InnerArrayJoin(separator, array, length); |
440 } | 440 } |
441 | 441 |
442 | 442 |
443 function ObservedArrayPop(n) { | 443 function ObservedArrayPop(n) { |
444 n--; | 444 n--; |
445 var value = this[n]; | 445 var value = this[n]; |
446 | 446 |
447 try { | 447 try { |
448 $observeBeginPerformSplice(this); | 448 $observeBeginPerformSplice(this); |
449 delete this[n]; | 449 delete this[n]; |
450 this.length = n; | 450 this.length = n; |
451 } finally { | 451 } finally { |
452 $observeEndPerformSplice(this); | 452 $observeEndPerformSplice(this); |
453 $observeEnqueueSpliceRecord(this, n, [value], 0); | 453 $observeEnqueueSpliceRecord(this, n, [value], 0); |
454 } | 454 } |
455 | 455 |
456 return value; | 456 return value; |
457 } | 457 } |
458 | 458 |
459 | 459 |
460 // Removes the last element from the array and returns it. See | 460 // Removes the last element from the array and returns it. See |
461 // ECMA-262, section 15.4.4.6. | 461 // ECMA-262, section 15.4.4.6. |
462 function ArrayPop() { | 462 function ArrayPop() { |
463 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.pop"); | 463 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.pop"); |
464 | 464 |
465 var array = TO_OBJECT(this); | 465 var array = TO_OBJECT(this); |
466 var n = TO_UINT32(array.length); | 466 var n = TO_LENGTH_OR_UINT32(array.length); |
467 if (n == 0) { | 467 if (n == 0) { |
468 array.length = n; | 468 array.length = n; |
469 return; | 469 return; |
470 } | 470 } |
471 | 471 |
472 if (%IsObserved(array)) | 472 if (%IsObserved(array)) |
473 return ObservedArrayPop.call(array, n); | 473 return ObservedArrayPop.call(array, n); |
474 | 474 |
475 n--; | 475 n--; |
476 var value = array[n]; | 476 var value = array[n]; |
477 Delete(array, n, true); | 477 Delete(array, n, true); |
478 array.length = n; | 478 array.length = n; |
479 return value; | 479 return value; |
480 } | 480 } |
481 | 481 |
482 | 482 |
483 function ObservedArrayPush() { | 483 function ObservedArrayPush() { |
484 var n = TO_UINT32(this.length); | 484 var n = TO_LENGTH_OR_UINT32(this.length); |
485 var m = %_ArgumentsLength(); | 485 var m = %_ArgumentsLength(); |
486 | 486 |
487 try { | 487 try { |
488 $observeBeginPerformSplice(this); | 488 $observeBeginPerformSplice(this); |
489 for (var i = 0; i < m; i++) { | 489 for (var i = 0; i < m; i++) { |
490 this[i+n] = %_Arguments(i); | 490 this[i+n] = %_Arguments(i); |
491 } | 491 } |
492 var new_length = n + m; | 492 var new_length = n + m; |
493 this.length = new_length; | 493 this.length = new_length; |
494 } finally { | 494 } finally { |
495 $observeEndPerformSplice(this); | 495 $observeEndPerformSplice(this); |
496 $observeEnqueueSpliceRecord(this, n, [], m); | 496 $observeEnqueueSpliceRecord(this, n, [], m); |
497 } | 497 } |
498 | 498 |
499 return new_length; | 499 return new_length; |
500 } | 500 } |
501 | 501 |
502 | 502 |
503 // Appends the arguments to the end of the array and returns the new | 503 // Appends the arguments to the end of the array and returns the new |
504 // length of the array. See ECMA-262, section 15.4.4.7. | 504 // length of the array. See ECMA-262, section 15.4.4.7. |
505 function ArrayPush() { | 505 function ArrayPush() { |
506 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push"); | 506 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push"); |
507 | 507 |
508 if (%IsObserved(this)) | 508 if (%IsObserved(this)) |
509 return ObservedArrayPush.apply(this, arguments); | 509 return ObservedArrayPush.apply(this, arguments); |
510 | 510 |
511 var array = TO_OBJECT(this); | 511 var array = TO_OBJECT(this); |
512 var n = TO_UINT32(array.length); | 512 var n = TO_LENGTH_OR_UINT32(array.length); |
513 var m = %_ArgumentsLength(); | 513 var m = %_ArgumentsLength(); |
514 | 514 |
515 for (var i = 0; i < m; i++) { | 515 for (var i = 0; i < m; i++) { |
516 array[i+n] = %_Arguments(i); | 516 array[i+n] = %_Arguments(i); |
517 } | 517 } |
518 | 518 |
519 var new_length = n + m; | 519 var new_length = n + m; |
520 array.length = new_length; | 520 array.length = new_length; |
521 return new_length; | 521 return new_length; |
522 } | 522 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 } | 599 } |
600 } | 600 } |
601 return array; | 601 return array; |
602 } | 602 } |
603 | 603 |
604 | 604 |
605 function ArrayReverse() { | 605 function ArrayReverse() { |
606 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse"); | 606 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse"); |
607 | 607 |
608 var array = TO_OBJECT(this); | 608 var array = TO_OBJECT(this); |
609 var len = TO_UINT32(array.length); | 609 var len = TO_LENGTH_OR_UINT32(array.length); |
610 var isArray = IS_ARRAY(array); | 610 var isArray = IS_ARRAY(array); |
611 | 611 |
612 if (UseSparseVariant(array, len, isArray, len)) { | 612 if (UseSparseVariant(array, len, isArray, len)) { |
613 %NormalizeElements(array); | 613 %NormalizeElements(array); |
614 SparseReverse(array, len); | 614 SparseReverse(array, len); |
615 return array; | 615 return array; |
616 } else if (isArray && %_HasFastPackedElements(array)) { | 616 } else if (isArray && %_HasFastPackedElements(array)) { |
617 return PackedArrayReverse(array, len); | 617 return PackedArrayReverse(array, len); |
618 } else { | 618 } else { |
619 return GenericArrayReverse(array, len); | 619 return GenericArrayReverse(array, len); |
(...skipping 14 matching lines...) Expand all Loading... |
634 } | 634 } |
635 | 635 |
636 return first; | 636 return first; |
637 } | 637 } |
638 | 638 |
639 | 639 |
640 function ArrayShift() { | 640 function ArrayShift() { |
641 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift"); | 641 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift"); |
642 | 642 |
643 var array = TO_OBJECT(this); | 643 var array = TO_OBJECT(this); |
644 var len = TO_UINT32(array.length); | 644 var len = TO_LENGTH_OR_UINT32(array.length); |
645 | 645 |
646 if (len === 0) { | 646 if (len === 0) { |
647 array.length = 0; | 647 array.length = 0; |
648 return; | 648 return; |
649 } | 649 } |
650 | 650 |
651 if (ObjectIsSealed(array)) throw MakeTypeError(kArrayFunctionsOnSealed); | 651 if (ObjectIsSealed(array)) throw MakeTypeError(kArrayFunctionsOnSealed); |
652 | 652 |
653 if (%IsObserved(array)) | 653 if (%IsObserved(array)) |
654 return ObservedArrayShift.call(array, len); | 654 return ObservedArrayShift.call(array, len); |
655 | 655 |
656 var first = array[0]; | 656 var first = array[0]; |
657 | 657 |
658 if (UseSparseVariant(array, len, IS_ARRAY(array), len)) { | 658 if (UseSparseVariant(array, len, IS_ARRAY(array), len)) { |
659 SparseMove(array, 0, 1, len, 0); | 659 SparseMove(array, 0, 1, len, 0); |
660 } else { | 660 } else { |
661 SimpleMove(array, 0, 1, len, 0); | 661 SimpleMove(array, 0, 1, len, 0); |
662 } | 662 } |
663 | 663 |
664 array.length = len - 1; | 664 array.length = len - 1; |
665 | 665 |
666 return first; | 666 return first; |
667 } | 667 } |
668 | 668 |
669 | 669 |
670 function ObservedArrayUnshift() { | 670 function ObservedArrayUnshift() { |
671 var len = TO_UINT32(this.length); | 671 var len = TO_LENGTH_OR_UINT32(this.length); |
672 var num_arguments = %_ArgumentsLength(); | 672 var num_arguments = %_ArgumentsLength(); |
673 | 673 |
674 try { | 674 try { |
675 $observeBeginPerformSplice(this); | 675 $observeBeginPerformSplice(this); |
676 SimpleMove(this, 0, 0, len, num_arguments); | 676 SimpleMove(this, 0, 0, len, num_arguments); |
677 for (var i = 0; i < num_arguments; i++) { | 677 for (var i = 0; i < num_arguments; i++) { |
678 this[i] = %_Arguments(i); | 678 this[i] = %_Arguments(i); |
679 } | 679 } |
680 var new_length = len + num_arguments; | 680 var new_length = len + num_arguments; |
681 this.length = new_length; | 681 this.length = new_length; |
682 } finally { | 682 } finally { |
683 $observeEndPerformSplice(this); | 683 $observeEndPerformSplice(this); |
684 $observeEnqueueSpliceRecord(this, 0, [], num_arguments); | 684 $observeEnqueueSpliceRecord(this, 0, [], num_arguments); |
685 } | 685 } |
686 | 686 |
687 return new_length; | 687 return new_length; |
688 } | 688 } |
689 | 689 |
690 | 690 |
691 function ArrayUnshift(arg1) { // length == 1 | 691 function ArrayUnshift(arg1) { // length == 1 |
692 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift"); | 692 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift"); |
693 | 693 |
694 if (%IsObserved(this)) | 694 if (%IsObserved(this)) |
695 return ObservedArrayUnshift.apply(this, arguments); | 695 return ObservedArrayUnshift.apply(this, arguments); |
696 | 696 |
697 var array = TO_OBJECT(this); | 697 var array = TO_OBJECT(this); |
698 var len = TO_UINT32(array.length); | 698 var len = TO_LENGTH_OR_UINT32(array.length); |
699 var num_arguments = %_ArgumentsLength(); | 699 var num_arguments = %_ArgumentsLength(); |
700 | 700 |
701 if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) && | 701 if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) && |
702 !ObjectIsSealed(array)) { | 702 !ObjectIsSealed(array)) { |
703 SparseMove(array, 0, 0, len, num_arguments); | 703 SparseMove(array, 0, 0, len, num_arguments); |
704 } else { | 704 } else { |
705 SimpleMove(array, 0, 0, len, num_arguments); | 705 SimpleMove(array, 0, 0, len, num_arguments); |
706 } | 706 } |
707 | 707 |
708 for (var i = 0; i < num_arguments; i++) { | 708 for (var i = 0; i < num_arguments; i++) { |
709 array[i] = %_Arguments(i); | 709 array[i] = %_Arguments(i); |
710 } | 710 } |
711 | 711 |
712 var new_length = len + num_arguments; | 712 var new_length = len + num_arguments; |
713 array.length = new_length; | 713 array.length = new_length; |
714 return new_length; | 714 return new_length; |
715 } | 715 } |
716 | 716 |
717 | 717 |
718 function ArraySlice(start, end) { | 718 function ArraySlice(start, end) { |
719 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); | 719 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); |
720 | 720 |
721 var array = TO_OBJECT(this); | 721 var array = TO_OBJECT(this); |
722 var len = TO_UINT32(array.length); | 722 var len = TO_LENGTH_OR_UINT32(array.length); |
723 var start_i = TO_INTEGER(start); | 723 var start_i = TO_INTEGER(start); |
724 var end_i = len; | 724 var end_i = len; |
725 | 725 |
726 if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end); | 726 if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end); |
727 | 727 |
728 if (start_i < 0) { | 728 if (start_i < 0) { |
729 start_i += len; | 729 start_i += len; |
730 if (start_i < 0) start_i = 0; | 730 if (start_i < 0) start_i = 0; |
731 } else { | 731 } else { |
732 if (start_i > len) start_i = len; | 732 if (start_i > len) start_i = len; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 | 783 |
784 if (del_count > len - start_i) | 784 if (del_count > len - start_i) |
785 return len - start_i; | 785 return len - start_i; |
786 | 786 |
787 return del_count; | 787 return del_count; |
788 } | 788 } |
789 | 789 |
790 | 790 |
791 function ObservedArraySplice(start, delete_count) { | 791 function ObservedArraySplice(start, delete_count) { |
792 var num_arguments = %_ArgumentsLength(); | 792 var num_arguments = %_ArgumentsLength(); |
793 var len = TO_UINT32(this.length); | 793 var len = TO_LENGTH_OR_UINT32(this.length); |
794 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); | 794 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); |
795 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, | 795 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, |
796 start_i); | 796 start_i); |
797 var deleted_elements = []; | 797 var deleted_elements = []; |
798 deleted_elements.length = del_count; | 798 deleted_elements.length = del_count; |
799 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; | 799 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; |
800 | 800 |
801 try { | 801 try { |
802 $observeBeginPerformSplice(this); | 802 $observeBeginPerformSplice(this); |
803 | 803 |
(...skipping 26 matching lines...) Expand all Loading... |
830 | 830 |
831 | 831 |
832 function ArraySplice(start, delete_count) { | 832 function ArraySplice(start, delete_count) { |
833 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice"); | 833 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice"); |
834 | 834 |
835 if (%IsObserved(this)) | 835 if (%IsObserved(this)) |
836 return ObservedArraySplice.apply(this, arguments); | 836 return ObservedArraySplice.apply(this, arguments); |
837 | 837 |
838 var num_arguments = %_ArgumentsLength(); | 838 var num_arguments = %_ArgumentsLength(); |
839 var array = TO_OBJECT(this); | 839 var array = TO_OBJECT(this); |
840 var len = TO_UINT32(array.length); | 840 var len = TO_LENGTH_OR_UINT32(array.length); |
841 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); | 841 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); |
842 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, | 842 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, |
843 start_i); | 843 start_i); |
844 var deleted_elements = []; | 844 var deleted_elements = []; |
845 deleted_elements.length = del_count; | 845 deleted_elements.length = del_count; |
846 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; | 846 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; |
847 | 847 |
848 if (del_count != num_elements_to_add && ObjectIsSealed(array)) { | 848 if (del_count != num_elements_to_add && ObjectIsSealed(array)) { |
849 throw MakeTypeError(kArrayFunctionsOnSealed); | 849 throw MakeTypeError(kArrayFunctionsOnSealed); |
850 } else if (del_count > 0 && ObjectIsFrozen(array)) { | 850 } else if (del_count > 0 && ObjectIsFrozen(array)) { |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1166 } | 1166 } |
1167 | 1167 |
1168 return array; | 1168 return array; |
1169 } | 1169 } |
1170 | 1170 |
1171 | 1171 |
1172 function ArraySort(comparefn) { | 1172 function ArraySort(comparefn) { |
1173 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort"); | 1173 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort"); |
1174 | 1174 |
1175 var array = TO_OBJECT(this); | 1175 var array = TO_OBJECT(this); |
1176 var length = TO_UINT32(array.length); | 1176 var length = TO_LENGTH_OR_UINT32(array.length); |
1177 return InnerArraySort(array, length, comparefn); | 1177 return InnerArraySort(array, length, comparefn); |
1178 } | 1178 } |
1179 | 1179 |
1180 | 1180 |
1181 // The following functions cannot be made efficient on sparse arrays while | 1181 // The following functions cannot be made efficient on sparse arrays while |
1182 // preserving the semantics, since the calls to the receiver function can add | 1182 // preserving the semantics, since the calls to the receiver function can add |
1183 // or delete elements from the array. | 1183 // or delete elements from the array. |
1184 function InnerArrayFilter(f, receiver, array, length) { | 1184 function InnerArrayFilter(f, receiver, array, length) { |
1185 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); | 1185 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); |
1186 | 1186 |
(...skipping 13 matching lines...) Expand all Loading... |
1200 } | 1200 } |
1201 return accumulator; | 1201 return accumulator; |
1202 } | 1202 } |
1203 | 1203 |
1204 function ArrayFilter(f, receiver) { | 1204 function ArrayFilter(f, receiver) { |
1205 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter"); | 1205 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter"); |
1206 | 1206 |
1207 // Pull out the length so that modifications to the length in the | 1207 // Pull out the length so that modifications to the length in the |
1208 // loop will not affect the looping and side effects are visible. | 1208 // loop will not affect the looping and side effects are visible. |
1209 var array = TO_OBJECT(this); | 1209 var array = TO_OBJECT(this); |
1210 var length = TO_UINT32(array.length); | 1210 var length = TO_LENGTH_OR_UINT32(array.length); |
1211 var accumulator = InnerArrayFilter(f, receiver, array, length); | 1211 var accumulator = InnerArrayFilter(f, receiver, array, length); |
1212 var result = new GlobalArray(); | 1212 var result = new GlobalArray(); |
1213 %MoveArrayContents(accumulator, result); | 1213 %MoveArrayContents(accumulator, result); |
1214 return result; | 1214 return result; |
1215 } | 1215 } |
1216 | 1216 |
1217 function InnerArrayForEach(f, receiver, array, length) { | 1217 function InnerArrayForEach(f, receiver, array, length) { |
1218 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); | 1218 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); |
1219 | 1219 |
1220 var is_array = IS_ARRAY(array); | 1220 var is_array = IS_ARRAY(array); |
1221 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); | 1221 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); |
1222 for (var i = 0; i < length; i++) { | 1222 for (var i = 0; i < length; i++) { |
1223 if (HAS_INDEX(array, i, is_array)) { | 1223 if (HAS_INDEX(array, i, is_array)) { |
1224 var element = array[i]; | 1224 var element = array[i]; |
1225 // Prepare break slots for debugger step in. | 1225 // Prepare break slots for debugger step in. |
1226 if (stepping) %DebugPrepareStepInIfStepping(f); | 1226 if (stepping) %DebugPrepareStepInIfStepping(f); |
1227 %_Call(f, receiver, element, i, array); | 1227 %_Call(f, receiver, element, i, array); |
1228 } | 1228 } |
1229 } | 1229 } |
1230 } | 1230 } |
1231 | 1231 |
1232 function ArrayForEach(f, receiver) { | 1232 function ArrayForEach(f, receiver) { |
1233 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach"); | 1233 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach"); |
1234 | 1234 |
1235 // Pull out the length so that modifications to the length in the | 1235 // Pull out the length so that modifications to the length in the |
1236 // loop will not affect the looping and side effects are visible. | 1236 // loop will not affect the looping and side effects are visible. |
1237 var array = TO_OBJECT(this); | 1237 var array = TO_OBJECT(this); |
1238 var length = TO_UINT32(array.length); | 1238 var length = TO_LENGTH_OR_UINT32(array.length); |
1239 InnerArrayForEach(f, receiver, array, length); | 1239 InnerArrayForEach(f, receiver, array, length); |
1240 } | 1240 } |
1241 | 1241 |
1242 | 1242 |
1243 function InnerArraySome(f, receiver, array, length) { | 1243 function InnerArraySome(f, receiver, array, length) { |
1244 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); | 1244 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); |
1245 | 1245 |
1246 var is_array = IS_ARRAY(array); | 1246 var is_array = IS_ARRAY(array); |
1247 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); | 1247 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); |
1248 for (var i = 0; i < length; i++) { | 1248 for (var i = 0; i < length; i++) { |
1249 if (HAS_INDEX(array, i, is_array)) { | 1249 if (HAS_INDEX(array, i, is_array)) { |
1250 var element = array[i]; | 1250 var element = array[i]; |
1251 // Prepare break slots for debugger step in. | 1251 // Prepare break slots for debugger step in. |
1252 if (stepping) %DebugPrepareStepInIfStepping(f); | 1252 if (stepping) %DebugPrepareStepInIfStepping(f); |
1253 if (%_Call(f, receiver, element, i, array)) return true; | 1253 if (%_Call(f, receiver, element, i, array)) return true; |
1254 } | 1254 } |
1255 } | 1255 } |
1256 return false; | 1256 return false; |
1257 } | 1257 } |
1258 | 1258 |
1259 | 1259 |
1260 // Executes the function once for each element present in the | 1260 // Executes the function once for each element present in the |
1261 // array until it finds one where callback returns true. | 1261 // array until it finds one where callback returns true. |
1262 function ArraySome(f, receiver) { | 1262 function ArraySome(f, receiver) { |
1263 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some"); | 1263 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some"); |
1264 | 1264 |
1265 // Pull out the length so that modifications to the length in the | 1265 // Pull out the length so that modifications to the length in the |
1266 // loop will not affect the looping and side effects are visible. | 1266 // loop will not affect the looping and side effects are visible. |
1267 var array = TO_OBJECT(this); | 1267 var array = TO_OBJECT(this); |
1268 var length = TO_UINT32(array.length); | 1268 var length = TO_LENGTH_OR_UINT32(array.length); |
1269 return InnerArraySome(f, receiver, array, length); | 1269 return InnerArraySome(f, receiver, array, length); |
1270 } | 1270 } |
1271 | 1271 |
1272 | 1272 |
1273 function InnerArrayEvery(f, receiver, array, length) { | 1273 function InnerArrayEvery(f, receiver, array, length) { |
1274 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); | 1274 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); |
1275 | 1275 |
1276 var is_array = IS_ARRAY(array); | 1276 var is_array = IS_ARRAY(array); |
1277 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); | 1277 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); |
1278 for (var i = 0; i < length; i++) { | 1278 for (var i = 0; i < length; i++) { |
1279 if (HAS_INDEX(array, i, is_array)) { | 1279 if (HAS_INDEX(array, i, is_array)) { |
1280 var element = array[i]; | 1280 var element = array[i]; |
1281 // Prepare break slots for debugger step in. | 1281 // Prepare break slots for debugger step in. |
1282 if (stepping) %DebugPrepareStepInIfStepping(f); | 1282 if (stepping) %DebugPrepareStepInIfStepping(f); |
1283 if (!%_Call(f, receiver, element, i, array)) return false; | 1283 if (!%_Call(f, receiver, element, i, array)) return false; |
1284 } | 1284 } |
1285 } | 1285 } |
1286 return true; | 1286 return true; |
1287 } | 1287 } |
1288 | 1288 |
1289 function ArrayEvery(f, receiver) { | 1289 function ArrayEvery(f, receiver) { |
1290 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every"); | 1290 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every"); |
1291 | 1291 |
1292 // Pull out the length so that modifications to the length in the | 1292 // Pull out the length so that modifications to the length in the |
1293 // loop will not affect the looping and side effects are visible. | 1293 // loop will not affect the looping and side effects are visible. |
1294 var array = TO_OBJECT(this); | 1294 var array = TO_OBJECT(this); |
1295 var length = TO_UINT32(array.length); | 1295 var length = TO_LENGTH_OR_UINT32(array.length); |
1296 return InnerArrayEvery(f, receiver, array, length); | 1296 return InnerArrayEvery(f, receiver, array, length); |
1297 } | 1297 } |
1298 | 1298 |
1299 | 1299 |
1300 function InnerArrayMap(f, receiver, array, length) { | 1300 function InnerArrayMap(f, receiver, array, length) { |
1301 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); | 1301 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); |
1302 | 1302 |
1303 var accumulator = new InternalArray(length); | 1303 var accumulator = new InternalArray(length); |
1304 var is_array = IS_ARRAY(array); | 1304 var is_array = IS_ARRAY(array); |
1305 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); | 1305 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); |
1306 for (var i = 0; i < length; i++) { | 1306 for (var i = 0; i < length; i++) { |
1307 if (HAS_INDEX(array, i, is_array)) { | 1307 if (HAS_INDEX(array, i, is_array)) { |
1308 var element = array[i]; | 1308 var element = array[i]; |
1309 // Prepare break slots for debugger step in. | 1309 // Prepare break slots for debugger step in. |
1310 if (stepping) %DebugPrepareStepInIfStepping(f); | 1310 if (stepping) %DebugPrepareStepInIfStepping(f); |
1311 accumulator[i] = %_Call(f, receiver, element, i, array); | 1311 accumulator[i] = %_Call(f, receiver, element, i, array); |
1312 } | 1312 } |
1313 } | 1313 } |
1314 return accumulator; | 1314 return accumulator; |
1315 } | 1315 } |
1316 | 1316 |
1317 | 1317 |
1318 function ArrayMap(f, receiver) { | 1318 function ArrayMap(f, receiver) { |
1319 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map"); | 1319 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map"); |
1320 | 1320 |
1321 // Pull out the length so that modifications to the length in the | 1321 // Pull out the length so that modifications to the length in the |
1322 // loop will not affect the looping and side effects are visible. | 1322 // loop will not affect the looping and side effects are visible. |
1323 var array = TO_OBJECT(this); | 1323 var array = TO_OBJECT(this); |
1324 var length = TO_UINT32(array.length); | 1324 var length = TO_LENGTH_OR_UINT32(array.length); |
1325 var accumulator = InnerArrayMap(f, receiver, array, length); | 1325 var accumulator = InnerArrayMap(f, receiver, array, length); |
1326 var result = new GlobalArray(); | 1326 var result = new GlobalArray(); |
1327 %MoveArrayContents(accumulator, result); | 1327 %MoveArrayContents(accumulator, result); |
1328 return result; | 1328 return result; |
1329 } | 1329 } |
1330 | 1330 |
1331 | 1331 |
1332 // For .indexOf, we don't need to pass in the number of arguments | 1332 // For .indexOf, we don't need to pass in the number of arguments |
1333 // at the callsite since ToInteger(undefined) == 0; however, for | 1333 // at the callsite since ToInteger(undefined) == 0; however, for |
1334 // .lastIndexOf, we need to pass it, since the behavior for passing | 1334 // .lastIndexOf, we need to pass it, since the behavior for passing |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1383 return i; | 1383 return i; |
1384 } | 1384 } |
1385 } | 1385 } |
1386 return -1; | 1386 return -1; |
1387 } | 1387 } |
1388 | 1388 |
1389 | 1389 |
1390 function ArrayIndexOf(element, index) { | 1390 function ArrayIndexOf(element, index) { |
1391 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.indexOf"); | 1391 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.indexOf"); |
1392 | 1392 |
1393 var length = TO_UINT32(this.length); | 1393 var length = TO_LENGTH_OR_UINT32(this.length); |
1394 return InnerArrayIndexOf(this, element, index, length); | 1394 return InnerArrayIndexOf(this, element, index, length); |
1395 } | 1395 } |
1396 | 1396 |
1397 | 1397 |
1398 function InnerArrayLastIndexOf(array, element, index, length, argumentsLength) { | 1398 function InnerArrayLastIndexOf(array, element, index, length, argumentsLength) { |
1399 if (length == 0) return -1; | 1399 if (length == 0) return -1; |
1400 if (argumentsLength < 2) { | 1400 if (argumentsLength < 2) { |
1401 index = length - 1; | 1401 index = length - 1; |
1402 } else { | 1402 } else { |
1403 index = TO_INTEGER(index); | 1403 index = TO_INTEGER(index); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1441 return i; | 1441 return i; |
1442 } | 1442 } |
1443 } | 1443 } |
1444 return -1; | 1444 return -1; |
1445 } | 1445 } |
1446 | 1446 |
1447 | 1447 |
1448 function ArrayLastIndexOf(element, index) { | 1448 function ArrayLastIndexOf(element, index) { |
1449 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.lastIndexOf"); | 1449 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.lastIndexOf"); |
1450 | 1450 |
1451 var length = TO_UINT32(this.length); | 1451 var length = TO_LENGTH_OR_UINT32(this.length); |
1452 return InnerArrayLastIndexOf(this, element, index, length, | 1452 return InnerArrayLastIndexOf(this, element, index, length, |
1453 %_ArgumentsLength()); | 1453 %_ArgumentsLength()); |
1454 } | 1454 } |
1455 | 1455 |
1456 | 1456 |
1457 function InnerArrayReduce(callback, current, array, length, argumentsLength) { | 1457 function InnerArrayReduce(callback, current, array, length, argumentsLength) { |
1458 if (!IS_CALLABLE(callback)) { | 1458 if (!IS_CALLABLE(callback)) { |
1459 throw MakeTypeError(kCalledNonCallable, callback); | 1459 throw MakeTypeError(kCalledNonCallable, callback); |
1460 } | 1460 } |
1461 | 1461 |
(...skipping 21 matching lines...) Expand all Loading... |
1483 return current; | 1483 return current; |
1484 } | 1484 } |
1485 | 1485 |
1486 | 1486 |
1487 function ArrayReduce(callback, current) { | 1487 function ArrayReduce(callback, current) { |
1488 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce"); | 1488 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce"); |
1489 | 1489 |
1490 // Pull out the length so that modifications to the length in the | 1490 // Pull out the length so that modifications to the length in the |
1491 // loop will not affect the looping and side effects are visible. | 1491 // loop will not affect the looping and side effects are visible. |
1492 var array = TO_OBJECT(this); | 1492 var array = TO_OBJECT(this); |
1493 var length = TO_UINT32(array.length); | 1493 var length = TO_LENGTH_OR_UINT32(array.length); |
1494 return InnerArrayReduce(callback, current, array, length, | 1494 return InnerArrayReduce(callback, current, array, length, |
1495 %_ArgumentsLength()); | 1495 %_ArgumentsLength()); |
1496 } | 1496 } |
1497 | 1497 |
1498 | 1498 |
1499 function InnerArrayReduceRight(callback, current, array, length, | 1499 function InnerArrayReduceRight(callback, current, array, length, |
1500 argumentsLength) { | 1500 argumentsLength) { |
1501 if (!IS_CALLABLE(callback)) { | 1501 if (!IS_CALLABLE(callback)) { |
1502 throw MakeTypeError(kCalledNonCallable, callback); | 1502 throw MakeTypeError(kCalledNonCallable, callback); |
1503 } | 1503 } |
(...skipping 22 matching lines...) Expand all Loading... |
1526 return current; | 1526 return current; |
1527 } | 1527 } |
1528 | 1528 |
1529 | 1529 |
1530 function ArrayReduceRight(callback, current) { | 1530 function ArrayReduceRight(callback, current) { |
1531 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight"); | 1531 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight"); |
1532 | 1532 |
1533 // Pull out the length so that side effects are visible before the | 1533 // Pull out the length so that side effects are visible before the |
1534 // callback function is checked. | 1534 // callback function is checked. |
1535 var array = TO_OBJECT(this); | 1535 var array = TO_OBJECT(this); |
1536 var length = TO_UINT32(array.length); | 1536 var length = TO_LENGTH_OR_UINT32(array.length); |
1537 return InnerArrayReduceRight(callback, current, array, length, | 1537 return InnerArrayReduceRight(callback, current, array, length, |
1538 %_ArgumentsLength()); | 1538 %_ArgumentsLength()); |
1539 } | 1539 } |
1540 | 1540 |
1541 // ES5, 15.4.3.2 | 1541 // ES5, 15.4.3.2 |
1542 function ArrayIsArray(obj) { | 1542 function ArrayIsArray(obj) { |
1543 return IS_ARRAY(obj); | 1543 return IS_ARRAY(obj); |
1544 } | 1544 } |
1545 | 1545 |
1546 | 1546 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1658 %InstallToContext([ | 1658 %InstallToContext([ |
1659 "array_pop", ArrayPop, | 1659 "array_pop", ArrayPop, |
1660 "array_push", ArrayPush, | 1660 "array_push", ArrayPush, |
1661 "array_shift", ArrayShift, | 1661 "array_shift", ArrayShift, |
1662 "array_splice", ArraySplice, | 1662 "array_splice", ArraySplice, |
1663 "array_slice", ArraySlice, | 1663 "array_slice", ArraySlice, |
1664 "array_unshift", ArrayUnshift, | 1664 "array_unshift", ArrayUnshift, |
1665 ]); | 1665 ]); |
1666 | 1666 |
1667 }); | 1667 }); |
OLD | NEW |