array.js revision 5710ceac03e2cf7a164ad7393b5a6b6114ea45e6
1b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Copyright 2010 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This file relies on the fact that the following declarations have been made 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// in runtime.js: 303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// var $Array = global.Array; 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------- 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Global list of arrays visited during toString, toLocaleString and 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// join invocations. 36e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvar visited_arrays = new InternalArray(); 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Gets a sorted array of array keys. Useful for operations on sparse 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// arrays. Dupes have not been removed. 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction GetSortedArrayKeys(array, intervals) { 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var length = intervals.length; 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var keys = []; 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var k = 0; k < length; k++) { 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var key = intervals[k]; 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (key < 0) { 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var j = -1 - key; 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var limit = j + intervals[++k]; 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (; j < limit; j++) { 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var e = array[j]; 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(e) || j in array) { 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block keys.push(j); 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The case where key is undefined also ends here. 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(key)) { 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var e = array[key]; 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(e) || key in array) { 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block keys.push(key); 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block keys.sort(function(a, b) { return a - b; }); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return keys; 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 70257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochfunction SparseJoinWithSeparator(array, len, convert, separator) { 71257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len)); 72257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var totalLength = 0; 73257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var elements = new InternalArray(keys.length * 2); 74257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var previousKey = -1; 75257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch for (var i = 0; i < keys.length; i++) { 76257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var key = keys[i]; 77257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (key != previousKey) { // keys may contain duplicates. 78257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var e = array[key]; 79257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!IS_STRING(e)) e = convert(e); 80257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch elements[i * 2] = key; 81257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch elements[i * 2 + 1] = e; 82257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch previousKey = key; 83257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 84257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 85257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return %SparseJoinWithSeparator(elements, len, separator); 86257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 87257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 88257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Optimized for sparse arrays if separator is ''. 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SparseJoin(array, len, convert) { 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len)); 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var last_key = -1; 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var keys_length = keys.length; 94e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 95e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch var elements = new InternalArray(keys_length); 96e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var elements_length = 0; 97e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < keys_length; i++) { 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var key = keys[i]; 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (key != last_key) { 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var e = array[key]; 102e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (!IS_STRING(e)) e = convert(e); 103e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke elements[elements_length++] = e; 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_key = key; 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 107e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return %StringBuilderConcat(elements, elements_length, ''); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction UseSparseVariant(object, length, is_array) { 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return is_array && 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block length > 1000 && 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (!%_IsSmi(length) || 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block %EstimateNumberOfElements(object) < (length >> 2)); 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction Join(array, length, separator, convert) { 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (length == 0) return ''; 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var is_array = IS_ARRAY(array); 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_array) { 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the array is cyclic, return the empty string for already 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // visited arrays. 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!%PushIfAbsent(visited_arrays, array)) return ''; 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Attempt to convert the elements. 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block try { 132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (UseSparseVariant(array, length, is_array)) { 133257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (separator.length == 0) { 134257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return SparseJoin(array, length, convert); 135257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 136257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return SparseJoinWithSeparator(array, length, convert, separator); 137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fast case for one-element arrays. 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (length == 1) { 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var e = array[0]; 143b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (IS_STRING(e)) return e; 144b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return convert(e); 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 147e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Construct an array for the elements. 148e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch var elements = new InternalArray(length); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // We pull the empty separator check outside the loop for speed! 151d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (separator.length == 0) { 152b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch var elements_length = 0; 153d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block for (var i = 0; i < length; i++) { 154d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var e = array[i]; 155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!IS_STRING(e)) e = convert(e); 156257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch elements[elements_length++] = e; 157d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 158086aeeaae12517475c22695a200be45495516549Ben Murdoch elements.length = elements_length; 159086aeeaae12517475c22695a200be45495516549Ben Murdoch var result = %_FastAsciiArrayJoin(elements, ''); 160086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_UNDEFINED(result)) return result; 161086aeeaae12517475c22695a200be45495516549Ben Murdoch return %StringBuilderConcat(elements, elements_length, ''); 162086aeeaae12517475c22695a200be45495516549Ben Murdoch } 163b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Non-empty separator case. 164e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If the first element is a number then use the heuristic that the 165b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // remaining elements are also likely to be numbers. 166b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (!IS_NUMBER(array[0])) { 167b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch for (var i = 0; i < length; i++) { 168b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch var e = array[i]; 169086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_STRING(e)) e = convert(e); 170086aeeaae12517475c22695a200be45495516549Ben Murdoch elements[i] = e; 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 172e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 173b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch for (var i = 0; i < length; i++) { 174b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch var e = array[i]; 17569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (IS_NUMBER(e)) { 17669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch e = %_NumberToString(e); 17769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else if (!IS_STRING(e)) { 17869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch e = convert(e); 17969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 18069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch elements[i] = e; 181b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 182086aeeaae12517475c22695a200be45495516549Ben Murdoch } 183e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch var result = %_FastAsciiArrayJoin(elements, separator); 184e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!IS_UNDEFINED(result)) return result; 185e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 186e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return %StringBuilderJoin(elements, length, separator); 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } finally { 1881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Make sure to remove the last element of the visited array no 1891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // matter what happens. 1901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (is_array) visited_arrays.length = visited_arrays.length - 1; 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochfunction ConvertToString(x) { 196e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Assumes x is a non-string. 197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (IS_NUMBER(x)) return %_NumberToString(x); 198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; 199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return (IS_NULL_OR_UNDEFINED(x)) ? '' : %ToString(%DefaultString(x)); 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ConvertToLocaleString(e) { 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (IS_NULL_OR_UNDEFINED(e)) { 205e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return ''; 206e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else { 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // According to ES5, section 15.4.4.3, the toLocaleString conversion 2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // must throw a TypeError if ToObject(e).toLocaleString isn't 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // callable. 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var e_obj = ToObject(e); 2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return %ToString(e_obj.toLocaleString()); 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This function implements the optimized splice implementation that can use 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// special array operations to handle sparse arrays in a sensible fashion. 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SmartSlice(array, start_i, del_count, len, deleted_elements) { 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move deleted elements to a new array (the return value from splice). 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Intervals array can contain keys and intervals. See comment in Concat. 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var intervals = %GetArrayKeys(array, start_i + del_count); 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var length = intervals.length; 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var k = 0; k < length; k++) { 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var key = intervals[k]; 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (key < 0) { 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var j = -1 - key; 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var interval_limit = j + intervals[++k]; 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (j < start_i) { 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j = start_i; 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (; j < interval_limit; j++) { 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 15.4.4.12 line 10. The spec could also be 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // interpreted such that %HasLocalProperty would be the 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // appropriate test. We follow KJS in consulting the 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype. 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current = array[j]; 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current) || j in array) { 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block deleted_elements[j - start_i] = current; 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(key)) { 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (key >= start_i) { 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 15.4.4.12 line 10. The spec could also be 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // interpreted such that %HasLocalProperty would be the 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // appropriate test. We follow KJS in consulting the 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype. 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current = array[key]; 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current) || key in array) { 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block deleted_elements[key - start_i] = current; 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This function implements the optimized splice implementation that can use 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// special array operations to handle sparse arrays in a sensible fashion. 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SmartMove(array, start_i, del_count, len, num_additional_args) { 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move data to new array. 263e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch var new_array = new InternalArray(len - del_count + num_additional_args); 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var intervals = %GetArrayKeys(array, len); 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var length = intervals.length; 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var k = 0; k < length; k++) { 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var key = intervals[k]; 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (key < 0) { 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var j = -1 - key; 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var interval_limit = j + intervals[++k]; 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (j < start_i && j < interval_limit) { 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The spec could also be interpreted such that 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // %HasLocalProperty would be the appropriate test. We follow 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // KJS in consulting the prototype. 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current = array[j]; 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current) || j in array) { 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new_array[j] = current; 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j++; 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j = start_i + del_count; 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (j < interval_limit) { 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 15.4.4.12 lines 24 and 41. The spec could also be 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // interpreted such that %HasLocalProperty would be the 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // appropriate test. We follow KJS in consulting the 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype. 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current = array[j]; 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current) || j in array) { 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new_array[j - del_count + num_additional_args] = current; 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j++; 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(key)) { 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (key < start_i) { 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The spec could also be interpreted such that 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // %HasLocalProperty would be the appropriate test. We follow 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // KJS in consulting the prototype. 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current = array[key]; 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current) || key in array) { 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new_array[key] = current; 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (key >= start_i + del_count) { 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 15.4.4.12 lines 24 and 41. The spec could also 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // be interpreted such that %HasLocalProperty would be the 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // appropriate test. We follow KJS in consulting the 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype. 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current = array[key]; 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current) || key in array) { 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new_array[key - del_count + num_additional_args] = current; 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move contents of new_array into this array 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block %MoveArrayContents(new_array, array); 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This is part of the old simple-minded splice. We are using it either 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// because the receiver is not an array (so we have no choice) or because we 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// know we are not deleting or moving a lot of elements. 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SimpleSlice(array, start_i, del_count, len, deleted_elements) { 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < del_count; i++) { 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var index = start_i + i; 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The spec could also be interpreted such that %HasLocalProperty 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // would be the appropriate test. We follow KJS in consulting the 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype. 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current = array[index]; 3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IS_UNDEFINED(current) || index in array) { 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block deleted_elements[i] = current; 3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SimpleMove(array, start_i, del_count, len, num_additional_args) { 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (num_additional_args !== del_count) { 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Move the existing elements after the elements to be deleted 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to the right position in the resulting array. 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (num_additional_args > del_count) { 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = len - del_count; i > start_i; i--) { 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var from_index = i + del_count - 1; 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var to_index = i + num_additional_args - 1; 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The spec could also be interpreted such that 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // %HasLocalProperty would be the appropriate test. We follow 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // KJS in consulting the prototype. 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current = array[from_index]; 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current) || from_index in array) { 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block array[to_index] = current; 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete array[to_index]; 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = start_i; i < len - del_count; i++) { 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var from_index = i + del_count; 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var to_index = i + num_additional_args; 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The spec could also be interpreted such that 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // %HasLocalProperty would be the appropriate test. We follow 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // KJS in consulting the prototype. 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current = array[from_index]; 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current) || from_index in array) { 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block array[to_index] = current; 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete array[to_index]; 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = len; i > len - del_count + num_additional_args; i--) { 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete array[i - 1]; 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------- 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayToString() { 3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var array; 3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var func; 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (IS_ARRAY(this)) { 3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch func = this.join; 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (func === ArrayJoin) { 3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Join(this, this.length, ',', ConvertToString); 3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array = this; 3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array = ToObject(this); 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch func = array.join; 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IS_SPEC_FUNCTION(func)) { 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return %_CallFunction(array, ObjectToString); 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return %_CallFunction(array, func); 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayToLocaleString() { 4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var array = ToObject(this); 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var arrayLen = array.length; 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var len = TO_UINT32(arrayLen); 4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (len === 0) return ""; 4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Join(array, len, ',', ConvertToLocaleString); 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayJoin(separator) { 411257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 412257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 413257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.join"]); 414257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 415257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 416e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (IS_UNDEFINED(separator)) { 417e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke separator = ','; 418e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else if (!IS_STRING(separator)) { 419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch separator = NonStringToString(separator); 420e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 4218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang var result = %_FastAsciiArrayJoin(this, separator); 423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!IS_UNDEFINED(result)) return result; 4248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return Join(this, TO_UINT32(this.length), separator, ConvertToString); 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Removes the last element from the array and returns it. See 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 15.4.4.6. 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayPop() { 432257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 433257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 434257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.pop"]); 435257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 436257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 437e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var n = TO_UINT32(this.length); 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (n == 0) { 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this.length = n; 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block n--; 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var value = this[n]; 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this.length = n; 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete this[n]; 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return value; 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Appends the arguments to the end of the array and returns the new 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// length of the array. See ECMA-262, section 15.4.4.7. 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayPush() { 453257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 454257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 455257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.push"]); 456257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 457257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 458e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var n = TO_UINT32(this.length); 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var m = %_ArgumentsLength(); 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < m; i++) { 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this[i+n] = %_Arguments(i); 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this.length = n + m; 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return this.length; 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayConcat(arg1) { // length == 1 469257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 470257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 471257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.concat"]); 472257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 473257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var arg_count = %_ArgumentsLength(); 475e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch var arrays = new InternalArray(1 + arg_count); 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arrays[0] = this; 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < arg_count; i++) { 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block arrays[i + 1] = %_Arguments(i); 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %ArrayConcat(arrays); 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// For implementing reverse() on large, sparse arrays. 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SparseReverse(array, len) { 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len)); 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var high_counter = keys.length - 1; 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var low_counter = 0; 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (low_counter <= high_counter) { 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var i = keys[low_counter]; 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var j = keys[high_counter]; 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var j_complement = len - j - 1; 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var low, high; 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (j_complement <= i) { 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block high = j; 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (keys[--high_counter] == j) { } 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block low = j_complement; 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (j_complement >= i) { 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block low = i; 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (keys[++low_counter] == i) { } 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block high = len - i - 1; 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current_i = array[low]; 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current_i) || low in array) { 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current_j = array[high]; 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current_j) || high in array) { 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block array[low] = current_j; 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block array[high] = current_i; 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block array[high] = current_i; 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete array[low]; 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current_j = array[high]; 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current_j) || high in array) { 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block array[low] = current_j; 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete array[high]; 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayReverse() { 530257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 531257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 532257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.reverse"]); 533257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 534257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 535e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var j = TO_UINT32(this.length) - 1; 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (UseSparseVariant(this, j, IS_ARRAY(this))) { 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SparseReverse(this, j+1); 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return this; 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < j; i++, j--) { 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current_i = this[i]; 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current_i) || i in this) { 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current_j = this[j]; 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current_j) || j in this) { 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this[i] = current_j; 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this[j] = current_i; 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this[j] = current_i; 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete this[i]; 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var current_j = this[j]; 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(current_j) || j in this) { 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this[i] = current_j; 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete this[j]; 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return this; 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayShift() { 566257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.shift"]); 569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 571e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var len = TO_UINT32(this.length); 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (len === 0) { 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this.length = 0; 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var first = this[0]; 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (IS_ARRAY(this)) { 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartMove(this, 0, 1, len, 0); 5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SimpleMove(this, 0, 1, len, 0); 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this.length = len - 1; 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return first; 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayUnshift(arg1) { // length == 1 593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.unshift"]); 596257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 597257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 598e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var len = TO_UINT32(this.length); 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var num_arguments = %_ArgumentsLength(); 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (IS_ARRAY(this)) { 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartMove(this, 0, 0, len, num_arguments); 6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SimpleMove(this, 0, 0, len, num_arguments); 6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < num_arguments; i++) { 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this[i] = %_Arguments(i); 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this.length = len + num_arguments; 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return len + num_arguments; 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArraySlice(start, end) { 618257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 619257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 620257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.slice"]); 621257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 622257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 623e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var len = TO_UINT32(this.length); 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var start_i = TO_INTEGER(start); 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var end_i = len; 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (end !== void 0) end_i = TO_INTEGER(end); 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start_i < 0) { 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_i += len; 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start_i < 0) start_i = 0; 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start_i > len) start_i = len; 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (end_i < 0) { 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block end_i += len; 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (end_i < 0) end_i = 0; 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (end_i > len) end_i = len; 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var result = []; 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (end_i < start_i) return result; 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (IS_ARRAY(this) && 6483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (end_i > 1000) && 6493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch (%EstimateNumberOfElements(this) < end_i)) { 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartSlice(this, start_i, end_i - start_i, len, result); 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SimpleSlice(this, start_i, end_i - start_i, len, result); 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.length = end_i - start_i; 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArraySplice(start, delete_count) { 662257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 663257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 664257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.splice"]); 665257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 666257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var num_arguments = %_ArgumentsLength(); 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 669e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var len = TO_UINT32(this.length); 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var start_i = TO_INTEGER(start); 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start_i < 0) { 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_i += len; 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start_i < 0) start_i = 0; 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start_i > len) start_i = len; 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 679402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is 6801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // given as a request to delete all the elements from the start. 6811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // And it differs from the case of undefined delete count. 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This does not follow ECMA-262, but we do the same for 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // compatibility. 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var del_count = 0; 6851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (num_arguments == 1) { 6861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block del_count = len - start_i; 6871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block del_count = TO_INTEGER(delete_count); 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (del_count < 0) del_count = 0; 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (del_count > len - start_i) del_count = len - start_i; 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var deleted_elements = []; 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block deleted_elements.length = del_count; 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Number of elements to add. 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var num_additional_args = 0; 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (num_arguments > 2) { 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block num_additional_args = num_arguments - 2; 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var use_simple_splice = true; 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_ARRAY(this) && num_additional_args !== del_count) { 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we are only deleting/moving a few things near the end of the 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // array then the simple version is going to be faster, because it 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // doesn't touch most of the array. 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var estimated_non_hole_elements = %EstimateNumberOfElements(this); 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (len > 20 && (estimated_non_hole_elements >> 2) < (len - start_i)) { 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block use_simple_splice = false; 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (use_simple_splice) { 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SimpleSlice(this, start_i, del_count, len, deleted_elements); 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SimpleMove(this, start_i, del_count, len, num_additional_args); 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartSlice(this, start_i, del_count, len, deleted_elements); 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmartMove(this, start_i, del_count, len, num_additional_args); 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Insert the arguments into the resulting array in 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // place of the deleted elements. 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var i = start_i; 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var arguments_index = 2; 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var arguments_length = %_ArgumentsLength(); 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (arguments_index < arguments_length) { 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this[i++] = %_Arguments(arguments_index++); 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this.length = len - del_count + num_additional_args; 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the deleted elements. 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return deleted_elements; 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArraySort(comparefn) { 738257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 739257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 740257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.sort"]); 741257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 742257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // In-place QuickSort algorithm. 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For short (length <= 22) arrays, insertion sort is used for efficiency. 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 746589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (!IS_SPEC_FUNCTION(comparefn)) { 7476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block comparefn = function (x, y) { 7486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (x === y) return 0; 7496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (%_IsSmi(x) && %_IsSmi(y)) { 7506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return %SmiLexicographicCompare(x, y); 7516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 7526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block x = ToString(x); 7536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block y = ToString(y); 7546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (x == y) return 0; 7556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block else return x < y ? -1 : 1; 7566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block }; 7576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 75869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch var receiver = %GetDefaultReceiver(comparefn); 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var InsertionSort = function InsertionSort(a, from, to) { 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = from + 1; i < to; i++) { 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var element = a[i]; 7636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block for (var j = i - 1; j >= from; j--) { 7646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block var tmp = a[j]; 7653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch var order = %_CallFunction(receiver, tmp, element, comparefn); 7666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (order > 0) { 7676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block a[j + 1] = tmp; 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 7696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block break; 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 7726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block a[j + 1] = element; 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var QuickSort = function QuickSort(a, from, to) { 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Insertion sort is faster for short arrays. 778b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (to - from <= 10) { 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InsertionSort(a, from, to); 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 782b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Find a pivot as the median of first, last and middle element. 783b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var v0 = a[from]; 784b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var v1 = a[to - 1]; 785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var middle_index = from + ((to - from) >> 1); 786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var v2 = a[middle_index]; 7873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch var c01 = %_CallFunction(receiver, v0, v1, comparefn); 788b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (c01 > 0) { 789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // v1 < v0, so swap them. 790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var tmp = v0; 791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v0 = v1; 792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v1 = tmp; 793b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } // v0 <= v1. 7943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch var c02 = %_CallFunction(receiver, v0, v2, comparefn); 795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (c02 >= 0) { 796b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // v2 <= v0 <= v1. 797b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var tmp = v0; 798b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v0 = v2; 799b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v2 = v1; 800b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v1 = tmp; 801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // v0 <= v1 && v0 < v2 8033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch var c12 = %_CallFunction(receiver, v1, v2, comparefn); 804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (c12 > 0) { 805b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // v0 <= v2 < v1 806b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var tmp = v1; 807b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v1 = v2; 808b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v2 = tmp; 809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 810b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 811b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // v0 <= v1 <= v2 812b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch a[from] = v0; 813b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch a[to - 1] = v2; 814b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var pivot = v1; 815b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var low_end = from + 1; // Upper bound of elements lower than pivot. 816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var high_start = to - 1; // Lower bound of elements greater than pivot. 817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch a[middle_index] = a[low_end]; 818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch a[low_end] = pivot; 819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // From low_end to i are elements equal to pivot. 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // From i to high_start are elements that haven't been compared yet. 822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch partition: for (var i = low_end + 1; i < high_start; i++) { 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var element = a[i]; 8243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch var order = %_CallFunction(receiver, element, pivot, comparefn); 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (order < 0) { 8265710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch a[i] = a[low_end]; 8275710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch a[low_end] = element; 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block low_end++; 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (order > 0) { 830b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch do { 831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch high_start--; 832b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (high_start == i) break partition; 833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var top_elem = a[high_start]; 8343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch order = %_CallFunction(receiver, top_elem, pivot, comparefn); 835b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } while (order > 0); 8365710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch a[i] = a[high_start]; 8375710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch a[high_start] = element; 838b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (order < 0) { 8395710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch element = a[i]; 8405710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch a[i] = a[low_end]; 8415710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch a[low_end] = element; 842b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch low_end++; 843b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block QuickSort(a, from, low_end); 847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block QuickSort(a, high_start, to); 8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Copy elements in the range 0..length from obj's prototype chain 851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // to obj itself, if obj has holes. Return one more than the maximal index 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // of a prototype property. 8533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var CopyFromPrototype = function CopyFromPrototype(obj, length) { 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var max = 0; 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var proto = obj.__proto__; proto; proto = proto.__proto__) { 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var indices = %GetArrayKeys(proto, length); 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (indices.length > 0) { 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (indices[0] == -1) { 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // It's an interval. 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var proto_length = indices[1]; 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < proto_length; i++) { 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!obj.hasOwnProperty(i) && proto.hasOwnProperty(i)) { 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block obj[i] = proto[i]; 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i >= max) { max = i + 1; } 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < indices.length; i++) { 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var index = indices[i]; 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(index) && 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !obj.hasOwnProperty(index) && proto.hasOwnProperty(index)) { 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block obj[index] = proto[index]; 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (index >= max) { max = index + 1; } 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return max; 8803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a value of "undefined" on all indices in the range from..to 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // where a prototype of obj has an element. I.e., shadow all prototype 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // elements in that range. 8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var ShadowPrototypeElements = function(obj, from, to) { 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var proto = obj.__proto__; proto; proto = proto.__proto__) { 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var indices = %GetArrayKeys(proto, to); 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (indices.length > 0) { 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (indices[0] == -1) { 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // It's an interval. 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var proto_length = indices[1]; 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = from; i < proto_length; i++) { 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (proto.hasOwnProperty(i)) { 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block obj[i] = void 0; 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < indices.length; i++) { 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var index = indices[i]; 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(index) && from <= index && 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block proto.hasOwnProperty(index)) { 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block obj[index] = void 0; 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 9083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var SafeRemoveArrayHoles = function SafeRemoveArrayHoles(obj) { 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Copy defined elements from the end to fill in all holes and undefineds 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in the beginning of the array. Write undefineds and holes at the end 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // after loop is finished. 914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var first_undefined = 0; 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var last_defined = length - 1; 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var num_holes = 0; 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (first_undefined < last_defined) { 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find first undefined element. 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (first_undefined < last_defined && 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !IS_UNDEFINED(obj[first_undefined])) { 921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block first_undefined++; 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Maintain the invariant num_holes = the number of holes in the original 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // array with indices <= first_undefined or > last_defined. 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!obj.hasOwnProperty(first_undefined)) { 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block num_holes++; 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find last defined element. 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (first_undefined < last_defined && 931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IS_UNDEFINED(obj[last_defined])) { 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!obj.hasOwnProperty(last_defined)) { 933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block num_holes++; 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_defined--; 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (first_undefined < last_defined) { 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill in hole or undefined. 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block obj[first_undefined] = obj[last_defined]; 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block obj[last_defined] = void 0; 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there were any undefineds in the entire array, first_undefined 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // points to one past the last defined element. Make this true if 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // there were no undefineds, as well, so that first_undefined == number 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // of defined elements. 947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_UNDEFINED(obj[first_undefined])) first_undefined++; 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill in the undefineds and the holes. There may be a hole where 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an undefined should be and vice versa. 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var i; 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (i = first_undefined; i < length - num_holes; i++) { 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block obj[i] = void 0; 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (i = length - num_holes; i < length; i++) { 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For compatability with Webkit, do not expose elements in the prototype. 956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i in obj.__proto__) { 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block obj[i] = void 0; 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete obj[i]; 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the number of defined elements. 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return first_undefined; 9653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block var length = TO_UINT32(this.length); 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (length < 2) return this; 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var is_array = IS_ARRAY(this); 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var max_prototype_element; 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!is_array) { 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For compatibility with JSC, we also sort elements inherited from 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the prototype chain on non-Array objects. 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We do this by copying them to this object and sorting only 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // local elements. This is not very efficient, but sorting with 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // inherited elements happens very, very rarely, if at all. 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The specification allows "implementation dependent" behavior 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // if an element on the prototype chain has an element that 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // might interact with sorting. 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max_prototype_element = CopyFromPrototype(this, length); 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var num_non_undefined = %RemoveArrayHoles(this, length); 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (num_non_undefined == -1) { 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // There were indexed accessors in the array. Move array holes and 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // undefineds to the end using a Javascript function that is safe 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in the presence of accessors. 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block num_non_undefined = SafeRemoveArrayHoles(this); 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block QuickSort(this, 0, num_non_undefined); 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!is_array && (num_non_undefined + 1 < max_prototype_element)) { 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For compatibility with JSC, we shadow any elements in the prototype 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // chain that has become exposed by sort moving a hole to its position. 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ShadowPrototypeElements(this, num_non_undefined, max_prototype_element); 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return this; 1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The following functions cannot be made efficient on sparse arrays while 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// preserving the semantics, since the calls to the receiver function can add 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// or delete elements from the array. 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayFilter(f, receiver) { 1008257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1009257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 1010257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.filter"]); 1011257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1012257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pull out the length so that modifications to the length in the 10143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // loop will not affect the looping and side effects are visible. 10153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var array = ToObject(this); 10163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var length = ToUint32(array.length); 10173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1018589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (!IS_SPEC_FUNCTION(f)) { 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw MakeTypeError('called_non_callable', [ f ]); 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 102169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (IS_NULL_OR_UNDEFINED(receiver)) { 102269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch receiver = %GetDefaultReceiver(f) || receiver; 10233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (!IS_SPEC_OBJECT(receiver)) { 10243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch receiver = ToObject(receiver); 102569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 10263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var result = new $Array(); 10283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var accumulator = new InternalArray(); 10293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var accumulator_length = 0; 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < length; i++) { 10313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (i in array) { 10323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var element = array[i]; 10333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (%_CallFunction(receiver, element, i, array, f)) { 10343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch accumulator[accumulator_length++] = element; 1035e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 10383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch %MoveArrayContents(accumulator, result); 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayForEach(f, receiver) { 1044257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1045257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 1046257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.forEach"]); 1047257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1048257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pull out the length so that modifications to the length in the 10503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // loop will not affect the looping and side effects are visible. 10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var array = ToObject(this); 10523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var length = TO_UINT32(array.length); 10533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1054589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (!IS_SPEC_FUNCTION(f)) { 1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw MakeTypeError('called_non_callable', [ f ]); 1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 105769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (IS_NULL_OR_UNDEFINED(receiver)) { 105869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch receiver = %GetDefaultReceiver(f) || receiver; 10593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (!IS_SPEC_OBJECT(receiver)) { 10603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch receiver = ToObject(receiver); 106169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 10623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < length; i++) { 10643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (i in array) { 10653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var element = array[i]; 10663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch %_CallFunction(receiver, element, i, array, f); 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Executes the function once for each element present in the 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// array until it finds one where callback returns true. 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArraySome(f, receiver) { 1075257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1076257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 1077257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.some"]); 1078257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1079257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pull out the length so that modifications to the length in the 10813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // loop will not affect the looping and side effects are visible. 10823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var array = ToObject(this); 10833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var length = TO_UINT32(array.length); 10843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1085589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (!IS_SPEC_FUNCTION(f)) { 1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw MakeTypeError('called_non_callable', [ f ]); 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 108869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (IS_NULL_OR_UNDEFINED(receiver)) { 108969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch receiver = %GetDefaultReceiver(f) || receiver; 10903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (!IS_SPEC_OBJECT(receiver)) { 10913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch receiver = ToObject(receiver); 109269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 10933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < length; i++) { 10953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (i in array) { 10963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var element = array[i]; 10973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (%_CallFunction(receiver, element, i, array, f)) return true; 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayEvery(f, receiver) { 1105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1106257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 1107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.every"]); 1108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 11103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pull out the length so that modifications to the length in the 11113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // loop will not affect the looping and side effects are visible. 11123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var array = ToObject(this); 11133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var length = TO_UINT32(array.length); 11143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1115589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (!IS_SPEC_FUNCTION(f)) { 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw MakeTypeError('called_non_callable', [ f ]); 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 111869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (IS_NULL_OR_UNDEFINED(receiver)) { 111969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch receiver = %GetDefaultReceiver(f) || receiver; 11203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (!IS_SPEC_OBJECT(receiver)) { 11213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch receiver = ToObject(receiver); 112269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 11233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < length; i++) { 11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (i in array) { 11263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var element = array[i]; 11273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!%_CallFunction(receiver, element, i, array, f)) return false; 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayMap(f, receiver) { 1134257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1135257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 1136257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.map"]); 1137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 11393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pull out the length so that modifications to the length in the 11403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // loop will not affect the looping and side effects are visible. 11413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var array = ToObject(this); 11423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var length = TO_UINT32(array.length); 11433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1144589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (!IS_SPEC_FUNCTION(f)) { 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw MakeTypeError('called_non_callable', [ f ]); 1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 114769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (IS_NULL_OR_UNDEFINED(receiver)) { 114869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch receiver = %GetDefaultReceiver(f) || receiver; 11493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (!IS_SPEC_OBJECT(receiver)) { 11503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch receiver = ToObject(receiver); 115169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 11523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1153e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch var result = new $Array(); 1154e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch var accumulator = new InternalArray(length); 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (var i = 0; i < length; i++) { 11563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (i in array) { 11573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var element = array[i]; 11583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch accumulator[i] = %_CallFunction(receiver, element, i, array, f); 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1161e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch %MoveArrayContents(accumulator, result); 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayIndexOf(element, index) { 1167257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1168257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 1169257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.indexOf"]); 1170257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1171257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 117280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen var length = TO_UINT32(this.length); 117380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (length == 0) return -1; 11748defd9ff6930b4e24729971a61cf7469daf119beSteve Block if (IS_UNDEFINED(index)) { 1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block index = 0; 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block index = TO_INTEGER(index); 1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If index is negative, index from the end of the array. 11791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (index < 0) { 11801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block index = length + index; 11811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // If index is still negative, search the entire array. 11821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (index < 0) index = 0; 11831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 118559151504615d929945dc59db37bf1166937748c6Steve Block var min = index; 118659151504615d929945dc59db37bf1166937748c6Steve Block var max = length; 1187e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (UseSparseVariant(this, length, IS_ARRAY(this))) { 118859151504615d929945dc59db37bf1166937748c6Steve Block var intervals = %GetArrayKeys(this, length); 118959151504615d929945dc59db37bf1166937748c6Steve Block if (intervals.length == 2 && intervals[0] < 0) { 119059151504615d929945dc59db37bf1166937748c6Steve Block // A single interval. 119159151504615d929945dc59db37bf1166937748c6Steve Block var intervalMin = -(intervals[0] + 1); 119259151504615d929945dc59db37bf1166937748c6Steve Block var intervalMax = intervalMin + intervals[1]; 1193e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (min < intervalMin) min = intervalMin; 119459151504615d929945dc59db37bf1166937748c6Steve Block max = intervalMax; // Capped by length already. 119559151504615d929945dc59db37bf1166937748c6Steve Block // Fall through to loop below. 119659151504615d929945dc59db37bf1166937748c6Steve Block } else { 119759151504615d929945dc59db37bf1166937748c6Steve Block if (intervals.length == 0) return -1; 119859151504615d929945dc59db37bf1166937748c6Steve Block // Get all the keys in sorted order. 119959151504615d929945dc59db37bf1166937748c6Steve Block var sortedKeys = GetSortedArrayKeys(this, intervals); 120059151504615d929945dc59db37bf1166937748c6Steve Block var n = sortedKeys.length; 120159151504615d929945dc59db37bf1166937748c6Steve Block var i = 0; 120259151504615d929945dc59db37bf1166937748c6Steve Block while (i < n && sortedKeys[i] < index) i++; 120359151504615d929945dc59db37bf1166937748c6Steve Block while (i < n) { 120459151504615d929945dc59db37bf1166937748c6Steve Block var key = sortedKeys[i]; 120559151504615d929945dc59db37bf1166937748c6Steve Block if (!IS_UNDEFINED(key) && this[key] === element) return key; 120659151504615d929945dc59db37bf1166937748c6Steve Block i++; 120759151504615d929945dc59db37bf1166937748c6Steve Block } 120859151504615d929945dc59db37bf1166937748c6Steve Block return -1; 120959151504615d929945dc59db37bf1166937748c6Steve Block } 121059151504615d929945dc59db37bf1166937748c6Steve Block } 121180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Lookup through the array. 12126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!IS_UNDEFINED(element)) { 121359151504615d929945dc59db37bf1166937748c6Steve Block for (var i = min; i < max; i++) { 12146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (this[i] === element) return i; 12156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 12166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return -1; 12176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 121859151504615d929945dc59db37bf1166937748c6Steve Block // Lookup through the array. 121959151504615d929945dc59db37bf1166937748c6Steve Block for (var i = min; i < max; i++) { 12206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (IS_UNDEFINED(this[i]) && i in this) { 12216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return i; 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return -1; 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayLastIndexOf(element, index) { 1229257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 1231257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.lastIndexOf"]); 1232257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1233257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 123480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen var length = TO_UINT32(this.length); 123580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (length == 0) return -1; 12368defd9ff6930b4e24729971a61cf7469daf119beSteve Block if (%_ArgumentsLength() < 2) { 1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block index = length - 1; 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block index = TO_INTEGER(index); 1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If index is negative, index from end of the array. 124159151504615d929945dc59db37bf1166937748c6Steve Block if (index < 0) index += length; 1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If index is still negative, do not search the array. 124359151504615d929945dc59db37bf1166937748c6Steve Block if (index < 0) return -1; 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else if (index >= length) index = length - 1; 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 124659151504615d929945dc59db37bf1166937748c6Steve Block var min = 0; 124759151504615d929945dc59db37bf1166937748c6Steve Block var max = index; 1248e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (UseSparseVariant(this, length, IS_ARRAY(this))) { 124959151504615d929945dc59db37bf1166937748c6Steve Block var intervals = %GetArrayKeys(this, index + 1); 125059151504615d929945dc59db37bf1166937748c6Steve Block if (intervals.length == 2 && intervals[0] < 0) { 125159151504615d929945dc59db37bf1166937748c6Steve Block // A single interval. 125259151504615d929945dc59db37bf1166937748c6Steve Block var intervalMin = -(intervals[0] + 1); 125359151504615d929945dc59db37bf1166937748c6Steve Block var intervalMax = intervalMin + intervals[1]; 1254e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (min < intervalMin) min = intervalMin; 125559151504615d929945dc59db37bf1166937748c6Steve Block max = intervalMax; // Capped by index already. 125659151504615d929945dc59db37bf1166937748c6Steve Block // Fall through to loop below. 125759151504615d929945dc59db37bf1166937748c6Steve Block } else { 125859151504615d929945dc59db37bf1166937748c6Steve Block if (intervals.length == 0) return -1; 125959151504615d929945dc59db37bf1166937748c6Steve Block // Get all the keys in sorted order. 126059151504615d929945dc59db37bf1166937748c6Steve Block var sortedKeys = GetSortedArrayKeys(this, intervals); 126159151504615d929945dc59db37bf1166937748c6Steve Block var i = sortedKeys.length - 1; 126259151504615d929945dc59db37bf1166937748c6Steve Block while (i >= 0) { 126359151504615d929945dc59db37bf1166937748c6Steve Block var key = sortedKeys[i]; 126459151504615d929945dc59db37bf1166937748c6Steve Block if (!IS_UNDEFINED(key) && this[key] === element) return key; 126559151504615d929945dc59db37bf1166937748c6Steve Block i--; 126659151504615d929945dc59db37bf1166937748c6Steve Block } 126759151504615d929945dc59db37bf1166937748c6Steve Block return -1; 126859151504615d929945dc59db37bf1166937748c6Steve Block } 126959151504615d929945dc59db37bf1166937748c6Steve Block } 1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Lookup through the array. 12716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!IS_UNDEFINED(element)) { 127259151504615d929945dc59db37bf1166937748c6Steve Block for (var i = max; i >= min; i--) { 12736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (this[i] === element) return i; 12746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 12756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return -1; 12766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 127759151504615d929945dc59db37bf1166937748c6Steve Block for (var i = max; i >= min; i--) { 12786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (IS_UNDEFINED(this[i]) && i in this) { 12796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return i; 1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return -1; 1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayReduce(callback, current) { 1287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 1289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.reduce"]); 1290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 12923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pull out the length so that modifications to the length in the 12933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // loop will not affect the looping and side effects are visible. 12943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var array = ToObject(this); 12953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var length = ToUint32(array.length); 12963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1297589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (!IS_SPEC_FUNCTION(callback)) { 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw MakeTypeError('called_non_callable', [callback]); 1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 130069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var i = 0; 1302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block find_initial: if (%_ArgumentsLength() < 2) { 1303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (; i < length; i++) { 13043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current = array[i]; 13053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IS_UNDEFINED(current) || i in array) { 1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i++; 1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break find_initial; 1308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw MakeTypeError('reduce_no_initial', []); 1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch var receiver = %GetDefaultReceiver(callback); 1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (; i < length; i++) { 13153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (i in array) { 13163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var element = array[i]; 13173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current = %_CallFunction(receiver, current, element, i, array, callback); 1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return current; 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayReduceRight(callback, current) { 1324257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 1325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 1326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["Array.prototype.reduceRight"]); 1327257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 13293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pull out the length so that side effects are visible before the 13303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // callback function is checked. 13313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var array = ToObject(this); 13323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var length = ToUint32(array.length); 13333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1334589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (!IS_SPEC_FUNCTION(callback)) { 1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw MakeTypeError('called_non_callable', [callback]); 1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var i = length - 1; 1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block find_initial: if (%_ArgumentsLength() < 2) { 1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (; i >= 0; i--) { 13413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current = array[i]; 13423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IS_UNDEFINED(current) || i in array) { 1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i--; 1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break find_initial; 1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw MakeTypeError('reduce_no_initial', []); 1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 135069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch var receiver = %GetDefaultReceiver(callback); 1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (; i >= 0; i--) { 13523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (i in array) { 13533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var element = array[i]; 13543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current = %_CallFunction(receiver, current, element, i, array, callback); 1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return current; 1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// ES5, 15.4.3.2 13613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockfunction ArrayIsArray(obj) { 13623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return IS_ARRAY(obj); 13633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------- 1367589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SetUpArray() { 1368589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch %CheckIsBootstrapping(); 1369589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set up non-enumerable constructor property on the Array.prototype 1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object. 1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block %SetProperty($Array.prototype, "constructor", $Array, DONT_ENUM); 1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1373589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set up non-enumerable functions on the Array object. 13743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block InstallFunctions($Array, DONT_ENUM, $Array( 13753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block "isArray", ArrayIsArray 13763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block )); 13773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 13786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block var specialFunctions = %SpecialArrayFunctions({}); 13796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 13803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch var getFunction = function(name, jsBuiltin, len) { 13816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block var f = jsBuiltin; 13826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (specialFunctions.hasOwnProperty(name)) { 13836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block f = specialFunctions[name]; 13846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 13856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!IS_UNDEFINED(len)) { 13866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block %FunctionSetLength(f, len); 13876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 13886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return f; 13893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 13906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1391589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set up non-enumerable functions of the Array.prototype object and 1392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // set their names. 1393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Manipulate the length of some of the functions to meet 1394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // expectations set by ECMA-262 or Mozilla. 13953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstallFunctions($Array.prototype, DONT_ENUM, $Array( 13966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "toString", getFunction("toString", ArrayToString), 13976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "toLocaleString", getFunction("toLocaleString", ArrayToLocaleString), 13986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "join", getFunction("join", ArrayJoin), 13996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "pop", getFunction("pop", ArrayPop), 14006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "push", getFunction("push", ArrayPush, 1), 14016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "concat", getFunction("concat", ArrayConcat, 1), 14026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "reverse", getFunction("reverse", ArrayReverse), 14036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "shift", getFunction("shift", ArrayShift), 14046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "unshift", getFunction("unshift", ArrayUnshift, 1), 14056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "slice", getFunction("slice", ArraySlice, 2), 14066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "splice", getFunction("splice", ArraySplice, 2), 14076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "sort", getFunction("sort", ArraySort), 14086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "filter", getFunction("filter", ArrayFilter, 1), 14096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "forEach", getFunction("forEach", ArrayForEach, 1), 14106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "some", getFunction("some", ArraySome, 1), 14116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "every", getFunction("every", ArrayEvery, 1), 14126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "map", getFunction("map", ArrayMap, 1), 14136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "indexOf", getFunction("indexOf", ArrayIndexOf, 1), 14146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1), 14156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "reduce", getFunction("reduce", ArrayReduce, 1), 14166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block "reduceRight", getFunction("reduceRight", ArrayReduceRight, 1) 14176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block )); 14186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 14196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block %FinishArrayPrototypeSetup($Array.prototype); 1420e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1421e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // The internal Array prototype doesn't need to be fancy, since it's never 1422589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // exposed to user code. 1423589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Adding only the functions that are actually used. 1424589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SetUpLockedPrototype(InternalArray, $Array(), $Array( 1425589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch "join", getFunction("join", ArrayJoin), 1426589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch "pop", getFunction("pop", ArrayPop), 1427589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch "push", getFunction("push", ArrayPush) 1428589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch )); 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1431589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpArray(); 1432