mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 918879 - Implement String#codePointAt and String.fromCodePoint r=till
This commit is contained in:
parent
b31872fe7b
commit
1ef4d3b422
@ -4,6 +4,35 @@
|
||||
|
||||
/*global intl_Collator: false, */
|
||||
|
||||
/* ES6 Draft September 5, 2013 21.1.3.3 */
|
||||
function String_codePointAt(pos) {
|
||||
// Steps 1-3.
|
||||
CheckObjectCoercible(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();
|
||||
|
||||
@ -117,6 +146,45 @@ function String_localeCompare(that) {
|
||||
return intl_CompareStrings(collator, S, That);
|
||||
}
|
||||
|
||||
/* ES6 Draft September 5, 2013 21.1.2.2 */
|
||||
function String_static_fromCodePoint() {
|
||||
// Step 1. is not relevant
|
||||
// Step 2.
|
||||
var length = arguments.length;
|
||||
|
||||
// Step 3.
|
||||
var elements = new List();
|
||||
|
||||
// Step 4-5., 5g.
|
||||
for (var nextIndex = 0; nextIndex < length; nextIndex++) {
|
||||
// Step 5a.
|
||||
var next = arguments[nextIndex];
|
||||
// Step 5b-c.
|
||||
var nextCP = ToNumber(next);
|
||||
|
||||
// Step 5d.
|
||||
if (nextCP !== ToInteger(nextCP) || std_isNaN(nextCP))
|
||||
ThrowError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP));
|
||||
|
||||
// Step 5e.
|
||||
if (nextCP < 0 || nextCP > 0x10FFFF)
|
||||
ThrowError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP));
|
||||
|
||||
// Step 5f.
|
||||
// Inlined UTF-16 Encoding
|
||||
if (nextCP <= 0xFFFF) {
|
||||
elements.push(nextCP);
|
||||
continue;
|
||||
}
|
||||
|
||||
elements.push((((nextCP - 0x10000) / 0x400) | 0) + 0xD800);
|
||||
elements.push((nextCP - 0x10000) % 0x400 + 0xDC00);
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
return callFunction(std_Function_apply, std_String_fromCharCode, null, elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare String str1 against String str2, using the locale and collation
|
||||
* options provided.
|
||||
@ -131,3 +199,4 @@ function String_static_localeCompare(str1, str2) {
|
||||
var options = arguments.length > 3 ? arguments[3] : undefined;
|
||||
return callFunction(String_localeCompare, str1, str2, locales, options);
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,7 @@ var std_Object_getOwnPropertyNames = Object.getOwnPropertyNames;
|
||||
var std_Object_hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var std_RegExp_test = RegExp.prototype.test;
|
||||
var Std_String = String;
|
||||
var std_String_fromCharCode = String.fromCharCode;
|
||||
var std_String_charCodeAt = String.prototype.charCodeAt;
|
||||
var std_String_indexOf = String.prototype.indexOf;
|
||||
var std_String_lastIndexOf = String.prototype.lastIndexOf;
|
||||
|
@ -223,7 +223,7 @@ MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 169, 0, JSEXN_SYNTAXERR, "too many catch v
|
||||
MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 170, 0, JSEXN_RANGEERR, "repeat count must be non-negative")
|
||||
MSG_DEF(JSMSG_INVALID_FOR_OF_INIT, 171, 0, JSEXN_SYNTAXERR, "for-of loop variable declaration may not have an initializer")
|
||||
MSG_DEF(JSMSG_INVALID_MAP_ITERABLE, 172, 0, JSEXN_TYPEERR, "iterable for map should have array-like objects")
|
||||
MSG_DEF(JSMSG_UNUSED173, 173, 0, JSEXN_NONE, "")
|
||||
MSG_DEF(JSMSG_NOT_A_CODEPOINT, 173, 1, JSEXN_RANGEERR, "{0} is not a valid code point")
|
||||
MSG_DEF(JSMSG_UNUSED174, 174, 0, JSEXN_NONE, "")
|
||||
MSG_DEF(JSMSG_NESTING_GENERATOR, 175, 0, JSEXN_TYPEERR, "already executing generator")
|
||||
MSG_DEF(JSMSG_UNUSED176, 176, 0, JSEXN_NONE, "")
|
||||
|
@ -3678,6 +3678,7 @@ static const JSFunctionSpec string_methods[] = {
|
||||
JS_FN("toUpperCase", str_toUpperCase, 0,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("charAt", js_str_charAt, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("charCodeAt", js_str_charCodeAt, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_SELF_HOSTED_FN("codePointAt", "String_codePointAt", 1,0),
|
||||
JS_FN("contains", str_contains, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("indexOf", str_indexOf, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("lastIndexOf", str_lastIndexOf, 1,JSFUN_GENERIC_NATIVE),
|
||||
@ -3792,6 +3793,7 @@ js::str_fromCharCode(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
||||
static const JSFunctionSpec string_static_methods[] = {
|
||||
JS_FN("fromCharCode", js::str_fromCharCode, 1, 0),
|
||||
JS_SELF_HOSTED_FN("fromCodePoint", "String_static_fromCodePoint", 0,0),
|
||||
|
||||
// This must be at the end because of bug 853075: functions listed after
|
||||
// self-hosted methods aren't available in self-hosted code.
|
||||
|
0
js/src/tests/ecma_6/String/browser.js
Normal file
0
js/src/tests/ecma_6/String/browser.js
Normal file
84
js/src/tests/ecma_6/String/codePointAt.js
Normal file
84
js/src/tests/ecma_6/String/codePointAt.js
Normal file
@ -0,0 +1,84 @@
|
||||
var BUGNUMBER = 918879;
|
||||
var summary = 'String.prototype.codePointAt';
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
// Tests taken from:
|
||||
// https://github.com/mathiasbynens/String.prototype.codePointAt/blob/master/tests/tests.js
|
||||
assertEq(String.prototype.codePointAt.length, 1);
|
||||
assertEq(String.prototype.propertyIsEnumerable('codePointAt'), false);
|
||||
|
||||
// String that starts with a BMP symbol
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(''), 0x61);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt('_'), 0x61);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(), 0x61);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(-Infinity), undefined);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(-1), undefined);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(-0), 0x61);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(0), 0x61);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(3), 0x1D306);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(4), 0xDF06);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(5), 0x64);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(42), undefined);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(Infinity), undefined);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(Infinity), undefined);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(NaN), 0x61);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(false), 0x61);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(null), 0x61);
|
||||
assertEq('abc\uD834\uDF06def'.codePointAt(undefined), 0x61);
|
||||
|
||||
// String that starts with an astral symbol
|
||||
assertEq('\uD834\uDF06def'.codePointAt(''), 0x1D306);
|
||||
assertEq('\uD834\uDF06def'.codePointAt('1'), 0xDF06);
|
||||
assertEq('\uD834\uDF06def'.codePointAt('_'), 0x1D306);
|
||||
assertEq('\uD834\uDF06def'.codePointAt(), 0x1D306);
|
||||
assertEq('\uD834\uDF06def'.codePointAt(-1), undefined);
|
||||
assertEq('\uD834\uDF06def'.codePointAt(-0), 0x1D306);
|
||||
assertEq('\uD834\uDF06def'.codePointAt(0), 0x1D306);
|
||||
assertEq('\uD834\uDF06def'.codePointAt(1), 0xDF06);
|
||||
assertEq('\uD834\uDF06def'.codePointAt(42), undefined);
|
||||
assertEq('\uD834\uDF06def'.codePointAt(false), 0x1D306);
|
||||
assertEq('\uD834\uDF06def'.codePointAt(null), 0x1D306);
|
||||
assertEq('\uD834\uDF06def'.codePointAt(undefined), 0x1D306);
|
||||
|
||||
// Lone high surrogates
|
||||
assertEq('\uD834abc'.codePointAt(''), 0xD834);
|
||||
assertEq('\uD834abc'.codePointAt('_'), 0xD834);
|
||||
assertEq('\uD834abc'.codePointAt(), 0xD834);
|
||||
assertEq('\uD834abc'.codePointAt(-1), undefined);
|
||||
assertEq('\uD834abc'.codePointAt(-0), 0xD834);
|
||||
assertEq('\uD834abc'.codePointAt(0), 0xD834);
|
||||
assertEq('\uD834abc'.codePointAt(false), 0xD834);
|
||||
assertEq('\uD834abc'.codePointAt(NaN), 0xD834);
|
||||
assertEq('\uD834abc'.codePointAt(null), 0xD834);
|
||||
assertEq('\uD834abc'.codePointAt(undefined), 0xD834);
|
||||
|
||||
// Lone low surrogates
|
||||
assertEq('\uDF06abc'.codePointAt(''), 0xDF06);
|
||||
assertEq('\uDF06abc'.codePointAt('_'), 0xDF06);
|
||||
assertEq('\uDF06abc'.codePointAt(), 0xDF06);
|
||||
assertEq('\uDF06abc'.codePointAt(-1), undefined);
|
||||
assertEq('\uDF06abc'.codePointAt(-0), 0xDF06);
|
||||
assertEq('\uDF06abc'.codePointAt(0), 0xDF06);
|
||||
assertEq('\uDF06abc'.codePointAt(false), 0xDF06);
|
||||
assertEq('\uDF06abc'.codePointAt(NaN), 0xDF06);
|
||||
assertEq('\uDF06abc'.codePointAt(null), 0xDF06);
|
||||
assertEq('\uDF06abc'.codePointAt(undefined), 0xDF06);
|
||||
|
||||
(function() { String.prototype.codePointAt.call(undefined); }, TypeError);
|
||||
assertThrowsInstanceOf(function() { String.prototype.codePointAt.call(undefined, 4); }, TypeError);
|
||||
assertThrowsInstanceOf(function() { String.prototype.codePointAt.call(null); }, TypeError);
|
||||
assertThrowsInstanceOf(function() { String.prototype.codePointAt.call(null, 4); }, TypeError);
|
||||
assertEq(String.prototype.codePointAt.call(42, 0), 0x34);
|
||||
assertEq(String.prototype.codePointAt.call(42, 1), 0x32);
|
||||
assertEq(String.prototype.codePointAt.call({ 'toString': function() { return 'abc'; } }, 2), 0x63);
|
||||
|
||||
assertThrowsInstanceOf(function() { String.prototype.codePointAt.apply(undefined); }, TypeError);
|
||||
assertThrowsInstanceOf(function() { String.prototype.codePointAt.apply(undefined, [4]); }, TypeError);
|
||||
assertThrowsInstanceOf(function() { String.prototype.codePointAt.apply(null); }, TypeError);
|
||||
assertThrowsInstanceOf(function() { String.prototype.codePointAt.apply(null, [4]); }, TypeError);
|
||||
assertEq(String.prototype.codePointAt.apply(42, [0]), 0x34);
|
||||
assertEq(String.prototype.codePointAt.apply(42, [1]), 0x32);
|
||||
assertEq(String.prototype.codePointAt.apply({ 'toString': function() { return 'abc'; } }, [2]), 0x63);
|
||||
|
||||
reportCompare(0, 0, "ok");
|
48
js/src/tests/ecma_6/String/fromCodePoint.js
Normal file
48
js/src/tests/ecma_6/String/fromCodePoint.js
Normal file
@ -0,0 +1,48 @@
|
||||
var BUGNUMBER = 918879;
|
||||
var summary = 'String.fromCodePoint';
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
// Tests taken from:
|
||||
// https://github.com/mathiasbynens/String.fromCodePoint/blob/master/tests/tests.js
|
||||
|
||||
assertEq(String.fromCodePoint.length, 0);
|
||||
assertEq(String.propertyIsEnumerable('fromCodePoint'), false);
|
||||
|
||||
assertEq(String.fromCodePoint(''), '\0');
|
||||
assertEq(String.fromCodePoint(), '');
|
||||
assertEq(String.fromCodePoint(-0), '\0');
|
||||
assertEq(String.fromCodePoint(0), '\0');
|
||||
assertEq(String.fromCodePoint(0x1D306), '\uD834\uDF06');
|
||||
assertEq(String.fromCodePoint(0x1D306, 0x61, 0x1D307), '\uD834\uDF06a\uD834\uDF07');
|
||||
assertEq(String.fromCodePoint(0x61, 0x62, 0x1D307), 'ab\uD834\uDF07');
|
||||
assertEq(String.fromCodePoint(false), '\0');
|
||||
assertEq(String.fromCodePoint(null), '\0');
|
||||
|
||||
assertThrowsInstanceOf(function() { String.fromCodePoint('_'); }, RangeError);
|
||||
assertThrowsInstanceOf(function() { String.fromCodePoint('+Infinity'); }, RangeError);
|
||||
assertThrowsInstanceOf(function() { String.fromCodePoint('-Infinity'); }, RangeError);
|
||||
assertThrowsInstanceOf(function() { String.fromCodePoint(-1); }, RangeError);
|
||||
assertThrowsInstanceOf(function() { String.fromCodePoint(0x10FFFF + 1); }, RangeError);
|
||||
assertThrowsInstanceOf(function() { String.fromCodePoint(3.14); }, RangeError);
|
||||
assertThrowsInstanceOf(function() { String.fromCodePoint(3e-2); }, RangeError);
|
||||
assertThrowsInstanceOf(function() { String.fromCodePoint(Infinity); }, RangeError);
|
||||
assertThrowsInstanceOf(function() { String.fromCodePoint(NaN); }, RangeError);
|
||||
assertThrowsInstanceOf(function() { String.fromCodePoint(undefined); }, RangeError);
|
||||
assertThrowsInstanceOf(function() { String.fromCodePoint({}); }, RangeError);
|
||||
|
||||
var counter = Math.pow(2, 15) * 3 / 2;
|
||||
var result = [];
|
||||
while (--counter >= 0) {
|
||||
result.push(0); // one code unit per symbol
|
||||
}
|
||||
String.fromCodePoint.apply(null, result); // must not throw
|
||||
|
||||
var counter = Math.pow(2, 15) * 3 / 2;
|
||||
var result = [];
|
||||
while (--counter >= 0) {
|
||||
result.push(0xFFFF + 1); // two code units per symbol
|
||||
}
|
||||
String.fromCodePoint.apply(null, result); // must not throw
|
||||
|
||||
reportCompare(0, 0, "ok");
|
0
js/src/tests/ecma_6/String/shell.js
Normal file
0
js/src/tests/ecma_6/String/shell.js
Normal file
Loading…
Reference in New Issue
Block a user