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 |
11 // ------------------------------------------------------------------- | 11 // ------------------------------------------------------------------- |
12 // Imports | 12 // Imports |
13 | 13 |
14 var Delete; | 14 var Delete; |
15 var GlobalArray = global.Array; | 15 var GlobalArray = global.Array; |
16 var InternalArray = utils.InternalArray; | 16 var InternalArray = utils.InternalArray; |
17 var InternalPackedArray = utils.InternalPackedArray; | 17 var InternalPackedArray = utils.InternalPackedArray; |
18 var MathMin; | 18 var MathMin; |
19 var ObjectHasOwnProperty; | 19 var ObjectHasOwnProperty; |
20 var ObjectIsFrozen; | 20 var ObjectIsFrozen; |
21 var ObjectIsSealed; | 21 var ObjectIsSealed; |
22 var ObjectToString; | 22 var ObjectToString; |
23 var ToNumber; | 23 var ToNumber; |
24 var ToString; | 24 var ToString; |
| 25 var ToLengthFlagged; |
25 | 26 |
26 utils.Import(function(from) { | 27 utils.Import(function(from) { |
27 Delete = from.Delete; | 28 Delete = from.Delete; |
28 MathMin = from.MathMin; | 29 MathMin = from.MathMin; |
29 ObjectHasOwnProperty = from.ObjectHasOwnProperty; | 30 ObjectHasOwnProperty = from.ObjectHasOwnProperty; |
30 ObjectIsFrozen = from.ObjectIsFrozen; | 31 ObjectIsFrozen = from.ObjectIsFrozen; |
31 ObjectIsSealed = from.ObjectIsSealed; | 32 ObjectIsSealed = from.ObjectIsSealed; |
32 ObjectToString = from.ObjectToString; | 33 ObjectToString = from.ObjectToString; |
33 ToNumber = from.ToNumber; | 34 ToNumber = from.ToNumber; |
34 ToString = from.ToString; | 35 ToString = from.ToString; |
| 36 ToLengthFlagged = from.ToLengthFlagged; |
35 }); | 37 }); |
36 | 38 |
37 // ------------------------------------------------------------------- | 39 // ------------------------------------------------------------------- |
38 | 40 |
39 // Global list of arrays visited during toString, toLocaleString and | 41 // Global list of arrays visited during toString, toLocaleString and |
40 // join invocations. | 42 // join invocations. |
41 var visited_arrays = new InternalArray(); | 43 var visited_arrays = new InternalArray(); |
42 | 44 |
43 | 45 |
44 // Gets a sorted array of array keys. Useful for operations on sparse | 46 // Gets a sorted array of array keys. Useful for operations on sparse |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 func = array.join; | 389 func = array.join; |
388 } | 390 } |
389 if (!IS_SPEC_FUNCTION(func)) { | 391 if (!IS_SPEC_FUNCTION(func)) { |
390 return %_CallFunction(array, ObjectToString); | 392 return %_CallFunction(array, ObjectToString); |
391 } | 393 } |
392 return %_CallFunction(array, func); | 394 return %_CallFunction(array, func); |
393 } | 395 } |
394 | 396 |
395 | 397 |
396 function InnerArrayToLocaleString(array, length) { | 398 function InnerArrayToLocaleString(array, length) { |
397 var len = TO_UINT32(length); | 399 var len = ToLengthFlagged(length); |
398 if (len === 0) return ""; | 400 if (len === 0) return ""; |
399 return Join(array, len, ',', ConvertToLocaleString); | 401 return Join(array, len, ',', ConvertToLocaleString); |
400 } | 402 } |
401 | 403 |
402 | 404 |
403 function ArrayToLocaleString() { | 405 function ArrayToLocaleString() { |
404 var array = TO_OBJECT(this); | 406 var array = TO_OBJECT(this); |
405 var arrayLen = array.length; | 407 var arrayLen = array.length; |
406 return InnerArrayToLocaleString(array, arrayLen); | 408 return InnerArrayToLocaleString(array, arrayLen); |
407 } | 409 } |
(...skipping 18 matching lines...) Expand all Loading... |
426 } | 428 } |
427 | 429 |
428 return Join(array, length, separator, ConvertToString); | 430 return Join(array, length, separator, ConvertToString); |
429 } | 431 } |
430 | 432 |
431 | 433 |
432 function ArrayJoin(separator) { | 434 function ArrayJoin(separator) { |
433 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join"); | 435 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join"); |
434 | 436 |
435 var array = TO_OBJECT(this); | 437 var array = TO_OBJECT(this); |
436 var length = TO_UINT32(array.length); | 438 var length = ToLengthFlagged(array.length); |
437 | 439 |
438 return InnerArrayJoin(separator, array, length); | 440 return InnerArrayJoin(separator, array, length); |
439 } | 441 } |
440 | 442 |
441 | 443 |
442 function ObservedArrayPop(n) { | 444 function ObservedArrayPop(n) { |
443 n--; | 445 n--; |
444 var value = this[n]; | 446 var value = this[n]; |
445 | 447 |
446 try { | 448 try { |
447 $observeBeginPerformSplice(this); | 449 $observeBeginPerformSplice(this); |
448 delete this[n]; | 450 delete this[n]; |
449 this.length = n; | 451 this.length = n; |
450 } finally { | 452 } finally { |
451 $observeEndPerformSplice(this); | 453 $observeEndPerformSplice(this); |
452 $observeEnqueueSpliceRecord(this, n, [value], 0); | 454 $observeEnqueueSpliceRecord(this, n, [value], 0); |
453 } | 455 } |
454 | 456 |
455 return value; | 457 return value; |
456 } | 458 } |
457 | 459 |
458 | 460 |
459 // Removes the last element from the array and returns it. See | 461 // Removes the last element from the array and returns it. See |
460 // ECMA-262, section 15.4.4.6. | 462 // ECMA-262, section 15.4.4.6. |
461 function ArrayPop() { | 463 function ArrayPop() { |
462 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.pop"); | 464 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.pop"); |
463 | 465 |
464 var array = TO_OBJECT(this); | 466 var array = TO_OBJECT(this); |
465 var n = TO_UINT32(array.length); | 467 var n = ToLengthFlagged(array.length); |
466 if (n == 0) { | 468 if (n == 0) { |
467 array.length = n; | 469 array.length = n; |
468 return; | 470 return; |
469 } | 471 } |
470 | 472 |
471 if (%IsObserved(array)) | 473 if (%IsObserved(array)) |
472 return ObservedArrayPop.call(array, n); | 474 return ObservedArrayPop.call(array, n); |
473 | 475 |
474 n--; | 476 n--; |
475 var value = array[n]; | 477 var value = array[n]; |
476 Delete(array, n, true); | 478 Delete(array, n, true); |
477 array.length = n; | 479 array.length = n; |
478 return value; | 480 return value; |
479 } | 481 } |
480 | 482 |
481 | 483 |
482 function ObservedArrayPush() { | 484 function ObservedArrayPush() { |
483 var n = TO_UINT32(this.length); | 485 var n = ToLengthFlagged(this.length); |
484 var m = %_ArgumentsLength(); | 486 var m = %_ArgumentsLength(); |
485 | 487 |
486 try { | 488 try { |
487 $observeBeginPerformSplice(this); | 489 $observeBeginPerformSplice(this); |
488 for (var i = 0; i < m; i++) { | 490 for (var i = 0; i < m; i++) { |
489 this[i+n] = %_Arguments(i); | 491 this[i+n] = %_Arguments(i); |
490 } | 492 } |
491 var new_length = n + m; | 493 var new_length = n + m; |
492 this.length = new_length; | 494 this.length = new_length; |
493 } finally { | 495 } finally { |
494 $observeEndPerformSplice(this); | 496 $observeEndPerformSplice(this); |
495 $observeEnqueueSpliceRecord(this, n, [], m); | 497 $observeEnqueueSpliceRecord(this, n, [], m); |
496 } | 498 } |
497 | 499 |
498 return new_length; | 500 return new_length; |
499 } | 501 } |
500 | 502 |
501 | 503 |
502 // Appends the arguments to the end of the array and returns the new | 504 // Appends the arguments to the end of the array and returns the new |
503 // length of the array. See ECMA-262, section 15.4.4.7. | 505 // length of the array. See ECMA-262, section 15.4.4.7. |
504 function ArrayPush() { | 506 function ArrayPush() { |
505 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push"); | 507 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push"); |
506 | 508 |
507 if (%IsObserved(this)) | 509 if (%IsObserved(this)) |
508 return ObservedArrayPush.apply(this, arguments); | 510 return ObservedArrayPush.apply(this, arguments); |
509 | 511 |
510 var array = TO_OBJECT(this); | 512 var array = TO_OBJECT(this); |
511 var n = TO_UINT32(array.length); | 513 var n = ToLengthFlagged(array.length); |
512 var m = %_ArgumentsLength(); | 514 var m = %_ArgumentsLength(); |
513 | 515 |
514 for (var i = 0; i < m; i++) { | 516 for (var i = 0; i < m; i++) { |
515 array[i+n] = %_Arguments(i); | 517 array[i+n] = %_Arguments(i); |
516 } | 518 } |
517 | 519 |
518 var new_length = n + m; | 520 var new_length = n + m; |
519 array.length = new_length; | 521 array.length = new_length; |
520 return new_length; | 522 return new_length; |
521 } | 523 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 } | 618 } |
617 } | 619 } |
618 return array; | 620 return array; |
619 } | 621 } |
620 | 622 |
621 | 623 |
622 function ArrayReverse() { | 624 function ArrayReverse() { |
623 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse"); | 625 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse"); |
624 | 626 |
625 var array = TO_OBJECT(this); | 627 var array = TO_OBJECT(this); |
626 var len = TO_UINT32(array.length); | 628 var len = ToLengthFlagged(array.length); |
627 var isArray = IS_ARRAY(array); | 629 var isArray = IS_ARRAY(array); |
628 | 630 |
629 if (UseSparseVariant(array, len, isArray, len)) { | 631 if (UseSparseVariant(array, len, isArray, len)) { |
630 %NormalizeElements(array); | 632 %NormalizeElements(array); |
631 SparseReverse(array, len); | 633 SparseReverse(array, len); |
632 return array; | 634 return array; |
633 } else if (isArray && %_HasFastPackedElements(array)) { | 635 } else if (isArray && %_HasFastPackedElements(array)) { |
634 return PackedArrayReverse(array, len); | 636 return PackedArrayReverse(array, len); |
635 } else { | 637 } else { |
636 return GenericArrayReverse(array, len); | 638 return GenericArrayReverse(array, len); |
(...skipping 14 matching lines...) Expand all Loading... |
651 } | 653 } |
652 | 654 |
653 return first; | 655 return first; |
654 } | 656 } |
655 | 657 |
656 | 658 |
657 function ArrayShift() { | 659 function ArrayShift() { |
658 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift"); | 660 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift"); |
659 | 661 |
660 var array = TO_OBJECT(this); | 662 var array = TO_OBJECT(this); |
661 var len = TO_UINT32(array.length); | 663 var len = ToLengthFlagged(array.length); |
662 | 664 |
663 if (len === 0) { | 665 if (len === 0) { |
664 array.length = 0; | 666 array.length = 0; |
665 return; | 667 return; |
666 } | 668 } |
667 | 669 |
668 if (ObjectIsSealed(array)) throw MakeTypeError(kArrayFunctionsOnSealed); | 670 if (ObjectIsSealed(array)) throw MakeTypeError(kArrayFunctionsOnSealed); |
669 | 671 |
670 if (%IsObserved(array)) | 672 if (%IsObserved(array)) |
671 return ObservedArrayShift.call(array, len); | 673 return ObservedArrayShift.call(array, len); |
672 | 674 |
673 var first = array[0]; | 675 var first = array[0]; |
674 | 676 |
675 if (UseSparseVariant(array, len, IS_ARRAY(array), len)) { | 677 if (UseSparseVariant(array, len, IS_ARRAY(array), len)) { |
676 SparseMove(array, 0, 1, len, 0); | 678 SparseMove(array, 0, 1, len, 0); |
677 } else { | 679 } else { |
678 SimpleMove(array, 0, 1, len, 0); | 680 SimpleMove(array, 0, 1, len, 0); |
679 } | 681 } |
680 | 682 |
681 array.length = len - 1; | 683 array.length = len - 1; |
682 | 684 |
683 return first; | 685 return first; |
684 } | 686 } |
685 | 687 |
686 | 688 |
687 function ObservedArrayUnshift() { | 689 function ObservedArrayUnshift() { |
688 var len = TO_UINT32(this.length); | 690 var len = ToLengthFlagged(this.length); |
689 var num_arguments = %_ArgumentsLength(); | 691 var num_arguments = %_ArgumentsLength(); |
690 | 692 |
691 try { | 693 try { |
692 $observeBeginPerformSplice(this); | 694 $observeBeginPerformSplice(this); |
693 SimpleMove(this, 0, 0, len, num_arguments); | 695 SimpleMove(this, 0, 0, len, num_arguments); |
694 for (var i = 0; i < num_arguments; i++) { | 696 for (var i = 0; i < num_arguments; i++) { |
695 this[i] = %_Arguments(i); | 697 this[i] = %_Arguments(i); |
696 } | 698 } |
697 var new_length = len + num_arguments; | 699 var new_length = len + num_arguments; |
698 this.length = new_length; | 700 this.length = new_length; |
699 } finally { | 701 } finally { |
700 $observeEndPerformSplice(this); | 702 $observeEndPerformSplice(this); |
701 $observeEnqueueSpliceRecord(this, 0, [], num_arguments); | 703 $observeEnqueueSpliceRecord(this, 0, [], num_arguments); |
702 } | 704 } |
703 | 705 |
704 return new_length; | 706 return new_length; |
705 } | 707 } |
706 | 708 |
707 | 709 |
708 function ArrayUnshift(arg1) { // length == 1 | 710 function ArrayUnshift(arg1) { // length == 1 |
709 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift"); | 711 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift"); |
710 | 712 |
711 if (%IsObserved(this)) | 713 if (%IsObserved(this)) |
712 return ObservedArrayUnshift.apply(this, arguments); | 714 return ObservedArrayUnshift.apply(this, arguments); |
713 | 715 |
714 var array = TO_OBJECT(this); | 716 var array = TO_OBJECT(this); |
715 var len = TO_UINT32(array.length); | 717 var len = ToLengthFlagged(array.length); |
716 var num_arguments = %_ArgumentsLength(); | 718 var num_arguments = %_ArgumentsLength(); |
717 | 719 |
718 if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) && | 720 if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) && |
719 !ObjectIsSealed(array)) { | 721 !ObjectIsSealed(array)) { |
720 SparseMove(array, 0, 0, len, num_arguments); | 722 SparseMove(array, 0, 0, len, num_arguments); |
721 } else { | 723 } else { |
722 SimpleMove(array, 0, 0, len, num_arguments); | 724 SimpleMove(array, 0, 0, len, num_arguments); |
723 } | 725 } |
724 | 726 |
725 for (var i = 0; i < num_arguments; i++) { | 727 for (var i = 0; i < num_arguments; i++) { |
726 array[i] = %_Arguments(i); | 728 array[i] = %_Arguments(i); |
727 } | 729 } |
728 | 730 |
729 var new_length = len + num_arguments; | 731 var new_length = len + num_arguments; |
730 array.length = new_length; | 732 array.length = new_length; |
731 return new_length; | 733 return new_length; |
732 } | 734 } |
733 | 735 |
734 | 736 |
735 function ArraySlice(start, end) { | 737 function ArraySlice(start, end) { |
736 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); | 738 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); |
737 | 739 |
738 var array = TO_OBJECT(this); | 740 var array = TO_OBJECT(this); |
739 var len = TO_UINT32(array.length); | 741 var len = ToLengthFlagged(array.length); |
740 var start_i = TO_INTEGER(start); | 742 var start_i = TO_INTEGER(start); |
741 var end_i = len; | 743 var end_i = len; |
742 | 744 |
743 if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end); | 745 if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end); |
744 | 746 |
745 if (start_i < 0) { | 747 if (start_i < 0) { |
746 start_i += len; | 748 start_i += len; |
747 if (start_i < 0) start_i = 0; | 749 if (start_i < 0) start_i = 0; |
748 } else { | 750 } else { |
749 if (start_i > len) start_i = len; | 751 if (start_i > len) start_i = len; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 | 802 |
801 if (del_count > len - start_i) | 803 if (del_count > len - start_i) |
802 return len - start_i; | 804 return len - start_i; |
803 | 805 |
804 return del_count; | 806 return del_count; |
805 } | 807 } |
806 | 808 |
807 | 809 |
808 function ObservedArraySplice(start, delete_count) { | 810 function ObservedArraySplice(start, delete_count) { |
809 var num_arguments = %_ArgumentsLength(); | 811 var num_arguments = %_ArgumentsLength(); |
810 var len = TO_UINT32(this.length); | 812 var len = ToLengthFlagged(this.length); |
811 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); | 813 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); |
812 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, | 814 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, |
813 start_i); | 815 start_i); |
814 var deleted_elements = []; | 816 var deleted_elements = []; |
815 deleted_elements.length = del_count; | 817 deleted_elements.length = del_count; |
816 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; | 818 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; |
817 | 819 |
818 try { | 820 try { |
819 $observeBeginPerformSplice(this); | 821 $observeBeginPerformSplice(this); |
820 | 822 |
(...skipping 26 matching lines...) Expand all Loading... |
847 | 849 |
848 | 850 |
849 function ArraySplice(start, delete_count) { | 851 function ArraySplice(start, delete_count) { |
850 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice"); | 852 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice"); |
851 | 853 |
852 if (%IsObserved(this)) | 854 if (%IsObserved(this)) |
853 return ObservedArraySplice.apply(this, arguments); | 855 return ObservedArraySplice.apply(this, arguments); |
854 | 856 |
855 var num_arguments = %_ArgumentsLength(); | 857 var num_arguments = %_ArgumentsLength(); |
856 var array = TO_OBJECT(this); | 858 var array = TO_OBJECT(this); |
857 var len = TO_UINT32(array.length); | 859 var len = ToLengthFlagged(array.length); |
858 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); | 860 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); |
859 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, | 861 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, |
860 start_i); | 862 start_i); |
861 var deleted_elements = []; | 863 var deleted_elements = []; |
862 deleted_elements.length = del_count; | 864 deleted_elements.length = del_count; |
863 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; | 865 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; |
864 | 866 |
865 if (del_count != num_elements_to_add && ObjectIsSealed(array)) { | 867 if (del_count != num_elements_to_add && ObjectIsSealed(array)) { |
866 throw MakeTypeError(kArrayFunctionsOnSealed); | 868 throw MakeTypeError(kArrayFunctionsOnSealed); |
867 } else if (del_count > 0 && ObjectIsFrozen(array)) { | 869 } else if (del_count > 0 && ObjectIsFrozen(array)) { |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 } | 1181 } |
1180 | 1182 |
1181 return this; | 1183 return this; |
1182 } | 1184 } |
1183 | 1185 |
1184 | 1186 |
1185 function ArraySort(comparefn) { | 1187 function ArraySort(comparefn) { |
1186 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort"); | 1188 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort"); |
1187 | 1189 |
1188 var array = TO_OBJECT(this); | 1190 var array = TO_OBJECT(this); |
1189 var length = TO_UINT32(array.length); | 1191 var length = ToLengthFlagged(array.length); |
1190 return %_CallFunction(array, length, comparefn, InnerArraySort); | 1192 return %_CallFunction(array, length, comparefn, InnerArraySort); |
1191 } | 1193 } |
1192 | 1194 |
1193 | 1195 |
1194 // The following functions cannot be made efficient on sparse arrays while | 1196 // The following functions cannot be made efficient on sparse arrays while |
1195 // preserving the semantics, since the calls to the receiver function can add | 1197 // preserving the semantics, since the calls to the receiver function can add |
1196 // or delete elements from the array. | 1198 // or delete elements from the array. |
1197 function InnerArrayFilter(f, receiver, array, length) { | 1199 function InnerArrayFilter(f, receiver, array, length) { |
1198 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); | 1200 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); |
1199 var needs_wrapper = false; | 1201 var needs_wrapper = false; |
(...skipping 20 matching lines...) Expand all Loading... |
1220 } | 1222 } |
1221 return accumulator; | 1223 return accumulator; |
1222 } | 1224 } |
1223 | 1225 |
1224 function ArrayFilter(f, receiver) { | 1226 function ArrayFilter(f, receiver) { |
1225 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter"); | 1227 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter"); |
1226 | 1228 |
1227 // Pull out the length so that modifications to the length in the | 1229 // Pull out the length so that modifications to the length in the |
1228 // loop will not affect the looping and side effects are visible. | 1230 // loop will not affect the looping and side effects are visible. |
1229 var array = TO_OBJECT(this); | 1231 var array = TO_OBJECT(this); |
1230 var length = TO_UINT32(array.length); | 1232 var length = ToLengthFlagged(array.length); |
1231 var accumulator = InnerArrayFilter(f, receiver, array, length); | 1233 var accumulator = InnerArrayFilter(f, receiver, array, length); |
1232 var result = new GlobalArray(); | 1234 var result = new GlobalArray(); |
1233 %MoveArrayContents(accumulator, result); | 1235 %MoveArrayContents(accumulator, result); |
1234 return result; | 1236 return result; |
1235 } | 1237 } |
1236 | 1238 |
1237 function InnerArrayForEach(f, receiver, array, length) { | 1239 function InnerArrayForEach(f, receiver, array, length) { |
1238 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); | 1240 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); |
1239 var needs_wrapper = false; | 1241 var needs_wrapper = false; |
1240 if (IS_NULL(receiver)) { | 1242 if (IS_NULL(receiver)) { |
(...skipping 14 matching lines...) Expand all Loading... |
1255 } | 1257 } |
1256 } | 1258 } |
1257 } | 1259 } |
1258 | 1260 |
1259 function ArrayForEach(f, receiver) { | 1261 function ArrayForEach(f, receiver) { |
1260 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach"); | 1262 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach"); |
1261 | 1263 |
1262 // Pull out the length so that modifications to the length in the | 1264 // Pull out the length so that modifications to the length in the |
1263 // loop will not affect the looping and side effects are visible. | 1265 // loop will not affect the looping and side effects are visible. |
1264 var array = TO_OBJECT(this); | 1266 var array = TO_OBJECT(this); |
1265 var length = TO_UINT32(array.length); | 1267 var length = ToLengthFlagged(array.length); |
1266 InnerArrayForEach(f, receiver, array, length); | 1268 InnerArrayForEach(f, receiver, array, length); |
1267 } | 1269 } |
1268 | 1270 |
1269 | 1271 |
1270 function InnerArraySome(f, receiver, array, length) { | 1272 function InnerArraySome(f, receiver, array, length) { |
1271 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); | 1273 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); |
1272 var needs_wrapper = false; | 1274 var needs_wrapper = false; |
1273 if (IS_NULL(receiver)) { | 1275 if (IS_NULL(receiver)) { |
1274 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; | 1276 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; |
1275 } else if (!IS_UNDEFINED(receiver)) { | 1277 } else if (!IS_UNDEFINED(receiver)) { |
(...skipping 16 matching lines...) Expand all Loading... |
1292 | 1294 |
1293 | 1295 |
1294 // Executes the function once for each element present in the | 1296 // Executes the function once for each element present in the |
1295 // array until it finds one where callback returns true. | 1297 // array until it finds one where callback returns true. |
1296 function ArraySome(f, receiver) { | 1298 function ArraySome(f, receiver) { |
1297 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some"); | 1299 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some"); |
1298 | 1300 |
1299 // Pull out the length so that modifications to the length in the | 1301 // Pull out the length so that modifications to the length in the |
1300 // loop will not affect the looping and side effects are visible. | 1302 // loop will not affect the looping and side effects are visible. |
1301 var array = TO_OBJECT(this); | 1303 var array = TO_OBJECT(this); |
1302 var length = TO_UINT32(array.length); | 1304 var length = ToLengthFlagged(array.length); |
1303 return InnerArraySome(f, receiver, array, length); | 1305 return InnerArraySome(f, receiver, array, length); |
1304 } | 1306 } |
1305 | 1307 |
1306 | 1308 |
1307 function InnerArrayEvery(f, receiver, array, length) { | 1309 function InnerArrayEvery(f, receiver, array, length) { |
1308 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); | 1310 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); |
1309 var needs_wrapper = false; | 1311 var needs_wrapper = false; |
1310 if (IS_NULL(receiver)) { | 1312 if (IS_NULL(receiver)) { |
1311 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; | 1313 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; |
1312 } else if (!IS_UNDEFINED(receiver)) { | 1314 } else if (!IS_UNDEFINED(receiver)) { |
(...skipping 13 matching lines...) Expand all Loading... |
1326 } | 1328 } |
1327 return true; | 1329 return true; |
1328 } | 1330 } |
1329 | 1331 |
1330 function ArrayEvery(f, receiver) { | 1332 function ArrayEvery(f, receiver) { |
1331 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every"); | 1333 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every"); |
1332 | 1334 |
1333 // Pull out the length so that modifications to the length in the | 1335 // Pull out the length so that modifications to the length in the |
1334 // loop will not affect the looping and side effects are visible. | 1336 // loop will not affect the looping and side effects are visible. |
1335 var array = TO_OBJECT(this); | 1337 var array = TO_OBJECT(this); |
1336 var length = TO_UINT32(array.length); | 1338 var length = ToLengthFlagged(array.length); |
1337 return InnerArrayEvery(f, receiver, array, length); | 1339 return InnerArrayEvery(f, receiver, array, length); |
1338 } | 1340 } |
1339 | 1341 |
1340 | 1342 |
1341 function InnerArrayMap(f, receiver, array, length) { | 1343 function InnerArrayMap(f, receiver, array, length) { |
1342 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); | 1344 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); |
1343 var needs_wrapper = false; | 1345 var needs_wrapper = false; |
1344 if (IS_NULL(receiver)) { | 1346 if (IS_NULL(receiver)) { |
1345 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; | 1347 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; |
1346 } else if (!IS_UNDEFINED(receiver)) { | 1348 } else if (!IS_UNDEFINED(receiver)) { |
(...skipping 15 matching lines...) Expand all Loading... |
1362 return accumulator; | 1364 return accumulator; |
1363 } | 1365 } |
1364 | 1366 |
1365 | 1367 |
1366 function ArrayMap(f, receiver) { | 1368 function ArrayMap(f, receiver) { |
1367 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map"); | 1369 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map"); |
1368 | 1370 |
1369 // Pull out the length so that modifications to the length in the | 1371 // Pull out the length so that modifications to the length in the |
1370 // loop will not affect the looping and side effects are visible. | 1372 // loop will not affect the looping and side effects are visible. |
1371 var array = TO_OBJECT(this); | 1373 var array = TO_OBJECT(this); |
1372 var length = TO_UINT32(array.length); | 1374 var length = ToLengthFlagged(array.length); |
1373 var accumulator = InnerArrayMap(f, receiver, array, length); | 1375 var accumulator = InnerArrayMap(f, receiver, array, length); |
1374 var result = new GlobalArray(); | 1376 var result = new GlobalArray(); |
1375 %MoveArrayContents(accumulator, result); | 1377 %MoveArrayContents(accumulator, result); |
1376 return result; | 1378 return result; |
1377 } | 1379 } |
1378 | 1380 |
1379 | 1381 |
1380 // For .indexOf, we don't need to pass in the number of arguments | 1382 // For .indexOf, we don't need to pass in the number of arguments |
1381 // at the callsite since ToInteger(undefined) == 0; however, for | 1383 // at the callsite since ToInteger(undefined) == 0; however, for |
1382 // .lastIndexOf, we need to pass it, since the behavior for passing | 1384 // .lastIndexOf, we need to pass it, since the behavior for passing |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 return i; | 1433 return i; |
1432 } | 1434 } |
1433 } | 1435 } |
1434 return -1; | 1436 return -1; |
1435 } | 1437 } |
1436 | 1438 |
1437 | 1439 |
1438 function ArrayIndexOf(element, index) { | 1440 function ArrayIndexOf(element, index) { |
1439 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.indexOf"); | 1441 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.indexOf"); |
1440 | 1442 |
1441 var length = TO_UINT32(this.length); | 1443 var length = ToLengthFlagged(this.length); |
1442 return %_CallFunction(this, element, index, length, InnerArrayIndexOf); | 1444 return %_CallFunction(this, element, index, length, InnerArrayIndexOf); |
1443 } | 1445 } |
1444 | 1446 |
1445 | 1447 |
1446 function InnerArrayLastIndexOf(element, index, length, argumentsLength) { | 1448 function InnerArrayLastIndexOf(element, index, length, argumentsLength) { |
1447 if (length == 0) return -1; | 1449 if (length == 0) return -1; |
1448 if (argumentsLength < 2) { | 1450 if (argumentsLength < 2) { |
1449 index = length - 1; | 1451 index = length - 1; |
1450 } else { | 1452 } else { |
1451 index = TO_INTEGER(index); | 1453 index = TO_INTEGER(index); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1489 return i; | 1491 return i; |
1490 } | 1492 } |
1491 } | 1493 } |
1492 return -1; | 1494 return -1; |
1493 } | 1495 } |
1494 | 1496 |
1495 | 1497 |
1496 function ArrayLastIndexOf(element, index) { | 1498 function ArrayLastIndexOf(element, index) { |
1497 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.lastIndexOf"); | 1499 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.lastIndexOf"); |
1498 | 1500 |
1499 var length = TO_UINT32(this.length); | 1501 var length = ToLengthFlagged(this.length); |
1500 return %_CallFunction(this, element, index, length, | 1502 return %_CallFunction(this, element, index, length, |
1501 %_ArgumentsLength(), InnerArrayLastIndexOf); | 1503 %_ArgumentsLength(), InnerArrayLastIndexOf); |
1502 } | 1504 } |
1503 | 1505 |
1504 | 1506 |
1505 function InnerArrayReduce(callback, current, array, length, argumentsLength) { | 1507 function InnerArrayReduce(callback, current, array, length, argumentsLength) { |
1506 if (!IS_SPEC_FUNCTION(callback)) { | 1508 if (!IS_SPEC_FUNCTION(callback)) { |
1507 throw MakeTypeError(kCalledNonCallable, callback); | 1509 throw MakeTypeError(kCalledNonCallable, callback); |
1508 } | 1510 } |
1509 | 1511 |
(...skipping 21 matching lines...) Expand all Loading... |
1531 return current; | 1533 return current; |
1532 } | 1534 } |
1533 | 1535 |
1534 | 1536 |
1535 function ArrayReduce(callback, current) { | 1537 function ArrayReduce(callback, current) { |
1536 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce"); | 1538 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce"); |
1537 | 1539 |
1538 // Pull out the length so that modifications to the length in the | 1540 // Pull out the length so that modifications to the length in the |
1539 // loop will not affect the looping and side effects are visible. | 1541 // loop will not affect the looping and side effects are visible. |
1540 var array = TO_OBJECT(this); | 1542 var array = TO_OBJECT(this); |
1541 var length = TO_UINT32(array.length); | 1543 var length = ToLengthFlagged(array.length); |
1542 return InnerArrayReduce(callback, current, array, length, | 1544 return InnerArrayReduce(callback, current, array, length, |
1543 %_ArgumentsLength()); | 1545 %_ArgumentsLength()); |
1544 } | 1546 } |
1545 | 1547 |
1546 | 1548 |
1547 function InnerArrayReduceRight(callback, current, array, length, | 1549 function InnerArrayReduceRight(callback, current, array, length, |
1548 argumentsLength) { | 1550 argumentsLength) { |
1549 if (!IS_SPEC_FUNCTION(callback)) { | 1551 if (!IS_SPEC_FUNCTION(callback)) { |
1550 throw MakeTypeError(kCalledNonCallable, callback); | 1552 throw MakeTypeError(kCalledNonCallable, callback); |
1551 } | 1553 } |
(...skipping 22 matching lines...) Expand all Loading... |
1574 return current; | 1576 return current; |
1575 } | 1577 } |
1576 | 1578 |
1577 | 1579 |
1578 function ArrayReduceRight(callback, current) { | 1580 function ArrayReduceRight(callback, current) { |
1579 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight"); | 1581 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight"); |
1580 | 1582 |
1581 // Pull out the length so that side effects are visible before the | 1583 // Pull out the length so that side effects are visible before the |
1582 // callback function is checked. | 1584 // callback function is checked. |
1583 var array = TO_OBJECT(this); | 1585 var array = TO_OBJECT(this); |
1584 var length = TO_UINT32(array.length); | 1586 var length = ToLengthFlagged(array.length); |
1585 return InnerArrayReduceRight(callback, current, array, length, | 1587 return InnerArrayReduceRight(callback, current, array, length, |
1586 %_ArgumentsLength()); | 1588 %_ArgumentsLength()); |
1587 } | 1589 } |
1588 | 1590 |
1589 // ES5, 15.4.3.2 | 1591 // ES5, 15.4.3.2 |
1590 function ArrayIsArray(obj) { | 1592 function ArrayIsArray(obj) { |
1591 return IS_ARRAY(obj); | 1593 return IS_ARRAY(obj); |
1592 } | 1594 } |
1593 | 1595 |
1594 | 1596 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1708 "array_concat", ArrayConcatJS, | 1710 "array_concat", ArrayConcatJS, |
1709 "array_pop", ArrayPop, | 1711 "array_pop", ArrayPop, |
1710 "array_push", ArrayPush, | 1712 "array_push", ArrayPush, |
1711 "array_shift", ArrayShift, | 1713 "array_shift", ArrayShift, |
1712 "array_splice", ArraySplice, | 1714 "array_splice", ArraySplice, |
1713 "array_slice", ArraySlice, | 1715 "array_slice", ArraySlice, |
1714 "array_unshift", ArrayUnshift, | 1716 "array_unshift", ArrayUnshift, |
1715 ]); | 1717 ]); |
1716 | 1718 |
1717 }); | 1719 }); |
OLD | NEW |