mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1119217 - Implement %TypedArray%.prototype.{keys, values, entries}. r=till
This commit is contained in:
parent
b2bf53a267
commit
bb29a349eb
@ -2,6 +2,22 @@
|
||||
* 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/. */
|
||||
|
||||
// ES6 draft rev30 (2014/12/24) 22.2.3.6 %TypedArray%.prototype.entries()
|
||||
function TypedArrayEntries() {
|
||||
// Step 1.
|
||||
var O = this;
|
||||
|
||||
// Step 2-3.
|
||||
if (!IsObject(O) || !IsTypedArray(O)) {
|
||||
return callFunction(CallTypedArrayMethodIfWrapped, O, "TypedArrayEntries");
|
||||
}
|
||||
|
||||
// Step 4-6. Bug 1101256: detachment checks
|
||||
|
||||
// Step 7.
|
||||
return CreateArrayIterator(O, ITEM_KIND_KEY_AND_VALUE);
|
||||
}
|
||||
|
||||
// ES6 draft rev30 (2014/12/24) 22.2.3.7 %TypedArray%.prototype.every(callbackfn[, thisArg]).
|
||||
function TypedArrayEvery(callbackfn, thisArg = undefined) {
|
||||
// This function is not generic.
|
||||
@ -251,6 +267,22 @@ function TypedArrayJoin(separator) {
|
||||
return R;
|
||||
}
|
||||
|
||||
// ES6 draft rev30 (2014/12/24) 22.2.3.15 %TypedArray%.prototype.keys()
|
||||
function TypedArrayKeys() {
|
||||
// Step 1.
|
||||
var O = this;
|
||||
|
||||
// Step 2-3.
|
||||
if (!IsObject(O) || !IsTypedArray(O)) {
|
||||
return callFunction(CallTypedArrayMethodIfWrapped, O, "TypedArrayKeys");
|
||||
}
|
||||
|
||||
// Step 4-6. Bug 1101256: detachment checks
|
||||
|
||||
// Step 7.
|
||||
return CreateArrayIterator(O, ITEM_KIND_KEY);
|
||||
}
|
||||
|
||||
// ES6 draft rev29 (2014/12/06) 22.2.3.16 %TypedArray%.prototype.lastIndexOf(searchElement [,fromIndex]).
|
||||
function TypedArrayLastIndexOf(searchElement, fromIndex = undefined) {
|
||||
// This function is not generic.
|
||||
@ -443,6 +475,22 @@ function TypedArraySome(callbackfn, thisArg = undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ES6 draft rev30 (2014/12/24) 22.2.3.30 %TypedArray%.prototype.values()
|
||||
function TypedArrayValues() {
|
||||
// Step 1.
|
||||
var O = this;
|
||||
|
||||
// Step 2-3.
|
||||
if (!IsObject(O) || !IsTypedArray(O)) {
|
||||
return callFunction(CallTypedArrayMethodIfWrapped, O, "TypedArrayValues");
|
||||
}
|
||||
|
||||
// Step 4-6. Bug 1101256: detachment checks
|
||||
|
||||
// Step 7.
|
||||
return CreateArrayIterator(O, ITEM_KIND_VALUE);
|
||||
}
|
||||
|
||||
// Proposed for ES7:
|
||||
// https://github.com/tc39/Array.prototype.includes/blob/7c023c19a0/spec.md
|
||||
function TypedArrayIncludes(searchElement, fromIndex = 0) {
|
||||
|
49
js/src/tests/ecma_6/TypedArray/entries.js
Normal file
49
js/src/tests/ecma_6/TypedArray/entries.js
Normal file
@ -0,0 +1,49 @@
|
||||
const constructors = [
|
||||
Int8Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
Int16Array,
|
||||
Uint16Array,
|
||||
Int32Array,
|
||||
Uint32Array,
|
||||
Float32Array,
|
||||
Float64Array
|
||||
];
|
||||
|
||||
for (var constructor of constructors) {
|
||||
assertEq(constructor.prototype.entries.length, 0);
|
||||
assertEq(constructor.prototype.entries.name, "entries");
|
||||
|
||||
assertDeepEq([...new constructor(0).entries()], []);
|
||||
assertDeepEq([...new constructor(1).entries()], [[0, 0]]);
|
||||
assertDeepEq([...new constructor(2).entries()], [[0, 0], [1, 0]]);
|
||||
assertDeepEq([...new constructor([15]).entries()], [[0, 15]]);
|
||||
|
||||
var arr = new constructor([1, 2, 3]);
|
||||
var iterator = arr.entries();
|
||||
assertDeepEq(iterator.next(), {value: [0, 1], done: false});
|
||||
assertDeepEq(iterator.next(), {value: [1, 2], done: false});
|
||||
assertDeepEq(iterator.next(), {value: [2, 3], done: false});
|
||||
assertDeepEq(iterator.next(), {value: undefined, done: true});
|
||||
|
||||
// Called from other globals.
|
||||
if (typeof newGlobal === "function") {
|
||||
var entries = newGlobal()[constructor.name].prototype.entries;
|
||||
assertDeepEq([...entries.call(new constructor(2))], [[0, 0], [1, 0]]);
|
||||
arr = newGlobal()[constructor.name](2);
|
||||
assertEq([...constructor.prototype.entries.call(arr)].toString(), "0,0,1,0");
|
||||
}
|
||||
|
||||
// Throws if `this` isn't a TypedArray.
|
||||
var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
|
||||
invalidReceivers.forEach(invalidReceiver => {
|
||||
assertThrowsInstanceOf(() => {
|
||||
constructor.prototype.entries.call(invalidReceiver);
|
||||
}, TypeError, "Assert that entries fails if this value is not a TypedArray");
|
||||
});
|
||||
// FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
|
||||
constructor.prototype.entries.call(new Proxy(new constructor(), {}));
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
49
js/src/tests/ecma_6/TypedArray/keys.js
Normal file
49
js/src/tests/ecma_6/TypedArray/keys.js
Normal file
@ -0,0 +1,49 @@
|
||||
const constructors = [
|
||||
Int8Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
Int16Array,
|
||||
Uint16Array,
|
||||
Int32Array,
|
||||
Uint32Array,
|
||||
Float32Array,
|
||||
Float64Array
|
||||
];
|
||||
|
||||
for (var constructor of constructors) {
|
||||
assertEq(constructor.prototype.keys.length, 0);
|
||||
assertEq(constructor.prototype.keys.name, "keys");
|
||||
|
||||
assertDeepEq([...new constructor(0).keys()], []);
|
||||
assertDeepEq([...new constructor(1).keys()], [0]);
|
||||
assertDeepEq([...new constructor(2).keys()], [0, 1]);
|
||||
assertDeepEq([...new constructor([15]).keys()], [0]);
|
||||
|
||||
var arr = new constructor([1, 2, 3]);
|
||||
var iterator = arr.keys();
|
||||
assertDeepEq(iterator.next(), {value: 0, done: false});
|
||||
assertDeepEq(iterator.next(), {value: 1, done: false});
|
||||
assertDeepEq(iterator.next(), {value: 2, done: false});
|
||||
assertDeepEq(iterator.next(), {value: undefined, done: true});
|
||||
|
||||
// Called from other globals.
|
||||
if (typeof newGlobal === "function") {
|
||||
var keys = newGlobal()[constructor.name].prototype.keys;
|
||||
assertDeepEq([...keys.call(new constructor(2))], [0, 1]);
|
||||
arr = newGlobal()[constructor.name](2);
|
||||
assertEq([...constructor.prototype.keys.call(arr)].toString(), "0,1");
|
||||
}
|
||||
|
||||
// Throws if `this` isn't a TypedArray.
|
||||
var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
|
||||
invalidReceivers.forEach(invalidReceiver => {
|
||||
assertThrowsInstanceOf(() => {
|
||||
constructor.prototype.keys.call(invalidReceiver);
|
||||
}, TypeError, "Assert that keys fails if this value is not a TypedArray");
|
||||
});
|
||||
// FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
|
||||
constructor.prototype.keys.call(new Proxy(new constructor(), {}));
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
50
js/src/tests/ecma_6/TypedArray/values.js
Normal file
50
js/src/tests/ecma_6/TypedArray/values.js
Normal file
@ -0,0 +1,50 @@
|
||||
const constructors = [
|
||||
Int8Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
Int16Array,
|
||||
Uint16Array,
|
||||
Int32Array,
|
||||
Uint32Array,
|
||||
Float32Array,
|
||||
Float64Array
|
||||
];
|
||||
|
||||
for (var constructor of constructors) {
|
||||
assertEq(constructor.prototype.values.length, 0);
|
||||
assertEq(constructor.prototype.values.name, "values");
|
||||
assertEq(constructor.prototype.values, constructor.prototype[Symbol.iterator]);
|
||||
|
||||
assertDeepEq([...new constructor(0).values()], []);
|
||||
assertDeepEq([...new constructor(1).values()], [0]);
|
||||
assertDeepEq([...new constructor(2).values()], [0, 0]);
|
||||
assertDeepEq([...new constructor([15]).values()], [15]);
|
||||
|
||||
var arr = new constructor([1, 2, 3]);
|
||||
var iterator = arr.values();
|
||||
assertDeepEq(iterator.next(), {value: 1, done: false});
|
||||
assertDeepEq(iterator.next(), {value: 2, done: false});
|
||||
assertDeepEq(iterator.next(), {value: 3, done: false});
|
||||
assertDeepEq(iterator.next(), {value: undefined, done: true});
|
||||
|
||||
// Called from other globals.
|
||||
if (typeof newGlobal === "function") {
|
||||
var values = newGlobal()[constructor.name].prototype.values;
|
||||
assertDeepEq([...values.call(new constructor([42, 36]))], [42, 36]);
|
||||
arr = newGlobal()[constructor.name]([42, 36]);
|
||||
assertEq([...constructor.prototype.values.call(arr)].toString(), "42,36");
|
||||
}
|
||||
|
||||
// Throws if `this` isn't a TypedArray.
|
||||
var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
|
||||
invalidReceivers.forEach(invalidReceiver => {
|
||||
assertThrowsInstanceOf(() => {
|
||||
constructor.prototype.values.call(invalidReceiver);
|
||||
}, TypeError, "Assert that values fails if this value is not a TypedArray");
|
||||
});
|
||||
// FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
|
||||
constructor.prototype.values.call(new Proxy(new constructor(), {}));
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
@ -211,6 +211,7 @@
|
||||
macro(useAsm, useAsm, "use asm") \
|
||||
macro(useStrict, useStrict, "use strict") \
|
||||
macro(value, value, "value") \
|
||||
macro(values, values, "values") \
|
||||
macro(valueOf, valueOf, "valueOf") \
|
||||
macro(var, var, "var") \
|
||||
macro(variable, variable, "variable") \
|
||||
|
@ -259,7 +259,6 @@ class TypedArrayObjectTemplate : public TypedArrayObject
|
||||
return false;
|
||||
|
||||
cx->global()->setCreateArrayFromBuffer<NativeType>(fun);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -695,6 +694,34 @@ TypedArrayConstructor(JSContext *cx, unsigned argc, Value *vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
FinishTypedArrayInit(JSContext *cx, HandleObject ctor, HandleObject proto)
|
||||
{
|
||||
// Define `values` and `@@iterator` manually, because they are supposed to be the same object.
|
||||
RootedId name(cx, NameToId(cx->names().values));
|
||||
RootedFunction fun(cx, GetSelfHostedFunction(cx, "TypedArrayValues", name, 0));
|
||||
if (!fun)
|
||||
return false;
|
||||
|
||||
RootedValue funValue(cx, ObjectValue(*fun));
|
||||
if (!JSObject::defineProperty(cx, proto, cx->names().values, funValue, nullptr, nullptr, 0))
|
||||
return false;
|
||||
|
||||
#ifdef JS_HAS_SYMBOLS
|
||||
RootedId iteratorId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator));
|
||||
if (!JSObject::defineGeneric(cx, proto, iteratorId, funValue, nullptr, nullptr, 0))
|
||||
return false;
|
||||
#else
|
||||
if (!JSObject::defineProperty(cx, proto, cx->names().std_iterator, funValue, nullptr,
|
||||
nullptr, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* These next 3 functions are brought to you by the buggy GCC we use to build
|
||||
* B2G ICS. Older GCC versions have a bug in which they fail to compile
|
||||
@ -779,7 +806,6 @@ TypedArrayObject::subarray(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
||||
/* static */ const JSFunctionSpec
|
||||
TypedArrayObject::protoFunctions[] = {
|
||||
JS_SELF_HOSTED_SYM_FN(iterator, "ArrayValues", 0, 0), \
|
||||
JS_FN("subarray", TypedArrayObject::subarray, 2, 0),
|
||||
JS_FN("set", TypedArrayObject::set, 2, 0),
|
||||
JS_FN("copyWithin", TypedArrayObject::copyWithin, 2, 0),
|
||||
@ -794,6 +820,11 @@ TypedArrayObject::protoFunctions[] = {
|
||||
JS_SELF_HOSTED_FN("reduceRight", "TypedArrayReduceRight", 1, 0),
|
||||
JS_SELF_HOSTED_FN("reverse", "TypedArrayReverse", 0, 0),
|
||||
JS_SELF_HOSTED_FN("some", "TypedArraySome", 2, 0),
|
||||
JS_SELF_HOSTED_FN("entries", "TypedArrayEntries", 0, 0),
|
||||
JS_SELF_HOSTED_FN("keys", "TypedArrayKeys", 0, 0),
|
||||
// Both of these are actually defined to the same object in FinishTypedArrayInit.
|
||||
JS_SELF_HOSTED_FN("values", "TypedArrayValues", 0, JSPROP_DEFINE_LATE),
|
||||
JS_SELF_HOSTED_SYM_FN(iterator, "TypedArrayValues", 0, JSPROP_DEFINE_LATE),
|
||||
#ifdef NIGHTLY_BUILD
|
||||
JS_SELF_HOSTED_FN("includes", "TypedArrayIncludes", 2, 0),
|
||||
#endif
|
||||
@ -834,7 +865,7 @@ TypedArrayObject::sharedTypedArrayPrototypeClass = {
|
||||
TypedArrayObject::staticFunctions,
|
||||
TypedArrayObject::protoFunctions,
|
||||
TypedArrayObject::protoAccessors,
|
||||
nullptr,
|
||||
FinishTypedArrayInit,
|
||||
ClassSpec::DontDefineConstructor
|
||||
}
|
||||
};
|
||||
|
@ -179,7 +179,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
|
||||
gPrototypeProperties['TypedArray'] =
|
||||
["length", "buffer", "byteLength", "byteOffset", kIteratorSymbol, "subarray",
|
||||
"set", "copyWithin", "find", "findIndex", "indexOf", "lastIndexOf", "reverse",
|
||||
"join", "every", "some", "reduce", "reduceRight"];
|
||||
"join", "every", "some", "reduce", "reduceRight", "entries", "keys", "values"];
|
||||
if (isNightlyBuild) {
|
||||
gPrototypeProperties['TypedArray'].push('includes');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user