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 var $arrayConcat; | 5 var $arrayConcat; |
6 var $arrayPush; | 6 var $arrayPush; |
7 var $arrayPop; | 7 var $arrayPop; |
8 var $arrayShift; | 8 var $arrayShift; |
9 var $arraySlice; | 9 var $arraySlice; |
10 var $arraySplice; | 10 var $arraySplice; |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 } | 220 } |
221 | 221 |
222 | 222 |
223 function ConvertToLocaleString(e) { | 223 function ConvertToLocaleString(e) { |
224 if (IS_NULL_OR_UNDEFINED(e)) { | 224 if (IS_NULL_OR_UNDEFINED(e)) { |
225 return ''; | 225 return ''; |
226 } else { | 226 } else { |
227 // According to ES5, section 15.4.4.3, the toLocaleString conversion | 227 // According to ES5, section 15.4.4.3, the toLocaleString conversion |
228 // must throw a TypeError if ToObject(e).toLocaleString isn't | 228 // must throw a TypeError if ToObject(e).toLocaleString isn't |
229 // callable. | 229 // callable. |
230 var e_obj = $toObject(e); | 230 var e_obj = TO_OBJECT(e); |
231 return $toString(e_obj.toLocaleString()); | 231 return $toString(e_obj.toLocaleString()); |
232 } | 232 } |
233 } | 233 } |
234 | 234 |
235 | 235 |
236 // This function implements the optimized splice implementation that can use | 236 // This function implements the optimized splice implementation that can use |
237 // special array operations to handle sparse arrays in a sensible fashion. | 237 // special array operations to handle sparse arrays in a sensible fashion. |
238 function SparseSlice(array, start_i, del_count, len, deleted_elements) { | 238 function SparseSlice(array, start_i, del_count, len, deleted_elements) { |
239 // Move deleted elements to a new array (the return value from splice). | 239 // Move deleted elements to a new array (the return value from splice). |
240 var indices = %GetArrayKeys(array, start_i + del_count); | 240 var indices = %GetArrayKeys(array, start_i + del_count); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 function ArrayToString() { | 381 function ArrayToString() { |
382 var array; | 382 var array; |
383 var func; | 383 var func; |
384 if (IS_ARRAY(this)) { | 384 if (IS_ARRAY(this)) { |
385 func = this.join; | 385 func = this.join; |
386 if (func === ArrayJoin) { | 386 if (func === ArrayJoin) { |
387 return Join(this, this.length, ',', ConvertToString); | 387 return Join(this, this.length, ',', ConvertToString); |
388 } | 388 } |
389 array = this; | 389 array = this; |
390 } else { | 390 } else { |
391 array = $toObject(this); | 391 array = TO_OBJECT(this); |
392 func = array.join; | 392 func = array.join; |
393 } | 393 } |
394 if (!IS_SPEC_FUNCTION(func)) { | 394 if (!IS_SPEC_FUNCTION(func)) { |
395 return %_CallFunction(array, ObjectToString); | 395 return %_CallFunction(array, ObjectToString); |
396 } | 396 } |
397 return %_CallFunction(array, func); | 397 return %_CallFunction(array, func); |
398 } | 398 } |
399 | 399 |
400 | 400 |
401 function InnerArrayToLocaleString(array, length) { | 401 function InnerArrayToLocaleString(array, length) { |
402 var len = TO_UINT32(length); | 402 var len = TO_UINT32(length); |
403 if (len === 0) return ""; | 403 if (len === 0) return ""; |
404 return Join(array, len, ',', ConvertToLocaleString); | 404 return Join(array, len, ',', ConvertToLocaleString); |
405 } | 405 } |
406 | 406 |
407 | 407 |
408 function ArrayToLocaleString() { | 408 function ArrayToLocaleString() { |
409 var array = $toObject(this); | 409 var array = TO_OBJECT(this); |
410 var arrayLen = array.length; | 410 var arrayLen = array.length; |
411 return InnerArrayToLocaleString(array, arrayLen); | 411 return InnerArrayToLocaleString(array, arrayLen); |
412 } | 412 } |
413 | 413 |
414 | 414 |
415 function InnerArrayJoin(separator, array, length) { | 415 function InnerArrayJoin(separator, array, length) { |
416 if (IS_UNDEFINED(separator)) { | 416 if (IS_UNDEFINED(separator)) { |
417 separator = ','; | 417 separator = ','; |
418 } else if (!IS_STRING(separator)) { | 418 } else if (!IS_STRING(separator)) { |
419 separator = $nonStringToString(separator); | 419 separator = $nonStringToString(separator); |
(...skipping 10 matching lines...) Expand all Loading... |
430 return $nonStringToString(e); | 430 return $nonStringToString(e); |
431 } | 431 } |
432 | 432 |
433 return Join(array, length, separator, ConvertToString); | 433 return Join(array, length, separator, ConvertToString); |
434 } | 434 } |
435 | 435 |
436 | 436 |
437 function ArrayJoin(separator) { | 437 function ArrayJoin(separator) { |
438 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join"); | 438 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join"); |
439 | 439 |
440 var array = TO_OBJECT_INLINE(this); | 440 var array = TO_OBJECT(this); |
441 var length = TO_UINT32(array.length); | 441 var length = TO_UINT32(array.length); |
442 | 442 |
443 return InnerArrayJoin(separator, array, length); | 443 return InnerArrayJoin(separator, array, length); |
444 } | 444 } |
445 | 445 |
446 | 446 |
447 function ObservedArrayPop(n) { | 447 function ObservedArrayPop(n) { |
448 n--; | 448 n--; |
449 var value = this[n]; | 449 var value = this[n]; |
450 | 450 |
451 try { | 451 try { |
452 $observeBeginPerformSplice(this); | 452 $observeBeginPerformSplice(this); |
453 delete this[n]; | 453 delete this[n]; |
454 this.length = n; | 454 this.length = n; |
455 } finally { | 455 } finally { |
456 $observeEndPerformSplice(this); | 456 $observeEndPerformSplice(this); |
457 $observeEnqueueSpliceRecord(this, n, [value], 0); | 457 $observeEnqueueSpliceRecord(this, n, [value], 0); |
458 } | 458 } |
459 | 459 |
460 return value; | 460 return value; |
461 } | 461 } |
462 | 462 |
463 | 463 |
464 // Removes the last element from the array and returns it. See | 464 // Removes the last element from the array and returns it. See |
465 // ECMA-262, section 15.4.4.6. | 465 // ECMA-262, section 15.4.4.6. |
466 function ArrayPop() { | 466 function ArrayPop() { |
467 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.pop"); | 467 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.pop"); |
468 | 468 |
469 var array = TO_OBJECT_INLINE(this); | 469 var array = TO_OBJECT(this); |
470 var n = TO_UINT32(array.length); | 470 var n = TO_UINT32(array.length); |
471 if (n == 0) { | 471 if (n == 0) { |
472 array.length = n; | 472 array.length = n; |
473 return; | 473 return; |
474 } | 474 } |
475 | 475 |
476 if (%IsObserved(array)) | 476 if (%IsObserved(array)) |
477 return ObservedArrayPop.call(array, n); | 477 return ObservedArrayPop.call(array, n); |
478 | 478 |
479 n--; | 479 n--; |
(...skipping 25 matching lines...) Expand all Loading... |
505 | 505 |
506 | 506 |
507 // Appends the arguments to the end of the array and returns the new | 507 // Appends the arguments to the end of the array and returns the new |
508 // length of the array. See ECMA-262, section 15.4.4.7. | 508 // length of the array. See ECMA-262, section 15.4.4.7. |
509 function ArrayPush() { | 509 function ArrayPush() { |
510 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push"); | 510 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push"); |
511 | 511 |
512 if (%IsObserved(this)) | 512 if (%IsObserved(this)) |
513 return ObservedArrayPush.apply(this, arguments); | 513 return ObservedArrayPush.apply(this, arguments); |
514 | 514 |
515 var array = TO_OBJECT_INLINE(this); | 515 var array = TO_OBJECT(this); |
516 var n = TO_UINT32(array.length); | 516 var n = TO_UINT32(array.length); |
517 var m = %_ArgumentsLength(); | 517 var m = %_ArgumentsLength(); |
518 | 518 |
519 for (var i = 0; i < m; i++) { | 519 for (var i = 0; i < m; i++) { |
520 array[i+n] = %_Arguments(i); | 520 array[i+n] = %_Arguments(i); |
521 } | 521 } |
522 | 522 |
523 var new_length = n + m; | 523 var new_length = n + m; |
524 array.length = new_length; | 524 array.length = new_length; |
525 return new_length; | 525 return new_length; |
526 } | 526 } |
527 | 527 |
528 | 528 |
529 // Returns an array containing the array elements of the object followed | 529 // Returns an array containing the array elements of the object followed |
530 // by the array elements of each argument in order. See ECMA-262, | 530 // by the array elements of each argument in order. See ECMA-262, |
531 // section 15.4.4.7. | 531 // section 15.4.4.7. |
532 function ArrayConcatJS(arg1) { // length == 1 | 532 function ArrayConcatJS(arg1) { // length == 1 |
533 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.concat"); | 533 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.concat"); |
534 | 534 |
535 var array = $toObject(this); | 535 var array = TO_OBJECT(this); |
536 var arg_count = %_ArgumentsLength(); | 536 var arg_count = %_ArgumentsLength(); |
537 var arrays = new InternalArray(1 + arg_count); | 537 var arrays = new InternalArray(1 + arg_count); |
538 arrays[0] = array; | 538 arrays[0] = array; |
539 for (var i = 0; i < arg_count; i++) { | 539 for (var i = 0; i < arg_count; i++) { |
540 arrays[i + 1] = %_Arguments(i); | 540 arrays[i + 1] = %_Arguments(i); |
541 } | 541 } |
542 | 542 |
543 return %ArrayConcat(arrays); | 543 return %ArrayConcat(arrays); |
544 } | 544 } |
545 | 545 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 } | 620 } |
621 } | 621 } |
622 } | 622 } |
623 return array; | 623 return array; |
624 } | 624 } |
625 | 625 |
626 | 626 |
627 function ArrayReverse() { | 627 function ArrayReverse() { |
628 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse"); | 628 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse"); |
629 | 629 |
630 var array = TO_OBJECT_INLINE(this); | 630 var array = TO_OBJECT(this); |
631 var len = TO_UINT32(array.length); | 631 var len = TO_UINT32(array.length); |
632 var isArray = IS_ARRAY(array); | 632 var isArray = IS_ARRAY(array); |
633 | 633 |
634 if (UseSparseVariant(array, len, isArray, len)) { | 634 if (UseSparseVariant(array, len, isArray, len)) { |
635 %NormalizeElements(array); | 635 %NormalizeElements(array); |
636 SparseReverse(array, len); | 636 SparseReverse(array, len); |
637 return array; | 637 return array; |
638 } else if (isArray && %_HasFastPackedElements(array)) { | 638 } else if (isArray && %_HasFastPackedElements(array)) { |
639 return PackedArrayReverse(array, len); | 639 return PackedArrayReverse(array, len); |
640 } else { | 640 } else { |
(...skipping 14 matching lines...) Expand all Loading... |
655 $observeEnqueueSpliceRecord(this, 0, [first], 0); | 655 $observeEnqueueSpliceRecord(this, 0, [first], 0); |
656 } | 656 } |
657 | 657 |
658 return first; | 658 return first; |
659 } | 659 } |
660 | 660 |
661 | 661 |
662 function ArrayShift() { | 662 function ArrayShift() { |
663 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift"); | 663 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift"); |
664 | 664 |
665 var array = TO_OBJECT_INLINE(this); | 665 var array = TO_OBJECT(this); |
666 var len = TO_UINT32(array.length); | 666 var len = TO_UINT32(array.length); |
667 | 667 |
668 if (len === 0) { | 668 if (len === 0) { |
669 array.length = 0; | 669 array.length = 0; |
670 return; | 670 return; |
671 } | 671 } |
672 | 672 |
673 if (ObjectIsSealed(array)) throw MakeTypeError(kArrayFunctionsOnSealed); | 673 if (ObjectIsSealed(array)) throw MakeTypeError(kArrayFunctionsOnSealed); |
674 | 674 |
675 if (%IsObserved(array)) | 675 if (%IsObserved(array)) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 return new_length; | 709 return new_length; |
710 } | 710 } |
711 | 711 |
712 | 712 |
713 function ArrayUnshift(arg1) { // length == 1 | 713 function ArrayUnshift(arg1) { // length == 1 |
714 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift"); | 714 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift"); |
715 | 715 |
716 if (%IsObserved(this)) | 716 if (%IsObserved(this)) |
717 return ObservedArrayUnshift.apply(this, arguments); | 717 return ObservedArrayUnshift.apply(this, arguments); |
718 | 718 |
719 var array = TO_OBJECT_INLINE(this); | 719 var array = TO_OBJECT(this); |
720 var len = TO_UINT32(array.length); | 720 var len = TO_UINT32(array.length); |
721 var num_arguments = %_ArgumentsLength(); | 721 var num_arguments = %_ArgumentsLength(); |
722 | 722 |
723 if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) && | 723 if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) && |
724 !ObjectIsSealed(array)) { | 724 !ObjectIsSealed(array)) { |
725 SparseMove(array, 0, 0, len, num_arguments); | 725 SparseMove(array, 0, 0, len, num_arguments); |
726 } else { | 726 } else { |
727 SimpleMove(array, 0, 0, len, num_arguments); | 727 SimpleMove(array, 0, 0, len, num_arguments); |
728 } | 728 } |
729 | 729 |
730 for (var i = 0; i < num_arguments; i++) { | 730 for (var i = 0; i < num_arguments; i++) { |
731 array[i] = %_Arguments(i); | 731 array[i] = %_Arguments(i); |
732 } | 732 } |
733 | 733 |
734 var new_length = len + num_arguments; | 734 var new_length = len + num_arguments; |
735 array.length = new_length; | 735 array.length = new_length; |
736 return new_length; | 736 return new_length; |
737 } | 737 } |
738 | 738 |
739 | 739 |
740 function ArraySlice(start, end) { | 740 function ArraySlice(start, end) { |
741 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); | 741 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice"); |
742 | 742 |
743 var array = TO_OBJECT_INLINE(this); | 743 var array = TO_OBJECT(this); |
744 var len = TO_UINT32(array.length); | 744 var len = TO_UINT32(array.length); |
745 var start_i = TO_INTEGER(start); | 745 var start_i = TO_INTEGER(start); |
746 var end_i = len; | 746 var end_i = len; |
747 | 747 |
748 if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end); | 748 if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end); |
749 | 749 |
750 if (start_i < 0) { | 750 if (start_i < 0) { |
751 start_i += len; | 751 start_i += len; |
752 if (start_i < 0) start_i = 0; | 752 if (start_i < 0) start_i = 0; |
753 } else { | 753 } else { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 } | 851 } |
852 | 852 |
853 | 853 |
854 function ArraySplice(start, delete_count) { | 854 function ArraySplice(start, delete_count) { |
855 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice"); | 855 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice"); |
856 | 856 |
857 if (%IsObserved(this)) | 857 if (%IsObserved(this)) |
858 return ObservedArraySplice.apply(this, arguments); | 858 return ObservedArraySplice.apply(this, arguments); |
859 | 859 |
860 var num_arguments = %_ArgumentsLength(); | 860 var num_arguments = %_ArgumentsLength(); |
861 var array = TO_OBJECT_INLINE(this); | 861 var array = TO_OBJECT(this); |
862 var len = TO_UINT32(array.length); | 862 var len = TO_UINT32(array.length); |
863 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); | 863 var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); |
864 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, | 864 var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, |
865 start_i); | 865 start_i); |
866 var deleted_elements = []; | 866 var deleted_elements = []; |
867 deleted_elements.length = del_count; | 867 deleted_elements.length = del_count; |
868 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; | 868 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; |
869 | 869 |
870 if (del_count != num_elements_to_add && ObjectIsSealed(array)) { | 870 if (del_count != num_elements_to_add && ObjectIsSealed(array)) { |
871 throw MakeTypeError(kArrayFunctionsOnSealed); | 871 throw MakeTypeError(kArrayFunctionsOnSealed); |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 ShadowPrototypeElements(this, num_non_undefined, max_prototype_element); | 1183 ShadowPrototypeElements(this, num_non_undefined, max_prototype_element); |
1184 } | 1184 } |
1185 | 1185 |
1186 return this; | 1186 return this; |
1187 } | 1187 } |
1188 | 1188 |
1189 | 1189 |
1190 function ArraySort(comparefn) { | 1190 function ArraySort(comparefn) { |
1191 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort"); | 1191 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort"); |
1192 | 1192 |
1193 var array = $toObject(this); | 1193 var array = TO_OBJECT(this); |
1194 var length = TO_UINT32(array.length); | 1194 var length = TO_UINT32(array.length); |
1195 return %_CallFunction(array, length, comparefn, InnerArraySort); | 1195 return %_CallFunction(array, length, comparefn, InnerArraySort); |
1196 } | 1196 } |
1197 | 1197 |
1198 | 1198 |
1199 // The following functions cannot be made efficient on sparse arrays while | 1199 // The following functions cannot be made efficient on sparse arrays while |
1200 // preserving the semantics, since the calls to the receiver function can add | 1200 // preserving the semantics, since the calls to the receiver function can add |
1201 // or delete elements from the array. | 1201 // or delete elements from the array. |
1202 function InnerArrayFilter(f, receiver, array, length) { | 1202 function InnerArrayFilter(f, receiver, array, length) { |
1203 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); | 1203 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); |
1204 var needs_wrapper = false; | 1204 var needs_wrapper = false; |
1205 if (IS_NULL(receiver)) { | 1205 if (IS_NULL(receiver)) { |
1206 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; | 1206 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; |
1207 } else if (!IS_UNDEFINED(receiver)) { | 1207 } else if (!IS_UNDEFINED(receiver)) { |
1208 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver); | 1208 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver); |
1209 } | 1209 } |
1210 | 1210 |
1211 var accumulator = new InternalArray(); | 1211 var accumulator = new InternalArray(); |
1212 var accumulator_length = 0; | 1212 var accumulator_length = 0; |
1213 var is_array = IS_ARRAY(array); | 1213 var is_array = IS_ARRAY(array); |
1214 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); | 1214 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); |
1215 for (var i = 0; i < length; i++) { | 1215 for (var i = 0; i < length; i++) { |
1216 if (HAS_INDEX(array, i, is_array)) { | 1216 if (HAS_INDEX(array, i, is_array)) { |
1217 var element = array[i]; | 1217 var element = array[i]; |
1218 // Prepare break slots for debugger step in. | 1218 // Prepare break slots for debugger step in. |
1219 if (stepping) %DebugPrepareStepInIfStepping(f); | 1219 if (stepping) %DebugPrepareStepInIfStepping(f); |
1220 var new_receiver = needs_wrapper ? $toObject(receiver) : receiver; | 1220 var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver; |
1221 if (%_CallFunction(new_receiver, element, i, array, f)) { | 1221 if (%_CallFunction(new_receiver, element, i, array, f)) { |
1222 accumulator[accumulator_length++] = element; | 1222 accumulator[accumulator_length++] = element; |
1223 } | 1223 } |
1224 } | 1224 } |
1225 } | 1225 } |
1226 return accumulator; | 1226 return accumulator; |
1227 } | 1227 } |
1228 | 1228 |
1229 function ArrayFilter(f, receiver) { | 1229 function ArrayFilter(f, receiver) { |
1230 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter"); | 1230 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter"); |
1231 | 1231 |
1232 // Pull out the length so that modifications to the length in the | 1232 // Pull out the length so that modifications to the length in the |
1233 // loop will not affect the looping and side effects are visible. | 1233 // loop will not affect the looping and side effects are visible. |
1234 var array = $toObject(this); | 1234 var array = TO_OBJECT(this); |
1235 var length = $toUint32(array.length); | 1235 var length = $toUint32(array.length); |
1236 var accumulator = InnerArrayFilter(f, receiver, array, length); | 1236 var accumulator = InnerArrayFilter(f, receiver, array, length); |
1237 var result = new GlobalArray(); | 1237 var result = new GlobalArray(); |
1238 %MoveArrayContents(accumulator, result); | 1238 %MoveArrayContents(accumulator, result); |
1239 return result; | 1239 return result; |
1240 } | 1240 } |
1241 | 1241 |
1242 function InnerArrayForEach(f, receiver, array, length) { | 1242 function InnerArrayForEach(f, receiver, array, length) { |
1243 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); | 1243 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); |
1244 var needs_wrapper = false; | 1244 var needs_wrapper = false; |
1245 if (IS_NULL(receiver)) { | 1245 if (IS_NULL(receiver)) { |
1246 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; | 1246 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; |
1247 } else if (!IS_UNDEFINED(receiver)) { | 1247 } else if (!IS_UNDEFINED(receiver)) { |
1248 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver); | 1248 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver); |
1249 } | 1249 } |
1250 | 1250 |
1251 var is_array = IS_ARRAY(array); | 1251 var is_array = IS_ARRAY(array); |
1252 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); | 1252 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); |
1253 for (var i = 0; i < length; i++) { | 1253 for (var i = 0; i < length; i++) { |
1254 if (HAS_INDEX(array, i, is_array)) { | 1254 if (HAS_INDEX(array, i, is_array)) { |
1255 var element = array[i]; | 1255 var element = array[i]; |
1256 // Prepare break slots for debugger step in. | 1256 // Prepare break slots for debugger step in. |
1257 if (stepping) %DebugPrepareStepInIfStepping(f); | 1257 if (stepping) %DebugPrepareStepInIfStepping(f); |
1258 var new_receiver = needs_wrapper ? $toObject(receiver) : receiver; | 1258 var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver; |
1259 %_CallFunction(new_receiver, element, i, array, f); | 1259 %_CallFunction(new_receiver, element, i, array, f); |
1260 } | 1260 } |
1261 } | 1261 } |
1262 } | 1262 } |
1263 | 1263 |
1264 function ArrayForEach(f, receiver) { | 1264 function ArrayForEach(f, receiver) { |
1265 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach"); | 1265 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach"); |
1266 | 1266 |
1267 // Pull out the length so that modifications to the length in the | 1267 // Pull out the length so that modifications to the length in the |
1268 // loop will not affect the looping and side effects are visible. | 1268 // loop will not affect the looping and side effects are visible. |
1269 var array = $toObject(this); | 1269 var array = TO_OBJECT(this); |
1270 var length = TO_UINT32(array.length); | 1270 var length = TO_UINT32(array.length); |
1271 InnerArrayForEach(f, receiver, array, length); | 1271 InnerArrayForEach(f, receiver, array, length); |
1272 } | 1272 } |
1273 | 1273 |
1274 | 1274 |
1275 function InnerArraySome(f, receiver, array, length) { | 1275 function InnerArraySome(f, receiver, array, length) { |
1276 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); | 1276 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); |
1277 var needs_wrapper = false; | 1277 var needs_wrapper = false; |
1278 if (IS_NULL(receiver)) { | 1278 if (IS_NULL(receiver)) { |
1279 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; | 1279 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; |
1280 } else if (!IS_UNDEFINED(receiver)) { | 1280 } else if (!IS_UNDEFINED(receiver)) { |
1281 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver); | 1281 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver); |
1282 } | 1282 } |
1283 | 1283 |
1284 var is_array = IS_ARRAY(array); | 1284 var is_array = IS_ARRAY(array); |
1285 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); | 1285 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); |
1286 for (var i = 0; i < length; i++) { | 1286 for (var i = 0; i < length; i++) { |
1287 if (HAS_INDEX(array, i, is_array)) { | 1287 if (HAS_INDEX(array, i, is_array)) { |
1288 var element = array[i]; | 1288 var element = array[i]; |
1289 // Prepare break slots for debugger step in. | 1289 // Prepare break slots for debugger step in. |
1290 if (stepping) %DebugPrepareStepInIfStepping(f); | 1290 if (stepping) %DebugPrepareStepInIfStepping(f); |
1291 var new_receiver = needs_wrapper ? $toObject(receiver) : receiver; | 1291 var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver; |
1292 if (%_CallFunction(new_receiver, element, i, array, f)) return true; | 1292 if (%_CallFunction(new_receiver, element, i, array, f)) return true; |
1293 } | 1293 } |
1294 } | 1294 } |
1295 return false; | 1295 return false; |
1296 } | 1296 } |
1297 | 1297 |
1298 | 1298 |
1299 // Executes the function once for each element present in the | 1299 // Executes the function once for each element present in the |
1300 // array until it finds one where callback returns true. | 1300 // array until it finds one where callback returns true. |
1301 function ArraySome(f, receiver) { | 1301 function ArraySome(f, receiver) { |
1302 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some"); | 1302 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some"); |
1303 | 1303 |
1304 // Pull out the length so that modifications to the length in the | 1304 // Pull out the length so that modifications to the length in the |
1305 // loop will not affect the looping and side effects are visible. | 1305 // loop will not affect the looping and side effects are visible. |
1306 var array = $toObject(this); | 1306 var array = TO_OBJECT(this); |
1307 var length = TO_UINT32(array.length); | 1307 var length = TO_UINT32(array.length); |
1308 return InnerArraySome(f, receiver, array, length); | 1308 return InnerArraySome(f, receiver, array, length); |
1309 } | 1309 } |
1310 | 1310 |
1311 | 1311 |
1312 function InnerArrayEvery(f, receiver, array, length) { | 1312 function InnerArrayEvery(f, receiver, array, length) { |
1313 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); | 1313 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); |
1314 var needs_wrapper = false; | 1314 var needs_wrapper = false; |
1315 if (IS_NULL(receiver)) { | 1315 if (IS_NULL(receiver)) { |
1316 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; | 1316 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; |
1317 } else if (!IS_UNDEFINED(receiver)) { | 1317 } else if (!IS_UNDEFINED(receiver)) { |
1318 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver); | 1318 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver); |
1319 } | 1319 } |
1320 | 1320 |
1321 var is_array = IS_ARRAY(array); | 1321 var is_array = IS_ARRAY(array); |
1322 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); | 1322 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); |
1323 for (var i = 0; i < length; i++) { | 1323 for (var i = 0; i < length; i++) { |
1324 if (HAS_INDEX(array, i, is_array)) { | 1324 if (HAS_INDEX(array, i, is_array)) { |
1325 var element = array[i]; | 1325 var element = array[i]; |
1326 // Prepare break slots for debugger step in. | 1326 // Prepare break slots for debugger step in. |
1327 if (stepping) %DebugPrepareStepInIfStepping(f); | 1327 if (stepping) %DebugPrepareStepInIfStepping(f); |
1328 var new_receiver = needs_wrapper ? $toObject(receiver) : receiver; | 1328 var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver; |
1329 if (!%_CallFunction(new_receiver, element, i, array, f)) return false; | 1329 if (!%_CallFunction(new_receiver, element, i, array, f)) return false; |
1330 } | 1330 } |
1331 } | 1331 } |
1332 return true; | 1332 return true; |
1333 } | 1333 } |
1334 | 1334 |
1335 function ArrayEvery(f, receiver) { | 1335 function ArrayEvery(f, receiver) { |
1336 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every"); | 1336 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every"); |
1337 | 1337 |
1338 // Pull out the length so that modifications to the length in the | 1338 // Pull out the length so that modifications to the length in the |
1339 // loop will not affect the looping and side effects are visible. | 1339 // loop will not affect the looping and side effects are visible. |
1340 var array = $toObject(this); | 1340 var array = TO_OBJECT(this); |
1341 var length = TO_UINT32(array.length); | 1341 var length = TO_UINT32(array.length); |
1342 return InnerArrayEvery(f, receiver, array, length); | 1342 return InnerArrayEvery(f, receiver, array, length); |
1343 } | 1343 } |
1344 | 1344 |
1345 | 1345 |
1346 function InnerArrayMap(f, receiver, array, length) { | 1346 function InnerArrayMap(f, receiver, array, length) { |
1347 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); | 1347 if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f); |
1348 var needs_wrapper = false; | 1348 var needs_wrapper = false; |
1349 if (IS_NULL(receiver)) { | 1349 if (IS_NULL(receiver)) { |
1350 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; | 1350 if (%IsSloppyModeFunction(f)) receiver = UNDEFINED; |
1351 } else if (!IS_UNDEFINED(receiver)) { | 1351 } else if (!IS_UNDEFINED(receiver)) { |
1352 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver); | 1352 needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver); |
1353 } | 1353 } |
1354 | 1354 |
1355 var accumulator = new InternalArray(length); | 1355 var accumulator = new InternalArray(length); |
1356 var is_array = IS_ARRAY(array); | 1356 var is_array = IS_ARRAY(array); |
1357 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); | 1357 var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f); |
1358 for (var i = 0; i < length; i++) { | 1358 for (var i = 0; i < length; i++) { |
1359 if (HAS_INDEX(array, i, is_array)) { | 1359 if (HAS_INDEX(array, i, is_array)) { |
1360 var element = array[i]; | 1360 var element = array[i]; |
1361 // Prepare break slots for debugger step in. | 1361 // Prepare break slots for debugger step in. |
1362 if (stepping) %DebugPrepareStepInIfStepping(f); | 1362 if (stepping) %DebugPrepareStepInIfStepping(f); |
1363 var new_receiver = needs_wrapper ? $toObject(receiver) : receiver; | 1363 var new_receiver = needs_wrapper ? TO_OBJECT(receiver) : receiver; |
1364 accumulator[i] = %_CallFunction(new_receiver, element, i, array, f); | 1364 accumulator[i] = %_CallFunction(new_receiver, element, i, array, f); |
1365 } | 1365 } |
1366 } | 1366 } |
1367 return accumulator; | 1367 return accumulator; |
1368 } | 1368 } |
1369 | 1369 |
1370 | 1370 |
1371 function ArrayMap(f, receiver) { | 1371 function ArrayMap(f, receiver) { |
1372 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map"); | 1372 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map"); |
1373 | 1373 |
1374 // Pull out the length so that modifications to the length in the | 1374 // Pull out the length so that modifications to the length in the |
1375 // loop will not affect the looping and side effects are visible. | 1375 // loop will not affect the looping and side effects are visible. |
1376 var array = $toObject(this); | 1376 var array = TO_OBJECT(this); |
1377 var length = TO_UINT32(array.length); | 1377 var length = TO_UINT32(array.length); |
1378 var accumulator = InnerArrayMap(f, receiver, array, length); | 1378 var accumulator = InnerArrayMap(f, receiver, array, length); |
1379 var result = new GlobalArray(); | 1379 var result = new GlobalArray(); |
1380 %MoveArrayContents(accumulator, result); | 1380 %MoveArrayContents(accumulator, result); |
1381 return result; | 1381 return result; |
1382 } | 1382 } |
1383 | 1383 |
1384 | 1384 |
1385 // For .indexOf, we don't need to pass in the number of arguments | 1385 // For .indexOf, we don't need to pass in the number of arguments |
1386 // at the callsite since ToInteger(undefined) == 0; however, for | 1386 // at the callsite since ToInteger(undefined) == 0; however, for |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1535 } | 1535 } |
1536 return current; | 1536 return current; |
1537 } | 1537 } |
1538 | 1538 |
1539 | 1539 |
1540 function ArrayReduce(callback, current) { | 1540 function ArrayReduce(callback, current) { |
1541 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce"); | 1541 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce"); |
1542 | 1542 |
1543 // Pull out the length so that modifications to the length in the | 1543 // Pull out the length so that modifications to the length in the |
1544 // loop will not affect the looping and side effects are visible. | 1544 // loop will not affect the looping and side effects are visible. |
1545 var array = $toObject(this); | 1545 var array = TO_OBJECT(this); |
1546 var length = $toUint32(array.length); | 1546 var length = $toUint32(array.length); |
1547 return InnerArrayReduce(callback, current, array, length, | 1547 return InnerArrayReduce(callback, current, array, length, |
1548 %_ArgumentsLength()); | 1548 %_ArgumentsLength()); |
1549 } | 1549 } |
1550 | 1550 |
1551 | 1551 |
1552 function InnerArrayReduceRight(callback, current, array, length, | 1552 function InnerArrayReduceRight(callback, current, array, length, |
1553 argumentsLength) { | 1553 argumentsLength) { |
1554 if (!IS_SPEC_FUNCTION(callback)) { | 1554 if (!IS_SPEC_FUNCTION(callback)) { |
1555 throw MakeTypeError(kCalledNonCallable, callback); | 1555 throw MakeTypeError(kCalledNonCallable, callback); |
(...skipping 22 matching lines...) Expand all Loading... |
1578 } | 1578 } |
1579 return current; | 1579 return current; |
1580 } | 1580 } |
1581 | 1581 |
1582 | 1582 |
1583 function ArrayReduceRight(callback, current) { | 1583 function ArrayReduceRight(callback, current) { |
1584 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight"); | 1584 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight"); |
1585 | 1585 |
1586 // Pull out the length so that side effects are visible before the | 1586 // Pull out the length so that side effects are visible before the |
1587 // callback function is checked. | 1587 // callback function is checked. |
1588 var array = $toObject(this); | 1588 var array = TO_OBJECT(this); |
1589 var length = $toUint32(array.length); | 1589 var length = $toUint32(array.length); |
1590 return InnerArrayReduceRight(callback, current, array, length, | 1590 return InnerArrayReduceRight(callback, current, array, length, |
1591 %_ArgumentsLength()); | 1591 %_ArgumentsLength()); |
1592 } | 1592 } |
1593 | 1593 |
1594 // ES5, 15.4.3.2 | 1594 // ES5, 15.4.3.2 |
1595 function ArrayIsArray(obj) { | 1595 function ArrayIsArray(obj) { |
1596 return IS_ARRAY(obj); | 1596 return IS_ARRAY(obj); |
1597 } | 1597 } |
1598 | 1598 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1710 | 1710 |
1711 $arrayConcat = ArrayConcatJS; | 1711 $arrayConcat = ArrayConcatJS; |
1712 $arrayPush = ArrayPush; | 1712 $arrayPush = ArrayPush; |
1713 $arrayPop = ArrayPop; | 1713 $arrayPop = ArrayPop; |
1714 $arrayShift = ArrayShift; | 1714 $arrayShift = ArrayShift; |
1715 $arraySlice = ArraySlice; | 1715 $arraySlice = ArraySlice; |
1716 $arraySplice = ArraySplice; | 1716 $arraySplice = ArraySplice; |
1717 $arrayUnshift = ArrayUnshift; | 1717 $arrayUnshift = ArrayUnshift; |
1718 | 1718 |
1719 }); | 1719 }); |
OLD | NEW |