| OLD | NEW |
| (Empty) |
| 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 (function(global, utils) { | |
| 6 | |
| 7 'use strict'; | |
| 8 | |
| 9 %CheckIsBootstrapping(); | |
| 10 | |
| 11 // ------------------------------------------------------------------- | |
| 12 // Imports | |
| 13 | |
| 14 var AddIndexedProperty; | |
| 15 var FLAG_harmony_tolength; | |
| 16 var GetIterator; | |
| 17 var GetMethod; | |
| 18 var GlobalArray = global.Array; | |
| 19 var iteratorSymbol = utils.ImportNow("iterator_symbol"); | |
| 20 var MakeTypeError; | |
| 21 var MaxSimple; | |
| 22 var MinSimple; | |
| 23 var ObjectIsFrozen; | |
| 24 var ObjectDefineProperty; | |
| 25 | |
| 26 utils.Import(function(from) { | |
| 27 AddIndexedProperty = from.AddIndexedProperty; | |
| 28 FLAG_harmony_tolength = from.FLAG_harmony_tolength; | |
| 29 GetIterator = from.GetIterator; | |
| 30 GetMethod = from.GetMethod; | |
| 31 MakeTypeError = from.MakeTypeError; | |
| 32 MaxSimple = from.MaxSimple; | |
| 33 MinSimple = from.MinSimple; | |
| 34 ObjectIsFrozen = from.ObjectIsFrozen; | |
| 35 ObjectDefineProperty = from.ObjectDefineProperty; | |
| 36 }); | |
| 37 | |
| 38 // ------------------------------------------------------------------- | |
| 39 | |
| 40 function InnerArrayCopyWithin(target, start, end, array, length) { | |
| 41 target = TO_INTEGER(target); | |
| 42 var to; | |
| 43 if (target < 0) { | |
| 44 to = MaxSimple(length + target, 0); | |
| 45 } else { | |
| 46 to = MinSimple(target, length); | |
| 47 } | |
| 48 | |
| 49 start = TO_INTEGER(start); | |
| 50 var from; | |
| 51 if (start < 0) { | |
| 52 from = MaxSimple(length + start, 0); | |
| 53 } else { | |
| 54 from = MinSimple(start, length); | |
| 55 } | |
| 56 | |
| 57 end = IS_UNDEFINED(end) ? length : TO_INTEGER(end); | |
| 58 var final; | |
| 59 if (end < 0) { | |
| 60 final = MaxSimple(length + end, 0); | |
| 61 } else { | |
| 62 final = MinSimple(end, length); | |
| 63 } | |
| 64 | |
| 65 var count = MinSimple(final - from, length - to); | |
| 66 var direction = 1; | |
| 67 if (from < to && to < (from + count)) { | |
| 68 direction = -1; | |
| 69 from = from + count - 1; | |
| 70 to = to + count - 1; | |
| 71 } | |
| 72 | |
| 73 while (count > 0) { | |
| 74 if (from in array) { | |
| 75 array[to] = array[from]; | |
| 76 } else { | |
| 77 delete array[to]; | |
| 78 } | |
| 79 from = from + direction; | |
| 80 to = to + direction; | |
| 81 count--; | |
| 82 } | |
| 83 | |
| 84 return array; | |
| 85 } | |
| 86 | |
| 87 // ES6 draft 03-17-15, section 22.1.3.3 | |
| 88 function ArrayCopyWithin(target, start, end) { | |
| 89 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.copyWithin"); | |
| 90 | |
| 91 var array = TO_OBJECT(this); | |
| 92 var length = TO_LENGTH(array.length); | |
| 93 | |
| 94 return InnerArrayCopyWithin(target, start, end, array, length); | |
| 95 } | |
| 96 | |
| 97 function InnerArrayFind(predicate, thisArg, array, length) { | |
| 98 if (!IS_CALLABLE(predicate)) { | |
| 99 throw MakeTypeError(kCalledNonCallable, predicate); | |
| 100 } | |
| 101 | |
| 102 for (var i = 0; i < length; i++) { | |
| 103 var element = array[i]; | |
| 104 if (%_Call(predicate, thisArg, element, i, array)) { | |
| 105 return element; | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 return; | |
| 110 } | |
| 111 | |
| 112 // ES6 draft 07-15-13, section 15.4.3.23 | |
| 113 function ArrayFind(predicate, thisArg) { | |
| 114 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.find"); | |
| 115 | |
| 116 var array = TO_OBJECT(this); | |
| 117 var length = TO_INTEGER(array.length); | |
| 118 | |
| 119 return InnerArrayFind(predicate, thisArg, array, length); | |
| 120 } | |
| 121 | |
| 122 function InnerArrayFindIndex(predicate, thisArg, array, length) { | |
| 123 if (!IS_CALLABLE(predicate)) { | |
| 124 throw MakeTypeError(kCalledNonCallable, predicate); | |
| 125 } | |
| 126 | |
| 127 for (var i = 0; i < length; i++) { | |
| 128 var element = array[i]; | |
| 129 if (%_Call(predicate, thisArg, element, i, array)) { | |
| 130 return i; | |
| 131 } | |
| 132 } | |
| 133 | |
| 134 return -1; | |
| 135 } | |
| 136 | |
| 137 // ES6 draft 07-15-13, section 15.4.3.24 | |
| 138 function ArrayFindIndex(predicate, thisArg) { | |
| 139 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.findIndex"); | |
| 140 | |
| 141 var array = TO_OBJECT(this); | |
| 142 var length = TO_INTEGER(array.length); | |
| 143 | |
| 144 return InnerArrayFindIndex(predicate, thisArg, array, length); | |
| 145 } | |
| 146 | |
| 147 // ES6, draft 04-05-14, section 22.1.3.6 | |
| 148 function InnerArrayFill(value, start, end, array, length) { | |
| 149 var i = IS_UNDEFINED(start) ? 0 : TO_INTEGER(start); | |
| 150 var end = IS_UNDEFINED(end) ? length : TO_INTEGER(end); | |
| 151 | |
| 152 if (i < 0) { | |
| 153 i += length; | |
| 154 if (i < 0) i = 0; | |
| 155 } else { | |
| 156 if (i > length) i = length; | |
| 157 } | |
| 158 | |
| 159 if (end < 0) { | |
| 160 end += length; | |
| 161 if (end < 0) end = 0; | |
| 162 } else { | |
| 163 if (end > length) end = length; | |
| 164 } | |
| 165 | |
| 166 if ((end - i) > 0 && ObjectIsFrozen(array)) { | |
| 167 throw MakeTypeError(kArrayFunctionsOnFrozen); | |
| 168 } | |
| 169 | |
| 170 for (; i < end; i++) | |
| 171 array[i] = value; | |
| 172 return array; | |
| 173 } | |
| 174 | |
| 175 // ES6, draft 04-05-14, section 22.1.3.6 | |
| 176 function ArrayFill(value, start, end) { | |
| 177 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.fill"); | |
| 178 | |
| 179 var array = TO_OBJECT(this); | |
| 180 var length = TO_LENGTH_OR_UINT32(array.length); | |
| 181 | |
| 182 return InnerArrayFill(value, start, end, array, length); | |
| 183 } | |
| 184 | |
| 185 function AddArrayElement(constructor, array, i, value) { | |
| 186 if (constructor === GlobalArray) { | |
| 187 AddIndexedProperty(array, i, value); | |
| 188 } else { | |
| 189 ObjectDefineProperty(array, i, { | |
| 190 value: value, writable: true, configurable: true, enumerable: true | |
| 191 }); | |
| 192 } | |
| 193 } | |
| 194 | |
| 195 // ES6, draft 10-14-14, section 22.1.2.1 | |
| 196 function ArrayFrom(arrayLike, mapfn, receiver) { | |
| 197 var items = TO_OBJECT(arrayLike); | |
| 198 var mapping = !IS_UNDEFINED(mapfn); | |
| 199 | |
| 200 if (mapping) { | |
| 201 if (!IS_CALLABLE(mapfn)) { | |
| 202 throw MakeTypeError(kCalledNonCallable, mapfn); | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 var iterable = GetMethod(items, iteratorSymbol); | |
| 207 var k; | |
| 208 var result; | |
| 209 var mappedValue; | |
| 210 var nextValue; | |
| 211 | |
| 212 if (!IS_UNDEFINED(iterable)) { | |
| 213 result = %IsConstructor(this) ? new this() : []; | |
| 214 | |
| 215 var iterator = GetIterator(items, iterable); | |
| 216 | |
| 217 k = 0; | |
| 218 while (true) { | |
| 219 var next = iterator.next(); | |
| 220 | |
| 221 if (!IS_OBJECT(next)) { | |
| 222 throw MakeTypeError(kIteratorResultNotAnObject, next); | |
| 223 } | |
| 224 | |
| 225 if (next.done) { | |
| 226 result.length = k; | |
| 227 return result; | |
| 228 } | |
| 229 | |
| 230 nextValue = next.value; | |
| 231 if (mapping) { | |
| 232 mappedValue = %_Call(mapfn, receiver, nextValue, k); | |
| 233 } else { | |
| 234 mappedValue = nextValue; | |
| 235 } | |
| 236 AddArrayElement(this, result, k, mappedValue); | |
| 237 k++; | |
| 238 } | |
| 239 } else { | |
| 240 var len = TO_LENGTH(items.length); | |
| 241 result = %IsConstructor(this) ? new this(len) : new GlobalArray(len); | |
| 242 | |
| 243 for (k = 0; k < len; ++k) { | |
| 244 nextValue = items[k]; | |
| 245 if (mapping) { | |
| 246 mappedValue = %_Call(mapfn, receiver, nextValue, k); | |
| 247 } else { | |
| 248 mappedValue = nextValue; | |
| 249 } | |
| 250 AddArrayElement(this, result, k, mappedValue); | |
| 251 } | |
| 252 | |
| 253 result.length = k; | |
| 254 return result; | |
| 255 } | |
| 256 } | |
| 257 | |
| 258 // ES6, draft 05-22-14, section 22.1.2.3 | |
| 259 function ArrayOf() { | |
| 260 var length = %_ArgumentsLength(); | |
| 261 var constructor = this; | |
| 262 // TODO: Implement IsConstructor (ES6 section 7.2.5) | |
| 263 var array = %IsConstructor(constructor) ? new constructor(length) : []; | |
| 264 for (var i = 0; i < length; i++) { | |
| 265 AddArrayElement(constructor, array, i, %_Arguments(i)); | |
| 266 } | |
| 267 array.length = length; | |
| 268 return array; | |
| 269 } | |
| 270 | |
| 271 // ------------------------------------------------------------------- | |
| 272 | |
| 273 %FunctionSetLength(ArrayCopyWithin, 2); | |
| 274 %FunctionSetLength(ArrayFrom, 1); | |
| 275 %FunctionSetLength(ArrayFill, 1); | |
| 276 %FunctionSetLength(ArrayFind, 1); | |
| 277 %FunctionSetLength(ArrayFindIndex, 1); | |
| 278 | |
| 279 // Set up non-enumerable functions on the Array object. | |
| 280 utils.InstallFunctions(GlobalArray, DONT_ENUM, [ | |
| 281 "from", ArrayFrom, | |
| 282 "of", ArrayOf | |
| 283 ]); | |
| 284 | |
| 285 // Set up the non-enumerable functions on the Array prototype object. | |
| 286 utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [ | |
| 287 "copyWithin", ArrayCopyWithin, | |
| 288 "find", ArrayFind, | |
| 289 "findIndex", ArrayFindIndex, | |
| 290 "fill", ArrayFill | |
| 291 ]); | |
| 292 | |
| 293 // ------------------------------------------------------------------- | |
| 294 // Exports | |
| 295 | |
| 296 utils.Export(function(to) { | |
| 297 to.ArrayFrom = ArrayFrom; | |
| 298 to.InnerArrayCopyWithin = InnerArrayCopyWithin; | |
| 299 to.InnerArrayFill = InnerArrayFill; | |
| 300 to.InnerArrayFind = InnerArrayFind; | |
| 301 to.InnerArrayFindIndex = InnerArrayFindIndex; | |
| 302 }); | |
| 303 | |
| 304 }) | |
| OLD | NEW |