Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(372)

Side by Side Diff: src/typedarray.js

Issue 1398733002: Move builtin JavaScript sources into own directory. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Also move macros.py file. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/templates.js ('k') | src/uri.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 GlobalArray = global.Array;
15 var GlobalArrayBuffer = global.ArrayBuffer;
16 var GlobalDataView = global.DataView;
17 var GlobalObject = global.Object;
18 var iteratorSymbol = utils.ImportNow("iterator_symbol");
19 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
20
21 macro TYPED_ARRAYS(FUNCTION)
22 // arrayIds below should be synchronized with Runtime_TypedArrayInitialize.
23 FUNCTION(1, Uint8Array, 1)
24 FUNCTION(2, Int8Array, 1)
25 FUNCTION(3, Uint16Array, 2)
26 FUNCTION(4, Int16Array, 2)
27 FUNCTION(5, Uint32Array, 4)
28 FUNCTION(6, Int32Array, 4)
29 FUNCTION(7, Float32Array, 4)
30 FUNCTION(8, Float64Array, 8)
31 FUNCTION(9, Uint8ClampedArray, 1)
32 endmacro
33
34 macro DECLARE_GLOBALS(INDEX, NAME, SIZE)
35 var GlobalNAME = global.NAME;
36 endmacro
37
38 TYPED_ARRAYS(DECLARE_GLOBALS)
39
40 var InternalArray = utils.InternalArray;
41
42 // --------------- Typed Arrays ---------------------
43
44 macro TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE)
45 function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) {
46 if (!IS_UNDEFINED(byteOffset)) {
47 byteOffset =
48 $toPositiveInteger(byteOffset, kInvalidTypedArrayLength);
49 }
50 if (!IS_UNDEFINED(length)) {
51 length = $toPositiveInteger(length, kInvalidTypedArrayLength);
52 }
53
54 var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
55 var offset;
56 if (IS_UNDEFINED(byteOffset)) {
57 offset = 0;
58 } else {
59 offset = byteOffset;
60
61 if (offset % ELEMENT_SIZE !== 0) {
62 throw MakeRangeError(kInvalidTypedArrayAlignment,
63 "start offset", "NAME", ELEMENT_SIZE);
64 }
65 if (offset > bufferByteLength) {
66 throw MakeRangeError(kInvalidTypedArrayOffset);
67 }
68 }
69
70 var newByteLength;
71 var newLength;
72 if (IS_UNDEFINED(length)) {
73 if (bufferByteLength % ELEMENT_SIZE !== 0) {
74 throw MakeRangeError(kInvalidTypedArrayAlignment,
75 "byte length", "NAME", ELEMENT_SIZE);
76 }
77 newByteLength = bufferByteLength - offset;
78 newLength = newByteLength / ELEMENT_SIZE;
79 } else {
80 var newLength = length;
81 newByteLength = newLength * ELEMENT_SIZE;
82 }
83 if ((offset + newByteLength > bufferByteLength)
84 || (newLength > %_MaxSmi())) {
85 throw MakeRangeError(kInvalidTypedArrayLength);
86 }
87 %_TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength, true);
88 }
89
90 function NAMEConstructByLength(obj, length) {
91 var l = IS_UNDEFINED(length) ?
92 0 : $toPositiveInteger(length, kInvalidTypedArrayLength);
93 if (l > %_MaxSmi()) {
94 throw MakeRangeError(kInvalidTypedArrayLength);
95 }
96 var byteLength = l * ELEMENT_SIZE;
97 if (byteLength > %_TypedArrayMaxSizeInHeap()) {
98 var buffer = new GlobalArrayBuffer(byteLength);
99 %_TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength, true);
100 } else {
101 %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, true);
102 }
103 }
104
105 function NAMEConstructByArrayLike(obj, arrayLike) {
106 var length = arrayLike.length;
107 var l = $toPositiveInteger(length, kInvalidTypedArrayLength);
108
109 if (l > %_MaxSmi()) {
110 throw MakeRangeError(kInvalidTypedArrayLength);
111 }
112 var initialized = false;
113 var byteLength = l * ELEMENT_SIZE;
114 if (byteLength <= %_TypedArrayMaxSizeInHeap()) {
115 %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, false);
116 } else {
117 initialized =
118 %TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l);
119 }
120 if (!initialized) {
121 for (var i = 0; i < l; i++) {
122 // It is crucial that we let any execptions from arrayLike[i]
123 // propagate outside the function.
124 obj[i] = arrayLike[i];
125 }
126 }
127 }
128
129 function NAMEConstructByIterable(obj, iterable, iteratorFn) {
130 var list = new InternalArray();
131 // Reading the Symbol.iterator property of iterable twice would be
132 // observable with getters, so instead, we call the function which
133 // was already looked up, and wrap it in another iterable. The
134 // __proto__ of the new iterable is set to null to avoid any chance
135 // of modifications to Object.prototype being observable here.
136 var iterator = %_Call(iteratorFn, iterable);
137 var newIterable = {
138 __proto__: null
139 };
140 // TODO(littledan): Computed properties don't work yet in nosnap.
141 // Rephrase when they do.
142 newIterable[iteratorSymbol] = function() { return iterator; }
143 for (var value of newIterable) {
144 list.push(value);
145 }
146 NAMEConstructByArrayLike(obj, list);
147 }
148
149 function NAMEConstructor(arg1, arg2, arg3) {
150 if (%_IsConstructCall()) {
151 if (IS_ARRAYBUFFER(arg1) || IS_SHAREDARRAYBUFFER(arg1)) {
152 NAMEConstructByArrayBuffer(this, arg1, arg2, arg3);
153 } else if (IS_NUMBER(arg1) || IS_STRING(arg1) ||
154 IS_BOOLEAN(arg1) || IS_UNDEFINED(arg1)) {
155 NAMEConstructByLength(this, arg1);
156 } else {
157 var iteratorFn = arg1[iteratorSymbol];
158 if (IS_UNDEFINED(iteratorFn) || iteratorFn === $arrayValues) {
159 NAMEConstructByArrayLike(this, arg1);
160 } else {
161 NAMEConstructByIterable(this, arg1, iteratorFn);
162 }
163 }
164 } else {
165 throw MakeTypeError(kConstructorNotFunction, "NAME")
166 }
167 }
168
169 function NAME_GetBuffer() {
170 if (!(%_ClassOf(this) === 'NAME')) {
171 throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.buffer", this);
172 }
173 return %TypedArrayGetBuffer(this);
174 }
175
176 function NAME_GetByteLength() {
177 if (!(%_ClassOf(this) === 'NAME')) {
178 throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.byteLength", this);
179 }
180 return %_ArrayBufferViewGetByteLength(this);
181 }
182
183 function NAME_GetByteOffset() {
184 if (!(%_ClassOf(this) === 'NAME')) {
185 throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.byteOffset", this);
186 }
187 return %_ArrayBufferViewGetByteOffset(this);
188 }
189
190 function NAME_GetLength() {
191 if (!(%_ClassOf(this) === 'NAME')) {
192 throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.length", this);
193 }
194 return %_TypedArrayGetLength(this);
195 }
196
197 function NAMESubArray(begin, end) {
198 if (!(%_ClassOf(this) === 'NAME')) {
199 throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.subarray", this);
200 }
201 var beginInt = TO_INTEGER(begin);
202 if (!IS_UNDEFINED(end)) {
203 var endInt = TO_INTEGER(end);
204 var srcLength = %_TypedArrayGetLength(this);
205 } else {
206 var srcLength = %_TypedArrayGetLength(this);
207 var endInt = srcLength;
208 }
209
210 if (beginInt < 0) {
211 beginInt = MAX_SIMPLE(0, srcLength + beginInt);
212 } else {
213 beginInt = MIN_SIMPLE(beginInt, srcLength);
214 }
215
216 if (endInt < 0) {
217 endInt = MAX_SIMPLE(0, srcLength + endInt);
218 } else {
219 endInt = MIN_SIMPLE(endInt, srcLength);
220 }
221
222 if (endInt < beginInt) {
223 endInt = beginInt;
224 }
225
226 var newLength = endInt - beginInt;
227 var beginByteOffset =
228 %_ArrayBufferViewGetByteOffset(this) + beginInt * ELEMENT_SIZE;
229 return new GlobalNAME(%TypedArrayGetBuffer(this),
230 beginByteOffset, newLength);
231 }
232 endmacro
233
234 TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR)
235
236
237 function TypedArraySetFromArrayLike(target, source, sourceLength, offset) {
238 if (offset > 0) {
239 for (var i = 0; i < sourceLength; i++) {
240 target[offset + i] = source[i];
241 }
242 }
243 else {
244 for (var i = 0; i < sourceLength; i++) {
245 target[i] = source[i];
246 }
247 }
248 }
249
250 function TypedArraySetFromOverlappingTypedArray(target, source, offset) {
251 var sourceElementSize = source.BYTES_PER_ELEMENT;
252 var targetElementSize = target.BYTES_PER_ELEMENT;
253 var sourceLength = source.length;
254
255 // Copy left part.
256 function CopyLeftPart() {
257 // First un-mutated byte after the next write
258 var targetPtr = target.byteOffset + (offset + 1) * targetElementSize;
259 // Next read at sourcePtr. We do not care for memory changing before
260 // sourcePtr - we have already copied it.
261 var sourcePtr = source.byteOffset;
262 for (var leftIndex = 0;
263 leftIndex < sourceLength && targetPtr <= sourcePtr;
264 leftIndex++) {
265 target[offset + leftIndex] = source[leftIndex];
266 targetPtr += targetElementSize;
267 sourcePtr += sourceElementSize;
268 }
269 return leftIndex;
270 }
271 var leftIndex = CopyLeftPart();
272
273 // Copy rigth part;
274 function CopyRightPart() {
275 // First unmutated byte before the next write
276 var targetPtr =
277 target.byteOffset + (offset + sourceLength - 1) * targetElementSize;
278 // Next read before sourcePtr. We do not care for memory changing after
279 // sourcePtr - we have already copied it.
280 var sourcePtr =
281 source.byteOffset + sourceLength * sourceElementSize;
282 for(var rightIndex = sourceLength - 1;
283 rightIndex >= leftIndex && targetPtr >= sourcePtr;
284 rightIndex--) {
285 target[offset + rightIndex] = source[rightIndex];
286 targetPtr -= targetElementSize;
287 sourcePtr -= sourceElementSize;
288 }
289 return rightIndex;
290 }
291 var rightIndex = CopyRightPart();
292
293 var temp = new GlobalArray(rightIndex + 1 - leftIndex);
294 for (var i = leftIndex; i <= rightIndex; i++) {
295 temp[i - leftIndex] = source[i];
296 }
297 for (i = leftIndex; i <= rightIndex; i++) {
298 target[offset + i] = temp[i - leftIndex];
299 }
300 }
301
302 function TypedArraySet(obj, offset) {
303 var intOffset = IS_UNDEFINED(offset) ? 0 : TO_INTEGER(offset);
304 if (intOffset < 0) throw MakeTypeError(kTypedArraySetNegativeOffset);
305
306 if (intOffset > %_MaxSmi()) {
307 throw MakeRangeError(kTypedArraySetSourceTooLarge);
308 }
309 switch (%TypedArraySetFastCases(this, obj, intOffset)) {
310 // These numbers should be synchronized with runtime.cc.
311 case 0: // TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE
312 return;
313 case 1: // TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING
314 TypedArraySetFromOverlappingTypedArray(this, obj, intOffset);
315 return;
316 case 2: // TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING
317 TypedArraySetFromArrayLike(this, obj, obj.length, intOffset);
318 return;
319 case 3: // TYPED_ARRAY_SET_NON_TYPED_ARRAY
320 var l = obj.length;
321 if (IS_UNDEFINED(l)) {
322 if (IS_NUMBER(obj)) {
323 // For number as a first argument, throw TypeError
324 // instead of silently ignoring the call, so that
325 // the user knows (s)he did something wrong.
326 // (Consistent with Firefox and Blink/WebKit)
327 throw MakeTypeError(kInvalidArgument);
328 }
329 return;
330 }
331 l = TO_LENGTH(l);
332 if (intOffset + l > this.length) {
333 throw MakeRangeError(kTypedArraySetSourceTooLarge);
334 }
335 TypedArraySetFromArrayLike(this, obj, l, intOffset);
336 return;
337 }
338 }
339
340 function TypedArrayGetToStringTag() {
341 if (!%_IsTypedArray(this)) return;
342 var name = %_ClassOf(this);
343 if (IS_UNDEFINED(name)) return;
344 return name;
345 }
346
347 // -------------------------------------------------------------------
348
349 macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
350 %SetCode(GlobalNAME, NAMEConstructor);
351 %FunctionSetPrototype(GlobalNAME, new GlobalObject());
352
353 %AddNamedProperty(GlobalNAME, "BYTES_PER_ELEMENT", ELEMENT_SIZE,
354 READ_ONLY | DONT_ENUM | DONT_DELETE);
355 %AddNamedProperty(GlobalNAME.prototype,
356 "constructor", global.NAME, DONT_ENUM);
357 %AddNamedProperty(GlobalNAME.prototype,
358 "BYTES_PER_ELEMENT", ELEMENT_SIZE,
359 READ_ONLY | DONT_ENUM | DONT_DELETE);
360 utils.InstallGetter(GlobalNAME.prototype, "buffer", NAME_GetBuffer);
361 utils.InstallGetter(GlobalNAME.prototype, "byteOffset", NAME_GetByteOffset,
362 DONT_ENUM | DONT_DELETE);
363 utils.InstallGetter(GlobalNAME.prototype, "byteLength", NAME_GetByteLength,
364 DONT_ENUM | DONT_DELETE);
365 utils.InstallGetter(GlobalNAME.prototype, "length", NAME_GetLength,
366 DONT_ENUM | DONT_DELETE);
367 utils.InstallGetter(GlobalNAME.prototype, toStringTagSymbol,
368 TypedArrayGetToStringTag);
369 utils.InstallFunctions(GlobalNAME.prototype, DONT_ENUM, [
370 "subarray", NAMESubArray,
371 "set", TypedArraySet
372 ]);
373 endmacro
374
375 TYPED_ARRAYS(SETUP_TYPED_ARRAY)
376
377 // --------------------------- DataView -----------------------------
378
379 function DataViewConstructor(buffer, byteOffset, byteLength) { // length = 3
380 if (%_IsConstructCall()) {
381 // TODO(binji): support SharedArrayBuffers?
382 if (!IS_ARRAYBUFFER(buffer)) throw MakeTypeError(kDataViewNotArrayBuffer);
383 if (!IS_UNDEFINED(byteOffset)) {
384 byteOffset = $toPositiveInteger(byteOffset, kInvalidDataViewOffset);
385 }
386 if (!IS_UNDEFINED(byteLength)) {
387 byteLength = TO_INTEGER(byteLength);
388 }
389
390 var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
391
392 var offset = IS_UNDEFINED(byteOffset) ? 0 : byteOffset;
393 if (offset > bufferByteLength) throw MakeRangeError(kInvalidDataViewOffset);
394
395 var length = IS_UNDEFINED(byteLength)
396 ? bufferByteLength - offset
397 : byteLength;
398 if (length < 0 || offset + length > bufferByteLength) {
399 throw new MakeRangeError(kInvalidDataViewLength);
400 }
401 %_DataViewInitialize(this, buffer, offset, length);
402 } else {
403 throw MakeTypeError(kConstructorNotFunction, "DataView");
404 }
405 }
406
407 function DataViewGetBufferJS() {
408 if (!IS_DATAVIEW(this)) {
409 throw MakeTypeError(kIncompatibleMethodReceiver, 'DataView.buffer', this);
410 }
411 return %DataViewGetBuffer(this);
412 }
413
414 function DataViewGetByteOffset() {
415 if (!IS_DATAVIEW(this)) {
416 throw MakeTypeError(kIncompatibleMethodReceiver,
417 'DataView.byteOffset', this);
418 }
419 return %_ArrayBufferViewGetByteOffset(this);
420 }
421
422 function DataViewGetByteLength() {
423 if (!IS_DATAVIEW(this)) {
424 throw MakeTypeError(kIncompatibleMethodReceiver,
425 'DataView.byteLength', this);
426 }
427 return %_ArrayBufferViewGetByteLength(this);
428 }
429
430 macro DATA_VIEW_TYPES(FUNCTION)
431 FUNCTION(Int8)
432 FUNCTION(Uint8)
433 FUNCTION(Int16)
434 FUNCTION(Uint16)
435 FUNCTION(Int32)
436 FUNCTION(Uint32)
437 FUNCTION(Float32)
438 FUNCTION(Float64)
439 endmacro
440
441
442 macro DATA_VIEW_GETTER_SETTER(TYPENAME)
443 function DataViewGetTYPENAMEJS(offset, little_endian) {
444 if (!IS_DATAVIEW(this)) {
445 throw MakeTypeError(kIncompatibleMethodReceiver,
446 'DataView.getTYPENAME', this);
447 }
448 if (%_ArgumentsLength() < 1) throw MakeTypeError(kInvalidArgument);
449 offset = $toPositiveInteger(offset, kInvalidDataViewAccessorOffset);
450 return %DataViewGetTYPENAME(this, offset, !!little_endian);
451 }
452
453 function DataViewSetTYPENAMEJS(offset, value, little_endian) {
454 if (!IS_DATAVIEW(this)) {
455 throw MakeTypeError(kIncompatibleMethodReceiver,
456 'DataView.setTYPENAME', this);
457 }
458 if (%_ArgumentsLength() < 2) throw MakeTypeError(kInvalidArgument);
459 offset = $toPositiveInteger(offset, kInvalidDataViewAccessorOffset);
460 %DataViewSetTYPENAME(this, offset, TO_NUMBER(value), !!little_endian);
461 }
462 endmacro
463
464 DATA_VIEW_TYPES(DATA_VIEW_GETTER_SETTER)
465
466 // Setup the DataView constructor.
467 %SetCode(GlobalDataView, DataViewConstructor);
468 %FunctionSetPrototype(GlobalDataView, new GlobalObject);
469
470 // Set up constructor property on the DataView prototype.
471 %AddNamedProperty(GlobalDataView.prototype, "constructor", GlobalDataView,
472 DONT_ENUM);
473 %AddNamedProperty(GlobalDataView.prototype, toStringTagSymbol, "DataView",
474 READ_ONLY|DONT_ENUM);
475
476 utils.InstallGetter(GlobalDataView.prototype, "buffer", DataViewGetBufferJS);
477 utils.InstallGetter(GlobalDataView.prototype, "byteOffset",
478 DataViewGetByteOffset);
479 utils.InstallGetter(GlobalDataView.prototype, "byteLength",
480 DataViewGetByteLength);
481
482 utils.InstallFunctions(GlobalDataView.prototype, DONT_ENUM, [
483 "getInt8", DataViewGetInt8JS,
484 "setInt8", DataViewSetInt8JS,
485
486 "getUint8", DataViewGetUint8JS,
487 "setUint8", DataViewSetUint8JS,
488
489 "getInt16", DataViewGetInt16JS,
490 "setInt16", DataViewSetInt16JS,
491
492 "getUint16", DataViewGetUint16JS,
493 "setUint16", DataViewSetUint16JS,
494
495 "getInt32", DataViewGetInt32JS,
496 "setInt32", DataViewSetInt32JS,
497
498 "getUint32", DataViewGetUint32JS,
499 "setUint32", DataViewSetUint32JS,
500
501 "getFloat32", DataViewGetFloat32JS,
502 "setFloat32", DataViewSetFloat32JS,
503
504 "getFloat64", DataViewGetFloat64JS,
505 "setFloat64", DataViewSetFloat64JS
506 ]);
507
508 })
OLDNEW
« no previous file with comments | « src/templates.js ('k') | src/uri.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698