Home | History | Annotate | Download | only in src
      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 'use strict';
     29 
     30 // This file relies on the fact that the following declaration has been made
     31 // in runtime.js:
     32 // var $String = global.String;
     33 // var $Array = global.Array;
     34 
     35 // -------------------------------------------------------------------
     36 
     37 // ES6 draft 07-15-13, section 15.5.3.21
     38 function StringRepeat(count) {
     39   if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
     40     throw MakeTypeError("called_on_null_or_undefined",
     41                         ["String.prototype.repeat"]);
     42   }
     43 
     44   var s = TO_STRING_INLINE(this);
     45   var n = ToInteger(count);
     46   if (n < 0 || !NUMBER_IS_FINITE(n)) {
     47     throw MakeRangeError("invalid_count_value", []);
     48   }
     49 
     50   var elements = new InternalArray(n);
     51   for (var i = 0; i < n; i++) {
     52     elements[i] = s;
     53   }
     54 
     55   return %StringBuilderConcat(elements, n, "");
     56 }
     57 
     58 
     59 // ES6 draft 07-15-13, section 15.5.3.22
     60 function StringStartsWith(searchString /* position */) {  // length == 1
     61   if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
     62     throw MakeTypeError("called_on_null_or_undefined",
     63                         ["String.prototype.startsWith"]);
     64   }
     65 
     66   var s = TO_STRING_INLINE(this);
     67   var ss = TO_STRING_INLINE(searchString);
     68   var pos = 0;
     69   if (%_ArgumentsLength() > 1) {
     70     pos = %_Arguments(1);  // position
     71     pos = ToInteger(pos);
     72   }
     73 
     74   var s_len = s.length;
     75   var start = MathMin(MathMax(pos, 0), s_len);
     76   var ss_len = ss.length;
     77   if (ss_len + start > s_len) {
     78     return false;
     79   }
     80 
     81   return %StringIndexOf(s, ss, start) === start;
     82 }
     83 
     84 
     85 // ES6 draft 07-15-13, section 15.5.3.23
     86 function StringEndsWith(searchString /* position */) {  // length == 1
     87   if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
     88     throw MakeTypeError("called_on_null_or_undefined",
     89                         ["String.prototype.endsWith"]);
     90   }
     91 
     92   var s = TO_STRING_INLINE(this);
     93   var ss = TO_STRING_INLINE(searchString);
     94   var s_len = s.length;
     95   var pos = s_len;
     96   if (%_ArgumentsLength() > 1) {
     97     var arg = %_Arguments(1);  // position
     98     if (!IS_UNDEFINED(arg)) {
     99       pos = ToInteger(arg);
    100     }
    101   }
    102 
    103   var end = MathMin(MathMax(pos, 0), s_len);
    104   var ss_len = ss.length;
    105   var start = end - ss_len;
    106   if (start < 0) {
    107     return false;
    108   }
    109 
    110   return %StringLastIndexOf(s, ss, start) === start;
    111 }
    112 
    113 
    114 // ES6 draft 07-15-13, section 15.5.3.24
    115 function StringContains(searchString /* position */) {  // length == 1
    116   if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
    117     throw MakeTypeError("called_on_null_or_undefined",
    118                         ["String.prototype.contains"]);
    119   }
    120 
    121   var s = TO_STRING_INLINE(this);
    122   var ss = TO_STRING_INLINE(searchString);
    123   var pos = 0;
    124   if (%_ArgumentsLength() > 1) {
    125     pos = %_Arguments(1);  // position
    126     pos = ToInteger(pos);
    127   }
    128 
    129   var s_len = s.length;
    130   var start = MathMin(MathMax(pos, 0), s_len);
    131   var ss_len = ss.length;
    132   if (ss_len + start > s_len) {
    133     return false;
    134   }
    135 
    136   return %StringIndexOf(s, ss, start) !== -1;
    137 }
    138 
    139 
    140 // -------------------------------------------------------------------
    141 
    142 function ExtendStringPrototype() {
    143   %CheckIsBootstrapping();
    144 
    145   // Set up the non-enumerable functions on the String prototype object.
    146   InstallFunctions($String.prototype, DONT_ENUM, $Array(
    147     "repeat", StringRepeat,
    148     "startsWith", StringStartsWith,
    149     "endsWith", StringEndsWith,
    150     "contains", StringContains
    151   ));
    152 }
    153 
    154 ExtendStringPrototype();
    155