Home | History | Annotate | Download | only in es6
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Flags: --allow-natives-syntax
      6 
      7 var typedArrayConstructors = [
      8   Uint8Array,
      9   Int8Array,
     10   Uint16Array,
     11   Int16Array,
     12   Uint32Array,
     13   Int32Array,
     14   Uint8ClampedArray,
     15   Float32Array,
     16   Float64Array];
     17 
     18 function CheckTypedArrayIsNeutered(array) {
     19   assertEquals(0, array.byteLength);
     20   assertEquals(0, array.byteOffset);
     21   assertEquals(0, array.length);
     22 }
     23 
     24 function TestTypedArrayForEach(constructor) {
     25   assertEquals(1, constructor.prototype.forEach.length);
     26 
     27   var a = new constructor(2);
     28   a[0] = 0;
     29   a[1] = 1;
     30 
     31   var count = 0;
     32   a.forEach(function (n) { count++; });
     33   assertEquals(2, count);
     34 
     35   // Use specified object as this object when calling the function.
     36   var o = { value: 42 };
     37   var result = [];
     38   a.forEach(function (n, index, array) { result.push(this.value); }, o);
     39   assertArrayEquals([42, 42], result);
     40 
     41   // Modify the original array.
     42   count = 0;
     43   a.forEach(function (n, index, array) { array[index] = n + 1; count++ });
     44   assertEquals(2, count);
     45   assertArrayEquals([1, 2], a);
     46 
     47   // Check that values passed as second argument are wrapped into
     48   // objects when calling into sloppy mode functions.
     49   function CheckWrapping(value, wrapper) {
     50     var wrappedValue = new wrapper(value);
     51 
     52     a.forEach(function () {
     53       assertEquals("object", typeof this);
     54       assertEquals(wrappedValue, this);
     55     }, value);
     56 
     57     a.forEach(function () {
     58       "use strict";
     59       assertEquals(typeof value, typeof this);
     60       assertEquals(value, this);
     61     }, value);
     62   }
     63   CheckWrapping(true, Boolean);
     64   CheckWrapping(false, Boolean);
     65   CheckWrapping("xxx", String);
     66   CheckWrapping(42, Number);
     67   CheckWrapping(3.14, Number);
     68   CheckWrapping({}, Object);
     69 
     70   // Throw before completing iteration, only the first element
     71   // should be modified when thorwing mid-way.
     72   count = 0;
     73   a[0] = 42;
     74   a[1] = 42;
     75   try {
     76     a.forEach(function (n, index, array) {
     77       if (count > 0) throw "meh";
     78       array[index] = n + 1;
     79       count++;
     80     });
     81   } catch (e) {
     82   }
     83   assertEquals(1, count);
     84   assertEquals(43, a[0]);
     85   assertEquals(42, a[1]);
     86 
     87   // Neutering the buffer backing the typed array mid-way should
     88   // still make .forEach() finish, but exiting early due to the missing
     89   // elements, and the array should keep being empty after detaching it.
     90   // TODO(dehrenberg): According to the ES6 spec, accessing or testing
     91   // for members on a detached TypedArray should throw, so really this
     92   // should throw in the third iteration. However, this behavior matches
     93   // the Khronos spec.
     94   a = new constructor(3);
     95   count = 0;
     96   a.forEach(function (n, index, array) {
     97     if (count > 0) %ArrayBufferNeuter(array.buffer);
     98     array[index] = n + 1;
     99     count++;
    100   });
    101   assertEquals(2, count);
    102   CheckTypedArrayIsNeutered(a);
    103   assertEquals(undefined, a[0]);
    104 
    105   // The method must work for typed arrays created from ArrayBuffer.
    106   // The length of the ArrayBuffer is chosen so it is a multiple of
    107   // all lengths of the typed array items.
    108   a = new constructor(new ArrayBuffer(64));
    109   count = 0;
    110   a.forEach(function (n) { count++ });
    111   assertEquals(a.length, count);
    112 
    113   // Externalizing the array mid-way accessing the .buffer property
    114   // should work.
    115   a = new constructor(2);
    116   count = 0;
    117   var buffer = undefined;
    118   a.forEach(function (n, index, array) {
    119     if (count++ > 0)
    120       buffer = array.buffer;
    121   });
    122   assertEquals(2, count);
    123   assertTrue(!!buffer);
    124   assertEquals("ArrayBuffer", %_ClassOf(buffer));
    125   assertSame(buffer, a.buffer);
    126 
    127   // The %TypedArray%.forEach() method should not work when
    128   // transplanted to objects that are not typed arrays.
    129   assertThrows(function () { constructor.prototype.forEach.call([1, 2, 3], function (x) {}) }, TypeError);
    130   assertThrows(function () { constructor.prototype.forEach.call("abc", function (x) {}) }, TypeError);
    131   assertThrows(function () { constructor.prototype.forEach.call({}, function (x) {}) }, TypeError);
    132   assertThrows(function () { constructor.prototype.forEach.call(0, function (x) {}) }, TypeError);
    133 
    134   // Method must be useable on instances of other typed arrays.
    135   for (var i = 0; i < typedArrayConstructors.length; i++) {
    136     count = 0;
    137     a = new typedArrayConstructors[i](4);
    138     constructor.prototype.forEach.call(a, function (x) { count++ });
    139     assertEquals(a.length, count);
    140   }
    141 
    142   // Shadowing length doesn't affect forEach, unlike Array.prototype.forEach
    143   a = new constructor([1, 2]);
    144   Object.defineProperty(a, 'length', {value: 1});
    145   var x = 0;
    146   assertEquals(a.forEach(function(elt) { x += elt; }), undefined);
    147   assertEquals(x, 3);
    148   assertEquals(Array.prototype.forEach.call(a,
    149       function(elt) { x += elt; }), undefined);
    150   assertEquals(x, 4);
    151 }
    152 
    153 for (i = 0; i < typedArrayConstructors.length; i++) {
    154   TestTypedArrayForEach(typedArrayConstructors[i]);
    155 }
    156