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 38function 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 60function 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 86function 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 115function 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 142function 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 154ExtendStringPrototype(); 155