From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- js/src/builtin/String.js | 872 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 872 insertions(+) create mode 100644 js/src/builtin/String.js (limited to 'js/src/builtin/String.js') diff --git a/js/src/builtin/String.js b/js/src/builtin/String.js new file mode 100644 index 000000000..4202d0de6 --- /dev/null +++ b/js/src/builtin/String.js @@ -0,0 +1,872 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*global intl_Collator: false, */ + +function StringProtoHasNoMatch() { + var ObjectProto = GetBuiltinPrototype("Object"); + var StringProto = GetBuiltinPrototype("String"); + if (!ObjectHasPrototype(StringProto, ObjectProto)) + return false; + return !(std_match in StringProto); +} + +function IsStringMatchOptimizable() { + var RegExpProto = GetBuiltinPrototype("RegExp"); + // If RegExpPrototypeOptimizable succeeds, `exec` and `@@match` are + // guaranteed to be data properties. + return RegExpPrototypeOptimizable(RegExpProto) && + RegExpProto.exec === RegExp_prototype_Exec && + RegExpProto[std_match] === RegExpMatch; +} + +// ES 2016 draft Mar 25, 2016 21.1.3.11. +function String_match(regexp) { + // Step 1. + RequireObjectCoercible(this); + + // Step 2. + var isPatternString = (typeof regexp === "string"); + if (!(isPatternString && StringProtoHasNoMatch()) && regexp !== undefined && regexp !== null) { + // Step 2.a. + var matcher = GetMethod(regexp, std_match); + + // Step 2.b. + if (matcher !== undefined) + return callContentFunction(matcher, regexp, this); + } + + // Step 3. + var S = ToString(this); + + if (isPatternString && IsStringMatchOptimizable()) { + var flatResult = FlatStringMatch(S, regexp); + if (flatResult !== undefined) + return flatResult; + } + + // Step 4. + var rx = RegExpCreate(regexp); + + // Step 5 (optimized case). + if (IsStringMatchOptimizable()) + return RegExpMatcher(rx, S, 0); + + // Step 5. + return callContentFunction(GetMethod(rx, std_match), rx, S); +} + +function String_generic_match(thisValue, regexp) { + if (thisValue === undefined) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.match'); + return callFunction(String_match, thisValue, regexp); +} + +/** + * A helper function implementing the logic for both String.prototype.padStart + * and String.prototype.padEnd as described in ES7 Draft March 29, 2016 + */ +function String_pad(maxLength, fillString, padEnd=false) { + + // Steps 1-2. + RequireObjectCoercible(this); + let str = ToString(this); + + // Steps 3-4. + let intMaxLength = ToLength(maxLength); + let strLen = str.length; + + // Step 5. + if (intMaxLength <= strLen) + return str; + + // Steps 6-7. + let filler = fillString === undefined ? " " : ToString(fillString); + + // Step 8. + if (filler === "") + return str; + + // Step 9. + let fillLen = intMaxLength - strLen; + + // Step 10. + let truncatedStringFiller = callFunction(String_repeat, filler, + fillLen / filler.length); + + truncatedStringFiller += callFunction(String_substr, filler, 0, + fillLen % filler.length); + + // Step 11. + if (padEnd === true) + return str + truncatedStringFiller; + return truncatedStringFiller + str; +} + +function String_pad_start(maxLength, fillString=" ") { + return callFunction(String_pad, this, maxLength, fillString, false); +} + +function String_pad_end(maxLength, fillString=" ") { + return callFunction(String_pad, this, maxLength, fillString, true); +} + +function StringProtoHasNoReplace() { + var ObjectProto = GetBuiltinPrototype("Object"); + var StringProto = GetBuiltinPrototype("String"); + if (!ObjectHasPrototype(StringProto, ObjectProto)) + return false; + return !(std_replace in StringProto); +} + +// A thin wrapper to call SubstringKernel with int32-typed arguments. +// Caller should check the range of |from| and |length|. +function Substring(str, from, length) { + assert(typeof str === "string", "|str| should be a string"); + assert(from | 0 === from, "coercing |from| into int32 should not change the value"); + assert(length | 0 === length, "coercing |length| into int32 should not change the value"); + + return SubstringKernel(str, from | 0, length | 0); +} + +// ES 2016 draft Mar 25, 2016 21.1.3.14. +function String_replace(searchValue, replaceValue) { + // Step 1. + RequireObjectCoercible(this); + + // Step 2. + if (!(typeof searchValue === "string" && StringProtoHasNoReplace()) && + searchValue !== undefined && searchValue !== null) + { + // Step 2.a. + var replacer = GetMethod(searchValue, std_replace); + + // Step 2.b. + if (replacer !== undefined) + return callContentFunction(replacer, searchValue, this, replaceValue); + } + + // Step 3. + var string = ToString(this); + + // Step 4. + var searchString = ToString(searchValue); + + if (typeof replaceValue === "string") { + // Steps 6-12: Optimized for string case. + return StringReplaceString(string, searchString, replaceValue); + } + + // Step 5. + if (!IsCallable(replaceValue)) { + // Steps 6-12. + return StringReplaceString(string, searchString, ToString(replaceValue)); + } + + // Step 7. + var pos = callFunction(std_String_indexOf, string, searchString); + if (pos === -1) + return string; + + // Step 8. + var replStr = ToString(callContentFunction(replaceValue, undefined, searchString, pos, string)); + + // Step 10. + var tailPos = pos + searchString.length; + + // Step 11. + var newString; + if (pos === 0) + newString = ""; + else + newString = Substring(string, 0, pos); + + newString += replStr; + var stringLength = string.length; + if (tailPos < stringLength) + newString += Substring(string, tailPos, stringLength - tailPos); + + // Step 12. + return newString; +} + +function String_generic_replace(thisValue, searchValue, replaceValue) { + if (thisValue === undefined) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.replace'); + return callFunction(String_replace, thisValue, searchValue, replaceValue); +} + +function StringProtoHasNoSearch() { + var ObjectProto = GetBuiltinPrototype("Object"); + var StringProto = GetBuiltinPrototype("String"); + if (!ObjectHasPrototype(StringProto, ObjectProto)) + return false; + return !(std_search in StringProto); +} + +function IsStringSearchOptimizable() { + var RegExpProto = GetBuiltinPrototype("RegExp"); + // If RegExpPrototypeOptimizable succeeds, `exec` and `@@search` are + // guaranteed to be data properties. + return RegExpPrototypeOptimizable(RegExpProto) && + RegExpProto.exec === RegExp_prototype_Exec && + RegExpProto[std_search] === RegExpSearch; +} + +// ES 2016 draft Mar 25, 2016 21.1.3.15. +function String_search(regexp) { + // Step 1. + RequireObjectCoercible(this); + + // Step 2. + var isPatternString = (typeof regexp === "string"); + if (!(isPatternString && StringProtoHasNoSearch()) && regexp !== undefined && regexp !== null) { + // Step 2.a. + var searcher = GetMethod(regexp, std_search); + + // Step 2.b. + if (searcher !== undefined) + return callContentFunction(searcher, regexp, this); + } + + // Step 3. + var string = ToString(this); + + if (isPatternString && IsStringSearchOptimizable()) { + var flatResult = FlatStringSearch(string, regexp); + if (flatResult !== -2) + return flatResult; + } + + // Step 4. + var rx = RegExpCreate(regexp); + + // Step 5. + return callContentFunction(GetMethod(rx, std_search), rx, string); +} + +function String_generic_search(thisValue, regexp) { + if (thisValue === undefined) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.search'); + return callFunction(String_search, thisValue, regexp); +} + +function StringProtoHasNoSplit() { + var ObjectProto = GetBuiltinPrototype("Object"); + var StringProto = GetBuiltinPrototype("String"); + if (!ObjectHasPrototype(StringProto, ObjectProto)) + return false; + return !(std_split in StringProto); +} + +// ES 2016 draft Mar 25, 2016 21.1.3.17. +function String_split(separator, limit) { + // Step 1. + RequireObjectCoercible(this); + + // Optimized path for string.split(string), especially when both strings + // are constants. Following sequence of if's cannot be put together in + // order that IonMonkey sees the constant if present (bug 1246141). + if (typeof this === "string") { + if (StringProtoHasNoSplit()) { + if (typeof separator === "string") { + if (limit === undefined) { + // inlineConstantStringSplitString needs both arguments to + // be MConstant, so pass them directly. + return StringSplitString(this, separator); + } + } + } + } + + // Step 2. + if (!(typeof separator == "string" && StringProtoHasNoSplit()) && + separator !== undefined && separator !== null) + { + // Step 2.a. + var splitter = GetMethod(separator, std_split); + + // Step 2.b. + if (splitter !== undefined) + return callContentFunction(splitter, separator, this, limit); + } + + // Step 3. + var S = ToString(this); + + // Step 6. + var R; + if (limit !== undefined) { + var lim = limit >>> 0; + + // Step 9. + R = ToString(separator); + + // Step 10. + if (lim === 0) + return []; + + // Step 11. + if (separator === undefined) + return [S]; + + // Steps 4, 8, 12-18. + return StringSplitStringLimit(S, R, lim); + } + + // Step 9. + R = ToString(separator); + + // Step 11. + if (separator === undefined) + return [S]; + + // Optimized path. + // Steps 4, 8, 12-18. + return StringSplitString(S, R); +} + +function String_generic_split(thisValue, separator, limit) { + if (thisValue === undefined) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.split'); + return callFunction(String_split, thisValue, separator, limit); +} + +/* ES6 Draft Oct 14, 2014 21.1.3.19 */ +function String_substring(start, end) { + // Steps 1-3. + RequireObjectCoercible(this); + var str = ToString(this); + + // Step 4. + var len = str.length; + + // Step 5. + var intStart = ToInteger(start); + + // Step 6. + var intEnd = (end === undefined) ? len : ToInteger(end); + + // Step 7. + var finalStart = std_Math_min(std_Math_max(intStart, 0), len); + + // Step 8. + var finalEnd = std_Math_min(std_Math_max(intEnd, 0), len); + + // Steps 9-10. + var from, to; + if (finalStart < finalEnd) { + from = finalStart; + to = finalEnd; + } else { + from = finalEnd; + to = finalStart; + } + + // Step 11. + // While |from| and |to - from| are bounded to the length of |str| and this + // and thus definitely in the int32 range, they can still be typed as + // double. Eagerly truncate since SubstringKernel only accepts int32. + return SubstringKernel(str, from | 0, (to - from) | 0); +} + +function String_static_substring(string, start, end) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.substring'); + return callFunction(String_substring, string, start, end); +} + +/* ES6 Draft Oct 14, 2014 B.2.3.1 */ +function String_substr(start, length) { + // Steps 1-2. + RequireObjectCoercible(this); + var str = ToString(this); + + // Steps 3-4. + var intStart = ToInteger(start); + + // Steps 5-7. + var size = str.length; + // Use |size| instead of +Infinity to avoid performing calculations with + // doubles. (The result is the same either way.) + var end = (length === undefined) ? size : ToInteger(length); + + // Step 8. + if (intStart < 0) + intStart = std_Math_max(intStart + size, 0); + + // Step 9. + var resultLength = std_Math_min(std_Math_max(end, 0), size - intStart); + + // Step 10. + if (resultLength <= 0) + return ""; + + // Step 11. + // While |intStart| and |resultLength| are bounded to the length of |str| + // and thus definitely in the int32 range, they can still be typed as + // double. Eagerly truncate since SubstringKernel only accepts int32. + return SubstringKernel(str, intStart | 0, resultLength | 0); +} + +function String_static_substr(string, start, length) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.substr'); + return callFunction(String_substr, string, start, length); +} + +/* ES6 Draft Oct 14, 2014 21.1.3.16 */ +function String_slice(start, end) { + // Steps 1-3. + RequireObjectCoercible(this); + var str = ToString(this); + + // Step 4. + var len = str.length; + + // Step 5. + var intStart = ToInteger(start); + + // Step 6. + var intEnd = (end === undefined) ? len : ToInteger(end); + + // Step 7. + var from = (intStart < 0) ? std_Math_max(len + intStart, 0) : std_Math_min(intStart, len); + + // Step 8. + var to = (intEnd < 0) ? std_Math_max(len + intEnd, 0) : std_Math_min(intEnd, len); + + // Step 9. + var span = std_Math_max(to - from, 0); + + // Step 10. + // While |from| and |span| are bounded to the length of |str| + // and thus definitely in the int32 range, they can still be typed as + // double. Eagerly truncate since SubstringKernel only accepts int32. + return SubstringKernel(str, from | 0, span | 0); +} + +function String_static_slice(string, start, end) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.slice'); + return callFunction(String_slice, string, start, end); +} + +/* ES6 Draft September 5, 2013 21.1.3.3 */ +function String_codePointAt(pos) { + // Steps 1-3. + RequireObjectCoercible(this); + var S = ToString(this); + + // Steps 4-5. + var position = ToInteger(pos); + + // Step 6. + var size = S.length; + + // Step 7. + if (position < 0 || position >= size) + return undefined; + + // Steps 8-9. + var first = callFunction(std_String_charCodeAt, S, position); + if (first < 0xD800 || first > 0xDBFF || position + 1 === size) + return first; + + // Steps 10-11. + var second = callFunction(std_String_charCodeAt, S, position + 1); + if (second < 0xDC00 || second > 0xDFFF) + return first; + + // Step 12. + return (first - 0xD800) * 0x400 + (second - 0xDC00) + 0x10000; +} + +var collatorCache = new Record(); + +/* ES6 20121122 draft 15.5.4.21. */ +function String_repeat(count) { + // Steps 1-3. + RequireObjectCoercible(this); + var S = ToString(this); + + // Steps 4-5. + var n = ToInteger(count); + + // Steps 6-7. + if (n < 0) + ThrowRangeError(JSMSG_NEGATIVE_REPETITION_COUNT); + + if (!(n * S.length < (1 << 28))) + ThrowRangeError(JSMSG_RESULTING_STRING_TOO_LARGE); + + // Communicate |n|'s possible range to the compiler. + n = n & ((1 << 28) - 1); + + // Steps 8-9. + var T = ""; + for (;;) { + if (n & 1) + T += S; + n >>= 1; + if (n) + S += S; + else + break; + } + return T; +} + +// ES6 draft specification, section 21.1.3.27, version 2013-09-27. +function String_iterator() { + RequireObjectCoercible(this); + var S = ToString(this); + var iterator = NewStringIterator(); + UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_TARGET, S); + UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_NEXT_INDEX, 0); + return iterator; +} + +function StringIteratorNext() { + if (!IsObject(this) || !IsStringIterator(this)) { + return callFunction(CallStringIteratorMethodIfWrapped, this, + "StringIteratorNext"); + } + + var S = UnsafeGetStringFromReservedSlot(this, ITERATOR_SLOT_TARGET); + // We know that JSString::MAX_LENGTH <= INT32_MAX (and assert this in + // SelfHostring.cpp) so our current index can never be anything other than + // an Int32Value. + var index = UnsafeGetInt32FromReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX); + var size = S.length; + var result = { value: undefined, done: false }; + + if (index >= size) { + result.done = true; + return result; + } + + var charCount = 1; + var first = callFunction(std_String_charCodeAt, S, index); + if (first >= 0xD800 && first <= 0xDBFF && index + 1 < size) { + var second = callFunction(std_String_charCodeAt, S, index + 1); + if (second >= 0xDC00 && second <= 0xDFFF) { + charCount = 2; + } + } + + UnsafeSetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX, index + charCount); + result.value = callFunction(String_substring, S, index, index + charCount); + + return result; +} + +/** + * Compare this String against that String, using the locale and collation + * options provided. + * + * Spec: ECMAScript Internationalization API Specification, 13.1.1. + */ +function String_localeCompare(that) { + // Steps 1-3. + RequireObjectCoercible(this); + var S = ToString(this); + var That = ToString(that); + + // Steps 4-5. + var locales = arguments.length > 1 ? arguments[1] : undefined; + var options = arguments.length > 2 ? arguments[2] : undefined; + + // Step 6. + var collator; + if (locales === undefined && options === undefined) { + // This cache only optimizes for the old ES5 localeCompare without + // locales and options. + if (collatorCache.collator === undefined) + collatorCache.collator = intl_Collator(locales, options); + collator = collatorCache.collator; + } else { + collator = intl_Collator(locales, options); + } + + // Step 7. + return intl_CompareStrings(collator, S, That); +} + +/* ES6 Draft May 22, 2014 21.1.2.4 */ +function String_static_raw(callSite, ...substitutions) { + // Step 1 (implicit). + // Step 2. + var numberOfSubstitutions = substitutions.length; + + // Steps 3-4. + var cooked = ToObject(callSite); + + // Steps 5-7. + var raw = ToObject(cooked.raw); + + // Steps 8-10. + var literalSegments = ToLength(raw.length); + + // Step 11. + if (literalSegments <= 0) + return ""; + + // Step 12. + var resultString = ""; + + // Step 13. + var nextIndex = 0; + + // Step 14. + while (true) { + // Steps a-d. + var nextSeg = ToString(raw[nextIndex]); + + // Step e. + resultString = resultString + nextSeg; + + // Step f. + if (nextIndex + 1 === literalSegments) + // Step f.i. + return resultString; + + // Steps g-j. + var nextSub; + if (nextIndex < numberOfSubstitutions) + nextSub = ToString(substitutions[nextIndex]); + else + nextSub = ""; + + // Step k. + resultString = resultString + nextSub; + + // Step l. + nextIndex++; + } +} + +/** + * Compare String str1 against String str2, using the locale and collation + * options provided. + * + * Mozilla proprietary. + * Spec: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String#String_generic_methods + */ +function String_static_localeCompare(str1, str2) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "String.localeCompare"); + var locales = arguments.length > 2 ? arguments[2] : undefined; + var options = arguments.length > 3 ? arguments[3] : undefined; +#if EXPOSE_INTL_API + return callFunction(String_localeCompare, str1, str2, locales, options); +#else + return callFunction(std_String_localeCompare, str1, str2, locales, options); +#endif +} + +// ES6 draft 2014-04-27 B.2.3.3 +function String_big() { + RequireObjectCoercible(this); + return "" + ToString(this) + ""; +} + +// ES6 draft 2014-04-27 B.2.3.4 +function String_blink() { + RequireObjectCoercible(this); + return "" + ToString(this) + ""; +} + +// ES6 draft 2014-04-27 B.2.3.5 +function String_bold() { + RequireObjectCoercible(this); + return "" + ToString(this) + ""; +} + +// ES6 draft 2014-04-27 B.2.3.6 +function String_fixed() { + RequireObjectCoercible(this); + return "" + ToString(this) + ""; +} + +// ES6 draft 2014-04-27 B.2.3.9 +function String_italics() { + RequireObjectCoercible(this); + return "" + ToString(this) + ""; +} + +// ES6 draft 2014-04-27 B.2.3.11 +function String_small() { + RequireObjectCoercible(this); + return "" + ToString(this) + ""; +} + +// ES6 draft 2014-04-27 B.2.3.12 +function String_strike() { + RequireObjectCoercible(this); + return "" + ToString(this) + ""; +} + +// ES6 draft 2014-04-27 B.2.3.13 +function String_sub() { + RequireObjectCoercible(this); + return "" + ToString(this) + ""; +} + +// ES6 draft 2014-04-27 B.2.3.14 +function String_sup() { + RequireObjectCoercible(this); + return "" + ToString(this) + ""; +} + +function EscapeAttributeValue(v) { + var inputStr = ToString(v); + var inputLen = inputStr.length; + var outputStr = ""; + var chunkStart = 0; + for (var i = 0; i < inputLen; i++) { + if (inputStr[i] === '"') { + outputStr += callFunction(String_substring, inputStr, chunkStart, i) + '"'; + chunkStart = i + 1; + } + } + if (chunkStart === 0) + return inputStr; + if (chunkStart < inputLen) + outputStr += callFunction(String_substring, inputStr, chunkStart); + return outputStr; +} + +// ES6 draft 2014-04-27 B.2.3.2 +function String_anchor(name) { + RequireObjectCoercible(this); + var S = ToString(this); + return '' + S + ""; +} + +// ES6 draft 2014-04-27 B.2.3.7 +function String_fontcolor(color) { + RequireObjectCoercible(this); + var S = ToString(this); + return '' + S + ""; +} + +// ES6 draft 2014-04-27 B.2.3.8 +function String_fontsize(size) { + RequireObjectCoercible(this); + var S = ToString(this); + return '' + S + ""; +} + +// ES6 draft 2014-04-27 B.2.3.10 +function String_link(url) { + RequireObjectCoercible(this); + var S = ToString(this); + return '' + S + ""; +} + +function String_static_toLowerCase(string) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.toLowerCase'); + return callFunction(std_String_toLowerCase, string); +} + +function String_static_toUpperCase(string) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.toUpperCase'); + return callFunction(std_String_toUpperCase, string); +} + +function String_static_charAt(string, pos) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.charAt'); + return callFunction(std_String_charAt, string, pos); +} + +function String_static_charCodeAt(string, pos) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.charCodeAt'); + return callFunction(std_String_charCodeAt, string, pos); +} + +function String_static_includes(string, searchString) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.includes'); + var position = arguments.length > 2 ? arguments[2] : undefined; + return callFunction(std_String_includes, string, searchString, position); +} + +function String_static_indexOf(string, searchString) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.indexOf'); + var position = arguments.length > 2 ? arguments[2] : undefined; + return callFunction(std_String_indexOf, string, searchString, position); +} + +function String_static_lastIndexOf(string, searchString) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.lastIndexOf'); + var position = arguments.length > 2 ? arguments[2] : undefined; + return callFunction(std_String_lastIndexOf, string, searchString, position); +} + +function String_static_startsWith(string, searchString) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.startsWith'); + var position = arguments.length > 2 ? arguments[2] : undefined; + return callFunction(std_String_startsWith, string, searchString, position); +} + +function String_static_endsWith(string, searchString) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.endsWith'); + var endPosition = arguments.length > 2 ? arguments[2] : undefined; + return callFunction(std_String_endsWith, string, searchString, endPosition); +} + +function String_static_trim(string) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.trim'); + return callFunction(std_String_trim, string); +} + +function String_static_trimLeft(string) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.trimLeft'); + return callFunction(std_String_trimLeft, string); +} + +function String_static_trimRight(string) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.trimRight'); + return callFunction(std_String_trimRight, string); +} + +function String_static_toLocaleLowerCase(string) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.toLocaleLowerCase'); + return callFunction(std_String_toLocaleLowerCase, string); +} + +function String_static_toLocaleUpperCase(string) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.toLocaleUpperCase'); + return callFunction(std_String_toLocaleUpperCase, string); +} + +#if EXPOSE_INTL_API +function String_static_normalize(string) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.normalize'); + var form = arguments.length > 1 ? arguments[1] : undefined; + return callFunction(std_String_normalize, string, form); +} +#endif + +function String_static_concat(string, arg1) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.concat'); + var args = callFunction(std_Array_slice, arguments, 1); + return callFunction(std_Function_apply, std_String_concat, string, args); +} -- cgit v1.2.3