js/src/builtin/String.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 /*global intl_Collator: false, */
michael@0 6
michael@0 7 /* ES6 Draft September 5, 2013 21.1.3.3 */
michael@0 8 function String_codePointAt(pos) {
michael@0 9 // Steps 1-3.
michael@0 10 CheckObjectCoercible(this);
michael@0 11 var S = ToString(this);
michael@0 12
michael@0 13 // Steps 4-5.
michael@0 14 var position = ToInteger(pos);
michael@0 15
michael@0 16 // Step 6.
michael@0 17 var size = S.length;
michael@0 18
michael@0 19 // Step 7.
michael@0 20 if (position < 0 || position >= size)
michael@0 21 return undefined;
michael@0 22
michael@0 23 // Steps 8-9.
michael@0 24 var first = callFunction(std_String_charCodeAt, S, position);
michael@0 25 if (first < 0xD800 || first > 0xDBFF || position + 1 === size)
michael@0 26 return first;
michael@0 27
michael@0 28 // Steps 10-11.
michael@0 29 var second = callFunction(std_String_charCodeAt, S, position + 1);
michael@0 30 if (second < 0xDC00 || second > 0xDFFF)
michael@0 31 return first;
michael@0 32
michael@0 33 // Step 12.
michael@0 34 return (first - 0xD800) * 0x400 + (second - 0xDC00) + 0x10000;
michael@0 35 }
michael@0 36
michael@0 37 var collatorCache = new Record();
michael@0 38
michael@0 39 /* ES6 20121122 draft 15.5.4.21. */
michael@0 40 function String_repeat(count) {
michael@0 41 // Steps 1-3.
michael@0 42 CheckObjectCoercible(this);
michael@0 43 var S = ToString(this);
michael@0 44
michael@0 45 // Steps 4-5.
michael@0 46 var n = ToInteger(count);
michael@0 47
michael@0 48 // Steps 6-7.
michael@0 49 if (n < 0)
michael@0 50 ThrowError(JSMSG_NEGATIVE_REPETITION_COUNT); // a RangeError
michael@0 51
michael@0 52 if (!(n * S.length < (1 << 28)))
michael@0 53 ThrowError(JSMSG_RESULTING_STRING_TOO_LARGE); // a RangeError
michael@0 54
michael@0 55 // Communicate |n|'s possible range to the compiler.
michael@0 56 n = n & ((1 << 28) - 1);
michael@0 57
michael@0 58 // Steps 8-9.
michael@0 59 var T = "";
michael@0 60 for (;;) {
michael@0 61 if (n & 1)
michael@0 62 T += S;
michael@0 63 n >>= 1;
michael@0 64 if (n)
michael@0 65 S += S;
michael@0 66 else
michael@0 67 break;
michael@0 68 }
michael@0 69 return T;
michael@0 70 }
michael@0 71
michael@0 72 #define STRING_ITERATOR_SLOT_ITERATED_OBJECT 0
michael@0 73 #define STRING_ITERATOR_SLOT_NEXT_INDEX 1
michael@0 74
michael@0 75 // ES6 draft specification, section 21.1.3.27, version 2013-09-27.
michael@0 76 function String_iterator() {
michael@0 77 CheckObjectCoercible(this);
michael@0 78 var S = ToString(this);
michael@0 79 var iterator = NewStringIterator();
michael@0 80 UnsafeSetReservedSlot(iterator, STRING_ITERATOR_SLOT_ITERATED_OBJECT, S);
michael@0 81 UnsafeSetReservedSlot(iterator, STRING_ITERATOR_SLOT_NEXT_INDEX, 0);
michael@0 82 return iterator;
michael@0 83 }
michael@0 84
michael@0 85 function StringIteratorIdentity() {
michael@0 86 return this;
michael@0 87 }
michael@0 88
michael@0 89 function StringIteratorNext() {
michael@0 90 // FIXME: Cross-compartment wrapper StringIterator objects should pass this test. Bug 924059.
michael@0 91 if (!IsObject(this) || !IsStringIterator(this))
michael@0 92 ThrowError(JSMSG_INCOMPATIBLE_METHOD, "StringIterator", "next", ToString(this));
michael@0 93
michael@0 94 var S = UnsafeGetReservedSlot(this, STRING_ITERATOR_SLOT_ITERATED_OBJECT);
michael@0 95 var index = UnsafeGetReservedSlot(this, STRING_ITERATOR_SLOT_NEXT_INDEX);
michael@0 96 var size = S.length;
michael@0 97
michael@0 98 if (index >= size) {
michael@0 99 return { value: undefined, done: true };
michael@0 100 }
michael@0 101
michael@0 102 var charCount = 1;
michael@0 103 var first = callFunction(std_String_charCodeAt, S, index);
michael@0 104 if (first >= 0xD800 && first <= 0xDBFF && index + 1 < size) {
michael@0 105 var second = callFunction(std_String_charCodeAt, S, index + 1);
michael@0 106 if (second >= 0xDC00 && second <= 0xDFFF) {
michael@0 107 charCount = 2;
michael@0 108 }
michael@0 109 }
michael@0 110
michael@0 111 UnsafeSetReservedSlot(this, STRING_ITERATOR_SLOT_NEXT_INDEX, index + charCount);
michael@0 112 var value = callFunction(std_String_substring, S, index, index + charCount);
michael@0 113
michael@0 114 return { value: value, done: false };
michael@0 115 }
michael@0 116
michael@0 117 /**
michael@0 118 * Compare this String against that String, using the locale and collation
michael@0 119 * options provided.
michael@0 120 *
michael@0 121 * Spec: ECMAScript Internationalization API Specification, 13.1.1.
michael@0 122 */
michael@0 123 function String_localeCompare(that) {
michael@0 124 // Steps 1-3.
michael@0 125 CheckObjectCoercible(this);
michael@0 126 var S = ToString(this);
michael@0 127 var That = ToString(that);
michael@0 128
michael@0 129 // Steps 4-5.
michael@0 130 var locales = arguments.length > 1 ? arguments[1] : undefined;
michael@0 131 var options = arguments.length > 2 ? arguments[2] : undefined;
michael@0 132
michael@0 133 // Step 6.
michael@0 134 var collator;
michael@0 135 if (locales === undefined && options === undefined) {
michael@0 136 // This cache only optimizes for the old ES5 localeCompare without
michael@0 137 // locales and options.
michael@0 138 if (collatorCache.collator === undefined)
michael@0 139 collatorCache.collator = intl_Collator(locales, options);
michael@0 140 collator = collatorCache.collator;
michael@0 141 } else {
michael@0 142 collator = intl_Collator(locales, options);
michael@0 143 }
michael@0 144
michael@0 145 // Step 7.
michael@0 146 return intl_CompareStrings(collator, S, That);
michael@0 147 }
michael@0 148
michael@0 149 /* ES6 Draft September 5, 2013 21.1.2.2 */
michael@0 150 function String_static_fromCodePoint() {
michael@0 151 // Step 1. is not relevant
michael@0 152 // Step 2.
michael@0 153 var length = arguments.length;
michael@0 154
michael@0 155 // Step 3.
michael@0 156 var elements = new List();
michael@0 157
michael@0 158 // Step 4-5., 5g.
michael@0 159 for (var nextIndex = 0; nextIndex < length; nextIndex++) {
michael@0 160 // Step 5a.
michael@0 161 var next = arguments[nextIndex];
michael@0 162 // Step 5b-c.
michael@0 163 var nextCP = ToNumber(next);
michael@0 164
michael@0 165 // Step 5d.
michael@0 166 if (nextCP !== ToInteger(nextCP) || std_isNaN(nextCP))
michael@0 167 ThrowError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP));
michael@0 168
michael@0 169 // Step 5e.
michael@0 170 if (nextCP < 0 || nextCP > 0x10FFFF)
michael@0 171 ThrowError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP));
michael@0 172
michael@0 173 // Step 5f.
michael@0 174 // Inlined UTF-16 Encoding
michael@0 175 if (nextCP <= 0xFFFF) {
michael@0 176 elements.push(nextCP);
michael@0 177 continue;
michael@0 178 }
michael@0 179
michael@0 180 elements.push((((nextCP - 0x10000) / 0x400) | 0) + 0xD800);
michael@0 181 elements.push((nextCP - 0x10000) % 0x400 + 0xDC00);
michael@0 182 }
michael@0 183
michael@0 184 // Step 6.
michael@0 185 return callFunction(std_Function_apply, std_String_fromCharCode, null, elements);
michael@0 186 }
michael@0 187
michael@0 188 /**
michael@0 189 * Compare String str1 against String str2, using the locale and collation
michael@0 190 * options provided.
michael@0 191 *
michael@0 192 * Mozilla proprietary.
michael@0 193 * Spec: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String#String_generic_methods
michael@0 194 */
michael@0 195 function String_static_localeCompare(str1, str2) {
michael@0 196 if (arguments.length < 1)
michael@0 197 ThrowError(JSMSG_MISSING_FUN_ARG, 0, "String.localeCompare");
michael@0 198 var locales = arguments.length > 2 ? arguments[2] : undefined;
michael@0 199 var options = arguments.length > 3 ? arguments[3] : undefined;
michael@0 200 return callFunction(String_localeCompare, str1, str2, locales, options);
michael@0 201 }
michael@0 202

mercurial