diff --git a/js/src/Makefile.in b/js/src/Makefile.in index 84b7e6cdb7a1..1fe5dcb8c0e7 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -326,6 +326,7 @@ selfhosting_srcs := \ $(srcdir)/builtin/Object.js \ $(srcdir)/builtin/String.js \ $(srcdir)/builtin/Set.js \ + $(srcdir)/builtin/TypedArray.js \ $(srcdir)/builtin/TypedObject.js \ $(srcdir)/builtin/WeakSet.js \ $(NULL) diff --git a/js/src/builtin/TypedArray.js b/js/src/builtin/TypedArray.js new file mode 100644 index 000000000000..548c9dd02f9b --- /dev/null +++ b/js/src/builtin/TypedArray.js @@ -0,0 +1,71 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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 rev28 (2014/10/14) 22.2.3.10 %TypedArray%.prototype.find(predicate [,thisArg]). +function TypedArrayFind(predicate, thisArg = undefined) { + // This function is not generic. + if (!IsObject(this) || !IsTypedArray(this)) + ThrowError(JSMSG_INCOMPATIBLE_PROTO, "%TypedArray%", "find", typeof this); + + // Steps 1-2. + var O = this; + + // Steps 3-5. + var len = TypedArrayLength(O); + + // Step 6. + if (arguments.length === 0) + ThrowError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.find"); + if (!IsCallable(predicate)) + ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); + + // Step 7. + var T = thisArg; + + // Steps 8-9. */ + // Steps a (implicit), and g. + for (var k = 0; k < len; k++) { + // Steps a-c. + var kValue = O[k]; + // Steps d-f. + if (callFunction(predicate, T, kValue, k, O)) + return kValue; + } + + // Step 10. + return undefined; +} + +// ES6 draft rev28 (2014/10/14) 22.2.3.11 %TypedArray%.prototype.findIndex(predicate [,thisArg]). +function TypedArrayFindIndex(predicate, thisArg = undefined) { + // This function is not generic. + if (!IsObject(this) || !IsTypedArray(this)) + ThrowError(JSMSG_INCOMPATIBLE_PROTO, "%TypedArray%", "findIndex", typeof this); + + // Steps 1-2. + var O = this; + + // Steps 3-5. + var len = TypedArrayLength(O); + + // Step 6. + if (arguments.length === 0) + ThrowError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.findIndex"); + if (!IsCallable(predicate)) + ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); + + // Step 7. + var T = thisArg; + + // Steps 8-9. + // Steps a (implicit), and g. + for (var k = 0; k < len; k++) { + // Steps a-f. + if (callFunction(predicate, T, O[k], k, O)) + return k; + } + + // Step 10. + return -1; +} diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 045db1f43f0f..85ac5af9772e 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -785,6 +785,31 @@ intrinsic_GeneratorSetClosed(JSContext *cx, unsigned argc, Value *vp) return true; } +// Return the value of [[ArrayLength]] internal slot of the TypedArray +static bool +intrinsic_TypedArrayLength(JSContext *cx, unsigned argc, Value *vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); + MOZ_ASSERT(args.length() == 1); + + RootedObject obj(cx, &args[0].toObject()); + MOZ_ASSERT(obj->is()); + args.rval().setInt32(obj->as().length()); + return true; +} + +static bool +intrinsic_IsTypedArray(JSContext *cx, unsigned argc, Value *vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); + MOZ_ASSERT(args.length() == 1); + MOZ_ASSERT(args[0].isObject()); + + RootedObject obj(cx, &args[0].toObject()); + args.rval().setBoolean(obj->is()); + return true; +} + bool CallSelfHostedNonGenericMethod(JSContext *cx, CallArgs args) { @@ -1081,6 +1106,9 @@ static const JSFunctionSpec intrinsic_functions[] = { JS_FN("GeneratorIsRunning", intrinsic_GeneratorIsRunning, 1,0), JS_FN("GeneratorSetClosed", intrinsic_GeneratorSetClosed, 1,0), + JS_FN("TypedArrayLength", intrinsic_TypedArrayLength, 1,0), + JS_FN("IsTypedArray", intrinsic_IsTypedArray, 1,0), + JS_FN("CallLegacyGeneratorMethodIfWrapped", (NativeMethod), 2, 0), JS_FN("CallStarGeneratorMethodIfWrapped", diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 9ed57574fbec..abb93452b550 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -785,6 +785,8 @@ TypedArrayObject::protoFunctions[] = { JS_FN("subarray", TypedArrayObject::subarray, 2, 0), JS_FN("set", TypedArrayObject::set, 2, 0), JS_FN("copyWithin", TypedArrayObject::copyWithin, 2, 0), + JS_SELF_HOSTED_FN("find", "TypedArrayFind", 2, 0), + JS_SELF_HOSTED_FN("findIndex", "TypedArrayFindIndex", 2, 0), JS_FS_END }; diff --git a/js/xpconnect/tests/chrome/test_xrayToJS.xul b/js/xpconnect/tests/chrome/test_xrayToJS.xul index be1766877599..7defe088cc54 100644 --- a/js/xpconnect/tests/chrome/test_xrayToJS.xul +++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul @@ -180,7 +180,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681 } gPrototypeProperties['TypedArray'] = ["length", "buffer", "byteLength", "byteOffset", kIteratorSymbol, "subarray", - "set", "copyWithin"]; + "set", "copyWithin", "find", "findIndex"]; for (var c of errorObjectClasses) { gPrototypeProperties[c] = ["constructor", "name",