1// Copyright 2013 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5'use strict';
6
7// This file relies on the fact that the following declaration has been made
8// in runtime.js:
9// var $Array = global.Array;
10
11// -------------------------------------------------------------------
12
13// ES6 draft 07-15-13, section 15.4.3.23
14function ArrayFind(predicate /* thisArg */) {  // length == 1
15  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.find");
16
17  var array = ToObject(this);
18  var length = ToInteger(array.length);
19
20  if (!IS_SPEC_FUNCTION(predicate)) {
21    throw MakeTypeError('called_non_callable', [predicate]);
22  }
23
24  var thisArg;
25  if (%_ArgumentsLength() > 1) {
26    thisArg = %_Arguments(1);
27  }
28
29  if (IS_NULL_OR_UNDEFINED(thisArg)) {
30    thisArg = %GetDefaultReceiver(predicate) || thisArg;
31  } else if (!IS_SPEC_OBJECT(thisArg) && %IsSloppyModeFunction(predicate)) {
32    thisArg = ToObject(thisArg);
33  }
34
35  for (var i = 0; i < length; i++) {
36    if (i in array) {
37      var element = array[i];
38      if (%_CallFunction(thisArg, element, i, array, predicate)) {
39        return element;
40      }
41    }
42  }
43
44  return;
45}
46
47
48// ES6 draft 07-15-13, section 15.4.3.24
49function ArrayFindIndex(predicate /* thisArg */) {  // length == 1
50  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.findIndex");
51
52  var array = ToObject(this);
53  var length = ToInteger(array.length);
54
55  if (!IS_SPEC_FUNCTION(predicate)) {
56    throw MakeTypeError('called_non_callable', [predicate]);
57  }
58
59  var thisArg;
60  if (%_ArgumentsLength() > 1) {
61    thisArg = %_Arguments(1);
62  }
63
64  if (IS_NULL_OR_UNDEFINED(thisArg)) {
65    thisArg = %GetDefaultReceiver(predicate) || thisArg;
66  } else if (!IS_SPEC_OBJECT(thisArg) && %IsSloppyModeFunction(predicate)) {
67    thisArg = ToObject(thisArg);
68  }
69
70  for (var i = 0; i < length; i++) {
71    if (i in array) {
72      var element = array[i];
73      if (%_CallFunction(thisArg, element, i, array, predicate)) {
74        return i;
75      }
76    }
77  }
78
79  return -1;
80}
81
82
83// ES6, draft 04-05-14, section 22.1.3.6
84function ArrayFill(value /* [, start [, end ] ] */) {  // length == 1
85  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.fill");
86
87  var array = ToObject(this);
88  var length = TO_UINT32(array.length);
89
90  var i = 0;
91  var end = length;
92
93  if (%_ArgumentsLength() > 1) {
94    i = %_Arguments(1);
95    i = IS_UNDEFINED(i) ? 0 : TO_INTEGER(i);
96    if (%_ArgumentsLength() > 2) {
97      end = %_Arguments(2);
98      end = IS_UNDEFINED(end) ? length : TO_INTEGER(end);
99    }
100  }
101
102  if (i < 0) {
103    i += length;
104    if (i < 0) i = 0;
105  } else {
106    if (i > length) i = length;
107  }
108
109  if (end < 0) {
110    end += length;
111    if (end < 0) end = 0;
112  } else {
113    if (end > length) end = length;
114  }
115
116  if ((end - i) > 0 && ObjectIsFrozen(array)) {
117    throw MakeTypeError("array_functions_on_frozen",
118                        ["Array.prototype.fill"]);
119  }
120
121  for (; i < end; i++)
122    array[i] = value;
123  return array;
124}
125
126// ES6, draft 05-22-14, section 22.1.2.3
127function ArrayOf() {
128  var length = %_ArgumentsLength();
129  var constructor = this;
130  // TODO: Implement IsConstructor (ES6 section 7.2.5)
131  var array = IS_SPEC_FUNCTION(constructor) ? new constructor(length) : [];
132  for (var i = 0; i < length; i++) {
133    %AddElement(array, i, %_Arguments(i), NONE);
134  }
135  array.length = length;
136  return array;
137}
138
139// -------------------------------------------------------------------
140
141function HarmonyArrayExtendArrayPrototype() {
142  %CheckIsBootstrapping();
143
144  // Set up non-enumerable functions on the Array object.
145  InstallFunctions($Array, DONT_ENUM, $Array(
146    "of", ArrayOf
147  ));
148
149  // Set up the non-enumerable functions on the Array prototype object.
150  InstallFunctions($Array.prototype, DONT_ENUM, $Array(
151    "find", ArrayFind,
152    "findIndex", ArrayFindIndex,
153    "fill", ArrayFill
154  ));
155}
156
157HarmonyArrayExtendArrayPrototype();
158