Home | History | Annotate | Download | only in src
      1 // Copyright 2013 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 'use strict';
      6 
      7 // This file relies on the fact that the following declaration has been made
      8 // in runtime.js:
      9 // var $Array = global.Array;
     10 
     11 // -------------------------------------------------------------------
     12 
     13 // ES6 draft 07-15-13, section 15.4.3.23
     14 function ArrayFind(predicate /* thisArg */) {  // length == 1
     15   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.find");
     16 
     17   var array = ToObject(this);
     18   var length = ToInteger(array.length);
     19 
     20   if (!IS_SPEC_FUNCTION(predicate)) {
     21     throw MakeTypeError('called_non_callable', [predicate]);
     22   }
     23 
     24   var thisArg;
     25   if (%_ArgumentsLength() > 1) {
     26     thisArg = %_Arguments(1);
     27   }
     28 
     29   if (IS_NULL_OR_UNDEFINED(thisArg)) {
     30     thisArg = %GetDefaultReceiver(predicate) || thisArg;
     31   } else if (!IS_SPEC_OBJECT(thisArg) && %IsSloppyModeFunction(predicate)) {
     32     thisArg = ToObject(thisArg);
     33   }
     34 
     35   for (var i = 0; i < length; i++) {
     36     if (i in array) {
     37       var element = array[i];
     38       if (%_CallFunction(thisArg, element, i, array, predicate)) {
     39         return element;
     40       }
     41     }
     42   }
     43 
     44   return;
     45 }
     46 
     47 
     48 // ES6 draft 07-15-13, section 15.4.3.24
     49 function ArrayFindIndex(predicate /* thisArg */) {  // length == 1
     50   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.findIndex");
     51 
     52   var array = ToObject(this);
     53   var length = ToInteger(array.length);
     54 
     55   if (!IS_SPEC_FUNCTION(predicate)) {
     56     throw MakeTypeError('called_non_callable', [predicate]);
     57   }
     58 
     59   var thisArg;
     60   if (%_ArgumentsLength() > 1) {
     61     thisArg = %_Arguments(1);
     62   }
     63 
     64   if (IS_NULL_OR_UNDEFINED(thisArg)) {
     65     thisArg = %GetDefaultReceiver(predicate) || thisArg;
     66   } else if (!IS_SPEC_OBJECT(thisArg) && %IsSloppyModeFunction(predicate)) {
     67     thisArg = ToObject(thisArg);
     68   }
     69 
     70   for (var i = 0; i < length; i++) {
     71     if (i in array) {
     72       var element = array[i];
     73       if (%_CallFunction(thisArg, element, i, array, predicate)) {
     74         return i;
     75       }
     76     }
     77   }
     78 
     79   return -1;
     80 }
     81 
     82 
     83 // ES6, draft 04-05-14, section 22.1.3.6
     84 function ArrayFill(value /* [, start [, end ] ] */) {  // length == 1
     85   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.fill");
     86 
     87   var array = ToObject(this);
     88   var length = TO_UINT32(array.length);
     89 
     90   var i = 0;
     91   var end = length;
     92 
     93   if (%_ArgumentsLength() > 1) {
     94     i = %_Arguments(1);
     95     i = IS_UNDEFINED(i) ? 0 : TO_INTEGER(i);
     96     if (%_ArgumentsLength() > 2) {
     97       end = %_Arguments(2);
     98       end = IS_UNDEFINED(end) ? length : TO_INTEGER(end);
     99     }
    100   }
    101 
    102   if (i < 0) {
    103     i += length;
    104     if (i < 0) i = 0;
    105   } else {
    106     if (i > length) i = length;
    107   }
    108 
    109   if (end < 0) {
    110     end += length;
    111     if (end < 0) end = 0;
    112   } else {
    113     if (end > length) end = length;
    114   }
    115 
    116   if ((end - i) > 0 && ObjectIsFrozen(array)) {
    117     throw MakeTypeError("array_functions_on_frozen",
    118                         ["Array.prototype.fill"]);
    119   }
    120 
    121   for (; i < end; i++)
    122     array[i] = value;
    123   return array;
    124 }
    125 
    126 // ES6, draft 05-22-14, section 22.1.2.3
    127 function ArrayOf() {
    128   var length = %_ArgumentsLength();
    129   var constructor = this;
    130   // TODO: Implement IsConstructor (ES6 section 7.2.5)
    131   var array = IS_SPEC_FUNCTION(constructor) ? new constructor(length) : [];
    132   for (var i = 0; i < length; i++) {
    133     %AddElement(array, i, %_Arguments(i), NONE);
    134   }
    135   array.length = length;
    136   return array;
    137 }
    138 
    139 // -------------------------------------------------------------------
    140 
    141 function HarmonyArrayExtendArrayPrototype() {
    142   %CheckIsBootstrapping();
    143 
    144   // Set up non-enumerable functions on the Array object.
    145   InstallFunctions($Array, DONT_ENUM, $Array(
    146     "of", ArrayOf
    147   ));
    148 
    149   // Set up the non-enumerable functions on the Array prototype object.
    150   InstallFunctions($Array.prototype, DONT_ENUM, $Array(
    151     "find", ArrayFind,
    152     "findIndex", ArrayFindIndex,
    153     "fill", ArrayFill
    154   ));
    155 }
    156 
    157 HarmonyArrayExtendArrayPrototype();
    158