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 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
352 } | 352 } |
353 } | 353 } |
354 } | 354 } |
355 } | 355 } |
356 | 356 |
357 | 357 |
358 // ------------------------------------------------------------------- | 358 // ------------------------------------------------------------------- |
359 | 359 |
360 | 360 |
361 function ArrayToString() { | 361 function ArrayToString() { |
362 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
363 throw MakeTypeError("called_on_null_or_undefined", | |
364 ["Array.prototype.toString"]); | |
365 } | |
362 if (!IS_ARRAY(this)) { | 366 if (!IS_ARRAY(this)) { |
Lasse Reichstein
2011/05/03 13:06:52
Remove the test above, then.
Rico
2011/05/03 13:15:38
Done.
| |
363 throw new $TypeError('Array.prototype.toString is not generic'); | 367 throw new $TypeError('Array.prototype.toString is not generic'); |
364 } | 368 } |
365 return Join(this, this.length, ',', ConvertToString); | 369 return Join(this, this.length, ',', ConvertToString); |
366 } | 370 } |
367 | 371 |
368 | 372 |
369 function ArrayToLocaleString() { | 373 function ArrayToLocaleString() { |
374 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
375 throw MakeTypeError("called_on_null_or_undefined", | |
376 ["Array.prototype.toLocaleString"]); | |
377 } | |
370 if (!IS_ARRAY(this)) { | 378 if (!IS_ARRAY(this)) { |
Lasse Reichstein
2011/05/03 13:06:52
Ditto
Rico
2011/05/03 13:15:38
Done.
| |
371 throw new $TypeError('Array.prototype.toString is not generic'); | 379 throw new $TypeError('Array.prototype.toString is not generic'); |
372 } | 380 } |
373 return Join(this, this.length, ',', ConvertToLocaleString); | 381 return Join(this, this.length, ',', ConvertToLocaleString); |
374 } | 382 } |
375 | 383 |
376 | 384 |
377 function ArrayJoin(separator) { | 385 function ArrayJoin(separator) { |
386 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
387 throw MakeTypeError("called_on_null_or_undefined", | |
388 ["Array.prototype.join"]); | |
389 } | |
390 | |
378 if (IS_UNDEFINED(separator)) { | 391 if (IS_UNDEFINED(separator)) { |
379 separator = ','; | 392 separator = ','; |
380 } else if (!IS_STRING(separator)) { | 393 } else if (!IS_STRING(separator)) { |
381 separator = NonStringToString(separator); | 394 separator = NonStringToString(separator); |
382 } | 395 } |
383 | 396 |
384 var result = %_FastAsciiArrayJoin(this, separator); | 397 var result = %_FastAsciiArrayJoin(this, separator); |
385 if (!IS_UNDEFINED(result)) return result; | 398 if (!IS_UNDEFINED(result)) return result; |
386 | 399 |
387 return Join(this, TO_UINT32(this.length), separator, ConvertToString); | 400 return Join(this, TO_UINT32(this.length), separator, ConvertToString); |
388 } | 401 } |
389 | 402 |
390 | 403 |
391 // Removes the last element from the array and returns it. See | 404 // Removes the last element from the array and returns it. See |
392 // ECMA-262, section 15.4.4.6. | 405 // ECMA-262, section 15.4.4.6. |
393 function ArrayPop() { | 406 function ArrayPop() { |
407 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
408 throw MakeTypeError("called_on_null_or_undefined", | |
409 ["Array.prototype.pop"]); | |
410 } | |
411 | |
394 var n = TO_UINT32(this.length); | 412 var n = TO_UINT32(this.length); |
395 if (n == 0) { | 413 if (n == 0) { |
396 this.length = n; | 414 this.length = n; |
397 return; | 415 return; |
398 } | 416 } |
399 n--; | 417 n--; |
400 var value = this[n]; | 418 var value = this[n]; |
401 this.length = n; | 419 this.length = n; |
402 delete this[n]; | 420 delete this[n]; |
403 return value; | 421 return value; |
404 } | 422 } |
405 | 423 |
406 | 424 |
407 // Appends the arguments to the end of the array and returns the new | 425 // Appends the arguments to the end of the array and returns the new |
408 // length of the array. See ECMA-262, section 15.4.4.7. | 426 // length of the array. See ECMA-262, section 15.4.4.7. |
409 function ArrayPush() { | 427 function ArrayPush() { |
428 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
429 throw MakeTypeError("called_on_null_or_undefined", | |
430 ["Array.prototype.push"]); | |
431 } | |
432 | |
410 var n = TO_UINT32(this.length); | 433 var n = TO_UINT32(this.length); |
411 var m = %_ArgumentsLength(); | 434 var m = %_ArgumentsLength(); |
412 for (var i = 0; i < m; i++) { | 435 for (var i = 0; i < m; i++) { |
413 this[i+n] = %_Arguments(i); | 436 this[i+n] = %_Arguments(i); |
414 } | 437 } |
415 this.length = n + m; | 438 this.length = n + m; |
416 return this.length; | 439 return this.length; |
417 } | 440 } |
418 | 441 |
419 | 442 |
420 function ArrayConcat(arg1) { // length == 1 | 443 function ArrayConcat(arg1) { // length == 1 |
444 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
445 throw MakeTypeError("called_on_null_or_undefined", | |
446 ["Array.prototype.concat"]); | |
447 } | |
448 | |
421 var arg_count = %_ArgumentsLength(); | 449 var arg_count = %_ArgumentsLength(); |
422 var arrays = new InternalArray(1 + arg_count); | 450 var arrays = new InternalArray(1 + arg_count); |
423 arrays[0] = this; | 451 arrays[0] = this; |
424 for (var i = 0; i < arg_count; i++) { | 452 for (var i = 0; i < arg_count; i++) { |
425 arrays[i + 1] = %_Arguments(i); | 453 arrays[i + 1] = %_Arguments(i); |
426 } | 454 } |
427 | 455 |
428 return %ArrayConcat(arrays); | 456 return %ArrayConcat(arrays); |
429 } | 457 } |
430 | 458 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
467 if (!IS_UNDEFINED(current_j) || high in array) { | 495 if (!IS_UNDEFINED(current_j) || high in array) { |
468 array[low] = current_j; | 496 array[low] = current_j; |
469 delete array[high]; | 497 delete array[high]; |
470 } | 498 } |
471 } | 499 } |
472 } | 500 } |
473 } | 501 } |
474 | 502 |
475 | 503 |
476 function ArrayReverse() { | 504 function ArrayReverse() { |
505 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
506 throw MakeTypeError("called_on_null_or_undefined", | |
507 ["Array.prototype.reverse"]); | |
508 } | |
509 | |
477 var j = TO_UINT32(this.length) - 1; | 510 var j = TO_UINT32(this.length) - 1; |
478 | 511 |
479 if (UseSparseVariant(this, j, IS_ARRAY(this))) { | 512 if (UseSparseVariant(this, j, IS_ARRAY(this))) { |
480 SparseReverse(this, j+1); | 513 SparseReverse(this, j+1); |
481 return this; | 514 return this; |
482 } | 515 } |
483 | 516 |
484 for (var i = 0; i < j; i++, j--) { | 517 for (var i = 0; i < j; i++, j--) { |
485 var current_i = this[i]; | 518 var current_i = this[i]; |
486 if (!IS_UNDEFINED(current_i) || i in this) { | 519 if (!IS_UNDEFINED(current_i) || i in this) { |
(...skipping 11 matching lines...) Expand all Loading... | |
498 this[i] = current_j; | 531 this[i] = current_j; |
499 delete this[j]; | 532 delete this[j]; |
500 } | 533 } |
501 } | 534 } |
502 } | 535 } |
503 return this; | 536 return this; |
504 } | 537 } |
505 | 538 |
506 | 539 |
507 function ArrayShift() { | 540 function ArrayShift() { |
541 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
542 throw MakeTypeError("called_on_null_or_undefined", | |
543 ["Array.prototype.shift"]); | |
544 } | |
545 | |
508 var len = TO_UINT32(this.length); | 546 var len = TO_UINT32(this.length); |
509 | 547 |
510 if (len === 0) { | 548 if (len === 0) { |
511 this.length = 0; | 549 this.length = 0; |
512 return; | 550 return; |
513 } | 551 } |
514 | 552 |
515 var first = this[0]; | 553 var first = this[0]; |
516 | 554 |
517 if (IS_ARRAY(this)) | 555 if (IS_ARRAY(this)) |
518 SmartMove(this, 0, 1, len, 0); | 556 SmartMove(this, 0, 1, len, 0); |
519 else | 557 else |
520 SimpleMove(this, 0, 1, len, 0); | 558 SimpleMove(this, 0, 1, len, 0); |
521 | 559 |
522 this.length = len - 1; | 560 this.length = len - 1; |
523 | 561 |
524 return first; | 562 return first; |
525 } | 563 } |
526 | 564 |
527 | 565 |
528 function ArrayUnshift(arg1) { // length == 1 | 566 function ArrayUnshift(arg1) { // length == 1 |
567 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
568 throw MakeTypeError("called_on_null_or_undefined", | |
569 ["Array.prototype.unshift"]); | |
570 } | |
571 | |
529 var len = TO_UINT32(this.length); | 572 var len = TO_UINT32(this.length); |
530 var num_arguments = %_ArgumentsLength(); | 573 var num_arguments = %_ArgumentsLength(); |
531 | 574 |
532 if (IS_ARRAY(this)) | 575 if (IS_ARRAY(this)) |
533 SmartMove(this, 0, 0, len, num_arguments); | 576 SmartMove(this, 0, 0, len, num_arguments); |
534 else | 577 else |
535 SimpleMove(this, 0, 0, len, num_arguments); | 578 SimpleMove(this, 0, 0, len, num_arguments); |
536 | 579 |
537 for (var i = 0; i < num_arguments; i++) { | 580 for (var i = 0; i < num_arguments; i++) { |
538 this[i] = %_Arguments(i); | 581 this[i] = %_Arguments(i); |
539 } | 582 } |
540 | 583 |
541 this.length = len + num_arguments; | 584 this.length = len + num_arguments; |
542 | 585 |
543 return len + num_arguments; | 586 return len + num_arguments; |
544 } | 587 } |
545 | 588 |
546 | 589 |
547 function ArraySlice(start, end) { | 590 function ArraySlice(start, end) { |
591 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
592 throw MakeTypeError("called_on_null_or_undefined", | |
593 ["Array.prototype.slice"]); | |
594 } | |
595 | |
548 var len = TO_UINT32(this.length); | 596 var len = TO_UINT32(this.length); |
549 var start_i = TO_INTEGER(start); | 597 var start_i = TO_INTEGER(start); |
550 var end_i = len; | 598 var end_i = len; |
551 | 599 |
552 if (end !== void 0) end_i = TO_INTEGER(end); | 600 if (end !== void 0) end_i = TO_INTEGER(end); |
553 | 601 |
554 if (start_i < 0) { | 602 if (start_i < 0) { |
555 start_i += len; | 603 start_i += len; |
556 if (start_i < 0) start_i = 0; | 604 if (start_i < 0) start_i = 0; |
557 } else { | 605 } else { |
(...skipping 17 matching lines...) Expand all Loading... | |
575 SimpleSlice(this, start_i, end_i - start_i, len, result); | 623 SimpleSlice(this, start_i, end_i - start_i, len, result); |
576 } | 624 } |
577 | 625 |
578 result.length = end_i - start_i; | 626 result.length = end_i - start_i; |
579 | 627 |
580 return result; | 628 return result; |
581 } | 629 } |
582 | 630 |
583 | 631 |
584 function ArraySplice(start, delete_count) { | 632 function ArraySplice(start, delete_count) { |
633 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
634 throw MakeTypeError("called_on_null_or_undefined", | |
635 ["Array.prototype.splice"]); | |
636 } | |
637 | |
585 var num_arguments = %_ArgumentsLength(); | 638 var num_arguments = %_ArgumentsLength(); |
586 | 639 |
587 var len = TO_UINT32(this.length); | 640 var len = TO_UINT32(this.length); |
588 var start_i = TO_INTEGER(start); | 641 var start_i = TO_INTEGER(start); |
589 | 642 |
590 if (start_i < 0) { | 643 if (start_i < 0) { |
591 start_i += len; | 644 start_i += len; |
592 if (start_i < 0) start_i = 0; | 645 if (start_i < 0) start_i = 0; |
593 } else { | 646 } else { |
594 if (start_i > len) start_i = len; | 647 if (start_i > len) start_i = len; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
646 this[i++] = %_Arguments(arguments_index++); | 699 this[i++] = %_Arguments(arguments_index++); |
647 } | 700 } |
648 this.length = len - del_count + num_additional_args; | 701 this.length = len - del_count + num_additional_args; |
649 | 702 |
650 // Return the deleted elements. | 703 // Return the deleted elements. |
651 return deleted_elements; | 704 return deleted_elements; |
652 } | 705 } |
653 | 706 |
654 | 707 |
655 function ArraySort(comparefn) { | 708 function ArraySort(comparefn) { |
709 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
710 throw MakeTypeError("called_on_null_or_undefined", | |
711 ["Array.prototype.sort"]); | |
712 } | |
713 | |
656 // In-place QuickSort algorithm. | 714 // In-place QuickSort algorithm. |
657 // For short (length <= 22) arrays, insertion sort is used for efficiency. | 715 // For short (length <= 22) arrays, insertion sort is used for efficiency. |
658 | 716 |
659 if (!IS_FUNCTION(comparefn)) { | 717 if (!IS_FUNCTION(comparefn)) { |
660 comparefn = function (x, y) { | 718 comparefn = function (x, y) { |
661 if (x === y) return 0; | 719 if (x === y) return 0; |
662 if (%_IsSmi(x) && %_IsSmi(y)) { | 720 if (%_IsSmi(x) && %_IsSmi(y)) { |
663 return %SmiLexicographicCompare(x, y); | 721 return %SmiLexicographicCompare(x, y); |
664 } | 722 } |
665 x = ToString(x); | 723 x = ToString(x); |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
907 } | 965 } |
908 | 966 |
909 return this; | 967 return this; |
910 } | 968 } |
911 | 969 |
912 | 970 |
913 // The following functions cannot be made efficient on sparse arrays while | 971 // The following functions cannot be made efficient on sparse arrays while |
914 // preserving the semantics, since the calls to the receiver function can add | 972 // preserving the semantics, since the calls to the receiver function can add |
915 // or delete elements from the array. | 973 // or delete elements from the array. |
916 function ArrayFilter(f, receiver) { | 974 function ArrayFilter(f, receiver) { |
975 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
976 throw MakeTypeError("called_on_null_or_undefined", | |
977 ["Array.prototype.filter"]); | |
978 } | |
979 | |
917 if (!IS_FUNCTION(f)) { | 980 if (!IS_FUNCTION(f)) { |
918 throw MakeTypeError('called_non_callable', [ f ]); | 981 throw MakeTypeError('called_non_callable', [ f ]); |
919 } | 982 } |
920 // Pull out the length so that modifications to the length in the | 983 // Pull out the length so that modifications to the length in the |
921 // loop will not affect the looping. | 984 // loop will not affect the looping. |
922 var length = this.length; | 985 var length = this.length; |
923 var result = []; | 986 var result = []; |
924 var result_length = 0; | 987 var result_length = 0; |
925 for (var i = 0; i < length; i++) { | 988 for (var i = 0; i < length; i++) { |
926 var current = this[i]; | 989 var current = this[i]; |
927 if (!IS_UNDEFINED(current) || i in this) { | 990 if (!IS_UNDEFINED(current) || i in this) { |
928 if (f.call(receiver, current, i, this)) { | 991 if (f.call(receiver, current, i, this)) { |
929 result[result_length++] = current; | 992 result[result_length++] = current; |
930 } | 993 } |
931 } | 994 } |
932 } | 995 } |
933 return result; | 996 return result; |
934 } | 997 } |
935 | 998 |
936 | 999 |
937 function ArrayForEach(f, receiver) { | 1000 function ArrayForEach(f, receiver) { |
1001 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1002 throw MakeTypeError("called_on_null_or_undefined", | |
1003 ["Array.prototype.forEach"]); | |
1004 } | |
1005 | |
938 if (!IS_FUNCTION(f)) { | 1006 if (!IS_FUNCTION(f)) { |
939 throw MakeTypeError('called_non_callable', [ f ]); | 1007 throw MakeTypeError('called_non_callable', [ f ]); |
940 } | 1008 } |
941 // Pull out the length so that modifications to the length in the | 1009 // Pull out the length so that modifications to the length in the |
942 // loop will not affect the looping. | 1010 // loop will not affect the looping. |
943 var length = TO_UINT32(this.length); | 1011 var length = TO_UINT32(this.length); |
944 for (var i = 0; i < length; i++) { | 1012 for (var i = 0; i < length; i++) { |
945 var current = this[i]; | 1013 var current = this[i]; |
946 if (!IS_UNDEFINED(current) || i in this) { | 1014 if (!IS_UNDEFINED(current) || i in this) { |
947 f.call(receiver, current, i, this); | 1015 f.call(receiver, current, i, this); |
948 } | 1016 } |
949 } | 1017 } |
950 } | 1018 } |
951 | 1019 |
952 | 1020 |
953 // Executes the function once for each element present in the | 1021 // Executes the function once for each element present in the |
954 // array until it finds one where callback returns true. | 1022 // array until it finds one where callback returns true. |
955 function ArraySome(f, receiver) { | 1023 function ArraySome(f, receiver) { |
1024 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1025 throw MakeTypeError("called_on_null_or_undefined", | |
1026 ["Array.prototype.some"]); | |
1027 } | |
1028 | |
956 if (!IS_FUNCTION(f)) { | 1029 if (!IS_FUNCTION(f)) { |
957 throw MakeTypeError('called_non_callable', [ f ]); | 1030 throw MakeTypeError('called_non_callable', [ f ]); |
958 } | 1031 } |
959 // Pull out the length so that modifications to the length in the | 1032 // Pull out the length so that modifications to the length in the |
960 // loop will not affect the looping. | 1033 // loop will not affect the looping. |
961 var length = TO_UINT32(this.length); | 1034 var length = TO_UINT32(this.length); |
962 for (var i = 0; i < length; i++) { | 1035 for (var i = 0; i < length; i++) { |
963 var current = this[i]; | 1036 var current = this[i]; |
964 if (!IS_UNDEFINED(current) || i in this) { | 1037 if (!IS_UNDEFINED(current) || i in this) { |
965 if (f.call(receiver, current, i, this)) return true; | 1038 if (f.call(receiver, current, i, this)) return true; |
966 } | 1039 } |
967 } | 1040 } |
968 return false; | 1041 return false; |
969 } | 1042 } |
970 | 1043 |
971 | 1044 |
972 function ArrayEvery(f, receiver) { | 1045 function ArrayEvery(f, receiver) { |
1046 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1047 throw MakeTypeError("called_on_null_or_undefined", | |
1048 ["Array.prototype.every"]); | |
1049 } | |
1050 | |
973 if (!IS_FUNCTION(f)) { | 1051 if (!IS_FUNCTION(f)) { |
974 throw MakeTypeError('called_non_callable', [ f ]); | 1052 throw MakeTypeError('called_non_callable', [ f ]); |
975 } | 1053 } |
976 // Pull out the length so that modifications to the length in the | 1054 // Pull out the length so that modifications to the length in the |
977 // loop will not affect the looping. | 1055 // loop will not affect the looping. |
978 var length = TO_UINT32(this.length); | 1056 var length = TO_UINT32(this.length); |
979 for (var i = 0; i < length; i++) { | 1057 for (var i = 0; i < length; i++) { |
980 var current = this[i]; | 1058 var current = this[i]; |
981 if (!IS_UNDEFINED(current) || i in this) { | 1059 if (!IS_UNDEFINED(current) || i in this) { |
982 if (!f.call(receiver, current, i, this)) return false; | 1060 if (!f.call(receiver, current, i, this)) return false; |
983 } | 1061 } |
984 } | 1062 } |
985 return true; | 1063 return true; |
986 } | 1064 } |
987 | 1065 |
988 function ArrayMap(f, receiver) { | 1066 function ArrayMap(f, receiver) { |
1067 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1068 throw MakeTypeError("called_on_null_or_undefined", | |
1069 ["Array.prototype.map"]); | |
1070 } | |
1071 | |
989 if (!IS_FUNCTION(f)) { | 1072 if (!IS_FUNCTION(f)) { |
990 throw MakeTypeError('called_non_callable', [ f ]); | 1073 throw MakeTypeError('called_non_callable', [ f ]); |
991 } | 1074 } |
992 // Pull out the length so that modifications to the length in the | 1075 // Pull out the length so that modifications to the length in the |
993 // loop will not affect the looping. | 1076 // loop will not affect the looping. |
994 var length = TO_UINT32(this.length); | 1077 var length = TO_UINT32(this.length); |
995 var result = new $Array(); | 1078 var result = new $Array(); |
996 var accumulator = new InternalArray(length); | 1079 var accumulator = new InternalArray(length); |
997 for (var i = 0; i < length; i++) { | 1080 for (var i = 0; i < length; i++) { |
998 var current = this[i]; | 1081 var current = this[i]; |
999 if (!IS_UNDEFINED(current) || i in this) { | 1082 if (!IS_UNDEFINED(current) || i in this) { |
1000 accumulator[i] = f.call(receiver, current, i, this); | 1083 accumulator[i] = f.call(receiver, current, i, this); |
1001 } | 1084 } |
1002 } | 1085 } |
1003 %MoveArrayContents(accumulator, result); | 1086 %MoveArrayContents(accumulator, result); |
1004 return result; | 1087 return result; |
1005 } | 1088 } |
1006 | 1089 |
1007 | 1090 |
1008 function ArrayIndexOf(element, index) { | 1091 function ArrayIndexOf(element, index) { |
1092 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1093 throw MakeTypeError("called_on_null_or_undefined", | |
1094 ["Array.prototype.indexOf"]); | |
1095 } | |
1096 | |
1009 var length = TO_UINT32(this.length); | 1097 var length = TO_UINT32(this.length); |
1010 if (length == 0) return -1; | 1098 if (length == 0) return -1; |
1011 if (IS_UNDEFINED(index)) { | 1099 if (IS_UNDEFINED(index)) { |
1012 index = 0; | 1100 index = 0; |
1013 } else { | 1101 } else { |
1014 index = TO_INTEGER(index); | 1102 index = TO_INTEGER(index); |
1015 // If index is negative, index from the end of the array. | 1103 // If index is negative, index from the end of the array. |
1016 if (index < 0) { | 1104 if (index < 0) { |
1017 index = length + index; | 1105 index = length + index; |
1018 // If index is still negative, search the entire array. | 1106 // If index is still negative, search the entire array. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1056 for (var i = min; i < max; i++) { | 1144 for (var i = min; i < max; i++) { |
1057 if (IS_UNDEFINED(this[i]) && i in this) { | 1145 if (IS_UNDEFINED(this[i]) && i in this) { |
1058 return i; | 1146 return i; |
1059 } | 1147 } |
1060 } | 1148 } |
1061 return -1; | 1149 return -1; |
1062 } | 1150 } |
1063 | 1151 |
1064 | 1152 |
1065 function ArrayLastIndexOf(element, index) { | 1153 function ArrayLastIndexOf(element, index) { |
1154 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1155 throw MakeTypeError("called_on_null_or_undefined", | |
1156 ["Array.prototype.lastIndexOf"]); | |
1157 } | |
1158 | |
1066 var length = TO_UINT32(this.length); | 1159 var length = TO_UINT32(this.length); |
1067 if (length == 0) return -1; | 1160 if (length == 0) return -1; |
1068 if (%_ArgumentsLength() < 2) { | 1161 if (%_ArgumentsLength() < 2) { |
1069 index = length - 1; | 1162 index = length - 1; |
1070 } else { | 1163 } else { |
1071 index = TO_INTEGER(index); | 1164 index = TO_INTEGER(index); |
1072 // If index is negative, index from end of the array. | 1165 // If index is negative, index from end of the array. |
1073 if (index < 0) index += length; | 1166 if (index < 0) index += length; |
1074 // If index is still negative, do not search the array. | 1167 // If index is still negative, do not search the array. |
1075 if (index < 0) return -1; | 1168 if (index < 0) return -1; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1109 for (var i = max; i >= min; i--) { | 1202 for (var i = max; i >= min; i--) { |
1110 if (IS_UNDEFINED(this[i]) && i in this) { | 1203 if (IS_UNDEFINED(this[i]) && i in this) { |
1111 return i; | 1204 return i; |
1112 } | 1205 } |
1113 } | 1206 } |
1114 return -1; | 1207 return -1; |
1115 } | 1208 } |
1116 | 1209 |
1117 | 1210 |
1118 function ArrayReduce(callback, current) { | 1211 function ArrayReduce(callback, current) { |
1212 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1213 throw MakeTypeError("called_on_null_or_undefined", | |
1214 ["Array.prototype.reduce"]); | |
1215 } | |
1216 | |
1119 if (!IS_FUNCTION(callback)) { | 1217 if (!IS_FUNCTION(callback)) { |
1120 throw MakeTypeError('called_non_callable', [callback]); | 1218 throw MakeTypeError('called_non_callable', [callback]); |
1121 } | 1219 } |
1122 // Pull out the length so that modifications to the length in the | 1220 // Pull out the length so that modifications to the length in the |
1123 // loop will not affect the looping. | 1221 // loop will not affect the looping. |
1124 var length = this.length; | 1222 var length = this.length; |
1125 var i = 0; | 1223 var i = 0; |
1126 | 1224 |
1127 find_initial: if (%_ArgumentsLength() < 2) { | 1225 find_initial: if (%_ArgumentsLength() < 2) { |
1128 for (; i < length; i++) { | 1226 for (; i < length; i++) { |
1129 current = this[i]; | 1227 current = this[i]; |
1130 if (!IS_UNDEFINED(current) || i in this) { | 1228 if (!IS_UNDEFINED(current) || i in this) { |
1131 i++; | 1229 i++; |
1132 break find_initial; | 1230 break find_initial; |
1133 } | 1231 } |
1134 } | 1232 } |
1135 throw MakeTypeError('reduce_no_initial', []); | 1233 throw MakeTypeError('reduce_no_initial', []); |
1136 } | 1234 } |
1137 | 1235 |
1138 for (; i < length; i++) { | 1236 for (; i < length; i++) { |
1139 var element = this[i]; | 1237 var element = this[i]; |
1140 if (!IS_UNDEFINED(element) || i in this) { | 1238 if (!IS_UNDEFINED(element) || i in this) { |
1141 current = callback.call(null, current, element, i, this); | 1239 current = callback.call(null, current, element, i, this); |
1142 } | 1240 } |
1143 } | 1241 } |
1144 return current; | 1242 return current; |
1145 } | 1243 } |
1146 | 1244 |
1147 function ArrayReduceRight(callback, current) { | 1245 function ArrayReduceRight(callback, current) { |
1246 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { | |
1247 throw MakeTypeError("called_on_null_or_undefined", | |
1248 ["Array.prototype.reduceRight"]); | |
1249 } | |
1250 | |
1148 if (!IS_FUNCTION(callback)) { | 1251 if (!IS_FUNCTION(callback)) { |
1149 throw MakeTypeError('called_non_callable', [callback]); | 1252 throw MakeTypeError('called_non_callable', [callback]); |
1150 } | 1253 } |
1151 var i = this.length - 1; | 1254 var i = this.length - 1; |
1152 | 1255 |
1153 find_initial: if (%_ArgumentsLength() < 2) { | 1256 find_initial: if (%_ArgumentsLength() < 2) { |
1154 for (; i >= 0; i--) { | 1257 for (; i >= 0; i--) { |
1155 current = this[i]; | 1258 current = this[i]; |
1156 if (!IS_UNDEFINED(current) || i in this) { | 1259 if (!IS_UNDEFINED(current) || i in this) { |
1157 i--; | 1260 i--; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1240 InternalArray.prototype.join = getFunction("join", ArrayJoin); | 1343 InternalArray.prototype.join = getFunction("join", ArrayJoin); |
1241 InternalArray.prototype.pop = getFunction("pop", ArrayPop); | 1344 InternalArray.prototype.pop = getFunction("pop", ArrayPop); |
1242 InternalArray.prototype.push = getFunction("push", ArrayPush); | 1345 InternalArray.prototype.push = getFunction("push", ArrayPush); |
1243 InternalArray.prototype.toString = function() { | 1346 InternalArray.prototype.toString = function() { |
1244 return "Internal Array, length " + this.length; | 1347 return "Internal Array, length " + this.length; |
1245 }; | 1348 }; |
1246 } | 1349 } |
1247 | 1350 |
1248 | 1351 |
1249 SetupArray(); | 1352 SetupArray(); |
OLD | NEW |