13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This file relies on the fact that the following declaration has been made 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// in runtime.js: 313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// var $String = global.String; 323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// var $NaN = 0/0; 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set the String function and constructor. 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%SetCode($String, function(x) { 37402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var value = %_ArgumentsLength() == 0 ? '' : TO_STRING_INLINE(x); 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%_IsConstructCall()) { 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block %_SetValueOf(this, value); 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return value; 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}); 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%FunctionSetPrototype($String, new $String()); 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.5.4.2 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringToString() { 493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IS_STRING(this) && !IS_STRING_WRAPPER(this)) { 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw new $TypeError('String.prototype.toString is not generic'); 513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %_ValueOf(this); 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.5.4.3 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringValueOf() { 583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IS_STRING(this) && !IS_STRING_WRAPPER(this)) { 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw new $TypeError('String.prototype.valueOf is not generic'); 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %_ValueOf(this); 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 15.5.4.4 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringCharAt(pos) { 67257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 68257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 69257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.charAt"]); 70257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch var result = %_StringCharAt(this, pos); 727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (%_IsSmi(result)) { 737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch result = %_StringCharAt(TO_STRING_INLINE(this), TO_INTEGER(pos)); 747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return result; 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.5.4.5 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringCharCodeAt(pos) { 81257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 82257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 83257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.charCodeAt"]); 84257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch var result = %_StringCharCodeAt(this, pos); 867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (!%_IsSmi(result)) { 877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch result = %_StringCharCodeAt(TO_STRING_INLINE(this), TO_INTEGER(pos)); 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return result; 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 15.5.4.6 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringConcat() { 95257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch throw MakeTypeError("called_on_null_or_undefined", 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ["String.prototype.concat"]); 98257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 99402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var len = %_ArgumentsLength(); 100402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var this_as_string = TO_STRING_INLINE(this); 101402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (len === 1) { 102402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return this_as_string + %_Arguments(0); 103e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 104e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch var parts = new InternalArray(len + 1); 105402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu parts[0] = this_as_string; 106402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu for (var i = 0; i < len; i++) { 107402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var part = %_Arguments(i); 108402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu parts[i + 1] = TO_STRING_INLINE(part); 109402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 110402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return %StringBuilderConcat(parts, len + 1, ""); 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Match ES3 and Safari 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%FunctionSetLength(StringConcat, 1); 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.5.4.7 118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochfunction StringIndexOf(pattern /* position */) { // length == 1 119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.indexOf"]); 122257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var subject = TO_STRING_INLINE(this); 1241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block pattern = TO_STRING_INLINE(pattern); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var index = 0; 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%_ArgumentsLength() > 1) { 1271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block index = %_Arguments(1); // position 1281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block index = TO_INTEGER(index); 1291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (index < 0) index = 0; 1301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (index > subject.length) index = subject.length; 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return %StringIndexOf(subject, pattern, index); 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.5.4.8 137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochfunction StringLastIndexOf(pat /* position */) { // length == 1 138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 139257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.lastIndexOf"]); 141257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 142402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var sub = TO_STRING_INLINE(this); 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var subLength = sub.length; 144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var pat = TO_STRING_INLINE(pat); 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var patLength = pat.length; 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var index = subLength - patLength; 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%_ArgumentsLength() > 1) { 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var position = ToNumber(%_Arguments(1)); 1499fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block if (!NUMBER_IS_NAN(position)) { 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block position = TO_INTEGER(position); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (position < 0) { 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block position = 0; 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (position + patLength < subLength) { 15569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch index = position; 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (index < 0) { 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return -1; 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %StringLastIndexOf(sub, pat, index); 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.5.4.9 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This function is implementation specific. For now, we do not 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// do anything locale specific. 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringLocaleCompare(other) { 171257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 172257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 173257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.localeCompare"]); 174257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%_ArgumentsLength() === 0) return 0; 17669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return %StringLocaleCompare(TO_STRING_INLINE(this), 177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TO_STRING_INLINE(other)); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.5.4.10 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringMatch(regexp) { 183257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 184257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 185257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.match"]); 186257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 187402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var subject = TO_STRING_INLINE(this); 1886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (IS_REGEXP(regexp)) { 189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0); 1906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]); 1916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // lastMatchInfo is defined in regexp.js. 1923e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu return %StringMatch(subject, regexp, lastMatchInfo); 1936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Non-regexp argument. 1956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block regexp = new $RegExp(regexp); 1966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return RegExpExecNoTests(regexp, subject, 0); 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SubString is an internal function that returns the sub string of 'string'. 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If resulting string is of length 1, we use the one character cache 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// otherwise we call the runtime system. 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SubString(string, start, end) { 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Use the one character string cache. 205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (start + 1 == end) return %_StringCharAt(string, start); 206e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return %_SubString(string, start, end); 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This has the same size as the lastMatchInfo array, and can be used for 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// functions that expect that structure to be returned. It is used when the 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// needle is a string rather than a regexp. In this case we can't update 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// lastMatchArray without erroneously affecting the properties on the global 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// RegExp object. 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar reusableMatchInfo = [2, "", "", -1, -1]; 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 15.5.4.11 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringReplace(search, replace) { 220257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 221257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 222257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.replace"]); 223257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 224402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var subject = TO_STRING_INLINE(this); 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Delegate to one of the regular expression variants if necessary. 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_REGEXP(search)) { 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]); 229589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (IS_SPEC_FUNCTION(replace)) { 23025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (search.global) { 23125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen return StringReplaceGlobalRegExpWithFunction(subject, search, replace); 23225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } else { 23325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen return StringReplaceNonGlobalRegExpWithFunction(subject, 23425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen search, 23525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen replace); 23625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return %StringReplaceRegExpWithString(subject, 239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch search, 240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TO_STRING_INLINE(replace), 241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch lastMatchInfo); 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Convert the search argument to a string and search for it. 246402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu search = TO_STRING_INLINE(search); 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (search.length == 1 && 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch subject.length > 0xFF && 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IS_STRING(replace) && 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch %StringIndexOf(replace, '$', 0) < 0) { 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Searching by traversing a cons string tree and replace with cons of 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // slices works only when the replaced string is a single character, being 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // replaced by a simple string and only pays off for long strings. 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return %StringReplaceOneCharWithString(subject, search, replace); 2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var start = %StringIndexOf(subject, search, 0); 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start < 0) return subject; 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var end = start + search.length; 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var builder = new ReplaceResultBuilder(subject); 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prefix 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder.addSpecialSlice(0, start); 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the string to replace with. 265589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (IS_SPEC_FUNCTION(replace)) { 26669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch var receiver = %GetDefaultReceiver(replace); 2673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch builder.add(%_CallFunction(receiver, 268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch search, 269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch start, 270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch subject, 271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch replace)); 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reusableMatchInfo[CAPTURE0] = start; 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reusableMatchInfo[CAPTURE1] = end; 275402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu replace = TO_STRING_INLINE(replace); 276e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ExpandReplacement(replace, subject, reusableMatchInfo, builder); 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // suffix 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder.addSpecialSlice(end, subject.length); 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return builder.generate(); 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Expand the $-expressions in the string and return a new string with 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the result. 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ExpandReplacement(string, subject, matchInfo, builder) { 289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var length = string.length; 290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var builder_elements = builder.elements; 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var next = %StringIndexOf(string, '$', 0); 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (next < 0) { 293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (length > 0) builder_elements.push(string); 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the number of captures; see ECMA-262, 15.5.4.11, p. 102. 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var m = NUMBER_OF_CAPTURES(matchInfo) >> 1; // Includes the match. 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (next > 0) builder_elements.push(SubString(string, 0, next)); 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var expansion = '$'; 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var position = next + 1; 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (position < length) { 3067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch var peek = %_StringCharCodeAt(string, position); 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (peek == 36) { // $$ 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ++position; 309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch builder_elements.push('$'); 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (peek == 38) { // $& - match 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ++position; 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder.addSpecialSlice(matchInfo[CAPTURE0], 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block matchInfo[CAPTURE1]); 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (peek == 96) { // $` - prefix 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ++position; 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder.addSpecialSlice(0, matchInfo[CAPTURE0]); 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (peek == 39) { // $' - suffix 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ++position; 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder.addSpecialSlice(matchInfo[CAPTURE1], subject.length); 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (peek >= 48 && peek <= 57) { // $n, 0 <= n <= 9 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ++position; 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var n = peek - 48; 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (position < length) { 3247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch peek = %_StringCharCodeAt(string, position); 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // $nn, 01 <= nn <= 99 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (n != 0 && peek == 48 || peek >= 49 && peek <= 57) { 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var nn = n * 10 + (peek - 48); 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (nn < m) { 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the two digit capture reference is within range of 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the captures, we use it instead of the single digit 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // one. Otherwise, we fall back to using the single 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // digit reference. This matches the behavior of 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // SpiderMonkey. 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ++position; 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block n = nn; 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (0 < n && n < m) { 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block addCaptureString(builder, matchInfo, n); 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Because of the captures range check in the parsing of two 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // digit capture references, we can only enter here when a 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // single digit capture reference is outside the range of 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // captures. 346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch builder_elements.push('$'); 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block --position; 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch builder_elements.push('$'); 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch builder_elements.push('$'); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Go the the next $ in the string. 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next = %StringIndexOf(string, '$', position); 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return if there are no more $ characters in the string. If we 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // haven't reached the end, we need to append the suffix. 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (next < 0) { 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (position < length) { 363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch builder_elements.push(SubString(string, position, length)); 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Append substring between the previous and the next $ character. 369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (next > position) { 370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch builder_elements.push(SubString(string, position, next)); 371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compute the string of a given regular expression capture. 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CaptureString(string, lastCaptureInfo, index) { 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scale the index. 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var scaled = index << 1; 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute start and end. 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var start = lastCaptureInfo[CAPTURE(scaled)]; 38225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // If start isn't valid, return undefined. 38325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (start < 0) return; 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var end = lastCaptureInfo[CAPTURE(scaled + 1)]; 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return SubString(string, start, end); 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Add the string of a given regular expression capture to the 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ReplaceResultBuilder 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction addCaptureString(builder, matchInfo, index) { 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scale the index. 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var scaled = index << 1; 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute start and end. 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var start = matchInfo[CAPTURE(scaled)]; 39625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (start < 0) return; 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var end = matchInfo[CAPTURE(scaled + 1)]; 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block builder.addSpecialSlice(start, end); 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// TODO(lrn): This array will survive indefinitely if replace is never 4026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// called again. However, it will be empty, since the contents are cleared 4036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// in the finally block. 404e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvar reusableReplaceArray = new InternalArray(16); 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function for replacing regular expressions with the result of a 4076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// function application in String.prototype.replace. 40825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenfunction StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) { 40925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var resultArray = reusableReplaceArray; 41025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (resultArray) { 41125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen reusableReplaceArray = null; 41225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } else { 41325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // Inside a nested replace (replace called from the replacement function 41425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // of another replace) or we have failed to set the reusable array 41525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // back due to an exception in a replacement function. Create a new 41625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // array to use in the future, or until the original is written back. 417e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch resultArray = new InternalArray(16); 41825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } 41925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var res = %RegExpExecMultiple(regexp, 42025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen subject, 42125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen lastMatchInfo, 42225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen resultArray); 42325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen regexp.lastIndex = 0; 42425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (IS_NULL(res)) { 42525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // No matches at all. 42625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen reusableReplaceArray = resultArray; 42725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen return subject; 42825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } 42925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var len = res.length; 43025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var i = 0; 43125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (NUMBER_OF_CAPTURES(lastMatchInfo) == 2) { 43225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var match_start = 0; 433e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch var override = new InternalArray(null, 0, subject); 43469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch var receiver = %GetDefaultReceiver(replace); 43525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen while (i < len) { 43625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var elem = res[i]; 43725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (%_IsSmi(elem)) { 43825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (elem > 0) { 43925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen match_start = (elem >> 11) + (elem & 0x7ff); 4406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 44125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen match_start = res[++i] - elem; 44225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } 44325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } else { 44425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen override[0] = elem; 44525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen override[1] = match_start; 44625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen lastMatchInfoOverride = override; 44725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var func_result = 44825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen %_CallFunction(receiver, elem, match_start, subject, replace); 4491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block res[i] = TO_STRING_INLINE(func_result); 45025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen match_start += elem.length; 451d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 45225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen i++; 45325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } 45425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } else { 455589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch var receiver = %GetDefaultReceiver(replace); 45625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen while (i < len) { 45725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var elem = res[i]; 45825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (!%_IsSmi(elem)) { 45925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // elem must be an Array. 46025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // Use the apply argument as backing for global RegExp properties. 46125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen lastMatchInfoOverride = elem; 462589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch var func_result = %Apply(replace, receiver, elem, 0, elem.length); 4631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block res[i] = TO_STRING_INLINE(func_result); 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 46525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen i++; 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 46825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var resultBuilder = new ReplaceResultBuilder(subject, res); 46925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var result = resultBuilder.generate(); 47025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen resultArray.length = 0; 47125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen reusableReplaceArray = resultArray; 47225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen return result; 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenfunction StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { 47725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var matchInfo = DoRegExpExec(regexp, subject, 0); 47825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (IS_NULL(matchInfo)) return subject; 47925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var result = new ReplaceResultBuilder(subject); 48025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var index = matchInfo[CAPTURE0]; 48125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen result.addSpecialSlice(0, index); 48225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var endOfMatch = matchInfo[CAPTURE1]; 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the parameter list consisting of the match, captures, index, 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and subject for the replace function invocation. 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The number of captures plus one for the match. 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var m = NUMBER_OF_CAPTURES(matchInfo) >> 1; 48725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var replacement; 488589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch var receiver = %GetDefaultReceiver(replace); 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (m == 1) { 49025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // No captures, only the match, which is always valid. 49125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen var s = SubString(subject, index, endOfMatch); 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't call directly to avoid exposing the built-in global object. 49325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen replacement = 4943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch %_CallFunction(receiver, s, index, subject, replace); 49525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } else { 496e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch var parameters = new InternalArray(m + 2); 49725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen for (var j = 0; j < m; j++) { 49825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen parameters[j] = CaptureString(subject, matchInfo, j); 49925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } 50025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen parameters[j] = index; 50125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen parameters[j + 1] = subject; 50225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 503589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch replacement = %Apply(replace, receiver, parameters, 0, j + 2); 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 50525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 50625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen result.add(replacement); // The add method converts to string if necessary. 50725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // Can't use matchInfo any more from here, since the function could 50825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // overwrite it. 50925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen result.addSpecialSlice(endOfMatch, subject.length); 51025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen return result.generate(); 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.5.4.12 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringSearch(re) { 516257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 518257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.search"]); 519257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 5206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block var regexp; 5216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (IS_STRING(re)) { 5226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block regexp = %_GetFromCache(STRING_TO_REGEXP_CACHE_ID, re); 5236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else if (IS_REGEXP(re)) { 5246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block regexp = re; 5256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 5266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block regexp = new $RegExp(re); 5276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var match = DoRegExpExec(regexp, TO_STRING_INLINE(this), 0); 5296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (match) { 5306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return match[CAPTURE0]; 5316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 5326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return -1; 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.5.4.13 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringSlice(start, end) { 538257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 539257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 540257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.slice"]); 541257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 542402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var s = TO_STRING_INLINE(this); 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var s_len = s.length; 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var start_i = TO_INTEGER(start); 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var end_i = s_len; 5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (end !== void 0) { 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block end_i = TO_INTEGER(end); 5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start_i < 0) { 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_i += s_len; 5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (start_i < 0) { 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_i = 0; 5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (start_i > s_len) { 5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ''; 5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (end_i < 0) { 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block end_i += s_len; 5633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (end_i < 0) { 5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ''; 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (end_i > s_len) { 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block end_i = s_len; 5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (end_i <= start_i) { 5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ''; 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return SubString(s, start_i, end_i); 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.5.4.14 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringSplit(separator, limit) { 582257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.split"]); 585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 586402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var subject = TO_STRING_INLINE(this); 587e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke limit = (IS_UNDEFINED(limit)) ? 0xffffffff : TO_UINT32(limit); 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262 says that if separator is undefined, the result should 5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // be an array of size 1 containing the entire string. 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (IS_UNDEFINED(separator)) { 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return [subject]; 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var length = subject.length; 596402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (!IS_REGEXP(separator)) { 597402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu separator = TO_STRING_INLINE(separator); 5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (limit === 0) return []; 6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 601402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var separator_length = separator.length; 602402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the separator string is empty then return the elements in the subject. 6048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (separator_length === 0) return %StringToArray(subject, limit); 605402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 6066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block var result = %StringSplit(subject, separator, limit); 607402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 608402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return result; 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (limit === 0) return []; 6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Separator is a regular expression. 6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return StringSplitOnRegExp(subject, separator, limit, length); 6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction StringSplitOnRegExp(subject, separator, limit, length) { 619402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]); 620402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (length === 0) { 6223e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (DoRegExpExec(separator, subject, 0, 0) != null) { 6236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return []; 6246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return [subject]; 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var currentIndex = 0; 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var startIndex = 0; 630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var startMatch = 0; 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var result = []; 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block outer_loop: 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (startIndex === length) { 637b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.push(SubString(subject, currentIndex, length)); 6386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block break; 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 641b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var matchInfo = DoRegExpExec(separator, subject, startIndex); 642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (matchInfo == null || length === (startMatch = matchInfo[CAPTURE0])) { 643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.push(SubString(subject, currentIndex, length)); 6446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block break; 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var endIndex = matchInfo[CAPTURE1]; 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We ignore a zero-length match at the currentIndex. 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (startIndex === endIndex && endIndex === currentIndex) { 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block startIndex++; 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 654b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (currentIndex + 1 == startMatch) { 655b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.push(%_StringCharAt(subject, currentIndex)); 656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.push(%_SubString(subject, currentIndex, startMatch)); 658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 659b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (result.length === limit) break; 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var matchinfo_len = NUMBER_OF_CAPTURES(matchInfo) + REGEXP_FIRST_CAPTURE; 663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (var i = REGEXP_FIRST_CAPTURE + 2; i < matchinfo_len; ) { 664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var start = matchInfo[i++]; 665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var end = matchInfo[i++]; 666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (end != -1) { 667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (start + 1 == end) { 668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.push(%_StringCharAt(subject, start)); 669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.push(%_SubString(subject, start, end)); 671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.push(void 0); 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (result.length === limit) break outer_loop; 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block startIndex = currentIndex = endIndex; 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return result; 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.5.4.15 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringSubstring(start, end) { 686257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 687257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 688257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.subString"]); 689257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 690402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var s = TO_STRING_INLINE(this); 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var s_len = s.length; 692e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var start_i = TO_INTEGER(start); 694e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (start_i < 0) { 695e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke start_i = 0; 696e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else if (start_i > s_len) { 697e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke start_i = s_len; 698e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 699e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var end_i = s_len; 701e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (!IS_UNDEFINED(end)) { 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block end_i = TO_INTEGER(end); 703e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (end_i > s_len) { 704e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke end_i = s_len; 705e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else { 706e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (end_i < 0) end_i = 0; 707e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (start_i > end_i) { 708e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var tmp = end_i; 709e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke end_i = start_i; 710e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke start_i = tmp; 711e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 712e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ((start_i + 1 == end_i) 716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ? %_StringCharAt(s, start_i) 717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : %_SubString(s, start_i, end_i)); 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This is not a part of ECMA-262. 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringSubstr(start, n) { 723257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 725257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.substr"]); 726257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 727402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var s = TO_STRING_INLINE(this); 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var len; 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Correct n: If not given, set to string length; if explicitly 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // set to undefined, zero, or negative, returns empty string. 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (n === void 0) { 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block len = s.length; 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block len = TO_INTEGER(n); 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (len <= 0) return ''; 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Correct start: If not given (or undefined), set to zero; otherwise 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // convert to integer and handle negative case. 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start === void 0) { 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start = 0; 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start = TO_INTEGER(start); 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If positive, and greater than or equal to the string length, 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // return empty string. 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start >= s.length) return ''; 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If negative and absolute value is larger than the string length, 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // use zero. 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start < 0) { 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start += s.length; 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (start < 0) start = 0; 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var end = start + len; 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (end > s.length) end = s.length; 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ((start + 1 == end) 760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ? %_StringCharAt(s, start) 761b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : %_SubString(s, start, end)); 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, 15.5.4.16 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringToLowerCase() { 767257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 768257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 769257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.toLowerCase"]); 770257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 771402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return %StringToLowerCase(TO_STRING_INLINE(this)); 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, 15.5.4.17 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringToLocaleLowerCase() { 777257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 778257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 779257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.toLocaleLowerCase"]); 780257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 781402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return %StringToLowerCase(TO_STRING_INLINE(this)); 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, 15.5.4.18 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringToUpperCase() { 787257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 788257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 789257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.toUpperCase"]); 790257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 791402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return %StringToUpperCase(TO_STRING_INLINE(this)); 792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, 15.5.4.19 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringToLocaleUpperCase() { 797257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 798257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 799257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.toLocaleUpperCase"]); 800257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 801402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return %StringToUpperCase(TO_STRING_INLINE(this)); 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// ES5, 15.5.4.20 8053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockfunction StringTrim() { 806257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 807257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 808257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.trim"]); 809257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 810402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return %StringTrim(TO_STRING_INLINE(this), true, true); 8113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 8123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockfunction StringTrimLeft() { 814257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 815257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 816257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.trimLeft"]); 817257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 818402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return %StringTrim(TO_STRING_INLINE(this), true, false); 8193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 8203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockfunction StringTrimRight() { 822257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { 823257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch throw MakeTypeError("called_on_null_or_undefined", 824257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ["String.prototype.trimRight"]); 825257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 826402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return %StringTrim(TO_STRING_INLINE(this), false, true); 8273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 829e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvar static_charcode_array = new InternalArray(4); 8306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 15.5.3.2 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringFromCharCode(code) { 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var n = %_ArgumentsLength(); 8346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (n == 1) { 8356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!%_IsSmi(code)) code = ToNumber(code); 8367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return %_StringCharFromCode(code & 0xffff); 8376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // NOTE: This is not super-efficient, but it is necessary because we 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // want to avoid converting to numbers from within the virtual 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // machine. Maybe we can find another way of doing this? 8426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block var codes = static_charcode_array; 8436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block for (var i = 0; i < n; i++) { 8446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block var code = %_Arguments(i); 8456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!%_IsSmi(code)) code = ToNumber(code); 8466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block codes[i] = code; 8476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 8486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block codes.length = n; 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %StringFromCharCodeArray(codes); 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function for very basic XSS protection. 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction HtmlEscape(str) { 855402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return TO_STRING_INLINE(str).replace(/</g, "<") 856402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu .replace(/>/g, ">") 857402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu .replace(/"/g, """) 858402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu .replace(/'/g, "'"); 8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compatibility support for KJS. 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tested by mozilla/js/tests/js1_5/Regress/regress-276103.js. 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringLink(s) { 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<a href=\"" + HtmlEscape(s) + "\">" + this + "</a>"; 866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringAnchor(name) { 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<a name=\"" + HtmlEscape(name) + "\">" + this + "</a>"; 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringFontcolor(color) { 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<font color=\"" + HtmlEscape(color) + "\">" + this + "</font>"; 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringFontsize(size) { 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<font size=\"" + HtmlEscape(size) + "\">" + this + "</font>"; 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringBig() { 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<big>" + this + "</big>"; 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringBlink() { 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<blink>" + this + "</blink>"; 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringBold() { 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<b>" + this + "</b>"; 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringFixed() { 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<tt>" + this + "</tt>"; 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringItalics() { 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<i>" + this + "</i>"; 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringSmall() { 910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<small>" + this + "</small>"; 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringStrike() { 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<strike>" + this + "</strike>"; 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringSub() { 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<sub>" + this + "</sub>"; 921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction StringSup() { 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "<sup>" + this + "</sup>"; 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 929e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// ReplaceResultBuilder support. 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ReplaceResultBuilder(str) { 9316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (%_ArgumentsLength() > 1) { 9326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block this.elements = %_Arguments(1); 9336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 934e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch this.elements = new InternalArray(); 9356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block this.special_string = str; 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 939589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpLockedPrototype(ReplaceResultBuilder, 940589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch $Array("elements", "special_string"), $Array( 941589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch "add", function(str) { 942589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch str = TO_STRING_INLINE(str); 943589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (str.length > 0) this.elements.push(str); 944589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch }, 945589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch "addSpecialSlice", function(start, end) { 946589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch var len = end - start; 947589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (start < 0 || len <= 0) return; 948589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (start < 0x80000 && len < 0x800) { 949589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch this.elements.push((start << 11) | len); 950589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else { 951589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // 0 < len <= String::kMaxLength and Smi::kMaxValue >= String::kMaxLength, 952589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // so -len is a smi. 953589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch var elements = this.elements; 954589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch elements.push(-len); 955589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch elements.push(start); 956589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 957589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch }, 958589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch "generate", function() { 959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var elements = this.elements; 960589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return %StringBuilderConcat(elements, elements.length, this.special_string); 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 962589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch)); 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------- 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 967589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SetUpString() { 968589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch %CheckIsBootstrapping(); 969589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set up the constructor property on the String prototype object. 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block %SetProperty($String.prototype, "constructor", $String, DONT_ENUM); 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 973589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set up the non-enumerable functions on the String object. 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InstallFunctions($String, DONT_ENUM, $Array( 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "fromCharCode", StringFromCharCode 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block )); 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 979589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set up the non-enumerable functions on the String prototype object. 9803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstallFunctions($String.prototype, DONT_ENUM, $Array( 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "valueOf", StringValueOf, 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "toString", StringToString, 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "charAt", StringCharAt, 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "charCodeAt", StringCharCodeAt, 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "concat", StringConcat, 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "indexOf", StringIndexOf, 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "lastIndexOf", StringLastIndexOf, 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "localeCompare", StringLocaleCompare, 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "match", StringMatch, 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "replace", StringReplace, 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "search", StringSearch, 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "slice", StringSlice, 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "split", StringSplit, 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "substring", StringSubstring, 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "substr", StringSubstr, 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "toLowerCase", StringToLowerCase, 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "toLocaleLowerCase", StringToLocaleLowerCase, 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "toUpperCase", StringToUpperCase, 999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "toLocaleUpperCase", StringToLocaleUpperCase, 10003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block "trim", StringTrim, 10013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block "trimLeft", StringTrimLeft, 10023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block "trimRight", StringTrimRight, 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "link", StringLink, 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "anchor", StringAnchor, 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "fontcolor", StringFontcolor, 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "fontsize", StringFontsize, 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "big", StringBig, 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "blink", StringBlink, 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "bold", StringBold, 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "fixed", StringFixed, 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "italics", StringItalics, 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "small", StringSmall, 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "strike", StringStrike, 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "sub", StringSub, 1015b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "sup", StringSup 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block )); 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1019589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpString(); 1020