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