1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/builtin/String.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,202 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/*global intl_Collator: false, */ 1.9 + 1.10 +/* ES6 Draft September 5, 2013 21.1.3.3 */ 1.11 +function String_codePointAt(pos) { 1.12 + // Steps 1-3. 1.13 + CheckObjectCoercible(this); 1.14 + var S = ToString(this); 1.15 + 1.16 + // Steps 4-5. 1.17 + var position = ToInteger(pos); 1.18 + 1.19 + // Step 6. 1.20 + var size = S.length; 1.21 + 1.22 + // Step 7. 1.23 + if (position < 0 || position >= size) 1.24 + return undefined; 1.25 + 1.26 + // Steps 8-9. 1.27 + var first = callFunction(std_String_charCodeAt, S, position); 1.28 + if (first < 0xD800 || first > 0xDBFF || position + 1 === size) 1.29 + return first; 1.30 + 1.31 + // Steps 10-11. 1.32 + var second = callFunction(std_String_charCodeAt, S, position + 1); 1.33 + if (second < 0xDC00 || second > 0xDFFF) 1.34 + return first; 1.35 + 1.36 + // Step 12. 1.37 + return (first - 0xD800) * 0x400 + (second - 0xDC00) + 0x10000; 1.38 +} 1.39 + 1.40 +var collatorCache = new Record(); 1.41 + 1.42 +/* ES6 20121122 draft 15.5.4.21. */ 1.43 +function String_repeat(count) { 1.44 + // Steps 1-3. 1.45 + CheckObjectCoercible(this); 1.46 + var S = ToString(this); 1.47 + 1.48 + // Steps 4-5. 1.49 + var n = ToInteger(count); 1.50 + 1.51 + // Steps 6-7. 1.52 + if (n < 0) 1.53 + ThrowError(JSMSG_NEGATIVE_REPETITION_COUNT); // a RangeError 1.54 + 1.55 + if (!(n * S.length < (1 << 28))) 1.56 + ThrowError(JSMSG_RESULTING_STRING_TOO_LARGE); // a RangeError 1.57 + 1.58 + // Communicate |n|'s possible range to the compiler. 1.59 + n = n & ((1 << 28) - 1); 1.60 + 1.61 + // Steps 8-9. 1.62 + var T = ""; 1.63 + for (;;) { 1.64 + if (n & 1) 1.65 + T += S; 1.66 + n >>= 1; 1.67 + if (n) 1.68 + S += S; 1.69 + else 1.70 + break; 1.71 + } 1.72 + return T; 1.73 +} 1.74 + 1.75 +#define STRING_ITERATOR_SLOT_ITERATED_OBJECT 0 1.76 +#define STRING_ITERATOR_SLOT_NEXT_INDEX 1 1.77 + 1.78 +// ES6 draft specification, section 21.1.3.27, version 2013-09-27. 1.79 +function String_iterator() { 1.80 + CheckObjectCoercible(this); 1.81 + var S = ToString(this); 1.82 + var iterator = NewStringIterator(); 1.83 + UnsafeSetReservedSlot(iterator, STRING_ITERATOR_SLOT_ITERATED_OBJECT, S); 1.84 + UnsafeSetReservedSlot(iterator, STRING_ITERATOR_SLOT_NEXT_INDEX, 0); 1.85 + return iterator; 1.86 +} 1.87 + 1.88 +function StringIteratorIdentity() { 1.89 + return this; 1.90 +} 1.91 + 1.92 +function StringIteratorNext() { 1.93 + // FIXME: Cross-compartment wrapper StringIterator objects should pass this test. Bug 924059. 1.94 + if (!IsObject(this) || !IsStringIterator(this)) 1.95 + ThrowError(JSMSG_INCOMPATIBLE_METHOD, "StringIterator", "next", ToString(this)); 1.96 + 1.97 + var S = UnsafeGetReservedSlot(this, STRING_ITERATOR_SLOT_ITERATED_OBJECT); 1.98 + var index = UnsafeGetReservedSlot(this, STRING_ITERATOR_SLOT_NEXT_INDEX); 1.99 + var size = S.length; 1.100 + 1.101 + if (index >= size) { 1.102 + return { value: undefined, done: true }; 1.103 + } 1.104 + 1.105 + var charCount = 1; 1.106 + var first = callFunction(std_String_charCodeAt, S, index); 1.107 + if (first >= 0xD800 && first <= 0xDBFF && index + 1 < size) { 1.108 + var second = callFunction(std_String_charCodeAt, S, index + 1); 1.109 + if (second >= 0xDC00 && second <= 0xDFFF) { 1.110 + charCount = 2; 1.111 + } 1.112 + } 1.113 + 1.114 + UnsafeSetReservedSlot(this, STRING_ITERATOR_SLOT_NEXT_INDEX, index + charCount); 1.115 + var value = callFunction(std_String_substring, S, index, index + charCount); 1.116 + 1.117 + return { value: value, done: false }; 1.118 +} 1.119 + 1.120 +/** 1.121 + * Compare this String against that String, using the locale and collation 1.122 + * options provided. 1.123 + * 1.124 + * Spec: ECMAScript Internationalization API Specification, 13.1.1. 1.125 + */ 1.126 +function String_localeCompare(that) { 1.127 + // Steps 1-3. 1.128 + CheckObjectCoercible(this); 1.129 + var S = ToString(this); 1.130 + var That = ToString(that); 1.131 + 1.132 + // Steps 4-5. 1.133 + var locales = arguments.length > 1 ? arguments[1] : undefined; 1.134 + var options = arguments.length > 2 ? arguments[2] : undefined; 1.135 + 1.136 + // Step 6. 1.137 + var collator; 1.138 + if (locales === undefined && options === undefined) { 1.139 + // This cache only optimizes for the old ES5 localeCompare without 1.140 + // locales and options. 1.141 + if (collatorCache.collator === undefined) 1.142 + collatorCache.collator = intl_Collator(locales, options); 1.143 + collator = collatorCache.collator; 1.144 + } else { 1.145 + collator = intl_Collator(locales, options); 1.146 + } 1.147 + 1.148 + // Step 7. 1.149 + return intl_CompareStrings(collator, S, That); 1.150 +} 1.151 + 1.152 +/* ES6 Draft September 5, 2013 21.1.2.2 */ 1.153 +function String_static_fromCodePoint() { 1.154 + // Step 1. is not relevant 1.155 + // Step 2. 1.156 + var length = arguments.length; 1.157 + 1.158 + // Step 3. 1.159 + var elements = new List(); 1.160 + 1.161 + // Step 4-5., 5g. 1.162 + for (var nextIndex = 0; nextIndex < length; nextIndex++) { 1.163 + // Step 5a. 1.164 + var next = arguments[nextIndex]; 1.165 + // Step 5b-c. 1.166 + var nextCP = ToNumber(next); 1.167 + 1.168 + // Step 5d. 1.169 + if (nextCP !== ToInteger(nextCP) || std_isNaN(nextCP)) 1.170 + ThrowError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP)); 1.171 + 1.172 + // Step 5e. 1.173 + if (nextCP < 0 || nextCP > 0x10FFFF) 1.174 + ThrowError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP)); 1.175 + 1.176 + // Step 5f. 1.177 + // Inlined UTF-16 Encoding 1.178 + if (nextCP <= 0xFFFF) { 1.179 + elements.push(nextCP); 1.180 + continue; 1.181 + } 1.182 + 1.183 + elements.push((((nextCP - 0x10000) / 0x400) | 0) + 0xD800); 1.184 + elements.push((nextCP - 0x10000) % 0x400 + 0xDC00); 1.185 + } 1.186 + 1.187 + // Step 6. 1.188 + return callFunction(std_Function_apply, std_String_fromCharCode, null, elements); 1.189 +} 1.190 + 1.191 +/** 1.192 + * Compare String str1 against String str2, using the locale and collation 1.193 + * options provided. 1.194 + * 1.195 + * Mozilla proprietary. 1.196 + * Spec: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String#String_generic_methods 1.197 + */ 1.198 +function String_static_localeCompare(str1, str2) { 1.199 + if (arguments.length < 1) 1.200 + ThrowError(JSMSG_MISSING_FUN_ARG, 0, "String.localeCompare"); 1.201 + var locales = arguments.length > 2 ? arguments[2] : undefined; 1.202 + var options = arguments.length > 3 ? arguments[3] : undefined; 1.203 + return callFunction(String_localeCompare, str1, str2, locales, options); 1.204 +} 1.205 +