| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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 macro TYPED_ARRAYS(FUNCTION) | |
| 15 // arrayIds below should be synchronized with Runtime_TypedArrayInitialize. | |
| 16 FUNCTION(Uint8Array) | |
| 17 FUNCTION(Int8Array) | |
| 18 FUNCTION(Uint16Array) | |
| 19 FUNCTION(Int16Array) | |
| 20 FUNCTION(Uint32Array) | |
| 21 FUNCTION(Int32Array) | |
| 22 FUNCTION(Float32Array) | |
| 23 FUNCTION(Float64Array) | |
| 24 FUNCTION(Uint8ClampedArray) | |
| 25 endmacro | |
| 26 | |
| 27 macro DECLARE_GLOBALS(NAME) | |
| 28 var GlobalNAME = global.NAME; | |
| 29 endmacro | |
| 30 | |
| 31 TYPED_ARRAYS(DECLARE_GLOBALS) | |
| 32 DECLARE_GLOBALS(Array) | |
| 33 | |
| 34 var ArrayFrom; | |
| 35 var ArrayToString; | |
| 36 var InnerArrayCopyWithin; | |
| 37 var InnerArrayEvery; | |
| 38 var InnerArrayFill; | |
| 39 var InnerArrayFilter; | |
| 40 var InnerArrayFind; | |
| 41 var InnerArrayFindIndex; | |
| 42 var InnerArrayForEach; | |
| 43 var InnerArrayIndexOf; | |
| 44 var InnerArrayJoin; | |
| 45 var InnerArrayLastIndexOf; | |
| 46 var InnerArrayMap; | |
| 47 var InnerArraySome; | |
| 48 var InnerArraySort; | |
| 49 var InnerArrayToLocaleString; | |
| 50 var IsNaN; | |
| 51 var MathMax; | |
| 52 var MathMin; | |
| 53 var PackedArrayReverse; | |
| 54 | |
| 55 utils.Import(function(from) { | |
| 56 ArrayFrom = from.ArrayFrom; | |
| 57 ArrayToString = from.ArrayToString; | |
| 58 InnerArrayCopyWithin = from.InnerArrayCopyWithin; | |
| 59 InnerArrayEvery = from.InnerArrayEvery; | |
| 60 InnerArrayFill = from.InnerArrayFill; | |
| 61 InnerArrayFilter = from.InnerArrayFilter; | |
| 62 InnerArrayFind = from.InnerArrayFind; | |
| 63 InnerArrayFindIndex = from.InnerArrayFindIndex; | |
| 64 InnerArrayForEach = from.InnerArrayForEach; | |
| 65 InnerArrayIndexOf = from.InnerArrayIndexOf; | |
| 66 InnerArrayJoin = from.InnerArrayJoin; | |
| 67 InnerArrayLastIndexOf = from.InnerArrayLastIndexOf; | |
| 68 InnerArrayMap = from.InnerArrayMap; | |
| 69 InnerArrayReduce = from.InnerArrayReduce; | |
| 70 InnerArrayReduceRight = from.InnerArrayReduceRight; | |
| 71 InnerArraySome = from.InnerArraySome; | |
| 72 InnerArraySort = from.InnerArraySort; | |
| 73 InnerArrayToLocaleString = from.InnerArrayToLocaleString; | |
| 74 IsNaN = from.IsNaN; | |
| 75 MathMax = from.MathMax; | |
| 76 MathMin = from.MathMin; | |
| 77 PackedArrayReverse = from.PackedArrayReverse; | |
| 78 }); | |
| 79 | |
| 80 // ------------------------------------------------------------------- | |
| 81 | |
| 82 function ConstructTypedArray(constructor, arg) { | |
| 83 // TODO(littledan): This is an approximation of the spec, which requires | |
| 84 // that only real TypedArray classes should be accepted (22.2.2.1.1) | |
| 85 if (!%IsConstructor(constructor) || IS_UNDEFINED(constructor.prototype) || | |
| 86 !%HasOwnProperty(constructor.prototype, "BYTES_PER_ELEMENT")) { | |
| 87 throw MakeTypeError(kNotTypedArray); | |
| 88 } | |
| 89 | |
| 90 // TODO(littledan): The spec requires that, rather than directly calling | |
| 91 // the constructor, a TypedArray is created with the proper proto and | |
| 92 // underlying size and element size, and elements are put in one by one. | |
| 93 // By contrast, this would allow subclasses to make a radically different | |
| 94 // constructor with different semantics. | |
| 95 return new constructor(arg); | |
| 96 } | |
| 97 | |
| 98 function ConstructTypedArrayLike(typedArray, arg) { | |
| 99 // TODO(littledan): The spec requires that we actuallly use | |
| 100 // typedArray.constructor[Symbol.species] (bug v8:4093) | |
| 101 // Also, it should default to the default constructor from | |
| 102 // table 49 if typedArray.constructor doesn't exist. | |
| 103 return ConstructTypedArray(typedArray.constructor, arg); | |
| 104 } | |
| 105 | |
| 106 function TypedArrayCopyWithin(target, start, end) { | |
| 107 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 108 | |
| 109 var length = %_TypedArrayGetLength(this); | |
| 110 | |
| 111 // TODO(littledan): Replace with a memcpy for better performance | |
| 112 return InnerArrayCopyWithin(target, start, end, this, length); | |
| 113 } | |
| 114 %FunctionSetLength(TypedArrayCopyWithin, 2); | |
| 115 | |
| 116 // ES6 draft 05-05-15, section 22.2.3.7 | |
| 117 function TypedArrayEvery(f, receiver) { | |
| 118 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 119 | |
| 120 var length = %_TypedArrayGetLength(this); | |
| 121 | |
| 122 return InnerArrayEvery(f, receiver, this, length); | |
| 123 } | |
| 124 %FunctionSetLength(TypedArrayEvery, 1); | |
| 125 | |
| 126 // ES6 draft 08-24-14, section 22.2.3.12 | |
| 127 function TypedArrayForEach(f, receiver) { | |
| 128 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 129 | |
| 130 var length = %_TypedArrayGetLength(this); | |
| 131 | |
| 132 InnerArrayForEach(f, receiver, this, length); | |
| 133 } | |
| 134 %FunctionSetLength(TypedArrayForEach, 1); | |
| 135 | |
| 136 // ES6 draft 04-05-14 section 22.2.3.8 | |
| 137 function TypedArrayFill(value, start, end) { | |
| 138 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 139 | |
| 140 var length = %_TypedArrayGetLength(this); | |
| 141 | |
| 142 return InnerArrayFill(value, start, end, this, length); | |
| 143 } | |
| 144 %FunctionSetLength(TypedArrayFill, 1); | |
| 145 | |
| 146 // ES6 draft 07-15-13, section 22.2.3.9 | |
| 147 function TypedArrayFilter(predicate, thisArg) { | |
| 148 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 149 | |
| 150 var length = %_TypedArrayGetLength(this); | |
| 151 var array = InnerArrayFilter(predicate, thisArg, this, length); | |
| 152 return ConstructTypedArrayLike(this, array); | |
| 153 } | |
| 154 %FunctionSetLength(TypedArrayFilter, 1); | |
| 155 | |
| 156 // ES6 draft 07-15-13, section 22.2.3.10 | |
| 157 function TypedArrayFind(predicate, thisArg) { | |
| 158 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 159 | |
| 160 var length = %_TypedArrayGetLength(this); | |
| 161 | |
| 162 return InnerArrayFind(predicate, thisArg, this, length); | |
| 163 } | |
| 164 %FunctionSetLength(TypedArrayFind, 1); | |
| 165 | |
| 166 // ES6 draft 07-15-13, section 22.2.3.11 | |
| 167 function TypedArrayFindIndex(predicate, thisArg) { | |
| 168 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 169 | |
| 170 var length = %_TypedArrayGetLength(this); | |
| 171 | |
| 172 return InnerArrayFindIndex(predicate, thisArg, this, length); | |
| 173 } | |
| 174 %FunctionSetLength(TypedArrayFindIndex, 1); | |
| 175 | |
| 176 // ES6 draft 05-18-15, section 22.2.3.21 | |
| 177 function TypedArrayReverse() { | |
| 178 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 179 | |
| 180 var length = %_TypedArrayGetLength(this); | |
| 181 | |
| 182 return PackedArrayReverse(this, length); | |
| 183 } | |
| 184 | |
| 185 | |
| 186 function TypedArrayComparefn(x, y) { | |
| 187 if (IsNaN(x) && IsNaN(y)) { | |
| 188 return IsNaN(y) ? 0 : 1; | |
| 189 } | |
| 190 if (IsNaN(x)) { | |
| 191 return 1; | |
| 192 } | |
| 193 if (x === 0 && x === y) { | |
| 194 if (%_IsMinusZero(x)) { | |
| 195 if (!%_IsMinusZero(y)) { | |
| 196 return -1; | |
| 197 } | |
| 198 } else if (%_IsMinusZero(y)) { | |
| 199 return 1; | |
| 200 } | |
| 201 } | |
| 202 return x - y; | |
| 203 } | |
| 204 | |
| 205 | |
| 206 // ES6 draft 05-18-15, section 22.2.3.25 | |
| 207 function TypedArraySort(comparefn) { | |
| 208 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 209 | |
| 210 var length = %_TypedArrayGetLength(this); | |
| 211 | |
| 212 if (IS_UNDEFINED(comparefn)) { | |
| 213 comparefn = TypedArrayComparefn; | |
| 214 } | |
| 215 | |
| 216 return InnerArraySort(this, length, comparefn); | |
| 217 } | |
| 218 | |
| 219 | |
| 220 // ES6 section 22.2.3.13 | |
| 221 function TypedArrayIndexOf(element, index) { | |
| 222 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 223 | |
| 224 var length = %_TypedArrayGetLength(this); | |
| 225 return InnerArrayIndexOf(this, element, index, length); | |
| 226 } | |
| 227 %FunctionSetLength(TypedArrayIndexOf, 1); | |
| 228 | |
| 229 | |
| 230 // ES6 section 22.2.3.16 | |
| 231 function TypedArrayLastIndexOf(element, index) { | |
| 232 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 233 | |
| 234 var length = %_TypedArrayGetLength(this); | |
| 235 | |
| 236 return InnerArrayLastIndexOf(this, element, index, length, | |
| 237 %_ArgumentsLength()); | |
| 238 } | |
| 239 %FunctionSetLength(TypedArrayLastIndexOf, 1); | |
| 240 | |
| 241 | |
| 242 // ES6 draft 07-15-13, section 22.2.3.18 | |
| 243 function TypedArrayMap(predicate, thisArg) { | |
| 244 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 245 | |
| 246 // TODO(littledan): Preallocate rather than making an intermediate | |
| 247 // InternalArray, for better performance. | |
| 248 var length = %_TypedArrayGetLength(this); | |
| 249 var array = InnerArrayMap(predicate, thisArg, this, length); | |
| 250 return ConstructTypedArrayLike(this, array); | |
| 251 } | |
| 252 %FunctionSetLength(TypedArrayMap, 1); | |
| 253 | |
| 254 | |
| 255 // ES6 draft 05-05-15, section 22.2.3.24 | |
| 256 function TypedArraySome(f, receiver) { | |
| 257 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 258 | |
| 259 var length = %_TypedArrayGetLength(this); | |
| 260 | |
| 261 return InnerArraySome(f, receiver, this, length); | |
| 262 } | |
| 263 %FunctionSetLength(TypedArraySome, 1); | |
| 264 | |
| 265 | |
| 266 // ES6 section 22.2.3.27 | |
| 267 function TypedArrayToLocaleString() { | |
| 268 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 269 | |
| 270 var length = %_TypedArrayGetLength(this); | |
| 271 | |
| 272 return InnerArrayToLocaleString(this, length); | |
| 273 } | |
| 274 | |
| 275 | |
| 276 // ES6 section 22.2.3.28 | |
| 277 function TypedArrayToString() { | |
| 278 return %_Call(ArrayToString, this); | |
| 279 } | |
| 280 | |
| 281 | |
| 282 // ES6 section 22.2.3.14 | |
| 283 function TypedArrayJoin(separator) { | |
| 284 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 285 | |
| 286 var length = %_TypedArrayGetLength(this); | |
| 287 | |
| 288 return InnerArrayJoin(separator, this, length); | |
| 289 } | |
| 290 | |
| 291 | |
| 292 // ES6 draft 07-15-13, section 22.2.3.19 | |
| 293 function TypedArrayReduce(callback, current) { | |
| 294 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 295 | |
| 296 var length = %_TypedArrayGetLength(this); | |
| 297 return InnerArrayReduce(callback, current, this, length, | |
| 298 %_ArgumentsLength()); | |
| 299 } | |
| 300 %FunctionSetLength(TypedArrayReduce, 1); | |
| 301 | |
| 302 | |
| 303 // ES6 draft 07-15-13, section 22.2.3.19 | |
| 304 function TypedArrayReduceRight(callback, current) { | |
| 305 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 306 | |
| 307 var length = %_TypedArrayGetLength(this); | |
| 308 return InnerArrayReduceRight(callback, current, this, length, | |
| 309 %_ArgumentsLength()); | |
| 310 } | |
| 311 %FunctionSetLength(TypedArrayReduceRight, 1); | |
| 312 | |
| 313 | |
| 314 function TypedArraySlice(start, end) { | |
| 315 if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray); | |
| 316 var len = %_TypedArrayGetLength(this); | |
| 317 | |
| 318 var relativeStart = TO_INTEGER(start); | |
| 319 | |
| 320 var k; | |
| 321 if (relativeStart < 0) { | |
| 322 k = MathMax(len + relativeStart, 0); | |
| 323 } else { | |
| 324 k = MathMin(relativeStart, len); | |
| 325 } | |
| 326 | |
| 327 var relativeEnd; | |
| 328 if (IS_UNDEFINED(end)) { | |
| 329 relativeEnd = len; | |
| 330 } else { | |
| 331 relativeEnd = TO_INTEGER(end); | |
| 332 } | |
| 333 | |
| 334 var final; | |
| 335 if (relativeEnd < 0) { | |
| 336 final = MathMax(len + relativeEnd, 0); | |
| 337 } else { | |
| 338 final = MathMin(relativeEnd, len); | |
| 339 } | |
| 340 | |
| 341 var count = MathMax(final - k, 0); | |
| 342 var array = ConstructTypedArrayLike(this, count); | |
| 343 // The code below is the 'then' branch; the 'else' branch species | |
| 344 // a memcpy. Because V8 doesn't canonicalize NaN, the difference is | |
| 345 // unobservable. | |
| 346 var n = 0; | |
| 347 while (k < final) { | |
| 348 var kValue = this[k]; | |
| 349 // TODO(littledan): The spec says to throw on an error in setting; | |
| 350 // does this throw? | |
| 351 array[n] = kValue; | |
| 352 k++; | |
| 353 n++; | |
| 354 } | |
| 355 return array; | |
| 356 } | |
| 357 | |
| 358 | |
| 359 // ES6 draft 08-24-14, section 22.2.2.2 | |
| 360 function TypedArrayOf() { | |
| 361 var length = %_ArgumentsLength(); | |
| 362 var array = new this(length); | |
| 363 for (var i = 0; i < length; i++) { | |
| 364 array[i] = %_Arguments(i); | |
| 365 } | |
| 366 return array; | |
| 367 } | |
| 368 | |
| 369 | |
| 370 function TypedArrayFrom(source, mapfn, thisArg) { | |
| 371 // TODO(littledan): Investigate if there is a receiver which could be | |
| 372 // faster to accumulate on than Array, e.g., a TypedVector. | |
| 373 var array = %_Call(ArrayFrom, GlobalArray, source, mapfn, thisArg); | |
| 374 return ConstructTypedArray(this, array); | |
| 375 } | |
| 376 %FunctionSetLength(TypedArrayFrom, 1); | |
| 377 | |
| 378 // TODO(littledan): Fix the TypedArray proto chain (bug v8:4085). | |
| 379 macro EXTEND_TYPED_ARRAY(NAME) | |
| 380 // Set up non-enumerable functions on the object. | |
| 381 utils.InstallFunctions(GlobalNAME, DONT_ENUM | DONT_DELETE | READ_ONLY, [ | |
| 382 "from", TypedArrayFrom, | |
| 383 "of", TypedArrayOf | |
| 384 ]); | |
| 385 | |
| 386 // Set up non-enumerable functions on the prototype object. | |
| 387 utils.InstallFunctions(GlobalNAME.prototype, DONT_ENUM, [ | |
| 388 "copyWithin", TypedArrayCopyWithin, | |
| 389 "every", TypedArrayEvery, | |
| 390 "fill", TypedArrayFill, | |
| 391 "filter", TypedArrayFilter, | |
| 392 "find", TypedArrayFind, | |
| 393 "findIndex", TypedArrayFindIndex, | |
| 394 "indexOf", TypedArrayIndexOf, | |
| 395 "join", TypedArrayJoin, | |
| 396 "lastIndexOf", TypedArrayLastIndexOf, | |
| 397 "forEach", TypedArrayForEach, | |
| 398 "map", TypedArrayMap, | |
| 399 "reduce", TypedArrayReduce, | |
| 400 "reduceRight", TypedArrayReduceRight, | |
| 401 "reverse", TypedArrayReverse, | |
| 402 "slice", TypedArraySlice, | |
| 403 "some", TypedArraySome, | |
| 404 "sort", TypedArraySort, | |
| 405 "toString", TypedArrayToString, | |
| 406 "toLocaleString", TypedArrayToLocaleString | |
| 407 ]); | |
| 408 endmacro | |
| 409 | |
| 410 TYPED_ARRAYS(EXTEND_TYPED_ARRAY) | |
| 411 | |
| 412 }) | |
| OLD | NEW |