| 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 |