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 30var intArray1 = 31 [0, 1, 2, 3, 100, 101, 102, 103, 128, 129, 130, 131, 252, 253, 254, 255]; 32var intArray2 = 33 [31, 32, 33, 0, 1, 2, 3, 100, 101, 102, 103, 128, 129, 130, 131, 252, 34 253, 254, 255]; 35var initialArray = 36 [204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 37 204, 204, 204]; 38 39var arayBuffer = null; 40var view = null; 41var viewStart = 0; 42var viewLength = 0; 43 44function 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 63function 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 76function 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 92function 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 99function 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 110function 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 194function 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 220function 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 254function 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 291function 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 301function 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 311TestGetters(); 312TestSetters(); 313 314function 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 322function 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 330function 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 338function 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 346function 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 354function 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 362function 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 394TestOutOfRange(); 395 396function 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 428TestGeneralAccessors(); 429 430function 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 461TestInsufficientArguments(); 462