OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 | 390 |
391 function ArrayToLocaleString() { | 391 function ArrayToLocaleString() { |
392 if (!IS_ARRAY(this)) { | 392 if (!IS_ARRAY(this)) { |
393 throw new $TypeError('Array.prototype.toString is not generic'); | 393 throw new $TypeError('Array.prototype.toString is not generic'); |
394 } | 394 } |
395 return Join(this, this.length, ',', ConvertToLocaleString); | 395 return Join(this, this.length, ',', ConvertToLocaleString); |
396 } | 396 } |
397 | 397 |
398 | 398 |
399 function ArrayJoin(separator) { | 399 function ArrayJoin(separator) { |
400 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
401 throw MakeTypeError("called_on_null_or_undefined", | |
402 ["Array.prototype.join"]); | |
403 } | |
404 | |
405 if (IS_UNDEFINED(separator)) { | 400 if (IS_UNDEFINED(separator)) { |
406 separator = ','; | 401 separator = ','; |
407 } else if (!IS_STRING(separator)) { | 402 } else if (!IS_STRING(separator)) { |
408 separator = NonStringToString(separator); | 403 separator = NonStringToString(separator); |
409 } | 404 } |
410 | 405 |
411 var result = %_FastAsciiArrayJoin(this, separator); | 406 var result = %_FastAsciiArrayJoin(this, separator); |
412 if (!IS_UNDEFINED(result)) return result; | 407 if (!IS_UNDEFINED(result)) return result; |
413 | 408 |
414 return Join(this, TO_UINT32(this.length), separator, ConvertToString); | 409 return Join(this, TO_UINT32(this.length), separator, ConvertToString); |
415 } | 410 } |
416 | 411 |
417 | 412 |
418 // Removes the last element from the array and returns it. See | 413 // Removes the last element from the array and returns it. See |
419 // ECMA-262, section 15.4.4.6. | 414 // ECMA-262, section 15.4.4.6. |
420 function ArrayPop() { | 415 function ArrayPop() { |
421 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
422 throw MakeTypeError("called_on_null_or_undefined", | |
423 ["Array.prototype.pop"]); | |
424 } | |
425 | |
426 var n = TO_UINT32(this.length); | 416 var n = TO_UINT32(this.length); |
427 if (n == 0) { | 417 if (n == 0) { |
428 this.length = n; | 418 this.length = n; |
429 return; | 419 return; |
430 } | 420 } |
431 n--; | 421 n--; |
432 var value = this[n]; | 422 var value = this[n]; |
433 this.length = n; | 423 this.length = n; |
434 delete this[n]; | 424 delete this[n]; |
435 return value; | 425 return value; |
436 } | 426 } |
437 | 427 |
438 | 428 |
439 // Appends the arguments to the end of the array and returns the new | 429 // Appends the arguments to the end of the array and returns the new |
440 // length of the array. See ECMA-262, section 15.4.4.7. | 430 // length of the array. See ECMA-262, section 15.4.4.7. |
441 function ArrayPush() { | 431 function ArrayPush() { |
442 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
443 throw MakeTypeError("called_on_null_or_undefined", | |
444 ["Array.prototype.push"]); | |
445 } | |
446 | |
447 var n = TO_UINT32(this.length); | 432 var n = TO_UINT32(this.length); |
448 var m = %_ArgumentsLength(); | 433 var m = %_ArgumentsLength(); |
449 for (var i = 0; i < m; i++) { | 434 for (var i = 0; i < m; i++) { |
450 this[i+n] = %_Arguments(i); | 435 this[i+n] = %_Arguments(i); |
451 } | 436 } |
452 this.length = n + m; | 437 this.length = n + m; |
453 return this.length; | 438 return this.length; |
454 } | 439 } |
455 | 440 |
456 | 441 |
457 function ArrayConcat(arg1) { // length == 1 | 442 function ArrayConcat(arg1) { // length == 1 |
458 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
459 throw MakeTypeError("called_on_null_or_undefined", | |
460 ["Array.prototype.concat"]); | |
461 } | |
462 | |
463 var arg_count = %_ArgumentsLength(); | 443 var arg_count = %_ArgumentsLength(); |
464 var arrays = new InternalArray(1 + arg_count); | 444 var arrays = new InternalArray(1 + arg_count); |
465 arrays[0] = this; | 445 arrays[0] = this; |
466 for (var i = 0; i < arg_count; i++) { | 446 for (var i = 0; i < arg_count; i++) { |
467 arrays[i + 1] = %_Arguments(i); | 447 arrays[i + 1] = %_Arguments(i); |
468 } | 448 } |
469 | 449 |
470 return %ArrayConcat(arrays); | 450 return %ArrayConcat(arrays); |
471 } | 451 } |
472 | 452 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 if (!IS_UNDEFINED(current_j) || high in array) { | 489 if (!IS_UNDEFINED(current_j) || high in array) { |
510 array[low] = current_j; | 490 array[low] = current_j; |
511 delete array[high]; | 491 delete array[high]; |
512 } | 492 } |
513 } | 493 } |
514 } | 494 } |
515 } | 495 } |
516 | 496 |
517 | 497 |
518 function ArrayReverse() { | 498 function ArrayReverse() { |
519 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
520 throw MakeTypeError("called_on_null_or_undefined", | |
521 ["Array.prototype.reverse"]); | |
522 } | |
523 | |
524 var j = TO_UINT32(this.length) - 1; | 499 var j = TO_UINT32(this.length) - 1; |
525 | 500 |
526 if (UseSparseVariant(this, j, IS_ARRAY(this))) { | 501 if (UseSparseVariant(this, j, IS_ARRAY(this))) { |
527 SparseReverse(this, j+1); | 502 SparseReverse(this, j+1); |
528 return this; | 503 return this; |
529 } | 504 } |
530 | 505 |
531 for (var i = 0; i < j; i++, j--) { | 506 for (var i = 0; i < j; i++, j--) { |
532 var current_i = this[i]; | 507 var current_i = this[i]; |
533 if (!IS_UNDEFINED(current_i) || i in this) { | 508 if (!IS_UNDEFINED(current_i) || i in this) { |
(...skipping 11 matching lines...) Expand all Loading... |
545 this[i] = current_j; | 520 this[i] = current_j; |
546 delete this[j]; | 521 delete this[j]; |
547 } | 522 } |
548 } | 523 } |
549 } | 524 } |
550 return this; | 525 return this; |
551 } | 526 } |
552 | 527 |
553 | 528 |
554 function ArrayShift() { | 529 function ArrayShift() { |
555 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
556 throw MakeTypeError("called_on_null_or_undefined", | |
557 ["Array.prototype.shift"]); | |
558 } | |
559 | |
560 var len = TO_UINT32(this.length); | 530 var len = TO_UINT32(this.length); |
561 | 531 |
562 if (len === 0) { | 532 if (len === 0) { |
563 this.length = 0; | 533 this.length = 0; |
564 return; | 534 return; |
565 } | 535 } |
566 | 536 |
567 var first = this[0]; | 537 var first = this[0]; |
568 | 538 |
569 if (IS_ARRAY(this)) | 539 if (IS_ARRAY(this)) |
570 SmartMove(this, 0, 1, len, 0); | 540 SmartMove(this, 0, 1, len, 0); |
571 else | 541 else |
572 SimpleMove(this, 0, 1, len, 0); | 542 SimpleMove(this, 0, 1, len, 0); |
573 | 543 |
574 this.length = len - 1; | 544 this.length = len - 1; |
575 | 545 |
576 return first; | 546 return first; |
577 } | 547 } |
578 | 548 |
579 | 549 |
580 function ArrayUnshift(arg1) { // length == 1 | 550 function ArrayUnshift(arg1) { // length == 1 |
581 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
582 throw MakeTypeError("called_on_null_or_undefined", | |
583 ["Array.prototype.unshift"]); | |
584 } | |
585 | |
586 var len = TO_UINT32(this.length); | 551 var len = TO_UINT32(this.length); |
587 var num_arguments = %_ArgumentsLength(); | 552 var num_arguments = %_ArgumentsLength(); |
588 | 553 |
589 if (IS_ARRAY(this)) | 554 if (IS_ARRAY(this)) |
590 SmartMove(this, 0, 0, len, num_arguments); | 555 SmartMove(this, 0, 0, len, num_arguments); |
591 else | 556 else |
592 SimpleMove(this, 0, 0, len, num_arguments); | 557 SimpleMove(this, 0, 0, len, num_arguments); |
593 | 558 |
594 for (var i = 0; i < num_arguments; i++) { | 559 for (var i = 0; i < num_arguments; i++) { |
595 this[i] = %_Arguments(i); | 560 this[i] = %_Arguments(i); |
596 } | 561 } |
597 | 562 |
598 this.length = len + num_arguments; | 563 this.length = len + num_arguments; |
599 | 564 |
600 return len + num_arguments; | 565 return len + num_arguments; |
601 } | 566 } |
602 | 567 |
603 | 568 |
604 function ArraySlice(start, end) { | 569 function ArraySlice(start, end) { |
605 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
606 throw MakeTypeError("called_on_null_or_undefined", | |
607 ["Array.prototype.slice"]); | |
608 } | |
609 | |
610 var len = TO_UINT32(this.length); | 570 var len = TO_UINT32(this.length); |
611 var start_i = TO_INTEGER(start); | 571 var start_i = TO_INTEGER(start); |
612 var end_i = len; | 572 var end_i = len; |
613 | 573 |
614 if (end !== void 0) end_i = TO_INTEGER(end); | 574 if (end !== void 0) end_i = TO_INTEGER(end); |
615 | 575 |
616 if (start_i < 0) { | 576 if (start_i < 0) { |
617 start_i += len; | 577 start_i += len; |
618 if (start_i < 0) start_i = 0; | 578 if (start_i < 0) start_i = 0; |
619 } else { | 579 } else { |
(...skipping 17 matching lines...) Expand all Loading... |
637 SimpleSlice(this, start_i, end_i - start_i, len, result); | 597 SimpleSlice(this, start_i, end_i - start_i, len, result); |
638 } | 598 } |
639 | 599 |
640 result.length = end_i - start_i; | 600 result.length = end_i - start_i; |
641 | 601 |
642 return result; | 602 return result; |
643 } | 603 } |
644 | 604 |
645 | 605 |
646 function ArraySplice(start, delete_count) { | 606 function ArraySplice(start, delete_count) { |
647 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
648 throw MakeTypeError("called_on_null_or_undefined", | |
649 ["Array.prototype.splice"]); | |
650 } | |
651 | |
652 var num_arguments = %_ArgumentsLength(); | 607 var num_arguments = %_ArgumentsLength(); |
653 | 608 |
654 var len = TO_UINT32(this.length); | 609 var len = TO_UINT32(this.length); |
655 var start_i = TO_INTEGER(start); | 610 var start_i = TO_INTEGER(start); |
656 | 611 |
657 if (start_i < 0) { | 612 if (start_i < 0) { |
658 start_i += len; | 613 start_i += len; |
659 if (start_i < 0) start_i = 0; | 614 if (start_i < 0) start_i = 0; |
660 } else { | 615 } else { |
661 if (start_i > len) start_i = len; | 616 if (start_i > len) start_i = len; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 this[i++] = %_Arguments(arguments_index++); | 668 this[i++] = %_Arguments(arguments_index++); |
714 } | 669 } |
715 this.length = len - del_count + num_additional_args; | 670 this.length = len - del_count + num_additional_args; |
716 | 671 |
717 // Return the deleted elements. | 672 // Return the deleted elements. |
718 return deleted_elements; | 673 return deleted_elements; |
719 } | 674 } |
720 | 675 |
721 | 676 |
722 function ArraySort(comparefn) { | 677 function ArraySort(comparefn) { |
723 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
724 throw MakeTypeError("called_on_null_or_undefined", | |
725 ["Array.prototype.sort"]); | |
726 } | |
727 | |
728 // In-place QuickSort algorithm. | 678 // In-place QuickSort algorithm. |
729 // For short (length <= 22) arrays, insertion sort is used for efficiency. | 679 // For short (length <= 22) arrays, insertion sort is used for efficiency. |
730 | 680 |
731 if (!IS_FUNCTION(comparefn)) { | 681 if (!IS_FUNCTION(comparefn)) { |
732 comparefn = function (x, y) { | 682 comparefn = function (x, y) { |
733 if (x === y) return 0; | 683 if (x === y) return 0; |
734 if (%_IsSmi(x) && %_IsSmi(y)) { | 684 if (%_IsSmi(x) && %_IsSmi(y)) { |
735 return %SmiLexicographicCompare(x, y); | 685 return %SmiLexicographicCompare(x, y); |
736 } | 686 } |
737 x = ToString(x); | 687 x = ToString(x); |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 } | 929 } |
980 | 930 |
981 return this; | 931 return this; |
982 } | 932 } |
983 | 933 |
984 | 934 |
985 // The following functions cannot be made efficient on sparse arrays while | 935 // The following functions cannot be made efficient on sparse arrays while |
986 // preserving the semantics, since the calls to the receiver function can add | 936 // preserving the semantics, since the calls to the receiver function can add |
987 // or delete elements from the array. | 937 // or delete elements from the array. |
988 function ArrayFilter(f, receiver) { | 938 function ArrayFilter(f, receiver) { |
989 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
990 throw MakeTypeError("called_on_null_or_undefined", | |
991 ["Array.prototype.filter"]); | |
992 } | |
993 | |
994 if (!IS_FUNCTION(f)) { | 939 if (!IS_FUNCTION(f)) { |
995 throw MakeTypeError('called_non_callable', [ f ]); | 940 throw MakeTypeError('called_non_callable', [ f ]); |
996 } | 941 } |
997 // Pull out the length so that modifications to the length in the | 942 // Pull out the length so that modifications to the length in the |
998 // loop will not affect the looping. | 943 // loop will not affect the looping. |
999 var length = this.length; | 944 var length = this.length; |
1000 var result = []; | 945 var result = []; |
1001 var result_length = 0; | 946 var result_length = 0; |
1002 for (var i = 0; i < length; i++) { | 947 for (var i = 0; i < length; i++) { |
1003 var current = this[i]; | 948 var current = this[i]; |
1004 if (!IS_UNDEFINED(current) || i in this) { | 949 if (!IS_UNDEFINED(current) || i in this) { |
1005 if (f.call(receiver, current, i, this)) { | 950 if (f.call(receiver, current, i, this)) { |
1006 result[result_length++] = current; | 951 result[result_length++] = current; |
1007 } | 952 } |
1008 } | 953 } |
1009 } | 954 } |
1010 return result; | 955 return result; |
1011 } | 956 } |
1012 | 957 |
1013 | 958 |
1014 function ArrayForEach(f, receiver) { | 959 function ArrayForEach(f, receiver) { |
1015 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1016 throw MakeTypeError("called_on_null_or_undefined", | |
1017 ["Array.prototype.forEach"]); | |
1018 } | |
1019 | |
1020 if (!IS_FUNCTION(f)) { | 960 if (!IS_FUNCTION(f)) { |
1021 throw MakeTypeError('called_non_callable', [ f ]); | 961 throw MakeTypeError('called_non_callable', [ f ]); |
1022 } | 962 } |
1023 // Pull out the length so that modifications to the length in the | 963 // Pull out the length so that modifications to the length in the |
1024 // loop will not affect the looping. | 964 // loop will not affect the looping. |
1025 var length = TO_UINT32(this.length); | 965 var length = TO_UINT32(this.length); |
1026 for (var i = 0; i < length; i++) { | 966 for (var i = 0; i < length; i++) { |
1027 var current = this[i]; | 967 var current = this[i]; |
1028 if (!IS_UNDEFINED(current) || i in this) { | 968 if (!IS_UNDEFINED(current) || i in this) { |
1029 f.call(receiver, current, i, this); | 969 f.call(receiver, current, i, this); |
1030 } | 970 } |
1031 } | 971 } |
1032 } | 972 } |
1033 | 973 |
1034 | 974 |
1035 // Executes the function once for each element present in the | 975 // Executes the function once for each element present in the |
1036 // array until it finds one where callback returns true. | 976 // array until it finds one where callback returns true. |
1037 function ArraySome(f, receiver) { | 977 function ArraySome(f, receiver) { |
1038 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1039 throw MakeTypeError("called_on_null_or_undefined", | |
1040 ["Array.prototype.some"]); | |
1041 } | |
1042 | |
1043 if (!IS_FUNCTION(f)) { | 978 if (!IS_FUNCTION(f)) { |
1044 throw MakeTypeError('called_non_callable', [ f ]); | 979 throw MakeTypeError('called_non_callable', [ f ]); |
1045 } | 980 } |
1046 // Pull out the length so that modifications to the length in the | 981 // Pull out the length so that modifications to the length in the |
1047 // loop will not affect the looping. | 982 // loop will not affect the looping. |
1048 var length = TO_UINT32(this.length); | 983 var length = TO_UINT32(this.length); |
1049 for (var i = 0; i < length; i++) { | 984 for (var i = 0; i < length; i++) { |
1050 var current = this[i]; | 985 var current = this[i]; |
1051 if (!IS_UNDEFINED(current) || i in this) { | 986 if (!IS_UNDEFINED(current) || i in this) { |
1052 if (f.call(receiver, current, i, this)) return true; | 987 if (f.call(receiver, current, i, this)) return true; |
1053 } | 988 } |
1054 } | 989 } |
1055 return false; | 990 return false; |
1056 } | 991 } |
1057 | 992 |
1058 | 993 |
1059 function ArrayEvery(f, receiver) { | 994 function ArrayEvery(f, receiver) { |
1060 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1061 throw MakeTypeError("called_on_null_or_undefined", | |
1062 ["Array.prototype.every"]); | |
1063 } | |
1064 | |
1065 if (!IS_FUNCTION(f)) { | 995 if (!IS_FUNCTION(f)) { |
1066 throw MakeTypeError('called_non_callable', [ f ]); | 996 throw MakeTypeError('called_non_callable', [ f ]); |
1067 } | 997 } |
1068 // Pull out the length so that modifications to the length in the | 998 // Pull out the length so that modifications to the length in the |
1069 // loop will not affect the looping. | 999 // loop will not affect the looping. |
1070 var length = TO_UINT32(this.length); | 1000 var length = TO_UINT32(this.length); |
1071 for (var i = 0; i < length; i++) { | 1001 for (var i = 0; i < length; i++) { |
1072 var current = this[i]; | 1002 var current = this[i]; |
1073 if (!IS_UNDEFINED(current) || i in this) { | 1003 if (!IS_UNDEFINED(current) || i in this) { |
1074 if (!f.call(receiver, current, i, this)) return false; | 1004 if (!f.call(receiver, current, i, this)) return false; |
1075 } | 1005 } |
1076 } | 1006 } |
1077 return true; | 1007 return true; |
1078 } | 1008 } |
1079 | 1009 |
1080 function ArrayMap(f, receiver) { | 1010 function ArrayMap(f, receiver) { |
1081 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1082 throw MakeTypeError("called_on_null_or_undefined", | |
1083 ["Array.prototype.map"]); | |
1084 } | |
1085 | |
1086 if (!IS_FUNCTION(f)) { | 1011 if (!IS_FUNCTION(f)) { |
1087 throw MakeTypeError('called_non_callable', [ f ]); | 1012 throw MakeTypeError('called_non_callable', [ f ]); |
1088 } | 1013 } |
1089 // Pull out the length so that modifications to the length in the | 1014 // Pull out the length so that modifications to the length in the |
1090 // loop will not affect the looping. | 1015 // loop will not affect the looping. |
1091 var length = TO_UINT32(this.length); | 1016 var length = TO_UINT32(this.length); |
1092 var result = new $Array(); | 1017 var result = new $Array(); |
1093 var accumulator = new InternalArray(length); | 1018 var accumulator = new InternalArray(length); |
1094 for (var i = 0; i < length; i++) { | 1019 for (var i = 0; i < length; i++) { |
1095 var current = this[i]; | 1020 var current = this[i]; |
1096 if (!IS_UNDEFINED(current) || i in this) { | 1021 if (!IS_UNDEFINED(current) || i in this) { |
1097 accumulator[i] = f.call(receiver, current, i, this); | 1022 accumulator[i] = f.call(receiver, current, i, this); |
1098 } | 1023 } |
1099 } | 1024 } |
1100 %MoveArrayContents(accumulator, result); | 1025 %MoveArrayContents(accumulator, result); |
1101 return result; | 1026 return result; |
1102 } | 1027 } |
1103 | 1028 |
1104 | 1029 |
1105 function ArrayIndexOf(element, index) { | 1030 function ArrayIndexOf(element, index) { |
1106 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1107 throw MakeTypeError("called_on_null_or_undefined", | |
1108 ["Array.prototype.indexOf"]); | |
1109 } | |
1110 | |
1111 var length = TO_UINT32(this.length); | 1031 var length = TO_UINT32(this.length); |
1112 if (length == 0) return -1; | 1032 if (length == 0) return -1; |
1113 if (IS_UNDEFINED(index)) { | 1033 if (IS_UNDEFINED(index)) { |
1114 index = 0; | 1034 index = 0; |
1115 } else { | 1035 } else { |
1116 index = TO_INTEGER(index); | 1036 index = TO_INTEGER(index); |
1117 // If index is negative, index from the end of the array. | 1037 // If index is negative, index from the end of the array. |
1118 if (index < 0) { | 1038 if (index < 0) { |
1119 index = length + index; | 1039 index = length + index; |
1120 // If index is still negative, search the entire array. | 1040 // If index is still negative, search the entire array. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1158 for (var i = min; i < max; i++) { | 1078 for (var i = min; i < max; i++) { |
1159 if (IS_UNDEFINED(this[i]) && i in this) { | 1079 if (IS_UNDEFINED(this[i]) && i in this) { |
1160 return i; | 1080 return i; |
1161 } | 1081 } |
1162 } | 1082 } |
1163 return -1; | 1083 return -1; |
1164 } | 1084 } |
1165 | 1085 |
1166 | 1086 |
1167 function ArrayLastIndexOf(element, index) { | 1087 function ArrayLastIndexOf(element, index) { |
1168 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1169 throw MakeTypeError("called_on_null_or_undefined", | |
1170 ["Array.prototype.lastIndexOf"]); | |
1171 } | |
1172 | |
1173 var length = TO_UINT32(this.length); | 1088 var length = TO_UINT32(this.length); |
1174 if (length == 0) return -1; | 1089 if (length == 0) return -1; |
1175 if (%_ArgumentsLength() < 2) { | 1090 if (%_ArgumentsLength() < 2) { |
1176 index = length - 1; | 1091 index = length - 1; |
1177 } else { | 1092 } else { |
1178 index = TO_INTEGER(index); | 1093 index = TO_INTEGER(index); |
1179 // If index is negative, index from end of the array. | 1094 // If index is negative, index from end of the array. |
1180 if (index < 0) index += length; | 1095 if (index < 0) index += length; |
1181 // If index is still negative, do not search the array. | 1096 // If index is still negative, do not search the array. |
1182 if (index < 0) return -1; | 1097 if (index < 0) return -1; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1216 for (var i = max; i >= min; i--) { | 1131 for (var i = max; i >= min; i--) { |
1217 if (IS_UNDEFINED(this[i]) && i in this) { | 1132 if (IS_UNDEFINED(this[i]) && i in this) { |
1218 return i; | 1133 return i; |
1219 } | 1134 } |
1220 } | 1135 } |
1221 return -1; | 1136 return -1; |
1222 } | 1137 } |
1223 | 1138 |
1224 | 1139 |
1225 function ArrayReduce(callback, current) { | 1140 function ArrayReduce(callback, current) { |
1226 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1227 throw MakeTypeError("called_on_null_or_undefined", | |
1228 ["Array.prototype.reduce"]); | |
1229 } | |
1230 | |
1231 if (!IS_FUNCTION(callback)) { | 1141 if (!IS_FUNCTION(callback)) { |
1232 throw MakeTypeError('called_non_callable', [callback]); | 1142 throw MakeTypeError('called_non_callable', [callback]); |
1233 } | 1143 } |
1234 // Pull out the length so that modifications to the length in the | 1144 // Pull out the length so that modifications to the length in the |
1235 // loop will not affect the looping. | 1145 // loop will not affect the looping. |
1236 var length = this.length; | 1146 var length = this.length; |
1237 var i = 0; | 1147 var i = 0; |
1238 | 1148 |
1239 find_initial: if (%_ArgumentsLength() < 2) { | 1149 find_initial: if (%_ArgumentsLength() < 2) { |
1240 for (; i < length; i++) { | 1150 for (; i < length; i++) { |
1241 current = this[i]; | 1151 current = this[i]; |
1242 if (!IS_UNDEFINED(current) || i in this) { | 1152 if (!IS_UNDEFINED(current) || i in this) { |
1243 i++; | 1153 i++; |
1244 break find_initial; | 1154 break find_initial; |
1245 } | 1155 } |
1246 } | 1156 } |
1247 throw MakeTypeError('reduce_no_initial', []); | 1157 throw MakeTypeError('reduce_no_initial', []); |
1248 } | 1158 } |
1249 | 1159 |
1250 for (; i < length; i++) { | 1160 for (; i < length; i++) { |
1251 var element = this[i]; | 1161 var element = this[i]; |
1252 if (!IS_UNDEFINED(element) || i in this) { | 1162 if (!IS_UNDEFINED(element) || i in this) { |
1253 current = callback.call(null, current, element, i, this); | 1163 current = callback.call(null, current, element, i, this); |
1254 } | 1164 } |
1255 } | 1165 } |
1256 return current; | 1166 return current; |
1257 } | 1167 } |
1258 | 1168 |
1259 function ArrayReduceRight(callback, current) { | 1169 function ArrayReduceRight(callback, current) { |
1260 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1261 throw MakeTypeError("called_on_null_or_undefined", | |
1262 ["Array.prototype.reduceRight"]); | |
1263 } | |
1264 | |
1265 if (!IS_FUNCTION(callback)) { | 1170 if (!IS_FUNCTION(callback)) { |
1266 throw MakeTypeError('called_non_callable', [callback]); | 1171 throw MakeTypeError('called_non_callable', [callback]); |
1267 } | 1172 } |
1268 var i = this.length - 1; | 1173 var i = this.length - 1; |
1269 | 1174 |
1270 find_initial: if (%_ArgumentsLength() < 2) { | 1175 find_initial: if (%_ArgumentsLength() < 2) { |
1271 for (; i >= 0; i--) { | 1176 for (; i >= 0; i--) { |
1272 current = this[i]; | 1177 current = this[i]; |
1273 if (!IS_UNDEFINED(current) || i in this) { | 1178 if (!IS_UNDEFINED(current) || i in this) { |
1274 i--; | 1179 i--; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 InternalArray.prototype.join = getFunction("join", ArrayJoin); | 1262 InternalArray.prototype.join = getFunction("join", ArrayJoin); |
1358 InternalArray.prototype.pop = getFunction("pop", ArrayPop); | 1263 InternalArray.prototype.pop = getFunction("pop", ArrayPop); |
1359 InternalArray.prototype.push = getFunction("push", ArrayPush); | 1264 InternalArray.prototype.push = getFunction("push", ArrayPush); |
1360 InternalArray.prototype.toString = function() { | 1265 InternalArray.prototype.toString = function() { |
1361 return "Internal Array, length " + this.length; | 1266 return "Internal Array, length " + this.length; |
1362 }; | 1267 }; |
1363 } | 1268 } |
1364 | 1269 |
1365 | 1270 |
1366 SetupArray(); | 1271 SetupArray(); |
OLD | NEW |