Home | History | Annotate | Download | only in src
      1 // 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 
     30 // This file relies on the fact that the following declaration has been made
     31 // in runtime.js:
     32 // var $Array = global.Array;
     33 
     34 
     35 
     36 // --------------- Typed Arrays ---------------------
     37 
     38 function CreateTypedArrayConstructor(name, elementSize, arrayId, constructor) {
     39   function ConstructByArrayBuffer(obj, buffer, byteOffset, length) {
     40     var offset = ToPositiveInteger(byteOffset, "invalid_typed_array_length")
     41 
     42     if (offset % elementSize !== 0) {
     43       throw MakeRangeError("invalid_typed_array_alignment",
     44           "start offset", name, elementSize);
     45     }
     46     var bufferByteLength = %ArrayBufferGetByteLength(buffer);
     47     if (offset > bufferByteLength) {
     48       throw MakeRangeError("invalid_typed_array_offset");
     49     }
     50 
     51     var newByteLength;
     52     var newLength;
     53     if (IS_UNDEFINED(length)) {
     54       if (bufferByteLength % elementSize !== 0) {
     55         throw MakeRangeError("invalid_typed_array_alignment",
     56           "byte length", name, elementSize);
     57       }
     58       newByteLength = bufferByteLength - offset;
     59       newLength = newByteLength / elementSize;
     60     } else {
     61       var newLength = ToPositiveInteger(length, "invalid_typed_array_length");
     62       newByteLength = newLength * elementSize;
     63     }
     64     if (offset + newByteLength > bufferByteLength) {
     65       throw MakeRangeError("invalid_typed_array_length");
     66     }
     67     %TypedArrayInitialize(obj, arrayId, buffer, offset, newByteLength);
     68   }
     69 
     70   function ConstructByLength(obj, length) {
     71     var l = ToPositiveInteger(length, "invalid_typed_array_length");
     72     var byteLength = l * elementSize;
     73     var buffer = new global.ArrayBuffer(byteLength);
     74     %TypedArrayInitialize(obj, arrayId, buffer, 0, byteLength);
     75   }
     76 
     77   function ConstructByArrayLike(obj, arrayLike) {
     78     var length = arrayLike.length;
     79     var l =  ToPositiveInteger(length, "invalid_typed_array_length");
     80     if(!%TypedArrayInitializeFromArrayLike(obj, arrayId, arrayLike, l)) {
     81       for (var i = 0; i < l; i++) {
     82         obj[i] = arrayLike[i];
     83       }
     84     }
     85   }
     86 
     87   return function (arg1, arg2, arg3) {
     88     if (%_IsConstructCall()) {
     89       if (IS_ARRAYBUFFER(arg1)) {
     90         ConstructByArrayBuffer(this, arg1, arg2, arg3);
     91       } else if (IS_NUMBER(arg1) || IS_STRING(arg1) ||
     92                  IS_BOOLEAN(arg1) || IS_UNDEFINED(arg1)) {
     93         ConstructByLength(this, arg1);
     94       } else {
     95         ConstructByArrayLike(this, arg1);
     96       }
     97     } else {
     98       throw MakeTypeError("constructor_not_function", [name])
     99     }
    100   }
    101 }
    102 
    103 function TypedArrayGetBuffer() {
    104   return %TypedArrayGetBuffer(this);
    105 }
    106 
    107 function TypedArrayGetByteLength() {
    108   return %TypedArrayGetByteLength(this);
    109 }
    110 
    111 function TypedArrayGetByteOffset() {
    112   return %TypedArrayGetByteOffset(this);
    113 }
    114 
    115 function TypedArrayGetLength() {
    116   return %TypedArrayGetLength(this);
    117 }
    118 
    119 function CreateSubArray(elementSize, constructor) {
    120   return function(begin, end) {
    121     var srcLength = %TypedArrayGetLength(this);
    122     var beginInt = TO_INTEGER(begin);
    123     if (beginInt < 0) {
    124       beginInt = MathMax(0, srcLength + beginInt);
    125     } else {
    126       beginInt = MathMin(srcLength, beginInt);
    127     }
    128 
    129     var endInt = IS_UNDEFINED(end) ? srcLength : TO_INTEGER(end);
    130     if (endInt < 0) {
    131       endInt = MathMax(0, srcLength + endInt);
    132     } else {
    133       endInt = MathMin(endInt, srcLength);
    134     }
    135     if (endInt < beginInt) {
    136       endInt = beginInt;
    137     }
    138     var newLength = endInt - beginInt;
    139     var beginByteOffset =
    140         %TypedArrayGetByteOffset(this) + beginInt * elementSize;
    141     return new constructor(%TypedArrayGetBuffer(this),
    142                            beginByteOffset, newLength);
    143   }
    144 }
    145 
    146 function TypedArraySetFromArrayLike(target, source, sourceLength, offset) {
    147   if (offset > 0) {
    148     for (var i = 0; i < sourceLength; i++) {
    149       target[offset + i] = source[i];
    150     }
    151   }
    152   else {
    153     for (var i = 0; i < sourceLength; i++) {
    154       target[i] = source[i];
    155     }
    156   }
    157 }
    158 
    159 function TypedArraySetFromOverlappingTypedArray(target, source, offset) {
    160   var sourceElementSize = source.BYTES_PER_ELEMENT;
    161   var targetElementSize = target.BYTES_PER_ELEMENT;
    162   var sourceLength = source.length;
    163 
    164   // Copy left part.
    165   function CopyLeftPart() {
    166     // First un-mutated byte after the next write
    167     var targetPtr = target.byteOffset + (offset + 1) * targetElementSize;
    168     // Next read at sourcePtr. We do not care for memory changing before
    169     // sourcePtr - we have already copied it.
    170     var sourcePtr = source.byteOffset;
    171     for (var leftIndex = 0;
    172          leftIndex < sourceLength && targetPtr <= sourcePtr;
    173          leftIndex++) {
    174       target[offset + leftIndex] = source[leftIndex];
    175       targetPtr += targetElementSize;
    176       sourcePtr += sourceElementSize;
    177     }
    178     return leftIndex;
    179   }
    180   var leftIndex = CopyLeftPart();
    181 
    182   // Copy rigth part;
    183   function CopyRightPart() {
    184     // First unmutated byte before the next write
    185     var targetPtr =
    186       target.byteOffset + (offset + sourceLength - 1) * targetElementSize;
    187     // Next read before sourcePtr. We do not care for memory changing after
    188     // sourcePtr - we have already copied it.
    189     var sourcePtr =
    190       source.byteOffset + sourceLength * sourceElementSize;
    191     for(var rightIndex = sourceLength - 1;
    192         rightIndex >= leftIndex && targetPtr >= sourcePtr;
    193         rightIndex--) {
    194       target[offset + rightIndex] = source[rightIndex];
    195       targetPtr -= targetElementSize;
    196       sourcePtr -= sourceElementSize;
    197     }
    198     return rightIndex;
    199   }
    200   var rightIndex = CopyRightPart();
    201 
    202   var temp = new $Array(rightIndex + 1 - leftIndex);
    203   for (var i = leftIndex; i <= rightIndex; i++) {
    204     temp[i - leftIndex] = source[i];
    205   }
    206   for (i = leftIndex; i <= rightIndex; i++) {
    207     target[offset + i] = temp[i - leftIndex];
    208   }
    209 }
    210 
    211 function TypedArraySet(obj, offset) {
    212   var intOffset = IS_UNDEFINED(offset) ? 0 : TO_INTEGER(offset);
    213   if (intOffset < 0) {
    214     throw MakeTypeError("typed_array_set_negative_offset");
    215   }
    216   switch (%TypedArraySetFastCases(this, obj, intOffset)) {
    217     // These numbers should be synchronized with runtime.cc.
    218     case 0: // TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE
    219       return;
    220     case 1: // TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING
    221       TypedArraySetFromOverlappingTypedArray(this, obj, intOffset);
    222       return;
    223     case 2: // TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING
    224       TypedArraySetFromArrayLike(this, obj, obj.length, intOffset);
    225       return;
    226     case 3: // TYPED_ARRAY_SET_NON_TYPED_ARRAY
    227       var l = obj.length;
    228       if (IS_UNDEFINED(l)) {
    229         if (IS_NUMBER(obj)) {
    230             // For number as a first argument, throw TypeError
    231             // instead of silently ignoring the call, so that
    232             // the user knows (s)he did something wrong.
    233             // (Consistent with Firefox and Blink/WebKit)
    234             throw MakeTypeError("invalid_argument");
    235         }
    236         return;
    237       }
    238       if (intOffset + l > this.length) {
    239         throw MakeRangeError("typed_array_set_source_too_large");
    240       }
    241       TypedArraySetFromArrayLike(this, obj, l, intOffset);
    242       return;
    243   }
    244 }
    245 
    246 // -------------------------------------------------------------------
    247 
    248 function SetupTypedArray(arrayId, name, constructor, elementSize) {
    249   %CheckIsBootstrapping();
    250   var fun = CreateTypedArrayConstructor(name, elementSize,
    251                                         arrayId, constructor);
    252   %SetCode(constructor, fun);
    253   %FunctionSetPrototype(constructor, new $Object());
    254 
    255   %SetProperty(constructor, "BYTES_PER_ELEMENT", elementSize,
    256                READ_ONLY | DONT_ENUM | DONT_DELETE);
    257   %SetProperty(constructor.prototype,
    258                "constructor", constructor, DONT_ENUM);
    259   %SetProperty(constructor.prototype,
    260                "BYTES_PER_ELEMENT", elementSize,
    261                READ_ONLY | DONT_ENUM | DONT_DELETE);
    262   InstallGetter(constructor.prototype, "buffer", TypedArrayGetBuffer);
    263   InstallGetter(constructor.prototype, "byteOffset", TypedArrayGetByteOffset);
    264   InstallGetter(constructor.prototype, "byteLength", TypedArrayGetByteLength);
    265   InstallGetter(constructor.prototype, "length", TypedArrayGetLength);
    266 
    267   InstallFunctions(constructor.prototype, DONT_ENUM, $Array(
    268         "subarray", CreateSubArray(elementSize, constructor),
    269         "set", TypedArraySet
    270   ));
    271 }
    272 
    273 // arrayIds below should be synchronized with Runtime_TypedArrayInitialize.
    274 SetupTypedArray(1, "Uint8Array", global.Uint8Array, 1);
    275 SetupTypedArray(2, "Int8Array", global.Int8Array, 1);
    276 SetupTypedArray(3, "Uint16Array", global.Uint16Array, 2);
    277 SetupTypedArray(4, "Int16Array", global.Int16Array, 2);
    278 SetupTypedArray(5, "Uint32Array", global.Uint32Array, 4);
    279 SetupTypedArray(6, "Int32Array", global.Int32Array, 4);
    280 SetupTypedArray(7, "Float32Array", global.Float32Array, 4);
    281 SetupTypedArray(8, "Float64Array", global.Float64Array, 8);
    282 SetupTypedArray(9, "Uint8ClampedArray", global.Uint8ClampedArray, 1);
    283 
    284 
    285 // --------------------------- DataView -----------------------------
    286 
    287 var $DataView = global.DataView;
    288 
    289 function DataViewConstructor(buffer, byteOffset, byteLength) { // length = 3
    290   if (%_IsConstructCall()) {
    291     if (!IS_ARRAYBUFFER(buffer)) {
    292       throw MakeTypeError('data_view_not_array_buffer', []);
    293     }
    294     var bufferByteLength = %ArrayBufferGetByteLength(buffer);
    295     var offset = ToPositiveInteger(byteOffset, 'invalid_data_view_offset');
    296     if (offset > bufferByteLength) {
    297       throw MakeRangeError('invalid_data_view_offset');
    298     }
    299     var length = IS_UNDEFINED(byteLength) ?
    300       bufferByteLength - offset : TO_INTEGER(byteLength);
    301     if (length < 0 || offset + length > bufferByteLength) {
    302       throw new MakeRangeError('invalid_data_view_length');
    303     }
    304     %DataViewInitialize(this, buffer, offset, length);
    305   } else {
    306     throw MakeTypeError('constructor_not_function', ["DataView"]);
    307   }
    308 }
    309 
    310 function DataViewGetBuffer() {
    311   if (!IS_DATAVIEW(this)) {
    312     throw MakeTypeError('incompatible_method_receiver',
    313                         ['DataView.buffer', this]);
    314   }
    315   return %DataViewGetBuffer(this);
    316 }
    317 
    318 function DataViewGetByteOffset() {
    319   if (!IS_DATAVIEW(this)) {
    320     throw MakeTypeError('incompatible_method_receiver',
    321                         ['DataView.byteOffset', this]);
    322   }
    323   return %DataViewGetByteOffset(this);
    324 }
    325 
    326 function DataViewGetByteLength() {
    327   if (!IS_DATAVIEW(this)) {
    328     throw MakeTypeError('incompatible_method_receiver',
    329                         ['DataView.byteLength', this]);
    330   }
    331   return %DataViewGetByteLength(this);
    332 }
    333 
    334 function ToPositiveDataViewOffset(offset) {
    335   return ToPositiveInteger(offset, 'invalid_data_view_accessor_offset');
    336 }
    337 
    338 function DataViewGetInt8(offset, little_endian) {
    339   if (!IS_DATAVIEW(this)) {
    340     throw MakeTypeError('incompatible_method_receiver',
    341                         ['DataView.getInt8', this]);
    342   }
    343   if (%_ArgumentsLength() < 1) {
    344     throw MakeTypeError('invalid_argument');
    345   }
    346   return %DataViewGetInt8(this,
    347                           ToPositiveDataViewOffset(offset),
    348                           !!little_endian);
    349 }
    350 
    351 function DataViewSetInt8(offset, value, little_endian) {
    352   if (!IS_DATAVIEW(this)) {
    353     throw MakeTypeError('incompatible_method_receiver',
    354                         ['DataView.setInt8', this]);
    355   }
    356   if (%_ArgumentsLength() < 2) {
    357     throw MakeTypeError('invalid_argument');
    358   }
    359   %DataViewSetInt8(this,
    360                    ToPositiveDataViewOffset(offset),
    361                    TO_NUMBER_INLINE(value),
    362                    !!little_endian);
    363 }
    364 
    365 function DataViewGetUint8(offset, little_endian) {
    366   if (!IS_DATAVIEW(this)) {
    367     throw MakeTypeError('incompatible_method_receiver',
    368                         ['DataView.getUint8', this]);
    369   }
    370   if (%_ArgumentsLength() < 1) {
    371     throw MakeTypeError('invalid_argument');
    372   }
    373   return %DataViewGetUint8(this,
    374                            ToPositiveDataViewOffset(offset),
    375                            !!little_endian);
    376 }
    377 
    378 function DataViewSetUint8(offset, value, little_endian) {
    379   if (!IS_DATAVIEW(this)) {
    380     throw MakeTypeError('incompatible_method_receiver',
    381                         ['DataView.setUint8', this]);
    382   }
    383   if (%_ArgumentsLength() < 2) {
    384     throw MakeTypeError('invalid_argument');
    385   }
    386   %DataViewSetUint8(this,
    387                    ToPositiveDataViewOffset(offset),
    388                    TO_NUMBER_INLINE(value),
    389                    !!little_endian);
    390 }
    391 
    392 function DataViewGetInt16(offset, little_endian) {
    393   if (!IS_DATAVIEW(this)) {
    394     throw MakeTypeError('incompatible_method_receiver',
    395                         ['DataView.getInt16', this]);
    396   }
    397   if (%_ArgumentsLength() < 1) {
    398     throw MakeTypeError('invalid_argument');
    399   }
    400   return %DataViewGetInt16(this,
    401                            ToPositiveDataViewOffset(offset),
    402                            !!little_endian);
    403 }
    404 
    405 function DataViewSetInt16(offset, value, little_endian) {
    406   if (!IS_DATAVIEW(this)) {
    407     throw MakeTypeError('incompatible_method_receiver',
    408                         ['DataView.setInt16', this]);
    409   }
    410   if (%_ArgumentsLength() < 2) {
    411     throw MakeTypeError('invalid_argument');
    412   }
    413   %DataViewSetInt16(this,
    414                     ToPositiveDataViewOffset(offset),
    415                     TO_NUMBER_INLINE(value),
    416                     !!little_endian);
    417 }
    418 
    419 function DataViewGetUint16(offset, little_endian) {
    420   if (!IS_DATAVIEW(this)) {
    421     throw MakeTypeError('incompatible_method_receiver',
    422                         ['DataView.getUint16', this]);
    423   }
    424   if (%_ArgumentsLength() < 1) {
    425     throw MakeTypeError('invalid_argument');
    426   }
    427   return %DataViewGetUint16(this,
    428                             ToPositiveDataViewOffset(offset),
    429                             !!little_endian);
    430 }
    431 
    432 function DataViewSetUint16(offset, value, little_endian) {
    433   if (!IS_DATAVIEW(this)) {
    434     throw MakeTypeError('incompatible_method_receiver',
    435                         ['DataView.setUint16', this]);
    436   }
    437   if (%_ArgumentsLength() < 2) {
    438     throw MakeTypeError('invalid_argument');
    439   }
    440   %DataViewSetUint16(this,
    441                      ToPositiveDataViewOffset(offset),
    442                      TO_NUMBER_INLINE(value),
    443                      !!little_endian);
    444 }
    445 
    446 function DataViewGetInt32(offset, little_endian) {
    447   if (!IS_DATAVIEW(this)) {
    448     throw MakeTypeError('incompatible_method_receiver',
    449                         ['DataView.getInt32', this]);
    450   }
    451   if (%_ArgumentsLength() < 1) {
    452     throw MakeTypeError('invalid_argument');
    453   }
    454   return %DataViewGetInt32(this,
    455                            ToPositiveDataViewOffset(offset),
    456                            !!little_endian);
    457 }
    458 
    459 function DataViewSetInt32(offset, value, little_endian) {
    460   if (!IS_DATAVIEW(this)) {
    461     throw MakeTypeError('incompatible_method_receiver',
    462                         ['DataView.setInt32', this]);
    463   }
    464   if (%_ArgumentsLength() < 2) {
    465     throw MakeTypeError('invalid_argument');
    466   }
    467   %DataViewSetInt32(this,
    468                     ToPositiveDataViewOffset(offset),
    469                     TO_NUMBER_INLINE(value),
    470                     !!little_endian);
    471 }
    472 
    473 function DataViewGetUint32(offset, little_endian) {
    474   if (!IS_DATAVIEW(this)) {
    475     throw MakeTypeError('incompatible_method_receiver',
    476                         ['DataView.getUint32', this]);
    477   }
    478   if (%_ArgumentsLength() < 1) {
    479     throw MakeTypeError('invalid_argument');
    480   }
    481   return %DataViewGetUint32(this,
    482                             ToPositiveDataViewOffset(offset),
    483                             !!little_endian);
    484 }
    485 
    486 function DataViewSetUint32(offset, value, little_endian) {
    487   if (!IS_DATAVIEW(this)) {
    488     throw MakeTypeError('incompatible_method_receiver',
    489                         ['DataView.setUint32', this]);
    490   }
    491   if (%_ArgumentsLength() < 2) {
    492     throw MakeTypeError('invalid_argument');
    493   }
    494   %DataViewSetUint32(this,
    495                      ToPositiveDataViewOffset(offset),
    496                      TO_NUMBER_INLINE(value),
    497                      !!little_endian);
    498 }
    499 
    500 function DataViewGetFloat32(offset, little_endian) {
    501   if (!IS_DATAVIEW(this)) {
    502     throw MakeTypeError('incompatible_method_receiver',
    503                         ['DataView.getFloat32', this]);
    504   }
    505   if (%_ArgumentsLength() < 1) {
    506     throw MakeTypeError('invalid_argument');
    507   }
    508   return %DataViewGetFloat32(this,
    509                              ToPositiveDataViewOffset(offset),
    510                              !!little_endian);
    511 }
    512 
    513 function DataViewSetFloat32(offset, value, little_endian) {
    514   if (!IS_DATAVIEW(this)) {
    515     throw MakeTypeError('incompatible_method_receiver',
    516                         ['DataView.setFloat32', this]);
    517   }
    518   if (%_ArgumentsLength() < 2) {
    519     throw MakeTypeError('invalid_argument');
    520   }
    521   %DataViewSetFloat32(this,
    522                       ToPositiveDataViewOffset(offset),
    523                       TO_NUMBER_INLINE(value),
    524                       !!little_endian);
    525 }
    526 
    527 function DataViewGetFloat64(offset, little_endian) {
    528   if (!IS_DATAVIEW(this)) {
    529     throw MakeTypeError('incompatible_method_receiver',
    530                         ['DataView.getFloat64', this]);
    531   }
    532   if (%_ArgumentsLength() < 1) {
    533     throw MakeTypeError('invalid_argument');
    534   }
    535   return %DataViewGetFloat64(this,
    536                              ToPositiveDataViewOffset(offset),
    537                              !!little_endian);
    538 }
    539 
    540 function DataViewSetFloat64(offset, value, little_endian) {
    541   if (!IS_DATAVIEW(this)) {
    542     throw MakeTypeError('incompatible_method_receiver',
    543                         ['DataView.setFloat64', this]);
    544   }
    545   if (%_ArgumentsLength() < 2) {
    546     throw MakeTypeError('invalid_argument');
    547   }
    548   %DataViewSetFloat64(this,
    549                       ToPositiveDataViewOffset(offset),
    550                       TO_NUMBER_INLINE(value),
    551                       !!little_endian);
    552 }
    553 
    554 function SetupDataView() {
    555   %CheckIsBootstrapping();
    556 
    557   // Setup the DataView constructor.
    558   %SetCode($DataView, DataViewConstructor);
    559   %FunctionSetPrototype($DataView, new $Object);
    560 
    561   // Set up constructor property on the DataView prototype.
    562   %SetProperty($DataView.prototype, "constructor", $DataView, DONT_ENUM);
    563 
    564   InstallGetter($DataView.prototype, "buffer", DataViewGetBuffer);
    565   InstallGetter($DataView.prototype, "byteOffset", DataViewGetByteOffset);
    566   InstallGetter($DataView.prototype, "byteLength", DataViewGetByteLength);
    567 
    568   InstallFunctions($DataView.prototype, DONT_ENUM, $Array(
    569       "getInt8", DataViewGetInt8,
    570       "setInt8", DataViewSetInt8,
    571 
    572       "getUint8", DataViewGetUint8,
    573       "setUint8", DataViewSetUint8,
    574 
    575       "getInt16", DataViewGetInt16,
    576       "setInt16", DataViewSetInt16,
    577 
    578       "getUint16", DataViewGetUint16,
    579       "setUint16", DataViewSetUint16,
    580 
    581       "getInt32", DataViewGetInt32,
    582       "setInt32", DataViewSetInt32,
    583 
    584       "getUint32", DataViewGetUint32,
    585       "setUint32", DataViewSetUint32,
    586 
    587       "getFloat32", DataViewGetFloat32,
    588       "setFloat32", DataViewSetFloat32,
    589 
    590       "getFloat64", DataViewGetFloat64,
    591       "setFloat64", DataViewSetFloat64
    592   ));
    593 }
    594 
    595 SetupDataView();
    596