Home | History | Annotate | Download | only in mjsunit
      1 // Copyright 2012 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 // Flags: --allow-natives-syntax
     29 
     30 // Helper
     31 function assertInstance(o, f) {
     32   assertSame(o.constructor, f);
     33   assertInstanceof(o, f);
     34 }
     35 
     36 // This is a regression test for overlapping key and value registers.
     37 function f(a) {
     38   a[0] = 0;
     39   a[1] = 0;
     40 }
     41 
     42 var a = new Int32Array(2);
     43 for (var i = 0; i < 5; i++) {
     44   f(a);
     45 }
     46 %OptimizeFunctionOnNextCall(f);
     47 f(a);
     48 
     49 assertEquals(0, a[0]);
     50 assertEquals(0, a[1]);
     51 
     52 // Test derivation from an ArrayBuffer
     53 var ab = new ArrayBuffer(12);
     54 assertInstance(ab, ArrayBuffer);
     55 var derived_uint8 = new Uint8Array(ab);
     56 assertInstance(derived_uint8, Uint8Array);
     57 assertSame(ab, derived_uint8.buffer);
     58 assertEquals(12, derived_uint8.length);
     59 assertEquals(12, derived_uint8.byteLength);
     60 assertEquals(0, derived_uint8.byteOffset);
     61 assertEquals(1, derived_uint8.BYTES_PER_ELEMENT);
     62 var derived_uint8_2 = new Uint8Array(ab,7);
     63 assertInstance(derived_uint8_2, Uint8Array);
     64 assertSame(ab, derived_uint8_2.buffer);
     65 assertEquals(5, derived_uint8_2.length);
     66 assertEquals(5, derived_uint8_2.byteLength);
     67 assertEquals(7, derived_uint8_2.byteOffset);
     68 assertEquals(1, derived_uint8_2.BYTES_PER_ELEMENT);
     69 var derived_int16 = new Int16Array(ab);
     70 assertInstance(derived_int16, Int16Array);
     71 assertSame(ab, derived_int16.buffer);
     72 assertEquals(6, derived_int16.length);
     73 assertEquals(12, derived_int16.byteLength);
     74 assertEquals(0, derived_int16.byteOffset);
     75 assertEquals(2, derived_int16.BYTES_PER_ELEMENT);
     76 var derived_int16_2 = new Int16Array(ab,6);
     77 assertInstance(derived_int16_2, Int16Array);
     78 assertSame(ab, derived_int16_2.buffer);
     79 assertEquals(3, derived_int16_2.length);
     80 assertEquals(6, derived_int16_2.byteLength);
     81 assertEquals(6, derived_int16_2.byteOffset);
     82 assertEquals(2, derived_int16_2.BYTES_PER_ELEMENT);
     83 var derived_uint32 = new Uint32Array(ab);
     84 assertInstance(derived_uint32, Uint32Array);
     85 assertSame(ab, derived_uint32.buffer);
     86 assertEquals(3, derived_uint32.length);
     87 assertEquals(12, derived_uint32.byteLength);
     88 assertEquals(0, derived_uint32.byteOffset);
     89 assertEquals(4, derived_uint32.BYTES_PER_ELEMENT);
     90 var derived_uint32_2 = new Uint32Array(ab,4);
     91 assertInstance(derived_uint32_2, Uint32Array);
     92 assertSame(ab, derived_uint32_2.buffer);
     93 assertEquals(2, derived_uint32_2.length);
     94 assertEquals(8, derived_uint32_2.byteLength);
     95 assertEquals(4, derived_uint32_2.byteOffset);
     96 assertEquals(4, derived_uint32_2.BYTES_PER_ELEMENT);
     97 var derived_uint32_3 = new Uint32Array(ab,4,1);
     98 assertInstance(derived_uint32_3, Uint32Array);
     99 assertSame(ab, derived_uint32_3.buffer);
    100 assertEquals(1, derived_uint32_3.length);
    101 assertEquals(4, derived_uint32_3.byteLength);
    102 assertEquals(4, derived_uint32_3.byteOffset);
    103 assertEquals(4, derived_uint32_3.BYTES_PER_ELEMENT);
    104 var derived_float64 = new Float64Array(ab,0,1);
    105 assertInstance(derived_float64, Float64Array);
    106 assertSame(ab, derived_float64.buffer);
    107 assertEquals(1, derived_float64.length);
    108 assertEquals(8, derived_float64.byteLength);
    109 assertEquals(0, derived_float64.byteOffset);
    110 assertEquals(8, derived_float64.BYTES_PER_ELEMENT);
    111 
    112 // If a given byteOffset and length references an area beyond the end of the
    113 // ArrayBuffer an exception is raised.
    114 function abfunc3() {
    115   new Uint32Array(ab,4,3);
    116 }
    117 assertThrows(abfunc3);
    118 function abfunc4() {
    119   new Uint32Array(ab,16);
    120 }
    121 assertThrows(abfunc4);
    122 
    123 // The given byteOffset must be a multiple of the element size of the specific
    124 // type, otherwise an exception is raised.
    125 function abfunc5() {
    126   new Uint32Array(ab,5);
    127 }
    128 assertThrows(abfunc5);
    129 
    130 // If length is not explicitly specified, the length of the ArrayBuffer minus
    131 // the byteOffset must be a multiple of the element size of the specific type,
    132 // or an exception is raised.
    133 var ab2 = new ArrayBuffer(13);
    134 function abfunc6() {
    135   new Uint32Array(ab2,4);
    136 }
    137 assertThrows(abfunc6);
    138 
    139 // Test that an array constructed without an array buffer creates one properly.
    140 a = new Uint8Array(31);
    141 assertEquals(a.byteLength, a.buffer.byteLength);
    142 assertEquals(a.length, a.buffer.byteLength);
    143 assertEquals(a.length * a.BYTES_PER_ELEMENT, a.buffer.byteLength);
    144 a = new Int16Array(5);
    145 assertEquals(a.byteLength, a.buffer.byteLength);
    146 assertEquals(a.length * a.BYTES_PER_ELEMENT, a.buffer.byteLength);
    147 a = new Float64Array(7);
    148 assertEquals(a.byteLength, a.buffer.byteLength);
    149 assertEquals(a.length * a.BYTES_PER_ELEMENT, a.buffer.byteLength);
    150 
    151 // Test that an implicitly created buffer is a valid buffer.
    152 a = new Float64Array(7);
    153 assertSame(a.buffer, (new Uint16Array(a.buffer)).buffer);
    154 assertSame(a.buffer, (new Float32Array(a.buffer,4)).buffer);
    155 assertSame(a.buffer, (new Int8Array(a.buffer,3,51)).buffer);
    156 assertInstance(a.buffer, ArrayBuffer);
    157 
    158 // Test the correct behavior of the |BYTES_PER_ELEMENT| property
    159 a = new Int32Array(2);
    160 assertEquals(4, a.BYTES_PER_ELEMENT);
    161 a.BYTES_PER_ELEMENT = 42;
    162 a = new Uint8Array(2);
    163 assertEquals(1, a.BYTES_PER_ELEMENT);
    164 a = new Int16Array(2);
    165 assertEquals(2, a.BYTES_PER_ELEMENT);
    166 
    167 // Test Float64Arrays.
    168 function get(a, index) {
    169   return a[index];
    170 }
    171 function set(a, index, value) {
    172   a[index] = value;
    173 }
    174 function temp() {
    175 var array = new Float64Array(2);
    176 for (var i = 0; i < 5; i++) {
    177   set(array, 0, 2.5);
    178   assertEquals(2.5, array[0]);
    179 }
    180 %OptimizeFunctionOnNextCall(set);
    181 set(array, 0, 2.5);
    182 assertEquals(2.5, array[0]);
    183 set(array, 1, 3.5);
    184 assertEquals(3.5, array[1]);
    185 for (var i = 0; i < 5; i++) {
    186   assertEquals(2.5, get(array, 0));
    187   assertEquals(3.5, array[1]);
    188 }
    189 %OptimizeFunctionOnNextCall(get);
    190 assertEquals(2.5, get(array, 0));
    191 assertEquals(3.5, get(array, 1));
    192 }
    193 
    194 // Test non-number parameters.
    195 var array_with_length_from_non_number = new Int32Array("2");
    196 assertEquals(2, array_with_length_from_non_number.length);
    197 
    198 // Test loads and stores.
    199 types = [Array, Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array,
    200          Uint32Array, Uint8ClampedArray, Float32Array, Float64Array];
    201 
    202 test_result_nan = [NaN, 0, 0, 0, 0, 0, 0, 0, NaN, NaN];
    203 test_result_low_int = [-1, -1, 255, -1, 65535, -1, 0xFFFFFFFF, 0, -1, -1];
    204 test_result_low_double = [-1.25, -1, 255, -1, 65535, -1, 0xFFFFFFFF, 0, -1.25, -1.25];
    205 test_result_middle = [253.75, -3, 253, 253, 253, 253, 253, 254, 253.75, 253.75];
    206 test_result_high_int = [256, 0, 0, 256, 256, 256, 256, 255, 256, 256];
    207 test_result_high_double = [256.25, 0, 0, 256, 256, 256, 256, 255, 256.25, 256.25];
    208 
    209 const kElementCount = 40;
    210 
    211 function test_load(array, sum) {
    212   for (var i = 0; i < kElementCount; i++) {
    213     sum += array[i];
    214   }
    215   return sum;
    216 }
    217 
    218 function test_load_const_key(array, sum) {
    219   sum += array[0];
    220   sum += array[1];
    221   sum += array[2];
    222   return sum;
    223 }
    224 
    225 function test_store(array, sum) {
    226   for (var i = 0; i < kElementCount; i++) {
    227     sum += array[i] = i+1;
    228   }
    229   return sum;
    230 }
    231 
    232 function test_store_const_key(array, sum) {
    233   sum += array[0] = 1;
    234   sum += array[1] = 2;
    235   sum += array[2] = 3;
    236   return sum;
    237 }
    238 
    239 function zero() {
    240   return 0.0;
    241 }
    242 
    243 function test_store_middle_tagged(array, sum) {
    244   array[0] = 253.75;
    245   return array[0];
    246 }
    247 
    248 function test_store_high_tagged(array, sum) {
    249   array[0] = 256.25;
    250   return array[0];
    251 }
    252 
    253 function test_store_middle_double(array, sum) {
    254   array[0] = 253.75 + zero(); // + forces double type feedback
    255   return array[0];
    256 }
    257 
    258 function test_store_high_double(array, sum) {
    259   array[0] = 256.25 + zero(); // + forces double type feedback
    260   return array[0];
    261 }
    262 
    263 function test_store_high_double(array, sum) {
    264   array[0] = 256.25;
    265   return array[0];
    266 }
    267 
    268 function test_store_low_int(array, sum) {
    269   array[0] = -1;
    270   return array[0];
    271 }
    272 
    273 function test_store_low_tagged(array, sum) {
    274   array[0] = -1.25;
    275   return array[0];
    276 }
    277 
    278 function test_store_low_double(array, sum) {
    279   array[0] = -1.25 + zero(); // + forces double type feedback
    280   return array[0];
    281 }
    282 
    283 function test_store_high_int(array, sum) {
    284   array[0] = 256;
    285   return array[0];
    286 }
    287 
    288 function test_store_nan(array, sum) {
    289   array[0] = NaN;
    290   return array[0];
    291 }
    292 
    293 const kRuns = 10;
    294 
    295 function run_test(test_func, array, expected_result) {
    296   for (var i = 0; i < 5; i++) test_func(array, 0);
    297   %OptimizeFunctionOnNextCall(test_func);
    298   var sum = 0;
    299   for (var i = 0; i < kRuns; i++) {
    300     sum = test_func(array, sum);
    301   }
    302   assertEquals(expected_result, sum);
    303   %DeoptimizeFunction(test_func);
    304   %ClearFunctionTypeFeedback(test_func);
    305 }
    306 
    307 function run_bounds_test(test_func, array, expected_result) {
    308   assertEquals(undefined, a[kElementCount]);
    309   a[kElementCount] = 456;
    310   assertEquals(undefined, a[kElementCount]);
    311   assertEquals(undefined, a[kElementCount+1]);
    312   a[kElementCount+1] = 456;
    313   assertEquals(undefined, a[kElementCount+1]);
    314 }
    315 
    316 for (var t = 0; t < types.length; t++) {
    317   var type = types[t];
    318   var a = new type(kElementCount);
    319 
    320   for (var i = 0; i < kElementCount; i++) {
    321     a[i] = i;
    322   }
    323 
    324   // Run test functions defined above.
    325   run_test(test_load, a, 780 * kRuns);
    326   run_test(test_load_const_key, a, 3 * kRuns);
    327   run_test(test_store, a, 820 * kRuns);
    328   run_test(test_store_const_key, a, 6 * kRuns);
    329   run_test(test_store_low_int, a, test_result_low_int[t]);
    330   run_test(test_store_low_double, a, test_result_low_double[t]);
    331   run_test(test_store_low_tagged, a, test_result_low_double[t]);
    332   run_test(test_store_high_int, a, test_result_high_int[t]);
    333   run_test(test_store_nan, a, test_result_nan[t]);
    334   run_test(test_store_middle_double, a, test_result_middle[t]);
    335   run_test(test_store_middle_tagged, a, test_result_middle[t]);
    336   run_test(test_store_high_double, a, test_result_high_double[t]);
    337   run_test(test_store_high_tagged, a, test_result_high_double[t]);
    338 
    339   // Test the correct behavior of the |length| property (which is read-only).
    340   if (t != 0) {
    341     assertEquals(kElementCount, a.length);
    342     a.length = 2;
    343     assertEquals(kElementCount, a.length);
    344     assertTrue(delete a.length);
    345 
    346     // Make sure bounds checks are handled correctly for external arrays.
    347     run_bounds_test(a);
    348     run_bounds_test(a);
    349     run_bounds_test(a);
    350     %OptimizeFunctionOnNextCall(run_bounds_test);
    351     run_bounds_test(a);
    352     %DeoptimizeFunction(run_bounds_test);
    353     %ClearFunctionTypeFeedback(run_bounds_test);
    354   }
    355 
    356   function array_load_set_smi_check(a) {
    357     return a[0] = a[0] = 1;
    358   }
    359 
    360   array_load_set_smi_check(a);
    361   array_load_set_smi_check(0);
    362 
    363   function array_load_set_smi_check2(a) {
    364     return a[0] = a[0] = 1;
    365   }
    366 
    367   array_load_set_smi_check2(a);
    368   %OptimizeFunctionOnNextCall(array_load_set_smi_check2);
    369   array_load_set_smi_check2(a);
    370   array_load_set_smi_check2(0);
    371   %DeoptimizeFunction(array_load_set_smi_check2);
    372   %ClearFunctionTypeFeedback(array_load_set_smi_check2);
    373 }
    374 
    375 // Check handling of undefined in 32- and 64-bit external float arrays.
    376 
    377 function store_float32_undefined(ext_array) {
    378   ext_array[0] = undefined;
    379 }
    380 
    381 var float32_array = new Float32Array(1);
    382 // Make sure runtime does it right
    383 store_float32_undefined(float32_array);
    384 assertTrue(isNaN(float32_array[0]));
    385 // Make sure the ICs do it right
    386 store_float32_undefined(float32_array);
    387 assertTrue(isNaN(float32_array[0]));
    388 // Make sure that Cranskshft does it right.
    389 %OptimizeFunctionOnNextCall(store_float32_undefined);
    390 store_float32_undefined(float32_array);
    391 assertTrue(isNaN(float32_array[0]));
    392 
    393 function store_float64_undefined(ext_array) {
    394   ext_array[0] = undefined;
    395 }
    396 
    397 var float64_array = new Float64Array(1);
    398 // Make sure runtime does it right
    399 store_float64_undefined(float64_array);
    400 assertTrue(isNaN(float64_array[0]));
    401 // Make sure the ICs do it right
    402 store_float64_undefined(float64_array);
    403 assertTrue(isNaN(float64_array[0]));
    404 // Make sure that Cranskshft does it right.
    405 %OptimizeFunctionOnNextCall(store_float64_undefined);
    406 store_float64_undefined(float64_array);
    407 assertTrue(isNaN(float64_array[0]));
    408 
    409 
    410 // Check handling of 0-sized buffers and arrays.
    411 ab = new ArrayBuffer(0);
    412 assertInstance(ab, ArrayBuffer);
    413 assertEquals(0, ab.byteLength);
    414 a = new Int8Array(ab);
    415 assertInstance(a, Int8Array);
    416 assertEquals(0, a.byteLength);
    417 assertEquals(0, a.length);
    418 a[0] = 1;
    419 assertEquals(undefined, a[0]);
    420 ab = new ArrayBuffer(16);
    421 assertInstance(ab, ArrayBuffer);
    422 a = new Float32Array(ab,4,0);
    423 assertInstance(a, Float32Array);
    424 assertEquals(0, a.byteLength);
    425 assertEquals(0, a.length);
    426 a[0] = 1;
    427 assertEquals(undefined, a[0]);
    428 a = new Uint16Array(0);
    429 assertInstance(a, Uint16Array);
    430 assertEquals(0, a.byteLength);
    431 assertEquals(0, a.length);
    432 a[0] = 1;
    433 assertEquals(undefined, a[0]);
    434 
    435 // Check construction from arrays.
    436 a = new Uint32Array([]);
    437 assertInstance(a, Uint32Array);
    438 assertEquals(0, a.length);
    439 assertEquals(0, a.byteLength);
    440 assertEquals(0, a.buffer.byteLength);
    441 assertEquals(4, a.BYTES_PER_ELEMENT);
    442 assertInstance(a.buffer, ArrayBuffer);
    443 a = new Uint16Array([1,2,3]);
    444 assertInstance(a, Uint16Array);
    445 assertEquals(3, a.length);
    446 assertEquals(6, a.byteLength);
    447 assertEquals(6, a.buffer.byteLength);
    448 assertEquals(2, a.BYTES_PER_ELEMENT);
    449 assertEquals(1, a[0]);
    450 assertEquals(3, a[2]);
    451 assertInstance(a.buffer, ArrayBuffer);
    452 a = new Uint32Array(a);
    453 assertInstance(a, Uint32Array);
    454 assertEquals(3, a.length);
    455 assertEquals(12, a.byteLength);
    456 assertEquals(12, a.buffer.byteLength);
    457 assertEquals(4, a.BYTES_PER_ELEMENT);
    458 assertEquals(1, a[0]);
    459 assertEquals(3, a[2]);
    460 assertInstance(a.buffer, ArrayBuffer);
    461 
    462 // Check subarrays.
    463 a = new Uint16Array([1,2,3,4,5,6]);
    464 aa = a.subarray(3);
    465 assertInstance(aa, Uint16Array);
    466 assertEquals(3, aa.length);
    467 assertEquals(6, aa.byteLength);
    468 assertEquals(2, aa.BYTES_PER_ELEMENT);
    469 assertSame(a.buffer, aa.buffer);
    470 aa = a.subarray(3,5);
    471 assertInstance(aa, Uint16Array);
    472 assertEquals(2, aa.length);
    473 assertEquals(4, aa.byteLength);
    474 assertEquals(2, aa.BYTES_PER_ELEMENT);
    475 assertSame(a.buffer, aa.buffer);
    476 aa = a.subarray(4,8);
    477 assertInstance(aa, Uint16Array);
    478 assertEquals(2, aa.length);
    479 assertEquals(4, aa.byteLength);
    480 assertEquals(2, aa.BYTES_PER_ELEMENT);
    481 assertSame(a.buffer, aa.buffer);
    482 aa = a.subarray(9);
    483 assertInstance(aa, Uint16Array);
    484 assertEquals(0, aa.length);
    485 assertEquals(0, aa.byteLength);
    486 assertEquals(2, aa.BYTES_PER_ELEMENT);
    487 assertSame(a.buffer, aa.buffer);
    488 aa = a.subarray(-4);
    489 assertInstance(aa, Uint16Array);
    490 assertEquals(4, aa.length);
    491 assertEquals(8, aa.byteLength);
    492 assertEquals(2, aa.BYTES_PER_ELEMENT);
    493 assertSame(a.buffer, aa.buffer);
    494 aa = a.subarray(-3,-1);
    495 assertInstance(aa, Uint16Array);
    496 assertEquals(2, aa.length);
    497 assertEquals(4, aa.byteLength);
    498 assertEquals(2, aa.BYTES_PER_ELEMENT);
    499 assertSame(a.buffer, aa.buffer);
    500 aa = a.subarray(3,2);
    501 assertInstance(aa, Uint16Array);
    502 assertEquals(0, aa.length);
    503 assertEquals(0, aa.byteLength);
    504 assertEquals(2, aa.BYTES_PER_ELEMENT);
    505 assertSame(a.buffer, aa.buffer);
    506 aa = a.subarray(-3,-4);
    507 assertInstance(aa, Uint16Array);
    508 assertEquals(0, aa.length);
    509 assertEquals(0, aa.byteLength);
    510 assertEquals(2, aa.BYTES_PER_ELEMENT);
    511 assertSame(a.buffer, aa.buffer);
    512 aa = a.subarray(0,-8);
    513 assertInstance(aa, Uint16Array);
    514 assertEquals(0, aa.length);
    515 assertEquals(0, aa.byteLength);
    516 assertEquals(2, aa.BYTES_PER_ELEMENT);
    517 assertSame(a.buffer, aa.buffer);
    518 
    519 assertThrows(function(){ a.subarray.call({}, 0) });
    520 assertThrows(function(){ a.subarray.call([], 0) });
    521 
    522 // Try to call constructors directly as functions, and through .call
    523 // and .apply. Should fail.
    524 
    525 assertThrows(function() { ArrayBuffer(100); }, TypeError);
    526 assertThrows(function() { Int8Array(b, 5, 77); }, TypeError);
    527 assertThrows(function() { ArrayBuffer.call(null, 10); }, TypeError);
    528 assertThrows(function() { Uint16Array.call(null, b, 2, 4); }, TypeError);
    529 assertThrows(function() { ArrayBuffer.apply(null, [1000]); }, TypeError);
    530 assertThrows(function() { Float32Array.apply(null, [b, 128, 1]); }, TypeError);
    531 
    532 // Test array.set in different combinations.
    533 var b = new ArrayBuffer(4)
    534 
    535 function assertArrayPrefix(expected, array) {
    536   for (var i = 0; i < expected.length; ++i) {
    537     assertEquals(expected[i], array[i]);
    538   }
    539 }
    540 
    541 var a11 = new Int16Array([1, 2, 3, 4, 0, -1])
    542 var a12 = new Uint16Array(15)
    543 a12.set(a11, 3)
    544 assertArrayPrefix([0, 0, 0, 1, 2, 3, 4, 0, 0xffff, 0, 0], a12)
    545 assertThrows(function(){ a11.set(a12) })
    546 
    547 var a21 = [1, undefined, 10, NaN, 0, -1, {valueOf: function() {return 3}}]
    548 var a22 = new Int32Array(12)
    549 a22.set(a21, 2)
    550 assertArrayPrefix([0, 0, 1, 0, 10, 0, 0, -1, 3, 0], a22)
    551 
    552 var a31 = new Float32Array([2, 4, 6, 8, 11, NaN, 1/0, -3])
    553 var a32 = a31.subarray(2, 6)
    554 a31.set(a32, 4)
    555 assertArrayPrefix([2, 4, 6, 8, 6, 8, 11, NaN], a31)
    556 assertArrayPrefix([6, 8, 6, 8], a32)
    557 
    558 var a4 = new Uint8ClampedArray([3,2,5,6])
    559 a4.set(a4)
    560 assertArrayPrefix([3, 2, 5, 6], a4)
    561 
    562 // Cases with overlapping backing store but different element sizes.
    563 var b = new ArrayBuffer(4)
    564 var a5 = new Int16Array(b)
    565 var a50 = new Int8Array(b)
    566 var a51 = new Int8Array(b, 0, 2)
    567 var a52 = new Int8Array(b, 1, 2)
    568 var a53 = new Int8Array(b, 2, 2)
    569 
    570 a5.set([0x5050, 0x0a0a])
    571 assertArrayPrefix([0x50, 0x50, 0x0a, 0x0a], a50)
    572 assertArrayPrefix([0x50, 0x50], a51)
    573 assertArrayPrefix([0x50, 0x0a], a52)
    574 assertArrayPrefix([0x0a, 0x0a], a53)
    575 
    576 a50.set([0x50, 0x50, 0x0a, 0x0a])
    577 a51.set(a5)
    578 assertArrayPrefix([0x50, 0x0a, 0x0a, 0x0a], a50)
    579 
    580 a50.set([0x50, 0x50, 0x0a, 0x0a])
    581 a52.set(a5)
    582 assertArrayPrefix([0x50, 0x50, 0x0a, 0x0a], a50)
    583 
    584 a50.set([0x50, 0x50, 0x0a, 0x0a])
    585 a53.set(a5)
    586 assertArrayPrefix([0x50, 0x50, 0x50, 0x0a], a50)
    587 
    588 a50.set([0x50, 0x51, 0x0a, 0x0b])
    589 a5.set(a51)
    590 assertArrayPrefix([0x0050, 0x0051], a5)
    591 
    592 a50.set([0x50, 0x51, 0x0a, 0x0b])
    593 a5.set(a52)
    594 assertArrayPrefix([0x0051, 0x000a], a5)
    595 
    596 a50.set([0x50, 0x51, 0x0a, 0x0b])
    597 a5.set(a53)
    598 assertArrayPrefix([0x000a, 0x000b], a5)
    599 
    600 // Mixed types of same size.
    601 var a61 = new Float32Array([1.2, 12.3])
    602 var a62 = new Int32Array(2)
    603 a62.set(a61)
    604 assertArrayPrefix([1, 12], a62)
    605 a61.set(a62)
    606 assertArrayPrefix([1, 12], a61)
    607 
    608 // Invalid source
    609 assertThrows(function() { a.set(0); }, TypeError);
    610 assertArrayPrefix([1,2,3,4,5,6], a);
    611 a.set({}); // does not throw
    612 assertArrayPrefix([1,2,3,4,5,6], a);
    613 
    614 
    615 // Test arraybuffer.slice
    616 
    617 var a0 = new Int8Array([1, 2, 3, 4, 5, 6])
    618 var b0 = a0.buffer
    619 
    620 var b1 = b0.slice(0)
    621 assertEquals(b0.byteLength, b1.byteLength)
    622 assertArrayPrefix([1, 2, 3, 4, 5, 6], new Int8Array(b1))
    623 
    624 var b2 = b0.slice(3)
    625 assertEquals(b0.byteLength - 3, b2.byteLength)
    626 assertArrayPrefix([4, 5, 6], new Int8Array(b2))
    627 
    628 var b3 = b0.slice(2, 4)
    629 assertEquals(2, b3.byteLength)
    630 assertArrayPrefix([3, 4], new Int8Array(b3))
    631 
    632 function goo(a, i) {
    633   return a[i];
    634 }
    635 
    636 function boo(a, i, v) {
    637   return a[i] = v;
    638 }
    639 
    640 function do_tagged_index_external_array_test(constructor) {
    641   var t_array = new constructor([1, 2, 3, 4, 5, 6]);
    642   assertEquals(1, goo(t_array, 0));
    643   assertEquals(1, goo(t_array, 0));
    644   boo(t_array, 0, 13);
    645   assertEquals(13, goo(t_array, 0));
    646   %OptimizeFunctionOnNextCall(goo);
    647   %OptimizeFunctionOnNextCall(boo);
    648   boo(t_array, 0, 15);
    649   assertEquals(15, goo(t_array, 0));
    650   %ClearFunctionTypeFeedback(goo);
    651   %ClearFunctionTypeFeedback(boo);
    652 }
    653 
    654 do_tagged_index_external_array_test(Int8Array);
    655 do_tagged_index_external_array_test(Uint8Array);
    656 do_tagged_index_external_array_test(Int16Array);
    657 do_tagged_index_external_array_test(Uint16Array);
    658 do_tagged_index_external_array_test(Int32Array);
    659 do_tagged_index_external_array_test(Uint32Array);
    660 do_tagged_index_external_array_test(Float32Array);
    661 do_tagged_index_external_array_test(Float64Array);
    662 
    663 var built_in_array = new Array(1, 2, 3, 4, 5, 6);
    664 assertEquals(1, goo(built_in_array, 0));
    665 assertEquals(1, goo(built_in_array, 0));
    666 %OptimizeFunctionOnNextCall(goo);
    667 %OptimizeFunctionOnNextCall(boo);
    668 boo(built_in_array, 0, 11);
    669 assertEquals(11, goo(built_in_array, 0));
    670 %ClearFunctionTypeFeedback(goo);
    671 %ClearFunctionTypeFeedback(boo);
    672 
    673 built_in_array = new Array(1.5, 2, 3, 4, 5, 6);
    674 assertEquals(1.5, goo(built_in_array, 0));
    675 assertEquals(1.5, goo(built_in_array, 0));
    676 %OptimizeFunctionOnNextCall(goo);
    677 %OptimizeFunctionOnNextCall(boo);
    678 boo(built_in_array, 0, 2.5);
    679 assertEquals(2.5, goo(built_in_array, 0));
    680 %ClearFunctionTypeFeedback(goo);
    681 %ClearFunctionTypeFeedback(boo);
    682 
    683 // Check all int range edge cases
    684 function checkRange() {
    685   var e32 = Math.pow(2,32); var e31 = Math.pow(2,31);
    686   var e16 = Math.pow(2,16); var e15 = Math.pow(2,15);
    687   var e8 = Math.pow(2,8);   var e7 = Math.pow(2,7);
    688   var a7 = new Uint32Array(2);  var a71 = new Int32Array(2);
    689   var a72 = new Uint16Array(2); var a73 = new Int16Array(2);
    690   var a74 = new Uint8Array(2);  var a75 = new Int8Array(2);
    691   for (i = 1; i <= Math.pow(2,33); i *= 2) {
    692     var j = i-1;
    693     a7[0] = i; a71[0] = i; a72[0] = i; a73[0] = i; a74[0] = i; a75[0] = i;
    694     a7[1] = j; a71[1] = j; a72[1] = j; a73[1] = j; a74[1] = j; a75[1] = j;
    695 
    696     if (i < e32) { assertEquals(a7[0], i); } else { assertEquals(a7[0], 0); }
    697     if (j < e32) { assertEquals(a7[1], j); } else { assertEquals(a7[1],e32-1); }
    698     if (i < e31) { assertEquals(a71[0], i); } else {
    699       assertEquals(a71[0], (i < e32) ? -e31 : 0 ); }
    700     if (j < e31) { assertEquals(a71[1], j); } else { assertEquals(a71[1], -1); }
    701 
    702     if (i < e16) { assertEquals(a72[0], i); } else { assertEquals(a72[0], 0); }
    703     if (j < e16) { assertEquals(a72[1], j); } else { assertEquals(a72[1], e16-1); }
    704     if (i < e15) { assertEquals(a73[0], i); } else {
    705       assertEquals(a73[0], (i < e16) ? -e15 : 0 ); }
    706     if (j < e15) { assertEquals(a73[1], j); } else { assertEquals(a73[1], -1); }
    707 
    708     if (i < e8) { assertEquals(a74[0], i); } else { assertEquals(a74[0], 0); }
    709     if (j < e8) { assertEquals(a74[1], j); } else { assertEquals(a74[1], e8-1); }
    710     if (i < e7) { assertEquals(a75[0], i); } else {
    711       assertEquals(a75[0], (i < e8) ? -e7 : 0); }
    712     if (j < e7) { assertEquals(a75[1], j); } else { assertEquals(a75[1], -1); }
    713   }
    714 }
    715 checkRange();
    716