Home | History | Annotate | Download | only in harmony
      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 // These tests are adapted from Khronos DataView tests
     29 
     30 var intArray1 =
     31   [0, 1, 2, 3, 100, 101, 102, 103, 128, 129, 130, 131, 252, 253, 254, 255];
     32 var intArray2 =
     33   [31, 32, 33, 0, 1, 2, 3, 100, 101, 102, 103, 128, 129, 130, 131, 252,
     34     253, 254, 255];
     35 var initialArray =
     36   [204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
     37     204, 204, 204];
     38 
     39 var arayBuffer = null;
     40 var view = null;
     41 var viewStart = 0;
     42 var viewLength = 0;
     43 
     44 function getElementSize(func) {
     45   switch (func) {
     46     case "Int8":
     47     case "Uint8":
     48       return 1;
     49     case "Int16":
     50     case "Uint16":
     51       return 2;
     52     case "Int32":
     53     case "Uint32":
     54     case "Float32":
     55       return 4;
     56     case "Float64":
     57       return 8;
     58     default:
     59       assertUnreachable(func);
     60   }
     61 }
     62 
     63 function checkGet(func, index, expected, littleEndian) {
     64   function doGet() {
     65     if (littleEndian != undefined)
     66       return view["get" + func](index, littleEndian);
     67     else
     68       return view["get" + func](index);
     69   }
     70   if (index >=0 && index + getElementSize(func) - 1 < view.byteLength)
     71       assertSame(expected, doGet());
     72   else
     73       assertThrows(doGet, RangeError);
     74 }
     75 
     76 function checkSet(func, index, value, littleEndian) {
     77   function doSet() {
     78     if (littleEndian != undefined)
     79       view["set" + func](index, value, littleEndian);
     80     else
     81       view["set" + func](index, value);
     82   }
     83   if (index >= 0 &&
     84       index + getElementSize(func) - 1 < view.byteLength) {
     85     assertSame(undefined, doSet());
     86     checkGet(func, index, value, littleEndian);
     87   } else {
     88     assertThrows(doSet, RangeError);
     89   }
     90 }
     91 
     92 function test(isTestingGet, func, index, value, littleEndian) {
     93   if (isTestingGet)
     94     checkGet(func, index, value, littleEndian);
     95   else
     96     checkSet(func, index, value, littleEndian);
     97 }
     98 
     99 function createDataView(
    100     array, frontPaddingNum, littleEndian, start, length) {
    101   if (!littleEndian)
    102     array.reverse();
    103   var paddingArray = new Array(frontPaddingNum);
    104   arrayBuffer = (new Uint8Array(paddingArray.concat(array))).buffer;
    105   view = new DataView(arrayBuffer, viewStart, viewLength);
    106   if (!littleEndian)
    107     array.reverse(); // restore the array.
    108 }
    109 
    110 function runIntegerTestCases(isTestingGet, array, start, length) {
    111   createDataView(array, 0, true, start, length);
    112 
    113   test(isTestingGet, "Int8", 0, 0);
    114   test(isTestingGet, "Int8", undefined, 0);
    115   test(isTestingGet, "Int8", 8, -128);
    116   test(isTestingGet, "Int8", 15, -1);
    117   test(isTestingGet, "Int8", 1e12, undefined);
    118 
    119   test(isTestingGet, "Uint8", 0, 0);
    120   test(isTestingGet, "Uint8", undefined, 0);
    121   test(isTestingGet, "Uint8", 8, 128);
    122   test(isTestingGet, "Uint8", 15, 255);
    123   test(isTestingGet, "Uint8", 1e12, undefined);
    124 
    125   // Little endian.
    126   test(isTestingGet, "Int16", 0, 256, true);
    127   test(isTestingGet, "Int16", undefined, 256, true);
    128   test(isTestingGet, "Int16", 5, 26213, true);
    129   test(isTestingGet, "Int16", 9, -32127, true);
    130   test(isTestingGet, "Int16", 14, -2, true);
    131   test(isTestingGet, "Int16", 1e12, undefined, true);
    132 
    133   // Big endian.
    134   test(isTestingGet, "Int16", 0, 1);
    135   test(isTestingGet, "Int16", undefined, 1);
    136   test(isTestingGet, "Int16", 5, 25958);
    137   test(isTestingGet, "Int16", 9, -32382);
    138   test(isTestingGet, "Int16", 14, -257);
    139   test(isTestingGet, "Int16", 1e12, undefined);
    140 
    141   // Little endian.
    142   test(isTestingGet, "Uint16", 0, 256, true);
    143   test(isTestingGet, "Uint16", undefined, 256, true);
    144   test(isTestingGet, "Uint16", 5, 26213, true);
    145   test(isTestingGet, "Uint16", 9, 33409, true);
    146   test(isTestingGet, "Uint16", 14, 65534, true);
    147   test(isTestingGet, "Uint16", 1e12, undefined, true);
    148 
    149   // Big endian.
    150   test(isTestingGet, "Uint16", 0, 1);
    151   test(isTestingGet, "Uint16", undefined, 1);
    152   test(isTestingGet, "Uint16", 5, 25958);
    153   test(isTestingGet, "Uint16", 9, 33154);
    154   test(isTestingGet, "Uint16", 14, 65279);
    155   test(isTestingGet, "Uint16", 1e12, undefined);
    156 
    157   // Little endian.
    158   test(isTestingGet, "Int32", 0, 50462976, true);
    159   test(isTestingGet, "Int32", undefined, 50462976, true);
    160   test(isTestingGet, "Int32", 3, 1717920771, true);
    161   test(isTestingGet, "Int32", 6, -2122291354, true);
    162   test(isTestingGet, "Int32", 9, -58490239, true);
    163   test(isTestingGet, "Int32", 12,-66052, true);
    164   test(isTestingGet, "Int32", 1e12, undefined, true);
    165 
    166   // Big endian.
    167   test(isTestingGet, "Int32", 0, 66051);
    168   test(isTestingGet, "Int32", undefined, 66051);
    169   test(isTestingGet, "Int32", 3, 56911206);
    170   test(isTestingGet, "Int32", 6, 1718059137);
    171   test(isTestingGet, "Int32", 9, -2122152964);
    172   test(isTestingGet, "Int32", 12, -50462977);
    173   test(isTestingGet, "Int32", 1e12, undefined);
    174 
    175   // Little endian.
    176   test(isTestingGet, "Uint32", 0, 50462976, true);
    177   test(isTestingGet, "Uint32", undefined, 50462976, true);
    178   test(isTestingGet, "Uint32", 3, 1717920771, true);
    179   test(isTestingGet, "Uint32", 6, 2172675942, true);
    180   test(isTestingGet, "Uint32", 9, 4236477057, true);
    181   test(isTestingGet, "Uint32", 12,4294901244, true);
    182   test(isTestingGet, "Uint32", 1e12, undefined, true);
    183 
    184   // Big endian.
    185   test(isTestingGet, "Uint32", 0, 66051);
    186   test(isTestingGet, "Uint32", undefined, 66051);
    187   test(isTestingGet, "Uint32", 3, 56911206);
    188   test(isTestingGet, "Uint32", 6, 1718059137);
    189   test(isTestingGet, "Uint32", 9, 2172814332);
    190   test(isTestingGet, "Uint32", 12, 4244504319);
    191   test(isTestingGet, "Uint32", 1e12, undefined);
    192 }
    193 
    194 function testFloat(isTestingGet, func, array, start, expected) {
    195   // Little endian.
    196   createDataView(array, 0, true, start);
    197   test(isTestingGet, func, 0, expected, true);
    198   test(isTestingGet, func, undefined, expected, true);
    199   createDataView(array, 3, true, start);
    200   test(isTestingGet, func, 3, expected, true);
    201   createDataView(array, 7, true, start);
    202   test(isTestingGet, func, 7, expected, true);
    203   createDataView(array, 10, true, start);
    204   test(isTestingGet, func, 10, expected, true);
    205   test(isTestingGet, func, 1e12, undefined, true);
    206 
    207   // Big endian.
    208   createDataView(array, 0, false);
    209   test(isTestingGet, func, 0, expected, false);
    210   test(isTestingGet, func, undefined, expected, false);
    211   createDataView(array, 3, false);
    212   test(isTestingGet, func, 3, expected, false);
    213   createDataView(array, 7, false);
    214   test(isTestingGet, func, 7, expected, false);
    215   createDataView(array, 10, false);
    216   test(isTestingGet, func, 10, expected, false);
    217   test(isTestingGet, func, 1e12, undefined, false);
    218 }
    219 
    220 function runFloatTestCases(isTestingGet, start) {
    221   testFloat(isTestingGet, "Float32",
    222     isTestingGet ? [0, 0, 32, 65] : initialArray, start, 10);
    223 
    224   testFloat(isTestingGet, "Float32",
    225     isTestingGet ? [164, 112, 157, 63] : initialArray,
    226       start, 1.2300000190734863);
    227   testFloat(isTestingGet, "Float32",
    228     isTestingGet ? [95, 53, 50, 199] : initialArray,
    229     start, -45621.37109375);
    230   testFloat(isTestingGet, "Float32",
    231     isTestingGet ? [255, 255, 255, 127] : initialArray,
    232     start, NaN);
    233   testFloat(isTestingGet, "Float32",
    234     isTestingGet ? [255, 255, 255, 255] : initialArray,
    235     start, -NaN);
    236 
    237   testFloat(isTestingGet, "Float64",
    238     isTestingGet ? [0, 0, 0, 0, 0, 0, 36, 64] : initialArray,
    239     start, 10);
    240   testFloat(isTestingGet, "Float64",
    241     isTestingGet ? [174, 71, 225, 122, 20, 174, 243, 63] : initialArray,
    242     start, 1.23);
    243   testFloat(isTestingGet, "Float64",
    244     isTestingGet ? [181, 55, 248, 30, 242, 179, 87, 193] : initialArray,
    245     start, -6213576.4839);
    246   testFloat(isTestingGet, "Float64",
    247     isTestingGet ? [255, 255, 255, 255, 255, 255, 255, 127] : initialArray,
    248     start, NaN);
    249   testFloat(isTestingGet, "Float64",
    250     isTestingGet ? [255, 255, 255, 255, 255, 255, 255, 255] : initialArray,
    251     start, -NaN);
    252 }
    253 
    254 function runNegativeIndexTests(isTestingGet) {
    255   createDataView(intArray1, 0, true, 0, 16);
    256 
    257   test(isTestingGet, "Int8", -1, 0);
    258   test(isTestingGet, "Int8", -2, 0);
    259 
    260   test(isTestingGet, "Uint8", -1, 0);
    261   test(isTestingGet, "Uint8", -2, 0);
    262 
    263   test(isTestingGet, "Int16", -1, 1);
    264   test(isTestingGet, "Int16", -2, 1);
    265   test(isTestingGet, "Int16", -3, 1);
    266 
    267   test(isTestingGet, "Uint16", -1, 1);
    268   test(isTestingGet, "Uint16", -2, 1);
    269   test(isTestingGet, "Uint16", -3, 1);
    270 
    271   test(isTestingGet, "Int32", -1, 66051);
    272   test(isTestingGet, "Int32", -3, 66051);
    273   test(isTestingGet, "Int32", -5, 66051);
    274 
    275   test(isTestingGet, "Uint32", -1, 66051);
    276   test(isTestingGet, "Uint32", -3, 66051);
    277   test(isTestingGet, "Uint32", -5, 66051);
    278 
    279   createDataView([0, 0, 0, 0, 0, 0, 0, 0], 0, true, 0, 8);
    280 
    281   test(isTestingGet, "Float32", -1, 0);
    282   test(isTestingGet, "Float32", -3, 0);
    283   test(isTestingGet, "Float32", -5, 0);
    284 
    285   test(isTestingGet, "Float64", -1, 0);
    286   test(isTestingGet, "Float64", -5, 0);
    287   test(isTestingGet, "Float64", -9, 0);
    288 }
    289 
    290 
    291 function TestGetters() {
    292   runIntegerTestCases(true, intArray1, 0, 16);
    293   runFloatTestCases(true, 0);
    294 
    295   runIntegerTestCases(true, intArray2, 3, 2);
    296   runFloatTestCases(true, 3);
    297 
    298   runNegativeIndexTests(true);
    299 }
    300 
    301 function TestSetters() {
    302   runIntegerTestCases(false, initialArray, 0, 16);
    303   runFloatTestCases(false);
    304 
    305   runIntegerTestCases(false, initialArray, 3, 2);
    306   runFloatTestCases(false, 7);
    307 
    308   runNegativeIndexTests(false);
    309 }
    310 
    311 TestGetters();
    312 TestSetters();
    313 
    314 function CheckOutOfRangeInt8(value, expected) {
    315   var view = new DataView(new ArrayBuffer(100));
    316   assertSame(undefined, view.setInt8(0, value));
    317   assertSame(expected, view.getInt8(0));
    318   assertSame(undefined, view.setInt8(0, value, true));
    319   assertSame(expected, view.getInt8(0, true));
    320 }
    321 
    322 function CheckOutOfRangeUint8(value, expected) {
    323   var view = new DataView(new ArrayBuffer(100));
    324   assertSame(undefined, view.setUint8(0, value));
    325   assertSame(expected, view.getUint8(0));
    326   assertSame(undefined, view.setUint8(0, value, true));
    327   assertSame(expected, view.getUint8(0, true));
    328 }
    329 
    330 function CheckOutOfRangeInt16(value, expected) {
    331   var view = new DataView(new ArrayBuffer(100));
    332   assertSame(undefined, view.setInt16(0, value));
    333   assertSame(expected, view.getInt16(0));
    334   assertSame(undefined, view.setInt16(0, value, true));
    335   assertSame(expected, view.getInt16(0, true));
    336 }
    337 
    338 function CheckOutOfRangeUint16(value, expected) {
    339   var view = new DataView(new ArrayBuffer(100));
    340   assertSame(undefined, view.setUint16(0, value));
    341   assertSame(expected, view.getUint16(0));
    342   assertSame(undefined, view.setUint16(0, value, true));
    343   assertSame(expected, view.getUint16(0, true));
    344 }
    345 
    346 function CheckOutOfRangeInt32(value, expected) {
    347   var view = new DataView(new ArrayBuffer(100));
    348   assertSame(undefined, view.setInt32(0, value));
    349   assertSame(expected, view.getInt32(0));
    350   assertSame(undefined, view.setInt32(0, value, true));
    351   assertSame(expected, view.getInt32(0, true));
    352 }
    353 
    354 function CheckOutOfRangeUint32(value, expected) {
    355   var view = new DataView(new ArrayBuffer(100));
    356   assertSame(undefined, view.setUint32(0, value));
    357   assertSame(expected, view.getUint32(0));
    358   assertSame(undefined, view.setUint32(0, value, true));
    359   assertSame(expected, view.getUint32(0, true));
    360 }
    361 
    362 function TestOutOfRange() {
    363   CheckOutOfRangeInt8(0x80,   -0x80);
    364   CheckOutOfRangeInt8(0x1000, 0);
    365   CheckOutOfRangeInt8(-0x81,  0x7F);
    366 
    367   CheckOutOfRangeUint8(0x100,  0);
    368   CheckOutOfRangeUint8(0x1000, 0);
    369   CheckOutOfRangeUint8(-0x80,  0x80);
    370   CheckOutOfRangeUint8(-1,     0xFF);
    371   CheckOutOfRangeUint8(-0xFF,  1);
    372 
    373   CheckOutOfRangeInt16(0x8000,  -0x8000);
    374   CheckOutOfRangeInt16(0x10000, 0);
    375   CheckOutOfRangeInt16(-0x8001, 0x7FFF);
    376 
    377   CheckOutOfRangeUint16(0x10000,  0);
    378   CheckOutOfRangeUint16(0x100000, 0);
    379   CheckOutOfRangeUint16(-0x8000,  0x8000);
    380   CheckOutOfRangeUint16(-1,       0xFFFF);
    381   CheckOutOfRangeUint16(-0xFFFF,  1);
    382 
    383   CheckOutOfRangeInt32(0x80000000,  -0x80000000);
    384   CheckOutOfRangeInt32(0x100000000, 0);
    385   CheckOutOfRangeInt32(-0x80000001, 0x7FFFFFFF);
    386 
    387   CheckOutOfRangeUint32(0x100000000,  0);
    388   CheckOutOfRangeUint32(0x1000000000, 0);
    389   CheckOutOfRangeUint32(-0x80000000,  0x80000000);
    390   CheckOutOfRangeUint32(-1,           0xFFFFFFFF);
    391   CheckOutOfRangeUint32(-0xFFFFFFFF,  1);
    392 }
    393 
    394 TestOutOfRange();
    395 
    396 function TestGeneralAccessors() {
    397   var a = new DataView(new ArrayBuffer(256));
    398   function CheckAccessor(name) {
    399     var f = a[name];
    400     assertThrows(function() { f(); }, TypeError);
    401     f.call(a, 0, 0); // should not throw
    402     assertThrows(function() { f.call({}, 0, 0); }, TypeError);
    403     assertThrows(function() { f.call(a); }, TypeError);
    404     if (name.indexOf("set") == 0) {
    405       assertThrows(function() { f.call(a, 1); }, TypeError);
    406     } else {
    407       f.call(a, 1); // should not throw
    408     }
    409   }
    410   CheckAccessor("getUint8");
    411   CheckAccessor("setUint8");
    412   CheckAccessor("getInt8");
    413   CheckAccessor("setInt8");
    414   CheckAccessor("getUint16");
    415   CheckAccessor("setUint16");
    416   CheckAccessor("getInt16");
    417   CheckAccessor("setInt16");
    418   CheckAccessor("getUint32");
    419   CheckAccessor("setUint32");
    420   CheckAccessor("getInt32");
    421   CheckAccessor("setInt32");
    422   CheckAccessor("getFloat32");
    423   CheckAccessor("setFloat32");
    424   CheckAccessor("getFloat64");
    425   CheckAccessor("setFloat64");
    426 }
    427 
    428 TestGeneralAccessors();
    429 
    430 function TestInsufficientArguments() {
    431   var a = new DataView(new ArrayBuffer(256));
    432 
    433   assertThrows(function() { a.getUint8(); }, TypeError);
    434   assertThrows(function() { a.getInt8(); }, TypeError);
    435   assertThrows(function() { a.getUint16(); }, TypeError);
    436   assertThrows(function() { a.getInt16(); }, TypeError);
    437   assertThrows(function() { a.getUint32(); }, TypeError);
    438   assertThrows(function() { a.getInt32(); }, TypeError);
    439   assertThrows(function() { a.getFloat32(); }, TypeError);
    440   assertThrows(function() { a.getFloat64(); }, TypeError);
    441 
    442   assertThrows(function() { a.setUint8(); }, TypeError);
    443   assertThrows(function() { a.setInt8(); }, TypeError);
    444   assertThrows(function() { a.setUint16(); }, TypeError);
    445   assertThrows(function() { a.setInt16(); }, TypeError);
    446   assertThrows(function() { a.setUint32(); }, TypeError);
    447   assertThrows(function() { a.setInt32(); }, TypeError);
    448   assertThrows(function() { a.setFloat32(); }, TypeError);
    449   assertThrows(function() { a.setFloat64(); }, TypeError);
    450 
    451   assertThrows(function() { a.setUint8(1) }, TypeError);
    452   assertThrows(function() { a.setInt8(1) }, TypeError);
    453   assertThrows(function() { a.setUint16(1) }, TypeError);
    454   assertThrows(function() { a.setInt16(1) }, TypeError);
    455   assertThrows(function() { a.setUint32(1) }, TypeError);
    456   assertThrows(function() { a.setInt32(1) }, TypeError);
    457   assertThrows(function() { a.setFloat32(1) }, TypeError);
    458   assertThrows(function() { a.setFloat64(1) }, TypeError);
    459 }
    460 
    461 TestInsufficientArguments();
    462