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