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