зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1121938 - Implement TypedArray.prototype.toString and .toLocaleString. r=waldo, r=froydnj
This commit is contained in:
Родитель
d10c483558
Коммит
878648c8cf
|
@ -97,7 +97,7 @@ var inputTests = [
|
|||
{
|
||||
input: "window.typedarray1",
|
||||
output: "Int32Array [ 1, 287, 8651, 40983, 8754 ]",
|
||||
printOutput: "[object Int32Array]",
|
||||
printOutput: "1,287,8651,40983,8754",
|
||||
inspectable: true,
|
||||
variablesViewLabel: "Int32Array[5]",
|
||||
},
|
||||
|
|
|
@ -802,7 +802,7 @@ function InvalidCommandError() {
|
|||
* or "Float32Array".
|
||||
*/
|
||||
function getConstructorName(obj) {
|
||||
return obj.toString().match(/\[object ([^\[\]]*)\]\]?$/)[1];
|
||||
return Object.prototype.toString.call(obj).match(/\[object ([^\[\]]*)\]\]?$/)[1];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -347,6 +347,9 @@ function* test_basics() {
|
|||
serverQueue = connectedResult.queue;
|
||||
|
||||
// -- Attempt to send non-string data.
|
||||
// Restore the original behavior by replacing toString with
|
||||
// Object.prototype.toString. (bug 1121938)
|
||||
bigUint8Array.toString = Object.prototype.toString;
|
||||
is(clientSocket.send(bigUint8Array), true,
|
||||
'Client sending a large non-string should only send a small string.');
|
||||
clientSocket.close();
|
||||
|
|
|
@ -171,11 +171,10 @@ function TypedArrayEvery(callbackfn, thisArg = undefined) {
|
|||
|
||||
// Steps 3-5.
|
||||
var len;
|
||||
if (isTypedArray) {
|
||||
if (isTypedArray)
|
||||
len = TypedArrayLength(O);
|
||||
} else {
|
||||
else
|
||||
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if (arguments.length === 0)
|
||||
|
@ -260,11 +259,10 @@ function TypedArrayFilter(callbackfn, thisArg = undefined) {
|
|||
|
||||
// Step 4.
|
||||
var len;
|
||||
if (isTypedArray) {
|
||||
if (isTypedArray)
|
||||
len = TypedArrayLength(O);
|
||||
} else {
|
||||
else
|
||||
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
if (arguments.length === 0)
|
||||
|
@ -329,11 +327,10 @@ function TypedArrayFind(predicate, thisArg = undefined) {
|
|||
|
||||
// Steps 3-5.
|
||||
var len;
|
||||
if (isTypedArray) {
|
||||
if (isTypedArray)
|
||||
len = TypedArrayLength(O);
|
||||
} else {
|
||||
else
|
||||
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if (arguments.length === 0)
|
||||
|
@ -372,11 +369,10 @@ function TypedArrayFindIndex(predicate, thisArg = undefined) {
|
|||
|
||||
// Steps 3-5.
|
||||
var len;
|
||||
if (isTypedArray) {
|
||||
if (isTypedArray)
|
||||
len = TypedArrayLength(O);
|
||||
} else {
|
||||
else
|
||||
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if (arguments.length === 0)
|
||||
|
@ -413,11 +409,10 @@ function TypedArrayForEach(callbackfn, thisArg = undefined) {
|
|||
|
||||
// Step 3-4.
|
||||
var len;
|
||||
if (isTypedArray) {
|
||||
if (isTypedArray)
|
||||
len = TypedArrayLength(O);
|
||||
} else {
|
||||
else
|
||||
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
if (arguments.length === 0)
|
||||
|
@ -518,7 +513,7 @@ function TypedArrayJoin(separator) {
|
|||
var element0 = O[0];
|
||||
|
||||
// Steps 10-11.
|
||||
// Omit the 'if' clause in step 10, since typed arrays can not have undefined or null elements.
|
||||
// Omit the 'if' clause in step 10, since typed arrays can't have undefined or null elements.
|
||||
var R = ToString(element0);
|
||||
|
||||
// Steps 12-13.
|
||||
|
@ -530,7 +525,7 @@ function TypedArrayJoin(separator) {
|
|||
var element = O[k];
|
||||
|
||||
// Steps 13.c-13.d.
|
||||
// Omit the 'if' clause in step 13.c, since typed arrays can not have undefined or null elements.
|
||||
// Omit the 'if' clause in step 13.c, since typed arrays can't have undefined or null elements.
|
||||
var next = ToString(element);
|
||||
|
||||
// Step 13.e.
|
||||
|
@ -607,11 +602,10 @@ function TypedArrayMap(callbackfn, thisArg = undefined) {
|
|||
|
||||
// Step 4.
|
||||
var len;
|
||||
if (isTypedArray) {
|
||||
if (isTypedArray)
|
||||
len = TypedArrayLength(O);
|
||||
} else {
|
||||
else
|
||||
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
if (arguments.length === 0)
|
||||
|
@ -657,11 +651,10 @@ function TypedArrayReduce(callbackfn/*, initialValue*/) {
|
|||
|
||||
// Steps 3-5.
|
||||
var len;
|
||||
if (isTypedArray) {
|
||||
if (isTypedArray)
|
||||
len = TypedArrayLength(O);
|
||||
} else {
|
||||
else
|
||||
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if (arguments.length === 0)
|
||||
|
@ -704,11 +697,10 @@ function TypedArrayReduceRight(callbackfn/*, initialValue*/) {
|
|||
|
||||
// Steps 3-5.
|
||||
var len;
|
||||
if (isTypedArray) {
|
||||
if (isTypedArray)
|
||||
len = TypedArrayLength(O);
|
||||
} else {
|
||||
else
|
||||
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if (arguments.length === 0)
|
||||
|
@ -870,7 +862,7 @@ function SetFromTypedArray(target, typedArray, targetOffset, targetLength) {
|
|||
}
|
||||
|
||||
// ES6 draft 20150304 %TypedArray%.prototype.set
|
||||
function TypedArraySet(overloaded, offset) {
|
||||
function TypedArraySet(overloaded, offset = 0) {
|
||||
// Steps 2-5, either algorithm.
|
||||
var target = this;
|
||||
if (!IsObject(target) || !IsTypedArray(target)) {
|
||||
|
@ -971,11 +963,10 @@ function TypedArraySome(callbackfn, thisArg = undefined) {
|
|||
|
||||
// Steps 3-5.
|
||||
var len;
|
||||
if (isTypedArray) {
|
||||
if (isTypedArray)
|
||||
len = TypedArrayLength(O);
|
||||
} else {
|
||||
else
|
||||
len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if (arguments.length === 0)
|
||||
|
@ -1051,11 +1042,10 @@ function TypedArraySort(comparefn) {
|
|||
|
||||
// Step 3.
|
||||
var len;
|
||||
if (isTypedArray) {
|
||||
if (isTypedArray)
|
||||
len = TypedArrayLength(obj);
|
||||
} else {
|
||||
else
|
||||
len = callFunction(CallTypedArrayMethodIfWrapped, obj, obj, "TypedArrayLength");
|
||||
}
|
||||
|
||||
if (comparefn === undefined) {
|
||||
comparefn = TypedArrayCompare;
|
||||
|
@ -1104,6 +1094,78 @@ function TypedArraySort(comparefn) {
|
|||
return QuickSort(obj, len, comparefn);
|
||||
}
|
||||
|
||||
// ES2017 draft rev f8a9be8ea4bd97237d176907a1e3080dce20c68f
|
||||
// 22.2.3.28 %TypedArray%.prototype.toLocaleString ([ reserved1 [ , reserved2 ] ])
|
||||
// ES2017 Intl draft rev 78bbe7d1095f5ff3760ac4017ed366026e4cb276
|
||||
// 13.4.1 Array.prototype.toLocaleString ([ locales [ , options ]])
|
||||
function TypedArrayToLocaleString(locales = undefined, options = undefined) {
|
||||
// ValidateTypedArray, then step 1.
|
||||
var array = this;
|
||||
|
||||
// This function is not generic.
|
||||
// We want to make sure that we have an attached buffer, per spec prose.
|
||||
var isTypedArray = IsTypedArrayEnsuringArrayBuffer(array);
|
||||
|
||||
// If we got here, `this` is either a typed array or a cross-compartment
|
||||
// wrapper for one.
|
||||
|
||||
// Step 2.
|
||||
var len;
|
||||
if (isTypedArray)
|
||||
len = TypedArrayLength(array);
|
||||
else
|
||||
len = callFunction(CallTypedArrayMethodIfWrapped, array, array, "TypedArrayLength");
|
||||
|
||||
// Step 4.
|
||||
if (len === 0)
|
||||
return "";
|
||||
|
||||
// Step 5.
|
||||
var firstElement = array[0];
|
||||
|
||||
// Steps 6-7.
|
||||
// Omit the 'if' clause in step 6, since typed arrays can't have undefined
|
||||
// or null elements.
|
||||
#if EXPOSE_INTL_API
|
||||
var R = ToString(callContentFunction(firstElement.toLocaleString, firstElement, locales, options));
|
||||
#else
|
||||
var R = ToString(callContentFunction(firstElement.toLocaleString, firstElement));
|
||||
#endif
|
||||
|
||||
// Step 3 (reordered).
|
||||
// We don't (yet?) implement locale-dependent separators.
|
||||
var separator = ",";
|
||||
|
||||
// Steps 8-9.
|
||||
for (var k = 1; k < len; k++) {
|
||||
// Step 9.a.
|
||||
var S = R + separator;
|
||||
|
||||
// Step 9.b.
|
||||
var nextElement = array[k];
|
||||
|
||||
// Step 9.c *should* be unreachable: typed array elements are numbers.
|
||||
// But bug 1079853 means |nextElement| *could* be |undefined|, if the
|
||||
// previous iteration's step 9.d or step 7 detached |array|'s buffer.
|
||||
// Conveniently, if this happens, evaluating |nextElement.toLocaleString|
|
||||
// throws the required TypeError, and the only observable difference is
|
||||
// the error message. So despite bug 1079853, we can skip step 9.c.
|
||||
|
||||
// Step 9.d.
|
||||
#if EXPOSE_INTL_API
|
||||
R = ToString(callContentFunction(nextElement.toLocaleString, nextElement, locales, options));
|
||||
#else
|
||||
R = ToString(callContentFunction(nextElement.toLocaleString, nextElement));
|
||||
#endif
|
||||
|
||||
// Step 9.e.
|
||||
R = S + R;
|
||||
}
|
||||
|
||||
// Step 10.
|
||||
return R;
|
||||
}
|
||||
|
||||
// ES6 draft 20150304 %TypedArray%.prototype.subarray
|
||||
function TypedArraySubarray(begin, end) {
|
||||
// Step 1.
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
// This test case was created before %TypedArrayPrototype%.toString was
|
||||
// implemented. Now that we've got %TypedArrayPrototype%.toString the test will
|
||||
// attempt to create a 300300001 character long string and either timeout or
|
||||
// throw an oom error. Restore the original behavior by replacing toString with
|
||||
// Object.prototype.toString.
|
||||
Uint8ClampedArray.prototype.toString = Object.prototype.toString;
|
||||
|
||||
function A(a) { this.a = a; }
|
||||
A.prototype.foo = function (x) {};
|
||||
function B(b) { this.b = b; }
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
if (typeof Intl === "object") {
|
||||
const constructors = [
|
||||
Int8Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
Int16Array,
|
||||
Uint16Array,
|
||||
Int32Array,
|
||||
Uint32Array,
|
||||
Float32Array,
|
||||
Float64Array,
|
||||
];
|
||||
|
||||
const localeSep = [,,].toLocaleString();
|
||||
|
||||
const originalNumberToLocaleString = Number.prototype.toLocaleString;
|
||||
|
||||
// Missing arguments are passed as |undefined|.
|
||||
for (let constructor of constructors) {
|
||||
Number.prototype.toLocaleString = function() {
|
||||
assertEq(arguments.length, 2);
|
||||
assertEq(arguments[0], undefined);
|
||||
assertEq(arguments[1], undefined);
|
||||
return "pass";
|
||||
};
|
||||
|
||||
// Single element case.
|
||||
assertEq(new constructor(1).toLocaleString(), "pass");
|
||||
|
||||
// More than one element.
|
||||
assertEq(new constructor(2).toLocaleString(), "pass" + localeSep + "pass");
|
||||
}
|
||||
Number.prototype.toLocaleString = originalNumberToLocaleString;
|
||||
|
||||
// Missing options is passed as |undefined|.
|
||||
for (let constructor of constructors) {
|
||||
Number.prototype.toLocaleString = function() {
|
||||
assertEq(arguments.length, 2);
|
||||
assertEq(arguments[0], locales);
|
||||
assertEq(arguments[1], undefined);
|
||||
return "pass";
|
||||
};
|
||||
let locales = {};
|
||||
|
||||
// Single element case.
|
||||
assertEq(new constructor(1).toLocaleString(locales), "pass");
|
||||
|
||||
// More than one element.
|
||||
assertEq(new constructor(2).toLocaleString(locales), "pass" + localeSep + "pass");
|
||||
}
|
||||
Number.prototype.toLocaleString = originalNumberToLocaleString;
|
||||
|
||||
// Ensure "locales" and "options" arguments are passed to the array elements.
|
||||
for (let constructor of constructors) {
|
||||
Number.prototype.toLocaleString = function() {
|
||||
assertEq(arguments.length, 2);
|
||||
assertEq(arguments[0], locales);
|
||||
assertEq(arguments[1], options);
|
||||
return "pass";
|
||||
};
|
||||
let locales = {};
|
||||
let options = {};
|
||||
|
||||
// Single element case.
|
||||
assertEq(new constructor(1).toLocaleString(locales, options), "pass");
|
||||
|
||||
// More than one element.
|
||||
assertEq(new constructor(2).toLocaleString(locales, options), "pass" + localeSep + "pass");
|
||||
}
|
||||
Number.prototype.toLocaleString = originalNumberToLocaleString;
|
||||
|
||||
assertEq(new Float32Array([NaN]).toLocaleString("ar"), "ليس رقم");
|
||||
assertEq(new Float64Array([NaN]).toLocaleString(["zh-hant", "ar"]), "非數值");
|
||||
assertEq(new Float32Array([Infinity]).toLocaleString(["dz"]), "གྲངས་མེད");
|
||||
assertEq(new Float64Array([-Infinity]).toLocaleString(["fr", "en"]), "-∞");
|
||||
|
||||
const sampleValues = [-0, +0, -1, +1, -2, +2, -0.5, +0.5];
|
||||
const sampleLocales = [
|
||||
void 0,
|
||||
"en",
|
||||
"th-th-u-nu-thai",
|
||||
["tlh", "de"],
|
||||
];
|
||||
const sampleOptions = [
|
||||
void 0,
|
||||
{},
|
||||
{style: "percent"},
|
||||
{style: "currency", currency: "USD", minimumIntegerDigits: 4},
|
||||
];
|
||||
for (let locale of sampleLocales) {
|
||||
for (let options of sampleOptions) {
|
||||
let nf = new Intl.NumberFormat(locale, options);
|
||||
for (let constructor of constructors) {
|
||||
let typedArray = new constructor(sampleValues);
|
||||
let expected = [].map.call(typedArray, nf.format).join(localeSep);
|
||||
assertEq(typedArray.toLocaleString(locale, options), expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
|
@ -0,0 +1,33 @@
|
|||
const TypedArrayPrototype = Object.getPrototypeOf(Int8Array.prototype);
|
||||
|
||||
const constructors = [
|
||||
Int8Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
Int16Array,
|
||||
Uint16Array,
|
||||
Int32Array,
|
||||
Uint32Array,
|
||||
Float32Array,
|
||||
Float64Array
|
||||
];
|
||||
|
||||
// %TypedArrayPrototype% has an own "set" function property.
|
||||
assertEq(TypedArrayPrototype.hasOwnProperty("set"), true);
|
||||
assertEq(typeof TypedArrayPrototype.set, "function");
|
||||
|
||||
// The concrete TypedArray prototypes do not have an own "set" property.
|
||||
assertEq(constructors.every(c => !c.hasOwnProperty("set")), true);
|
||||
|
||||
assertDeepEq(Object.getOwnPropertyDescriptor(TypedArrayPrototype, "set"), {
|
||||
value: TypedArrayPrototype.set,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
assertEq(TypedArrayPrototype.set.name, "set");
|
||||
assertEq(TypedArrayPrototype.set.length, 1);
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
|
@ -0,0 +1,50 @@
|
|||
if (typeof detachArrayBuffer === "function") {
|
||||
const constructors = [
|
||||
Int8Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
Int16Array,
|
||||
Uint16Array,
|
||||
Int32Array,
|
||||
Uint32Array,
|
||||
Float32Array,
|
||||
Float64Array,
|
||||
];
|
||||
|
||||
const originalNumberToLocaleString = Number.prototype.toLocaleString;
|
||||
|
||||
// Throws if array buffer is detached.
|
||||
for (let constructor of constructors) {
|
||||
let typedArray = new constructor(42);
|
||||
detachArrayBuffer(typedArray.buffer, "same-data");
|
||||
assertThrowsInstanceOf(() => typedArray.toLocaleString(), TypeError);
|
||||
}
|
||||
|
||||
// Throws a TypeError if detached in Number.prototype.toLocaleString.
|
||||
for (let constructor of constructors) {
|
||||
Number.prototype.toLocaleString = function() {
|
||||
"use strict";
|
||||
if (!detached) {
|
||||
detachArrayBuffer(typedArray.buffer, "same-data");
|
||||
detached = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
// No error for single element arrays.
|
||||
let detached = false;
|
||||
let typedArray = new constructor(1);
|
||||
assertEq(typedArray.toLocaleString(), "0");
|
||||
assertEq(detached, true);
|
||||
|
||||
// TypeError if more than one element is present.
|
||||
detached = false;
|
||||
typedArray = new constructor(2);
|
||||
assertThrowsInstanceOf(() => typedArray.toLocaleString(), TypeError);
|
||||
assertEq(detached, true);
|
||||
}
|
||||
Number.prototype.toLocaleString = originalNumberToLocaleString;
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
|
@ -0,0 +1,52 @@
|
|||
if (typeof Intl !== "object") {
|
||||
const constructors = [
|
||||
Int8Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
Int16Array,
|
||||
Uint16Array,
|
||||
Int32Array,
|
||||
Uint32Array,
|
||||
Float32Array,
|
||||
Float64Array,
|
||||
];
|
||||
|
||||
const localeSep = [,,].toLocaleString();
|
||||
|
||||
const originalNumberToLocaleString = Number.prototype.toLocaleString;
|
||||
|
||||
// Ensure no arguments are passed to the array elements.
|
||||
for (let constructor of constructors) {
|
||||
Number.prototype.toLocaleString = function() {
|
||||
assertEq(arguments.length, 0);
|
||||
return "pass";
|
||||
};
|
||||
|
||||
// Single element case.
|
||||
assertEq(new constructor(1).toLocaleString(), "pass");
|
||||
|
||||
// More than one element.
|
||||
assertEq(new constructor(2).toLocaleString(), "pass" + localeSep + "pass");
|
||||
}
|
||||
Number.prototype.toLocaleString = originalNumberToLocaleString;
|
||||
|
||||
// Ensure no arguments are passed to the array elements even if supplied.
|
||||
for (let constructor of constructors) {
|
||||
Number.prototype.toLocaleString = function() {
|
||||
assertEq(arguments.length, 0);
|
||||
return "pass";
|
||||
};
|
||||
let locales = {};
|
||||
let options = {};
|
||||
|
||||
// Single element case.
|
||||
assertEq(new constructor(1).toLocaleString(locales, options), "pass");
|
||||
|
||||
// More than one element.
|
||||
assertEq(new constructor(2).toLocaleString(locales, options), "pass" + localeSep + "pass");
|
||||
}
|
||||
Number.prototype.toLocaleString = originalNumberToLocaleString;
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
|
@ -0,0 +1,92 @@
|
|||
const TypedArrayPrototype = Object.getPrototypeOf(Int8Array.prototype);
|
||||
|
||||
const constructors = [
|
||||
Int8Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
Int16Array,
|
||||
Uint16Array,
|
||||
Int32Array,
|
||||
Uint32Array,
|
||||
Float32Array,
|
||||
Float64Array,
|
||||
];
|
||||
|
||||
// %TypedArrayPrototype% has an own "toLocaleString" function property.
|
||||
assertEq(TypedArrayPrototype.hasOwnProperty("toLocaleString"), true);
|
||||
assertEq(typeof TypedArrayPrototype.toLocaleString, "function");
|
||||
|
||||
// The initial value of %TypedArrayPrototype%.toLocaleString is not Array.prototype.toLocaleString.
|
||||
assertEq(TypedArrayPrototype.toLocaleString === Array.prototype.toLocaleString, false);
|
||||
|
||||
// The concrete TypedArray prototypes do not have an own "toLocaleString" property.
|
||||
assertEq(constructors.every(c => !c.hasOwnProperty("toLocaleString")), true);
|
||||
|
||||
assertDeepEq(Object.getOwnPropertyDescriptor(TypedArrayPrototype, "toLocaleString"), {
|
||||
value: TypedArrayPrototype.toLocaleString,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
assertEq(TypedArrayPrototype.toLocaleString.name, "toLocaleString");
|
||||
assertEq(TypedArrayPrototype.toLocaleString.length, 0);
|
||||
|
||||
// It's not a generic method.
|
||||
assertThrowsInstanceOf(() => TypedArrayPrototype.toLocaleString.call(), TypeError);
|
||||
for (let invalid of [void 0, null, {}, [], function(){}, true, 0, "", Symbol()]) {
|
||||
assertThrowsInstanceOf(() => TypedArrayPrototype.toLocaleString.call(invalid), TypeError);
|
||||
}
|
||||
|
||||
const localeOne = 1..toLocaleString(),
|
||||
localeTwo = 2..toLocaleString(),
|
||||
localeSep = [,,].toLocaleString();
|
||||
|
||||
for (let constructor of constructors) {
|
||||
assertEq(new constructor([]).toLocaleString(), "");
|
||||
assertEq(new constructor([1]).toLocaleString(), localeOne);
|
||||
assertEq(new constructor([1, 2]).toLocaleString(), localeOne + localeSep + localeTwo);
|
||||
}
|
||||
|
||||
const originalNumberToLocaleString = Number.prototype.toLocaleString;
|
||||
|
||||
// Calls Number.prototype.toLocaleString on each element.
|
||||
for (let constructor of constructors) {
|
||||
Number.prototype.toLocaleString = function() {
|
||||
"use strict";
|
||||
|
||||
// Ensure this-value is not boxed.
|
||||
assertEq(typeof this, "number");
|
||||
|
||||
// Test ToString is applied.
|
||||
return {
|
||||
valueOf: () => {
|
||||
throw new Error("valueOf called");
|
||||
},
|
||||
toString: () => {
|
||||
return this + 10;
|
||||
}
|
||||
};
|
||||
};
|
||||
let typedArray = new constructor([1, 2]);
|
||||
assertEq(typedArray.toLocaleString(), "11" + localeSep + "12");
|
||||
}
|
||||
Number.prototype.toLocaleString = originalNumberToLocaleString;
|
||||
|
||||
// Calls Number.prototype.toLocaleString from the current Realm.
|
||||
const otherGlobal = newGlobal();
|
||||
for (let constructor of constructors) {
|
||||
Number.prototype.toLocaleString = function() {
|
||||
"use strict";
|
||||
called = true;
|
||||
return this;
|
||||
};
|
||||
let typedArray = new otherGlobal[constructor.name]([1]);
|
||||
let called = false;
|
||||
assertEq(TypedArrayPrototype.toLocaleString.call(typedArray), "1");
|
||||
assertEq(called, true);
|
||||
}
|
||||
Number.prototype.toLocaleString = originalNumberToLocaleString;
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
|
@ -0,0 +1,48 @@
|
|||
const TypedArrayPrototype = Object.getPrototypeOf(Int8Array.prototype);
|
||||
|
||||
const constructors = [
|
||||
Int8Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
Int16Array,
|
||||
Uint16Array,
|
||||
Int32Array,
|
||||
Uint32Array,
|
||||
Float32Array,
|
||||
Float64Array,
|
||||
];
|
||||
|
||||
// %TypedArrayPrototype% has an own "toString" property.
|
||||
assertEq(TypedArrayPrototype.hasOwnProperty("toString"), true);
|
||||
|
||||
// The initial value of %TypedArrayPrototype%.toString is Array.prototype.toString.
|
||||
assertEq(TypedArrayPrototype.toString, Array.prototype.toString);
|
||||
|
||||
// The concrete TypedArray prototypes do not have an own "toString" property.
|
||||
assertEq(constructors.every(c => !c.hasOwnProperty("toString")), true);
|
||||
|
||||
assertDeepEq(Object.getOwnPropertyDescriptor(TypedArrayPrototype, "toString"), {
|
||||
value: TypedArrayPrototype.toString,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
for (let constructor of constructors) {
|
||||
assertEq(new constructor([]).toString(), "");
|
||||
assertEq(new constructor([1]).toString(), "1");
|
||||
assertEq(new constructor([1, 2]).toString(), "1,2");
|
||||
}
|
||||
|
||||
assertEq(new Int8Array([-1, 2, -3, 4, NaN]).toString(), "-1,2,-3,4,0");
|
||||
assertEq(new Uint8Array([255, 2, 3, 4, NaN]).toString(), "255,2,3,4,0");
|
||||
assertEq(new Uint8ClampedArray([255, 256, 2, 3, 4, NaN]).toString(), "255,255,2,3,4,0");
|
||||
assertEq(new Int16Array([-1, 2, -3, 4, NaN]).toString(), "-1,2,-3,4,0");
|
||||
assertEq(new Uint16Array([-1, 2, 3, 4, NaN]).toString(), "65535,2,3,4,0");
|
||||
assertEq(new Int32Array([-1, 2, -3, 4, NaN]).toString(), "-1,2,-3,4,0");
|
||||
assertEq(new Uint32Array([-1, 2, 3, 4, NaN]).toString(), "4294967295,2,3,4,0");
|
||||
assertEq(new Float32Array([-0, 0, 0.5, -0.5, NaN, Infinity, -Infinity]).toString(), "0,0,0.5,-0.5,NaN,Infinity,-Infinity");
|
||||
assertEq(new Float64Array([-0, 0, 0.5, -0.5, NaN, Infinity, -Infinity]).toString(), "0,0,0.5,-0.5,NaN,Infinity,-Infinity");
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
|
@ -1353,7 +1353,7 @@ TypedArrayObject::protoFunctions[] = {
|
|||
#if 0 /* disabled until perf-testing is completed */
|
||||
JS_SELF_HOSTED_FN("set", "TypedArraySet", 2, 0),
|
||||
#else
|
||||
JS_FN("set", TypedArrayObject::set, 2, 0),
|
||||
JS_FN("set", TypedArrayObject::set, 1, 0),
|
||||
#endif
|
||||
JS_SELF_HOSTED_FN("copyWithin", "TypedArrayCopyWithin", 3, 0),
|
||||
JS_SELF_HOSTED_FN("every", "TypedArrayEvery", 2, 0),
|
||||
|
@ -1377,6 +1377,8 @@ TypedArrayObject::protoFunctions[] = {
|
|||
JS_SELF_HOSTED_FN("values", "TypedArrayValues", 0, 0),
|
||||
JS_SELF_HOSTED_SYM_FN(iterator, "TypedArrayValues", 0, 0),
|
||||
JS_SELF_HOSTED_FN("includes", "TypedArrayIncludes", 2, 0),
|
||||
JS_SELF_HOSTED_FN("toString", "ArrayToString", 0, 0),
|
||||
JS_SELF_HOSTED_FN("toLocaleString", "TypedArrayToLocaleString", 2, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
|
|
@ -4,5 +4,5 @@ function run_test() {
|
|||
var xhr = Cu.evalInSandbox('new XMLHttpRequest()', sb);
|
||||
do_check_eq(xhr.toString(), '[object XMLHttpRequest]');
|
||||
do_check_eq((new sb.Object()).toString(), '[object Object]');
|
||||
do_check_eq((new sb.Uint16Array()).toString(), '[object Uint16Array]');
|
||||
do_check_eq(sb.Object.prototype.toString.call(new sb.Uint16Array()), '[object Uint16Array]');
|
||||
}
|
||||
|
|
|
@ -1158,7 +1158,7 @@
|
|||
date = date.getTime();
|
||||
}
|
||||
|
||||
if (isNaN(date)) {
|
||||
if (typeof date !== "number" || isNaN(date)) {
|
||||
throw new TypeError("|date| parameter of " + fn + " must be a " +
|
||||
"|Date| instance or number");
|
||||
}
|
||||
|
|
|
@ -98,7 +98,8 @@ add_task(function* test_transfer_with_meta() {
|
|||
Assert.equal(array.buffer.byteLength, 0, "The buffer has been detached");
|
||||
|
||||
// Check that the result is correct
|
||||
Assert.equal(result.toString(), "[object Uint8Array]", "The result appears to be a Typed Array");
|
||||
Assert.equal(Object.prototype.toString.call(result), "[object Uint8Array]",
|
||||
"The result appears to be a Typed Array");
|
||||
Assert.equal(result.byteLength, 4, "The result has the right size");
|
||||
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче