blob: 1e67bc30c6cd7d21023620acec95a9aa69bb0e42 [file] [log] [blame]
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001// Copyright 2013 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28"use strict";
29
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000030// This file relies on the fact that the following declaration has been made
31// in runtime.js:
32// var $Array = global.Array;
mstarzinger@chromium.orgb4968be2013-10-16 09:00:56 +000033var $ArrayBuffer = global.ArrayBuffer;
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +000034
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +000035
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000036// --------------- Typed Arrays ---------------------
37
38function CreateTypedArrayConstructor(name, elementSize, arrayId, constructor) {
danno@chromium.orgf005df62013-04-30 16:36:45 +000039 function ConstructByArrayBuffer(obj, buffer, byteOffset, length) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +000040 var offset = ToPositiveInteger(byteOffset, "invalid_typed_array_length")
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000041
danno@chromium.orgf005df62013-04-30 16:36:45 +000042 if (offset % elementSize !== 0) {
43 throw MakeRangeError("invalid_typed_array_alignment",
44 "start offset", name, elementSize);
45 }
46 var bufferByteLength = %ArrayBufferGetByteLength(buffer);
ulan@chromium.org57ff8812013-05-10 08:16:55 +000047 if (offset > bufferByteLength) {
danno@chromium.orgf005df62013-04-30 16:36:45 +000048 throw MakeRangeError("invalid_typed_array_offset");
49 }
50
51 var newByteLength;
52 var newLength;
53 if (IS_UNDEFINED(length)) {
54 if (bufferByteLength % elementSize !== 0) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000055 throw MakeRangeError("invalid_typed_array_alignment",
danno@chromium.orgf005df62013-04-30 16:36:45 +000056 "byte length", name, elementSize);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000057 }
danno@chromium.orgf005df62013-04-30 16:36:45 +000058 newByteLength = bufferByteLength - offset;
59 newLength = newByteLength / elementSize;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000060 } else {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +000061 var newLength = ToPositiveInteger(length, "invalid_typed_array_length");
danno@chromium.orgf005df62013-04-30 16:36:45 +000062 newByteLength = newLength * elementSize;
63 }
ulan@chromium.org57ff8812013-05-10 08:16:55 +000064 if (offset + newByteLength > bufferByteLength) {
danno@chromium.orgf005df62013-04-30 16:36:45 +000065 throw MakeRangeError("invalid_typed_array_length");
66 }
67 %TypedArrayInitialize(obj, arrayId, buffer, offset, newByteLength);
68 }
69
70 function ConstructByLength(obj, length) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +000071 var l = ToPositiveInteger(length, "invalid_typed_array_length");
danno@chromium.orgf005df62013-04-30 16:36:45 +000072 var byteLength = l * elementSize;
mstarzinger@chromium.orgb4968be2013-10-16 09:00:56 +000073 var buffer = new $ArrayBuffer(byteLength);
ulan@chromium.org57ff8812013-05-10 08:16:55 +000074 %TypedArrayInitialize(obj, arrayId, buffer, 0, byteLength);
75 }
76
77 function ConstructByArrayLike(obj, arrayLike) {
78 var length = arrayLike.length;
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +000079 var l = ToPositiveInteger(length, "invalid_typed_array_length");
danno@chromium.orgd3c42102013-08-01 16:58:23 +000080 if(!%TypedArrayInitializeFromArrayLike(obj, arrayId, arrayLike, l)) {
81 for (var i = 0; i < l; i++) {
machenbach@chromium.org3d079fe2013-09-25 08:19:55 +000082 // It is crucial that we let any execptions from arrayLike[i]
83 // propagate outside the function.
danno@chromium.orgd3c42102013-08-01 16:58:23 +000084 obj[i] = arrayLike[i];
85 }
ulan@chromium.org57ff8812013-05-10 08:16:55 +000086 }
danno@chromium.orgf005df62013-04-30 16:36:45 +000087 }
88
89 return function (arg1, arg2, arg3) {
90 if (%_IsConstructCall()) {
91 if (IS_ARRAYBUFFER(arg1)) {
92 ConstructByArrayBuffer(this, arg1, arg2, arg3);
danno@chromium.orgbee51992013-07-10 14:57:15 +000093 } else if (IS_NUMBER(arg1) || IS_STRING(arg1) ||
94 IS_BOOLEAN(arg1) || IS_UNDEFINED(arg1)) {
danno@chromium.orgf005df62013-04-30 16:36:45 +000095 ConstructByLength(this, arg1);
ulan@chromium.org57ff8812013-05-10 08:16:55 +000096 } else {
danno@chromium.orgbee51992013-07-10 14:57:15 +000097 ConstructByArrayLike(this, arg1);
danno@chromium.orgf005df62013-04-30 16:36:45 +000098 }
99 } else {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000100 throw MakeTypeError("constructor_not_function", [name])
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000101 }
102 }
103}
104
105function TypedArrayGetBuffer() {
106 return %TypedArrayGetBuffer(this);
107}
108
109function TypedArrayGetByteLength() {
110 return %TypedArrayGetByteLength(this);
111}
112
113function TypedArrayGetByteOffset() {
114 return %TypedArrayGetByteOffset(this);
115}
116
117function TypedArrayGetLength() {
118 return %TypedArrayGetLength(this);
119}
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000120
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000121function CreateSubArray(elementSize, constructor) {
122 return function(begin, end) {
123 var srcLength = %TypedArrayGetLength(this);
124 var beginInt = TO_INTEGER(begin);
125 if (beginInt < 0) {
126 beginInt = MathMax(0, srcLength + beginInt);
127 } else {
128 beginInt = MathMin(srcLength, beginInt);
129 }
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000130
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000131 var endInt = IS_UNDEFINED(end) ? srcLength : TO_INTEGER(end);
132 if (endInt < 0) {
133 endInt = MathMax(0, srcLength + endInt);
134 } else {
135 endInt = MathMin(endInt, srcLength);
136 }
137 if (endInt < beginInt) {
138 endInt = beginInt;
139 }
140 var newLength = endInt - beginInt;
141 var beginByteOffset =
142 %TypedArrayGetByteOffset(this) + beginInt * elementSize;
143 return new constructor(%TypedArrayGetBuffer(this),
144 beginByteOffset, newLength);
145 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000146}
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000147
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000148function TypedArraySetFromArrayLike(target, source, sourceLength, offset) {
149 if (offset > 0) {
150 for (var i = 0; i < sourceLength; i++) {
151 target[offset + i] = source[i];
152 }
153 }
154 else {
155 for (var i = 0; i < sourceLength; i++) {
156 target[i] = source[i];
157 }
158 }
159}
160
161function TypedArraySetFromOverlappingTypedArray(target, source, offset) {
162 var sourceElementSize = source.BYTES_PER_ELEMENT;
163 var targetElementSize = target.BYTES_PER_ELEMENT;
164 var sourceLength = source.length;
165
166 // Copy left part.
167 function CopyLeftPart() {
168 // First un-mutated byte after the next write
169 var targetPtr = target.byteOffset + (offset + 1) * targetElementSize;
170 // Next read at sourcePtr. We do not care for memory changing before
171 // sourcePtr - we have already copied it.
172 var sourcePtr = source.byteOffset;
173 for (var leftIndex = 0;
174 leftIndex < sourceLength && targetPtr <= sourcePtr;
175 leftIndex++) {
176 target[offset + leftIndex] = source[leftIndex];
177 targetPtr += targetElementSize;
178 sourcePtr += sourceElementSize;
179 }
180 return leftIndex;
181 }
182 var leftIndex = CopyLeftPart();
183
184 // Copy rigth part;
185 function CopyRightPart() {
186 // First unmutated byte before the next write
187 var targetPtr =
188 target.byteOffset + (offset + sourceLength - 1) * targetElementSize;
189 // Next read before sourcePtr. We do not care for memory changing after
190 // sourcePtr - we have already copied it.
191 var sourcePtr =
192 source.byteOffset + sourceLength * sourceElementSize;
193 for(var rightIndex = sourceLength - 1;
194 rightIndex >= leftIndex && targetPtr >= sourcePtr;
195 rightIndex--) {
196 target[offset + rightIndex] = source[rightIndex];
197 targetPtr -= targetElementSize;
198 sourcePtr -= sourceElementSize;
199 }
200 return rightIndex;
201 }
202 var rightIndex = CopyRightPart();
203
204 var temp = new $Array(rightIndex + 1 - leftIndex);
205 for (var i = leftIndex; i <= rightIndex; i++) {
206 temp[i - leftIndex] = source[i];
207 }
208 for (i = leftIndex; i <= rightIndex; i++) {
209 target[offset + i] = temp[i - leftIndex];
210 }
211}
212
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000213function TypedArraySet(obj, offset) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000214 var intOffset = IS_UNDEFINED(offset) ? 0 : TO_INTEGER(offset);
215 if (intOffset < 0) {
216 throw MakeTypeError("typed_array_set_negative_offset");
217 }
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000218 switch (%TypedArraySetFastCases(this, obj, intOffset)) {
219 // These numbers should be synchronized with runtime.cc.
220 case 0: // TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE
221 return;
222 case 1: // TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING
223 TypedArraySetFromOverlappingTypedArray(this, obj, intOffset);
224 return;
225 case 2: // TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING
226 TypedArraySetFromArrayLike(this, obj, obj.length, intOffset);
227 return;
228 case 3: // TYPED_ARRAY_SET_NON_TYPED_ARRAY
229 var l = obj.length;
230 if (IS_UNDEFINED(l)) {
231 if (IS_NUMBER(obj)) {
232 // For number as a first argument, throw TypeError
233 // instead of silently ignoring the call, so that
234 // the user knows (s)he did something wrong.
235 // (Consistent with Firefox and Blink/WebKit)
236 throw MakeTypeError("invalid_argument");
237 }
238 return;
239 }
240 if (intOffset + l > this.length) {
241 throw MakeRangeError("typed_array_set_source_too_large");
242 }
243 TypedArraySetFromArrayLike(this, obj, l, intOffset);
244 return;
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000245 }
246}
247
248// -------------------------------------------------------------------
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000249
250function SetupTypedArray(arrayId, name, constructor, elementSize) {
danno@chromium.orgf005df62013-04-30 16:36:45 +0000251 %CheckIsBootstrapping();
252 var fun = CreateTypedArrayConstructor(name, elementSize,
253 arrayId, constructor);
254 %SetCode(constructor, fun);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000255 %FunctionSetPrototype(constructor, new $Object());
256
jkummerow@chromium.orgba72ec82013-07-22 09:21:20 +0000257 %SetProperty(constructor, "BYTES_PER_ELEMENT", elementSize,
258 READ_ONLY | DONT_ENUM | DONT_DELETE);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000259 %SetProperty(constructor.prototype,
260 "constructor", constructor, DONT_ENUM);
261 %SetProperty(constructor.prototype,
262 "BYTES_PER_ELEMENT", elementSize,
263 READ_ONLY | DONT_ENUM | DONT_DELETE);
264 InstallGetter(constructor.prototype, "buffer", TypedArrayGetBuffer);
265 InstallGetter(constructor.prototype, "byteOffset", TypedArrayGetByteOffset);
266 InstallGetter(constructor.prototype, "byteLength", TypedArrayGetByteLength);
267 InstallGetter(constructor.prototype, "length", TypedArrayGetLength);
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000268
269 InstallFunctions(constructor.prototype, DONT_ENUM, $Array(
270 "subarray", CreateSubArray(elementSize, constructor),
271 "set", TypedArraySet
272 ));
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000273}
274
275// arrayIds below should be synchronized with Runtime_TypedArrayInitialize.
danno@chromium.orgf005df62013-04-30 16:36:45 +0000276SetupTypedArray(1, "Uint8Array", global.Uint8Array, 1);
277SetupTypedArray(2, "Int8Array", global.Int8Array, 1);
278SetupTypedArray(3, "Uint16Array", global.Uint16Array, 2);
279SetupTypedArray(4, "Int16Array", global.Int16Array, 2);
280SetupTypedArray(5, "Uint32Array", global.Uint32Array, 4);
281SetupTypedArray(6, "Int32Array", global.Int32Array, 4);
282SetupTypedArray(7, "Float32Array", global.Float32Array, 4);
283SetupTypedArray(8, "Float64Array", global.Float64Array, 8);
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000284SetupTypedArray(9, "Uint8ClampedArray", global.Uint8ClampedArray, 1);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000285
286
287// --------------------------- DataView -----------------------------
288
289var $DataView = global.DataView;
290
291function DataViewConstructor(buffer, byteOffset, byteLength) { // length = 3
292 if (%_IsConstructCall()) {
293 if (!IS_ARRAYBUFFER(buffer)) {
294 throw MakeTypeError('data_view_not_array_buffer', []);
295 }
296 var bufferByteLength = %ArrayBufferGetByteLength(buffer);
297 var offset = ToPositiveInteger(byteOffset, 'invalid_data_view_offset');
298 if (offset > bufferByteLength) {
299 throw MakeRangeError('invalid_data_view_offset');
300 }
301 var length = IS_UNDEFINED(byteLength) ?
302 bufferByteLength - offset : TO_INTEGER(byteLength);
303 if (length < 0 || offset + length > bufferByteLength) {
304 throw new MakeRangeError('invalid_data_view_length');
305 }
306 %DataViewInitialize(this, buffer, offset, length);
307 } else {
308 throw MakeTypeError('constructor_not_function', ["DataView"]);
309 }
310}
311
312function DataViewGetBuffer() {
313 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000314 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000315 ['DataView.buffer', this]);
316 }
317 return %DataViewGetBuffer(this);
318}
319
320function DataViewGetByteOffset() {
321 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000322 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000323 ['DataView.byteOffset', this]);
324 }
325 return %DataViewGetByteOffset(this);
326}
327
328function DataViewGetByteLength() {
329 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000330 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000331 ['DataView.byteLength', this]);
332 }
333 return %DataViewGetByteLength(this);
334}
335
336function ToPositiveDataViewOffset(offset) {
337 return ToPositiveInteger(offset, 'invalid_data_view_accessor_offset');
338}
339
340function DataViewGetInt8(offset, little_endian) {
341 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000342 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000343 ['DataView.getInt8', this]);
344 }
danno@chromium.org169691d2013-07-15 08:01:13 +0000345 if (%_ArgumentsLength() < 1) {
346 throw MakeTypeError('invalid_argument');
347 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000348 return %DataViewGetInt8(this,
349 ToPositiveDataViewOffset(offset),
350 !!little_endian);
351}
352
353function DataViewSetInt8(offset, value, little_endian) {
354 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000355 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000356 ['DataView.setInt8', this]);
357 }
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000358 if (%_ArgumentsLength() < 2) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000359 throw MakeTypeError('invalid_argument');
360 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000361 %DataViewSetInt8(this,
362 ToPositiveDataViewOffset(offset),
363 TO_NUMBER_INLINE(value),
364 !!little_endian);
365}
366
367function DataViewGetUint8(offset, little_endian) {
368 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000369 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000370 ['DataView.getUint8', this]);
371 }
danno@chromium.org169691d2013-07-15 08:01:13 +0000372 if (%_ArgumentsLength() < 1) {
373 throw MakeTypeError('invalid_argument');
374 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000375 return %DataViewGetUint8(this,
376 ToPositiveDataViewOffset(offset),
377 !!little_endian);
378}
379
380function DataViewSetUint8(offset, value, little_endian) {
381 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000382 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000383 ['DataView.setUint8', this]);
384 }
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000385 if (%_ArgumentsLength() < 2) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000386 throw MakeTypeError('invalid_argument');
387 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000388 %DataViewSetUint8(this,
389 ToPositiveDataViewOffset(offset),
390 TO_NUMBER_INLINE(value),
391 !!little_endian);
392}
393
394function DataViewGetInt16(offset, little_endian) {
395 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000396 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000397 ['DataView.getInt16', this]);
398 }
danno@chromium.org169691d2013-07-15 08:01:13 +0000399 if (%_ArgumentsLength() < 1) {
400 throw MakeTypeError('invalid_argument');
401 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000402 return %DataViewGetInt16(this,
403 ToPositiveDataViewOffset(offset),
404 !!little_endian);
405}
406
407function DataViewSetInt16(offset, value, little_endian) {
408 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000409 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000410 ['DataView.setInt16', this]);
411 }
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000412 if (%_ArgumentsLength() < 2) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000413 throw MakeTypeError('invalid_argument');
414 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000415 %DataViewSetInt16(this,
416 ToPositiveDataViewOffset(offset),
417 TO_NUMBER_INLINE(value),
418 !!little_endian);
419}
420
421function DataViewGetUint16(offset, little_endian) {
422 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000423 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000424 ['DataView.getUint16', this]);
425 }
danno@chromium.org169691d2013-07-15 08:01:13 +0000426 if (%_ArgumentsLength() < 1) {
427 throw MakeTypeError('invalid_argument');
428 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000429 return %DataViewGetUint16(this,
430 ToPositiveDataViewOffset(offset),
431 !!little_endian);
432}
433
434function DataViewSetUint16(offset, value, little_endian) {
435 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000436 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000437 ['DataView.setUint16', this]);
438 }
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000439 if (%_ArgumentsLength() < 2) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000440 throw MakeTypeError('invalid_argument');
441 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000442 %DataViewSetUint16(this,
443 ToPositiveDataViewOffset(offset),
444 TO_NUMBER_INLINE(value),
445 !!little_endian);
446}
447
448function DataViewGetInt32(offset, little_endian) {
449 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000450 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000451 ['DataView.getInt32', this]);
452 }
danno@chromium.org169691d2013-07-15 08:01:13 +0000453 if (%_ArgumentsLength() < 1) {
454 throw MakeTypeError('invalid_argument');
455 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000456 return %DataViewGetInt32(this,
457 ToPositiveDataViewOffset(offset),
458 !!little_endian);
459}
460
461function DataViewSetInt32(offset, value, little_endian) {
462 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000463 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000464 ['DataView.setInt32', this]);
465 }
danno@chromium.org169691d2013-07-15 08:01:13 +0000466 if (%_ArgumentsLength() < 2) {
467 throw MakeTypeError('invalid_argument');
468 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000469 %DataViewSetInt32(this,
470 ToPositiveDataViewOffset(offset),
471 TO_NUMBER_INLINE(value),
472 !!little_endian);
473}
474
475function DataViewGetUint32(offset, little_endian) {
476 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000477 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000478 ['DataView.getUint32', this]);
479 }
danno@chromium.org169691d2013-07-15 08:01:13 +0000480 if (%_ArgumentsLength() < 1) {
481 throw MakeTypeError('invalid_argument');
482 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000483 return %DataViewGetUint32(this,
484 ToPositiveDataViewOffset(offset),
485 !!little_endian);
486}
487
488function DataViewSetUint32(offset, value, little_endian) {
489 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000490 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000491 ['DataView.setUint32', this]);
492 }
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000493 if (%_ArgumentsLength() < 2) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000494 throw MakeTypeError('invalid_argument');
495 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000496 %DataViewSetUint32(this,
497 ToPositiveDataViewOffset(offset),
498 TO_NUMBER_INLINE(value),
499 !!little_endian);
500}
501
502function DataViewGetFloat32(offset, little_endian) {
503 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000504 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000505 ['DataView.getFloat32', this]);
506 }
danno@chromium.org169691d2013-07-15 08:01:13 +0000507 if (%_ArgumentsLength() < 1) {
508 throw MakeTypeError('invalid_argument');
509 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000510 return %DataViewGetFloat32(this,
511 ToPositiveDataViewOffset(offset),
512 !!little_endian);
513}
514
515function DataViewSetFloat32(offset, value, little_endian) {
516 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000517 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000518 ['DataView.setFloat32', this]);
519 }
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000520 if (%_ArgumentsLength() < 2) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000521 throw MakeTypeError('invalid_argument');
522 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000523 %DataViewSetFloat32(this,
524 ToPositiveDataViewOffset(offset),
525 TO_NUMBER_INLINE(value),
526 !!little_endian);
527}
528
529function DataViewGetFloat64(offset, little_endian) {
530 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000531 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000532 ['DataView.getFloat64', this]);
533 }
danno@chromium.org169691d2013-07-15 08:01:13 +0000534 if (%_ArgumentsLength() < 1) {
535 throw MakeTypeError('invalid_argument');
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000536 }
537 return %DataViewGetFloat64(this,
538 ToPositiveDataViewOffset(offset),
539 !!little_endian);
540}
541
542function DataViewSetFloat64(offset, value, little_endian) {
543 if (!IS_DATAVIEW(this)) {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000544 throw MakeTypeError('incompatible_method_receiver',
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000545 ['DataView.setFloat64', this]);
546 }
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000547 if (%_ArgumentsLength() < 2) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000548 throw MakeTypeError('invalid_argument');
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000549 }
550 %DataViewSetFloat64(this,
551 ToPositiveDataViewOffset(offset),
552 TO_NUMBER_INLINE(value),
553 !!little_endian);
554}
555
556function SetupDataView() {
557 %CheckIsBootstrapping();
558
559 // Setup the DataView constructor.
560 %SetCode($DataView, DataViewConstructor);
561 %FunctionSetPrototype($DataView, new $Object);
562
563 // Set up constructor property on the DataView prototype.
564 %SetProperty($DataView.prototype, "constructor", $DataView, DONT_ENUM);
565
566 InstallGetter($DataView.prototype, "buffer", DataViewGetBuffer);
567 InstallGetter($DataView.prototype, "byteOffset", DataViewGetByteOffset);
568 InstallGetter($DataView.prototype, "byteLength", DataViewGetByteLength);
569
570 InstallFunctions($DataView.prototype, DONT_ENUM, $Array(
571 "getInt8", DataViewGetInt8,
572 "setInt8", DataViewSetInt8,
573
574 "getUint8", DataViewGetUint8,
575 "setUint8", DataViewSetUint8,
576
577 "getInt16", DataViewGetInt16,
578 "setInt16", DataViewSetInt16,
579
580 "getUint16", DataViewGetUint16,
581 "setUint16", DataViewSetUint16,
582
583 "getInt32", DataViewGetInt32,
584 "setInt32", DataViewSetInt32,
585
586 "getUint32", DataViewGetUint32,
587 "setUint32", DataViewSetUint32,
588
589 "getFloat32", DataViewGetFloat32,
590 "setFloat32", DataViewSetFloat32,
591
592 "getFloat64", DataViewGetFloat64,
593 "setFloat64", DataViewSetFloat64
594 ));
595}
596
597SetupDataView();