1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch(function(global, utils, extrasUtils) {
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch"use strict";
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch%CheckIsBootstrapping();
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// -------------------------------------------------------------------
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Imports
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar GetIterator;
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar GetMethod;
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar GlobalArray = global.Array;
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar InternalArray = utils.InternalArray;
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar InternalPackedArray = utils.InternalPackedArray;
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar MaxSimple;
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar MinSimple;
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar ObjectHasOwnProperty;
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar ObjectToString = utils.ImportNow("object_to_string");
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar iteratorSymbol = utils.ImportNow("iterator_symbol");
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar unscopablesSymbol = utils.ImportNow("unscopables_symbol");
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochutils.Import(function(from) {
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GetIterator = from.GetIterator;
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GetMethod = from.GetMethod;
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaxSimple = from.MaxSimple;
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MinSimple = from.MinSimple;
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ObjectHasOwnProperty = from.ObjectHasOwnProperty;
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch});
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -------------------------------------------------------------------
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArraySpeciesCreate(array, length) {
38bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  length = INVERT_NEG_ZERO(length);
3913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  var constructor = %ArraySpeciesConstructor(array);
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new constructor(length);
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochfunction KeySortCompare(a, b) {
453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return a - b;
463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction GetSortedArrayKeys(array, indices) {
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IS_NUMBER(indices)) {
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // It's an interval
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var limit = indices;
52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    var keys = new InternalArray();
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < limit; ++i) {
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var e = array[i];
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!IS_UNDEFINED(e) || i in array) {
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        keys.push(i);
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return keys;
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return InnerArraySort(indices, indices.length, KeySortCompare);
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochfunction SparseJoinWithSeparatorJS(array, keys, length, use_locale, separator) {
663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  var keys_length = keys.length;
673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  var elements = new InternalArray(keys_length * 2);
683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (var i = 0; i < keys_length; i++) {
69257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    var key = keys[i];
703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    elements[i * 2] = key;
71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    elements[i * 2 + 1] = ConvertToString(use_locale, array[key]);
72257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return %SparseJoinWithSeparator(elements, length, separator);
74257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
75257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
76257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Optimized for sparse arrays if separator is ''.
78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochfunction SparseJoin(array, keys, use_locale) {
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var keys_length = keys.length;
80e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  var elements = new InternalArray(keys_length);
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < keys_length; i++) {
82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    elements[i] = ConvertToString(use_locale, array[keys[i]]);
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return %StringBuilderConcat(elements, keys_length, '');
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction UseSparseVariant(array, length, is_array, touched) {
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Only use the sparse variant on arrays that are likely to be sparse and the
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // number of elements touched in the operation is relatively small compared to
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the overall size of the array.
92bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (!is_array || length < 1000 || %HasComplexElements(array)) {
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!%_IsSmi(length)) {
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return true;
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var elements_threshold = length >> 2;  // No more than 75% holes
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var estimated_elements = %EstimateNumberOfElements(array);
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (estimated_elements < elements_threshold) &&
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    (touched > estimated_elements * 4);
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochfunction Stack() {
1053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  this.length = 0;
1063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  this.values = new InternalArray();
1073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// Predeclare the instance variables on the prototype. Otherwise setting them in
1103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// the constructor will leak the instance through settings on Object.prototype.
1113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochStack.prototype.length = null;
1123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochStack.prototype.values = null;
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochfunction StackPush(stack, value) {
1153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  stack.values[stack.length++] = value;
1163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochfunction StackPop(stack) {
1193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  stack.values[--stack.length] = null
1203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
1213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochfunction StackHas(stack, v) {
1233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  var length = stack.length;
1243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  var values = stack.values;
1253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (var i = 0; i < length; i++) {
1263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (values[i] === v) return true;
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return false;
1293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// Global list of arrays visited during toString, toLocaleString and
1323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// join invocations.
1333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvar visited_arrays = new Stack();
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochfunction DoJoin(array, length, is_array, separator, use_locale) {
1363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (UseSparseVariant(array, length, is_array, length)) {
1373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    %NormalizeElements(array);
1383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, length));
1393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (separator === '') {
1403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (keys.length === 0) return '';
141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return SparseJoin(array, keys, use_locale);
1423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else {
143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return SparseJoinWithSeparatorJS(
144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          array, keys, length, use_locale, separator);
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Fast case for one-element arrays.
1493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (length === 1) {
150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return ConvertToString(use_locale, array[0]);
1513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Construct an array for the elements.
1543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  var elements = new InternalArray(length);
155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  for (var i = 0; i < length; i++) {
156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    elements[i] = ConvertToString(use_locale, array[i]);
157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (separator === '') {
1603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return %StringBuilderConcat(elements, length, '');
1613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return %StringBuilderJoin(elements, length, separator);
1633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
1653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochfunction Join(array, length, separator, use_locale) {
1673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (length === 0) return '';
1683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  var is_array = IS_ARRAY(array);
1703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (is_array) {
1723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // If the array is cyclic, return the empty string for already
1733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // visited arrays.
1743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (StackHas(visited_arrays, array)) return '';
1753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    StackPush(visited_arrays, array);
1763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Attempt to convert the elements.
1793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  try {
180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return DoJoin(array, length, is_array, separator, use_locale);
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } finally {
1821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Make sure to remove the last element of the visited array no
1831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // matter what happens.
1843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (is_array) StackPop(visited_arrays);
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochfunction ConvertToString(use_locale, x) {
1903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (IS_NULL_OR_UNDEFINED(x)) return '';
191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return TO_STRING(use_locale ? x.toLocaleString() : x);
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This function implements the optimized splice implementation that can use
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// special array operations to handle sparse arrays in a sensible fashion.
197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierfunction SparseSlice(array, start_i, del_count, len, deleted_elements) {
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Move deleted elements to a new array (the return value from splice).
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var indices = %GetArrayKeys(array, start_i + del_count);
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IS_NUMBER(indices)) {
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var limit = indices;
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = start_i; i < limit; ++i) {
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var current = array[i];
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!IS_UNDEFINED(current) || i in array) {
205bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        %CreateDataProperty(deleted_elements, i - start_i, current);
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var length = indices.length;
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var k = 0; k < length; ++k) {
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var key = indices[k];
2123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (key >= start_i) {
2133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        var current = array[key];
2143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (!IS_UNDEFINED(current) || key in array) {
215bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          %CreateDataProperty(deleted_elements, key - start_i, current);
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This function implements the optimized splice implementation that can use
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// special array operations to handle sparse arrays in a sensible fashion.
225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierfunction SparseMove(array, start_i, del_count, len, num_additional_args) {
226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Bail out if no moving is necessary.
227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (num_additional_args === del_count) return;
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Move data to new array.
229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  var new_array = new InternalArray(
230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Clamp array length to 2^32-1 to avoid early RangeError.
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MinSimple(len - del_count + num_additional_args, 0xffffffff));
232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  var big_indices;
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var indices = %GetArrayKeys(array, len);
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IS_NUMBER(indices)) {
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var limit = indices;
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < start_i && i < limit; ++i) {
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var current = array[i];
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!IS_UNDEFINED(current) || i in array) {
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        new_array[i] = current;
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = start_i + del_count; i < limit; ++i) {
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var current = array[i];
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!IS_UNDEFINED(current) || i in array) {
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        new_array[i - del_count + num_additional_args] = current;
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var length = indices.length;
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var k = 0; k < length; ++k) {
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var key = indices[k];
2523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (key < start_i) {
2533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        var current = array[key];
2543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (!IS_UNDEFINED(current) || key in array) {
2553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          new_array[key] = current;
2563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
2573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else if (key >= start_i + del_count) {
2583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        var current = array[key];
2593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (!IS_UNDEFINED(current) || key in array) {
2603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          var new_key = key - del_count + num_additional_args;
2613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          new_array[new_key] = current;
2623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          if (new_key > 0xfffffffe) {
2633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            big_indices = big_indices || new InternalArray();
2643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            big_indices.push(new_key);
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          }
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Move contents of new_array into this array
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  %MoveArrayContents(new_array, array);
272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Add any moved values that aren't elements anymore.
273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!IS_UNDEFINED(big_indices)) {
274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    var length = big_indices.length;
275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (var i = 0; i < length; ++i) {
276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      var key = big_indices[i];
277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      array[key] = new_array[key];
278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This is part of the old simple-minded splice.  We are using it either
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// because the receiver is not an array (so we have no choice) or because we
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// know we are not deleting or moving a lot of elements.
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SimpleSlice(array, start_i, del_count, len, deleted_elements) {
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < del_count; i++) {
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var index = start_i + i;
28913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (index in array) {
290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      var current = array[index];
291bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      %CreateDataProperty(deleted_elements, i, current);
2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SimpleMove(array, start_i, del_count, len, num_additional_args) {
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (num_additional_args !== del_count) {
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Move the existing elements after the elements to be deleted
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // to the right position in the resulting array.
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (num_additional_args > del_count) {
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      for (var i = len - del_count; i > start_i; i--) {
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        var from_index = i + del_count - 1;
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        var to_index = i + num_additional_args - 1;
30513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (from_index in array) {
306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          array[to_index] = array[from_index];
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        } else {
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          delete array[to_index];
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      for (var i = start_i; i < len - del_count; i++) {
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        var from_index = i + del_count;
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        var to_index = i + num_additional_args;
31513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (from_index in array) {
316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          array[to_index] = array[from_index];
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        } else {
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          delete array[to_index];
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      for (var i = len; i > len - del_count + num_additional_args; i--) {
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        delete array[i - 1];
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -------------------------------------------------------------------
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayToString() {
3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var array;
3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var func;
3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IS_ARRAY(this)) {
3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    func = this.join;
3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (func === ArrayJoin) {
338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return Join(this, this.length, ',', false);
3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    array = this;
3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    array = TO_OBJECT(this);
3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    func = array.join;
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!IS_CALLABLE(func)) {
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return %_Call(ObjectToString, array);
3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return %_Call(func, array);
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArrayToLocaleString(array, length) {
353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return Join(array, TO_LENGTH(length), ',', true);
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArrayToLocaleString() {
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var arrayLen = array.length;
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArrayToLocaleString(array, arrayLen);
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArrayJoin(separator, array, length) {
365e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (IS_UNDEFINED(separator)) {
366e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    separator = ',';
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    separator = TO_STRING(separator);
369e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
3708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Fast case for one-element arrays.
372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (length === 1) {
373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    var e = array[0];
374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (IS_NULL_OR_UNDEFINED(e)) return '';
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return TO_STRING(e);
376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return Join(array, length, separator, false);
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArrayJoin(separator) {
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join");
384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
386109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = TO_LENGTH(array.length);
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArrayJoin(separator, array, length);
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Removes the last element from the array and returns it. See
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 15.4.4.6.
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayPop() {
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.pop");
396257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
398109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var n = TO_LENGTH(array.length);
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (n == 0) {
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    array.length = n;
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  n--;
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var value = array[n];
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  %DeleteProperty_Strict(array, n);
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  array.length = n;
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return value;
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Appends the arguments to the end of the array and returns the new
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// length of the array. See ECMA-262, section 15.4.4.7.
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayPush() {
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push");
416257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
418109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var n = TO_LENGTH(array.length);
419109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var m = arguments.length;
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
421bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Subtract n from kMaxSafeInteger rather than testing m + n >
422bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // kMaxSafeInteger. n may already be kMaxSafeInteger. In that case adding
423bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // e.g., 1 would not be safe.
424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (m > kMaxSafeInteger - n) throw %make_type_error(kPushPastSafeLength, m, n);
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < m; i++) {
427109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    array[i+n] = arguments[i];
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var new_length = n + m;
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  array.length = new_length;
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new_length;
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// For implementing reverse() on large, sparse arrays.
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SparseReverse(array, len) {
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len));
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var high_counter = keys.length - 1;
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var low_counter = 0;
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (low_counter <= high_counter) {
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var i = keys[low_counter];
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var j = keys[high_counter];
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var j_complement = len - j - 1;
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var low, high;
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (j_complement <= i) {
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      high = j;
4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      while (keys[--high_counter] == j) { }
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      low = j_complement;
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (j_complement >= i) {
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      low = i;
4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      while (keys[++low_counter] == i) { }
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      high = len - i - 1;
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var current_i = array[low];
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!IS_UNDEFINED(current_i) || low in array) {
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      var current_j = array[high];
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (!IS_UNDEFINED(current_j) || high in array) {
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        array[low] = current_j;
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        array[high] = current_i;
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      } else {
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        array[high] = current_i;
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        delete array[low];
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      var current_j = array[high];
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (!IS_UNDEFINED(current_j) || high in array) {
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        array[low] = current_j;
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        delete array[high];
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction PackedArrayReverse(array, len) {
480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var j = len - 1;
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (var i = 0; i < j; i++, j--) {
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    var current_i = array[i];
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    var current_j = array[j];
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    array[i] = current_j;
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    array[j] = current_i;
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return array;
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction GenericArrayReverse(array, len) {
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var j = len - 1;
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < j; i++, j--) {
494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i in array) {
495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      var current_i = array[i];
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (j in array) {
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        var current_j = array[j];
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        array[i] = current_j;
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        array[j] = current_i;
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      } else {
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        array[j] = current_i;
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        delete array[i];
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (j in array) {
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        var current_j = array[j];
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        array[i] = current_j;
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        delete array[j];
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return array;
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArrayReverse() {
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse");
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var len = TO_LENGTH(array.length);
521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var isArray = IS_ARRAY(array);
522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (UseSparseVariant(array, len, isArray, len)) {
524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    %NormalizeElements(array);
525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SparseReverse(array, len);
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return array;
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (isArray && %_HasFastPackedElements(array)) {
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return PackedArrayReverse(array, len);
529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return GenericArrayReverse(array, len);
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction ArrayShift() {
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift");
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var len = TO_LENGTH(array.length);
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (len === 0) {
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    array.length = 0;
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (%object_is_sealed(array)) throw %make_type_error(kArrayFunctionsOnSealed);
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var first = array[0];
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (UseSparseVariant(array, len, IS_ARRAY(array), len)) {
551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    SparseMove(array, 0, 1, len, 0);
5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SimpleMove(array, 0, 1, len, 0);
5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  array.length = len - 1;
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return first;
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction ArrayUnshift(arg1) {  // length == 1
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift");
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var len = TO_LENGTH(array.length);
567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var num_arguments = arguments.length;
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) &&
570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      !%object_is_sealed(array)) {
571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    SparseMove(array, 0, 0, len, num_arguments);
5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SimpleMove(array, 0, 0, len, num_arguments);
5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < num_arguments; i++) {
577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    array[i] = arguments[i];
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var new_length = len + num_arguments;
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  array.length = new_length;
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new_length;
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArraySlice(start, end) {
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice");
588257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
590109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var len = TO_LENGTH(array.length);
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var start_i = TO_INTEGER(start);
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var end_i = len;
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end);
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (start_i < 0) {
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    start_i += len;
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (start_i < 0) start_i = 0;
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (start_i > len) start_i = len;
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (end_i < 0) {
604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    end_i += len;
605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (end_i < 0) end_i = 0;
606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (end_i > len) end_i = len;
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var result = ArraySpeciesCreate(array, MaxSimple(end_i - start_i, 0));
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (end_i < start_i) return result;
613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    %NormalizeElements(array);
61613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (IS_ARRAY(result)) %NormalizeElements(result);
617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    SparseSlice(array, start_i, end_i - start_i, len, result);
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SimpleSlice(array, start_i, end_i - start_i, len, result);
620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  result.length = end_i - start_i;
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction ComputeSpliceStartIndex(start_i, len) {
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (start_i < 0) {
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    start_i += len;
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return start_i < 0 ? 0 : start_i;
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return start_i > len ? len : start_i;
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction ComputeSpliceDeleteCount(delete_count, num_arguments, len, start_i) {
639402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
6401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // given as a request to delete all the elements from the start.
6411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // And it differs from the case of undefined delete count.
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This does not follow ECMA-262, but we do the same for
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // compatibility.
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var del_count = 0;
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (num_arguments == 1)
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return len - start_i;
647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  del_count = TO_INTEGER(delete_count);
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (del_count < 0)
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0;
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (del_count > len - start_i)
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return len - start_i;
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return del_count;
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction ArraySplice(start, delete_count) {
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice");
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
662109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var num_arguments = arguments.length;
663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
664109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var len = TO_LENGTH(array.length);
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           start_i);
668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var deleted_elements = ArraySpeciesCreate(array, del_count);
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  deleted_elements.length = del_count;
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (del_count != num_elements_to_add && %object_is_sealed(array)) {
673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    throw %make_type_error(kArrayFunctionsOnSealed);
674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (del_count > 0 && %object_is_frozen(array)) {
675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    throw %make_type_error(kArrayFunctionsOnFrozen);
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var changed_elements = del_count;
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (num_elements_to_add != del_count) {
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the slice needs to do a actually move elements after the insertion
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // point, then include those in the estimate of changed elements.
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    changed_elements += len - start_i - del_count;
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (UseSparseVariant(array, len, IS_ARRAY(array), changed_elements)) {
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    %NormalizeElements(array);
68613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (IS_ARRAY(deleted_elements)) %NormalizeElements(deleted_elements);
687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    SparseSlice(array, start_i, del_count, len, deleted_elements);
688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    SparseMove(array, start_i, del_count, len, num_elements_to_add);
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SimpleSlice(array, start_i, del_count, len, deleted_elements);
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SimpleMove(array, start_i, del_count, len, num_elements_to_add);
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Insert the arguments into the resulting array in
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // place of the deleted elements.
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var i = start_i;
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var arguments_index = 2;
698109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var arguments_length = arguments.length;
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (arguments_index < arguments_length) {
700109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    array[i++] = arguments[arguments_index++];
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  array.length = len - del_count + num_elements_to_add;
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the deleted elements.
705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return deleted_elements;
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArraySort(array, length, comparefn) {
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // In-place QuickSort algorithm.
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // For short (length <= 22) arrays, insertion sort is used for efficiency.
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!IS_CALLABLE(comparefn)) {
7146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    comparefn = function (x, y) {
7156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (x === y) return 0;
7166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (%_IsSmi(x) && %_IsSmi(y)) {
7176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        return %SmiLexicographicCompare(x, y);
7186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      }
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      x = TO_STRING(x);
720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      y = TO_STRING(y);
7216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (x == y) return 0;
7226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      else return x < y ? -1 : 1;
7236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    };
7246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
72562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  function InsertionSort(a, from, to) {
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (var i = from + 1; i < to; i++) {
727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      var element = a[i];
7286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      for (var j = i - 1; j >= from; j--) {
7296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        var tmp = a[j];
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        var order = comparefn(tmp, element);
7316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        if (order > 0) {
7326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          a[j + 1] = tmp;
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        } else {
7346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          break;
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
7376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      a[j + 1] = element;
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
7393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
74162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  function GetThirdIndex(a, from, to) {
742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    var t_array = new InternalArray();
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Use both 'from' and 'to' to determine the pivot candidates.
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var increment = 200 + ((to - from) & 15);
745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    var j = 0;
746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    from += 1;
747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    to -= 1;
748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (var i = from; i < to; i += increment) {
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      t_array[j] = [i, a[i]];
750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      j++;
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    t_array.sort(function(a, b) {
753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return comparefn(a[1], b[1]);
754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    });
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var third_index = t_array[t_array.length >> 1][0];
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return third_index;
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
75962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  function QuickSort(a, from, to) {
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var third_index = 0;
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (true) {
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Insertion sort is faster for short arrays.
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (to - from <= 10) {
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InsertionSort(a, from, to);
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return;
766b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (to - from > 1000) {
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        third_index = GetThirdIndex(a, from, to);
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        third_index = from + ((to - from) >> 1);
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Find a pivot as the median of first, last and middle element.
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var v0 = a[from];
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var v1 = a[to - 1];
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var v2 = a[third_index];
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      var c01 = comparefn(v0, v1);
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (c01 > 0) {
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // v1 < v0, so swap them.
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        var tmp = v0;
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v0 = v1;
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v1 = tmp;
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } // v0 <= v1.
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      var c02 = comparefn(v0, v2);
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (c02 >= 0) {
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // v2 <= v0 <= v1.
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        var tmp = v0;
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v0 = v2;
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v2 = v1;
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v1 = tmp;
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // v0 <= v1 && v0 < v2
792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        var c12 = comparefn(v1, v2);
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (c12 > 0) {
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // v0 <= v2 < v1
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          var tmp = v1;
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          v1 = v2;
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          v2 = tmp;
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // v0 <= v1 <= v2
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      a[from] = v0;
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      a[to - 1] = v2;
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var pivot = v1;
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var low_end = from + 1;   // Upper bound of elements lower than pivot.
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      var high_start = to - 1;  // Lower bound of elements greater than pivot.
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      a[third_index] = a[low_end];
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      a[low_end] = pivot;
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // From low_end to i are elements equal to pivot.
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // From i to high_start are elements that haven't been compared yet.
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      partition: for (var i = low_end + 1; i < high_start; i++) {
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        var element = a[i];
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        var order = comparefn(element, pivot);
814b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        if (order < 0) {
8155710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch          a[i] = a[low_end];
8165710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch          a[low_end] = element;
817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          low_end++;
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else if (order > 0) {
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          do {
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            high_start--;
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            if (high_start == i) break partition;
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            var top_elem = a[high_start];
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            order = comparefn(top_elem, pivot);
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          } while (order > 0);
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          a[i] = a[high_start];
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          a[high_start] = element;
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (order < 0) {
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            element = a[i];
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            a[i] = a[low_end];
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            a[low_end] = element;
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            low_end++;
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        }
834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (to - high_start < low_end - from) {
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        QuickSort(a, high_start, to);
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        to = low_end;
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        QuickSort(a, from, low_end);
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        from = high_start;
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
8433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Copy elements in the range 0..length from obj's prototype chain
846b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // to obj itself, if obj has holes. Return one more than the maximal index
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // of a prototype property.
84862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  function CopyFromPrototype(obj, length) {
849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var max = 0;
850bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    for (var proto = %object_get_prototype_of(obj); proto;
851bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         proto = %object_get_prototype_of(proto)) {
852109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      var indices = IS_PROXY(proto) ? length : %GetArrayKeys(proto, length);
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (IS_NUMBER(indices)) {
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // It's an interval.
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        var proto_length = indices;
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (var i = 0; i < proto_length; i++) {
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (!HAS_OWN_PROPERTY(obj, i) && HAS_OWN_PROPERTY(proto, i)) {
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            obj[i] = proto[i];
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            if (i >= max) { max = i + 1; }
860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          }
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (var i = 0; i < indices.length; i++) {
864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          var index = indices[i];
8653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          if (!HAS_OWN_PROPERTY(obj, index) && HAS_OWN_PROPERTY(proto, index)) {
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            obj[index] = proto[index];
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            if (index >= max) { max = index + 1; }
868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          }
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return max;
8733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set a value of "undefined" on all indices in the range from..to
876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // where a prototype of obj has an element. I.e., shadow all prototype
877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // elements in that range.
87862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  function ShadowPrototypeElements(obj, from, to) {
879bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    for (var proto = %object_get_prototype_of(obj); proto;
880bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         proto = %object_get_prototype_of(proto)) {
881109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      var indices = IS_PROXY(proto) ? to : %GetArrayKeys(proto, to);
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (IS_NUMBER(indices)) {
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // It's an interval.
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        var proto_length = indices;
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (var i = from; i < proto_length; i++) {
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (HAS_OWN_PROPERTY(proto, i)) {
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            obj[i] = UNDEFINED;
888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          }
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (var i = 0; i < indices.length; i++) {
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          var index = indices[i];
8933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          if (from <= index && HAS_OWN_PROPERTY(proto, index)) {
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            obj[index] = UNDEFINED;
895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          }
896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
8993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  function SafeRemoveArrayHoles(obj) {
902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Copy defined elements from the end to fill in all holes and undefineds
903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // in the beginning of the array.  Write undefineds and holes at the end
904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // after loop is finished.
905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var first_undefined = 0;
906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var last_defined = length - 1;
907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var num_holes = 0;
908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    while (first_undefined < last_defined) {
909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Find first undefined element.
910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      while (first_undefined < last_defined &&
911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             !IS_UNDEFINED(obj[first_undefined])) {
912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        first_undefined++;
913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Maintain the invariant num_holes = the number of holes in the original
915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // array with indices <= first_undefined or > last_defined.
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!HAS_OWN_PROPERTY(obj, first_undefined)) {
917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        num_holes++;
918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Find last defined element.
921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      while (first_undefined < last_defined &&
922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             IS_UNDEFINED(obj[last_defined])) {
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (!HAS_OWN_PROPERTY(obj, last_defined)) {
924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          num_holes++;
925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        last_defined--;
927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (first_undefined < last_defined) {
929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // Fill in hole or undefined.
930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        obj[first_undefined] = obj[last_defined];
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        obj[last_defined] = UNDEFINED;
932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If there were any undefineds in the entire array, first_undefined
935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // points to one past the last defined element.  Make this true if
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // there were no undefineds, as well, so that first_undefined == number
937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // of defined elements.
938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!IS_UNDEFINED(obj[first_undefined])) first_undefined++;
939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Fill in the undefineds and the holes.  There may be a hole where
940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // an undefined should be and vice versa.
941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var i;
942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (i = first_undefined; i < length - num_holes; i++) {
943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      obj[i] = UNDEFINED;
944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (i = length - num_holes; i < length; i++) {
946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // For compatability with Webkit, do not expose elements in the prototype.
947bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (i in %object_get_prototype_of(obj)) {
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        obj[i] = UNDEFINED;
949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      } else {
950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        delete obj[i];
951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Return the number of defined elements.
955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return first_undefined;
9563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (length < 2) return array;
959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var is_array = IS_ARRAY(array);
961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var max_prototype_element;
962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!is_array) {
963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // For compatibility with JSC, we also sort elements inherited from
964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // the prototype chain on non-Array objects.
965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // We do this by copying them to this object and sorting only
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // own elements. This is not very efficient, but sorting with
967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // inherited elements happens very, very rarely, if at all.
968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // The specification allows "implementation dependent" behavior
969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // if an element on the prototype chain has an element that
970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // might interact with sorting.
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_prototype_element = CopyFromPrototype(array, length);
972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // %RemoveArrayHoles returns -1 if fast removal is not supported.
975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var num_non_undefined = %RemoveArrayHoles(array, length);
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (num_non_undefined == -1) {
978bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // There were indexed accessors in the array.
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Move array holes and undefineds to the end using a Javascript function
980bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // that is safe in the presence of accessors.
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    num_non_undefined = SafeRemoveArrayHoles(array);
982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  QuickSort(array, 0, num_non_undefined);
985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!is_array && (num_non_undefined + 1 < max_prototype_element)) {
987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // For compatibility with JSC, we shadow any elements in the prototype
988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // chain that has become exposed by sort moving a hole to its position.
989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ShadowPrototypeElements(array, num_non_undefined, max_prototype_element);
990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return array;
993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArraySort(comparefn) {
997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort");
998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
1000109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = TO_LENGTH(array.length);
1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArraySort(array, length, comparefn);
1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The following functions cannot be made efficient on sparse arrays while
1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// preserving the semantics, since the calls to the receiver function can add
1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// or delete elements from the array.
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArrayFilter(f, receiver, array, length, result) {
1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var result_length = 0;
1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (var i = 0; i < length; i++) {
101113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (i in array) {
1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      var element = array[i];
1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (%_Call(f, receiver, element, i, array)) {
1014bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        %CreateDataProperty(result, result_length, element);
1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        result_length++;
1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayFilter(f, receiver) {
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter");
1026257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
10273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Pull out the length so that modifications to the length in the
10283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // loop will not affect the looping and side effects are visible.
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
1030109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = TO_LENGTH(array.length);
1031f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var result = ArraySpeciesCreate(array, 0);
1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArrayFilter(f, receiver, array, length, result);
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
10353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
10363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArrayForEach(f, receiver, array, length) {
1038f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
10403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (IS_UNDEFINED(receiver)) {
10413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (var i = 0; i < length; i++) {
104213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (i in array) {
10433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        var element = array[i];
10443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        f(element, i, array);
10453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
10463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
10473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
10483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (var i = 0; i < length; i++) {
104913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (i in array) {
10503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        var element = array[i];
10513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        %_Call(f, receiver, element, i, array);
10523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayForEach(f, receiver) {
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach");
1060257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
10613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Pull out the length so that modifications to the length in the
10623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // loop will not affect the looping and side effects are visible.
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
1064109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = TO_LENGTH(array.length);
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InnerArrayForEach(f, receiver, array, length);
1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
10673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArraySome(f, receiver, array, length) {
1070f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
10713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < length; i++) {
107313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (i in array) {
10743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      var element = array[i];
1075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (%_Call(f, receiver, element, i, array)) return true;
1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Executes the function once for each element present in the
1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// array until it finds one where callback returns true.
1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArraySome(f, receiver) {
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some");
1086257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
10873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Pull out the length so that modifications to the length in the
10883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // loop will not affect the looping and side effects are visible.
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
1090109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = TO_LENGTH(array.length);
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArraySome(f, receiver, array, length);
1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
10933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArrayEvery(f, receiver, array, length) {
1096f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
10973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < length; i++) {
109913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (i in array) {
11003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      var element = array[i];
1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!%_Call(f, receiver, element, i, array)) return false;
1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayEvery(f, receiver) {
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every");
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.
1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
1113109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = TO_LENGTH(array.length);
1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArrayEvery(f, receiver, array, length);
1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ArrayMap(f, receiver) {
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map");
1120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
11213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Pull out the length so that modifications to the length in the
11223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // loop will not affect the looping and side effects are visible.
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
1124109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = TO_LENGTH(array.length);
1125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var result = ArraySpeciesCreate(array, length);
1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < length; i++) {
112813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (i in array) {
11293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      var element = array[i];
1130bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      %CreateDataProperty(result, i, %_Call(f, receiver, element, i, array));
1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArrayLastIndexOf(array, element, index, length, argumentsLength) {
113880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  if (length == 0) return -1;
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (argumentsLength < 2) {
1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    index = length - 1;
1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
1142bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    index = INVERT_NEG_ZERO(TO_INTEGER(index));
1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If index is negative, index from end of the array.
114459151504615d929945dc59db37bf1166937748c6Steve Block    if (index < 0) index += length;
1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If index is still negative, do not search the array.
114659151504615d929945dc59db37bf1166937748c6Steve Block    if (index < 0) return -1;
1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    else if (index >= length) index = length - 1;
1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
114959151504615d929945dc59db37bf1166937748c6Steve Block  var min = 0;
115059151504615d929945dc59db37bf1166937748c6Steve Block  var max = index;
1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (UseSparseVariant(array, length, IS_ARRAY(array), index)) {
1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    %NormalizeElements(array);
1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    var indices = %GetArrayKeys(array, index + 1);
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (IS_NUMBER(indices)) {
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // It's an interval.
1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max = indices;  // Capped by index already.
115759151504615d929945dc59db37bf1166937748c6Steve Block      // Fall through to loop below.
115859151504615d929945dc59db37bf1166937748c6Steve Block    } else {
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (indices.length == 0) return -1;
116059151504615d929945dc59db37bf1166937748c6Steve Block      // Get all the keys in sorted order.
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      var sortedKeys = GetSortedArrayKeys(array, indices);
116259151504615d929945dc59db37bf1166937748c6Steve Block      var i = sortedKeys.length - 1;
116359151504615d929945dc59db37bf1166937748c6Steve Block      while (i >= 0) {
116459151504615d929945dc59db37bf1166937748c6Steve Block        var key = sortedKeys[i];
11653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (array[key] === element) return key;
116659151504615d929945dc59db37bf1166937748c6Steve Block        i--;
116759151504615d929945dc59db37bf1166937748c6Steve Block      }
116859151504615d929945dc59db37bf1166937748c6Steve Block      return -1;
116959151504615d929945dc59db37bf1166937748c6Steve Block    }
117059151504615d929945dc59db37bf1166937748c6Steve Block  }
1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Lookup through the array.
11726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (!IS_UNDEFINED(element)) {
117359151504615d929945dc59db37bf1166937748c6Steve Block    for (var i = max; i >= min; i--) {
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (array[i] === element) return i;
11756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
11766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return -1;
11776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
117859151504615d929945dc59db37bf1166937748c6Steve Block  for (var i = max; i >= min; i--) {
1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (IS_UNDEFINED(array[i]) && i in array) {
11806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      return i;
1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return -1;
1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArrayLastIndexOf(element, index) {
1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.lastIndexOf");
1189257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1190109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = TO_LENGTH(this.length);
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArrayLastIndexOf(this, element, index, length,
1192109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                               arguments.length);
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
11943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArrayReduce(callback, current, array, length, argumentsLength) {
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!IS_CALLABLE(callback)) {
1198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    throw %make_type_error(kCalledNonCallable, callback);
1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
120069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var i = 0;
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  find_initial: if (argumentsLength < 2) {
1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (; i < length; i++) {
120413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (i in array) {
1205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        current = array[i++];
1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break find_initial;
1207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    throw %make_type_error(kReduceNoInitial);
1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (; i < length; i++) {
121313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (i in array) {
12143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      var element = array[i];
1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current = callback(current, element, i, array);
1216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return current;
1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1221257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArrayReduce(callback, current) {
1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce");
12243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Pull out the length so that modifications to the length in the
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // loop will not affect the looping and side effects are visible.
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
1228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = TO_LENGTH(array.length);
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArrayReduce(callback, current, array, length,
1230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                          arguments.length);
1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArrayReduceRight(callback, current, array, length,
1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               argumentsLength) {
1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!IS_CALLABLE(callback)) {
1237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    throw %make_type_error(kCalledNonCallable, callback);
1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var i = length - 1;
1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  find_initial: if (argumentsLength < 2) {
1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (; i >= 0; i--) {
124313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (i in array) {
1244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        current = array[i--];
1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break find_initial;
1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    throw %make_type_error(kReduceNoInitial);
1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (; i >= 0; i--) {
125213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (i in array) {
12533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      var element = array[i];
1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current = callback(current, element, i, array);
1255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return current;
1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArrayReduceRight(callback, current) {
1262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight");
1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Pull out the length so that side effects are visible before the
1265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // callback function is checked.
1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
1267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = TO_LENGTH(array.length);
1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArrayReduceRight(callback, current, array, length,
1269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                               arguments.length);
12703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
127362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// ES#sec-array.prototype.copywithin
127462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// (Array.prototype.copyWithin ( target, start [ , end ] )
127562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochfunction ArrayCopyWithin(target, start, end) {
127662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.copyWithin");
127762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
127862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  var array = TO_OBJECT(this);
127962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  var length = TO_LENGTH(array.length);
128062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  target = TO_INTEGER(target);
1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var to;
1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (target < 0) {
1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    to = MaxSimple(length + target, 0);
1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    to = MinSimple(target, length);
1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  start = TO_INTEGER(start);
1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var from;
1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (start < 0) {
1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    from = MaxSimple(length + start, 0);
1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    from = MinSimple(start, length);
1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  end = IS_UNDEFINED(end) ? length : TO_INTEGER(end);
1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var final;
1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (end < 0) {
1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    final = MaxSimple(length + end, 0);
1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    final = MinSimple(end, length);
1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var count = MinSimple(final - from, length - to);
1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var direction = 1;
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (from < to && to < (from + count)) {
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    direction = -1;
1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    from = from + count - 1;
1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    to = to + count - 1;
1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (count > 0) {
1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (from in array) {
1315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      array[to] = array[from];
1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      delete array[to];
1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    from = from + direction;
1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    to = to + direction;
1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    count--;
1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return array;
1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArrayFind(predicate, thisArg, array, length) {
1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!IS_CALLABLE(predicate)) {
1330f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    throw %make_type_error(kCalledNonCallable, predicate);
1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (var i = 0; i < length; i++) {
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    var element = array[i];
1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (%_Call(predicate, thisArg, element, i, array)) {
1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return element;
13376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return;
1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ES6 draft 07-15-13, section 15.4.3.23
1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArrayFind(predicate, thisArg) {
1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.find");
1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
1349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var length = TO_INTEGER(array.length);
1350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArrayFind(predicate, thisArg, array, length);
1352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArrayFindIndex(predicate, thisArg, array, length) {
1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!IS_CALLABLE(predicate)) {
1357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    throw %make_type_error(kCalledNonCallable, predicate);
1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (var i = 0; i < length; i++) {
1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    var element = array[i];
1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (%_Call(predicate, thisArg, element, i, array)) {
1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return i;
13646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -1;
1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ES6 draft 07-15-13, section 15.4.3.24
1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArrayFindIndex(predicate, thisArg) {
1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.findIndex");
1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
1376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var length = TO_INTEGER(array.length);
1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArrayFindIndex(predicate, thisArg, array, length);
1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ES6, draft 04-05-14, section 22.1.3.6
1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction InnerArrayFill(value, start, end, array, length) {
1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var i = IS_UNDEFINED(start) ? 0 : TO_INTEGER(start);
1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var end = IS_UNDEFINED(end) ? length : TO_INTEGER(end);
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (i < 0) {
1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    i += length;
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i < 0) i = 0;
1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i > length) i = length;
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (end < 0) {
1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    end += length;
1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (end < 0) end = 0;
1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (end > length) end = length;
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if ((end - i) > 0 && %object_is_frozen(array)) {
1402f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    throw %make_type_error(kArrayFunctionsOnFrozen);
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (; i < end; i++)
1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    array[i] = value;
1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return array;
1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ES6, draft 04-05-14, section 22.1.3.6
1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArrayFill(value, start, end) {
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.fill");
1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = TO_OBJECT(this);
1416109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = TO_LENGTH(array.length);
1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InnerArrayFill(value, start, end, array, length);
1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ES6, draft 10-14-14, section 22.1.2.1
1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction ArrayFrom(arrayLike, mapfn, receiver) {
1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var items = TO_OBJECT(arrayLike);
1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var mapping = !IS_UNDEFINED(mapfn);
1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mapping) {
1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!IS_CALLABLE(mapfn)) {
1429f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      throw %make_type_error(kCalledNonCallable, mapfn);
1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var iterable = GetMethod(items, iteratorSymbol);
1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var k;
1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var result;
1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var mappedValue;
1437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var nextValue;
1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!IS_UNDEFINED(iterable)) {
1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result = %IsConstructor(this) ? new this() : [];
1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    k = 0;
1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1443109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (nextValue of
1444109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         { [iteratorSymbol]() { return GetIterator(items, iterable) } }) {
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (mapping) {
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        mappedValue = %_Call(mapfn, receiver, nextValue, k);
1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        mappedValue = nextValue;
1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1450bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      %CreateDataProperty(result, k, mappedValue);
1451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      k++;
1452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1453109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    result.length = k;
1454109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return result;
1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    var len = TO_LENGTH(items.length);
1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result = %IsConstructor(this) ? new this(len) : new GlobalArray(len);
1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (k = 0; k < len; ++k) {
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      nextValue = items[k];
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (mapping) {
1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        mappedValue = %_Call(mapfn, receiver, nextValue, k);
1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        mappedValue = nextValue;
1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1466bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      %CreateDataProperty(result, k, mappedValue);
1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result.length = k;
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return result;
1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
14746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ES6, draft 05-22-14, section 22.1.2.3
1476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochfunction ArrayOf(...args) {
1477109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  var length = args.length;
1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var constructor = this;
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO: Implement IsConstructor (ES6 section 7.2.5)
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = %IsConstructor(constructor) ? new constructor(length) : [];
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (var i = 0; i < length; i++) {
1482bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    %CreateDataProperty(array, i, args[i]);
1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array.length = length;
1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return array;
1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// -------------------------------------------------------------------
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Set up non-enumerable constructor property on the Array.prototype
1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// object.
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch%AddNamedProperty(GlobalArray.prototype, "constructor", GlobalArray,
1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  DONT_ENUM);
1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Set up unscopable properties on the Array.prototype object.
1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar unscopables = {
1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __proto__: null,
1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  copyWithin: true,
1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  entries: true,
1500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  fill: true,
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  find: true,
1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  findIndex: true,
150313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  includes: true,
1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  keys: true,
1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch%AddNamedProperty(GlobalArray.prototype, unscopablesSymbol, unscopables,
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  DONT_ENUM | READ_ONLY);
1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch%FunctionSetLength(ArrayFrom, 1);
1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Set up non-enumerable functions on the Array object.
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochutils.InstallFunctions(GlobalArray, DONT_ENUM, [
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "from", ArrayFrom,
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "of", ArrayOf
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch]);
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar specialFunctions = %SpecialArrayFunctions();
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
152062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochfunction getFunction(name, jsBuiltin, len) {
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var f = jsBuiltin;
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (specialFunctions.hasOwnProperty(name)) {
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    f = specialFunctions[name];
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!IS_UNDEFINED(len)) {
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    %FunctionSetLength(f, len);
1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return f;
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
153162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Array prototype functions that return iterators. They are exposed to the
153262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// public API via Template::SetIntrinsicDataProperty().
153362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvar IteratorFunctions = {
153462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    "entries": getFunction("entries", null, 0),
153562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    "forEach": getFunction("forEach", ArrayForEach, 1),
153662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    "keys": getFunction("keys", null, 0),
153762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    "values": getFunction("values", null, 0)
153862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
1539c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Set up non-enumerable functions of the Array.prototype object and
1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// set their names.
1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Manipulate the length of some of the functions to meet
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// expectations set by ECMA-262 or Mozilla.
1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochutils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "toString", getFunction("toString", ArrayToString),
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "toLocaleString", getFunction("toLocaleString", ArrayToLocaleString),
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "join", getFunction("join", ArrayJoin),
1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "pop", getFunction("pop", ArrayPop),
1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "push", getFunction("push", ArrayPush, 1),
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "reverse", getFunction("reverse", ArrayReverse),
1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "shift", getFunction("shift", ArrayShift),
1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "unshift", getFunction("unshift", ArrayUnshift, 1),
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "slice", getFunction("slice", ArraySlice, 2),
1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "splice", getFunction("splice", ArraySplice, 2),
1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "sort", getFunction("sort", ArraySort),
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "filter", getFunction("filter", ArrayFilter, 1),
1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "some", getFunction("some", ArraySome, 1),
1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "every", getFunction("every", ArrayEvery, 1),
1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "map", getFunction("map", ArrayMap, 1),
1560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  "indexOf", getFunction("indexOf", null, 1),
1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1),
1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "reduce", getFunction("reduce", ArrayReduce, 1),
1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "reduceRight", getFunction("reduceRight", ArrayReduceRight, 1),
1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "copyWithin", getFunction("copyWithin", ArrayCopyWithin, 2),
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "find", getFunction("find", ArrayFind, 1),
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "findIndex", getFunction("findIndex", ArrayFindIndex, 1),
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "fill", getFunction("fill", ArrayFill, 1),
1568c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  "includes", getFunction("includes", null, 1),
156962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  "entries", IteratorFunctions.entries,
157062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  "forEach", IteratorFunctions.forEach,
157162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  "keys", IteratorFunctions.keys,
157262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  iteratorSymbol, IteratorFunctions.values
1573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch]);
1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
157562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochutils.ForEachFunction = GlobalArray.prototype.forEach;
1576c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
157762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch%FunctionSetName(IteratorFunctions.entries, "entries");
157862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch%FunctionSetName(IteratorFunctions.forEach, "forEach");
157962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch%FunctionSetName(IteratorFunctions.keys, "keys");
158062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch%FunctionSetName(IteratorFunctions.values, "values");
158113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch%FinishArrayPrototypeSetup(GlobalArray.prototype);
1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The internal Array prototype doesn't need to be fancy, since it's never
1585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// exposed to user code.
1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Adding only the functions that are actually used.
1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochutils.SetUpLockedPrototype(InternalArray, GlobalArray(), [
1588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  "indexOf", getFunction("indexOf", null),
1589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "join", getFunction("join", ArrayJoin),
1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "pop", getFunction("pop", ArrayPop),
1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "push", getFunction("push", ArrayPush),
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "shift", getFunction("shift", ArrayShift),
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "sort", getFunction("sort", ArraySort),
1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "splice", getFunction("splice", ArraySplice)
1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch]);
1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochutils.SetUpLockedPrototype(InternalPackedArray, GlobalArray(), [
1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "join", getFunction("join", ArrayJoin),
1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "pop", getFunction("pop", ArrayPop),
1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "push", getFunction("push", ArrayPush),
1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "shift", getFunction("shift", ArrayShift)
1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch]);
1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// V8 extras get a separate copy of InternalPackedArray. We give them the basic
1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// manipulation methods.
1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochutils.SetUpLockedPrototype(extrasUtils.InternalPackedArray, GlobalArray(), [
1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "push", getFunction("push", ArrayPush),
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "pop", getFunction("pop", ArrayPop),
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "shift", getFunction("shift", ArrayShift),
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "unshift", getFunction("unshift", ArrayUnshift),
1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "splice", getFunction("splice", ArraySplice),
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "slice", getFunction("slice", ArraySlice)
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch]);
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// -------------------------------------------------------------------
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Exports
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochutils.Export(function(to) {
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.ArrayFrom = ArrayFrom;
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.ArrayJoin = ArrayJoin;
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.ArrayPush = ArrayPush;
1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.ArrayToString = ArrayToString;
162362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  to.ArrayValues = IteratorFunctions.values,
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArrayEvery = InnerArrayEvery;
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArrayFill = InnerArrayFill;
1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArrayFilter = InnerArrayFilter;
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArrayFind = InnerArrayFind;
1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArrayFindIndex = InnerArrayFindIndex;
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArrayForEach = InnerArrayForEach;
1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArrayJoin = InnerArrayJoin;
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArrayLastIndexOf = InnerArrayLastIndexOf;
1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArrayReduce = InnerArrayReduce;
1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArrayReduceRight = InnerArrayReduceRight;
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArraySome = InnerArraySome;
1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArraySort = InnerArraySort;
1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.InnerArrayToLocaleString = InnerArrayToLocaleString;
1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to.PackedArrayReverse = PackedArrayReverse;
1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch});
1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch%InstallToContext([
164162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  "array_entries_iterator", IteratorFunctions.entries,
164262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  "array_for_each_iterator", IteratorFunctions.forEach,
164362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  "array_keys_iterator", IteratorFunctions.keys,
1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "array_pop", ArrayPop,
1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "array_push", ArrayPush,
1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "array_shift", ArrayShift,
1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "array_splice", ArraySplice,
1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "array_slice", ArraySlice,
1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  "array_unshift", ArrayUnshift,
165062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  "array_values_iterator", IteratorFunctions.values,
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch]);
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch});
1654