diff --git a/js/src/vm/TypedArrayCommon.h b/js/src/vm/TypedArrayCommon.h index 56afbed5277d..e1bf762fd1fe 100644 --- a/js/src/vm/TypedArrayCommon.h +++ b/js/src/vm/TypedArrayCommon.h @@ -602,191 +602,6 @@ class TypedArrayMethods typedef typename SomeTypedArray::template OfType::Type Uint8ClampedArrayType; public: - // subarray(start[, end]) - // %TypedArray%.prototype.subarray is a self-hosted method, so this code is - // only used for shared typed arrays. We should self-host both methods - // eventually (but note TypedArraySubarray will require changes to be used - // with shared typed arrays), but we need to rejigger the shared typed - // array prototype chain before we can do that. - static bool - subarray(JSContext* cx, const CallArgs& args) - { - MOZ_ASSERT(SomeTypedArray::is(args.thisv())); - - Rooted tarray(cx, &args.thisv().toObject().as()); - - // These are the default values. - uint32_t initialLength = tarray->length(); - uint32_t begin = 0, end = initialLength; - - if (args.length() > 0) { - if (!ToClampedIndex(cx, args[0], initialLength, &begin)) - return false; - - if (args.length() > 1) { - if (!ToClampedIndex(cx, args[1], initialLength, &end)) - return false; - } - } - - if (begin > end) - begin = end; - - if (begin > tarray->length() || end > tarray->length() || begin > end) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX); - return false; - } - - if (!SomeTypedArray::ensureHasBuffer(cx, tarray)) - return false; - - Rooted bufobj(cx, tarray->buffer()); - MOZ_ASSERT(bufobj); - - uint32_t length = end - begin; - - size_t elementSize = tarray->bytesPerElement(); - MOZ_ASSERT(begin < UINT32_MAX / elementSize); - - uint32_t arrayByteOffset = tarray->byteOffset(); - MOZ_ASSERT(UINT32_MAX - begin * elementSize >= arrayByteOffset); - - uint32_t byteOffset = arrayByteOffset + begin * elementSize; - - JSObject* nobj = nullptr; - switch (tarray->type()) { - case Scalar::Int8: - nobj = Int8ArrayType::makeInstance(cx, bufobj, byteOffset, length); - break; - case Scalar::Uint8: - nobj = Uint8ArrayType::makeInstance(cx, bufobj, byteOffset, length); - break; - case Scalar::Int16: - nobj = Int16ArrayType::makeInstance(cx, bufobj, byteOffset, length); - break; - case Scalar::Uint16: - nobj = Uint16ArrayType::makeInstance(cx, bufobj, byteOffset, length); - break; - case Scalar::Int32: - nobj = Int32ArrayType::makeInstance(cx, bufobj, byteOffset, length); - break; - case Scalar::Uint32: - nobj = Uint32ArrayType::makeInstance(cx, bufobj, byteOffset, length); - break; - case Scalar::Float32: - nobj = Float32ArrayType::makeInstance(cx, bufobj, byteOffset, length); - break; - case Scalar::Float64: - nobj = Float64ArrayType::makeInstance(cx, bufobj, byteOffset, length); - break; - case Scalar::Uint8Clamped: - nobj = Uint8ClampedArrayType::makeInstance(cx, bufobj, byteOffset, length); - break; - default: - MOZ_CRASH("nonsense target element type"); - break; - } - if (!nobj) - return false; - - args.rval().setObject(*nobj); - return true; - } - - /* copyWithin(target, start[, end]) */ - // ES6 draft rev 26, 22.2.3.5 - // %TypedArray%.prototype.copyWithin is a self-hosted method, so this code - // is only used for shared typed arrays. We should self-host both methods - // eventually (but note TypedArrayCopyWithin will require changes to be - // usable for shared typed arrays), but we need to rejigger the shared - // typed array prototype chain before we can do that. - static bool - copyWithin(JSContext* cx, const CallArgs& args) - { - MOZ_ASSERT(SomeTypedArray::is(args.thisv())); - - // Steps 1-2. - Rooted obj(cx, &args.thisv().toObject().as()); - - // Steps 3-4. - uint32_t len = obj->length(); - - // Steps 6-8. - uint32_t to; - if (!ToClampedIndex(cx, args.get(0), len, &to)) - return false; - - // Steps 9-11. - uint32_t from; - if (!ToClampedIndex(cx, args.get(1), len, &from)) - return false; - - // Steps 12-14. - uint32_t final; - if (args.get(2).isUndefined()) { - final = len; - } else { - if (!ToClampedIndex(cx, args.get(2), len, &final)) - return false; - } - - // Steps 15-18. - - // If |final - from < 0|, then |count| will be less than 0, so step 18 - // never loops. Exit early so |count| can use a non-negative type. - // Also exit early if elements are being moved to their pre-existing - // location. - if (final < from || to == from) { - args.rval().setObject(*obj); - return true; - } - - uint32_t count = Min(final - from, len - to); - uint32_t lengthDuringMove = obj->length(); // beware ToClampedIndex - - // Technically |from + count| and |to + count| can't overflow, because - // buffer contents are limited to INT32_MAX length. But eventually - // we're going to lift this restriction, and the extra checking cost is - // negligible, so just handle it anyway. - if (from > lengthDuringMove || - to > lengthDuringMove || - count > lengthDuringMove - from || - count > lengthDuringMove - to) - { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS); - return false; - } - - const size_t ElementSize = obj->bytesPerElement(); - - MOZ_ASSERT(to <= UINT32_MAX / ElementSize); - uint32_t byteDest = to * ElementSize; - - MOZ_ASSERT(from <= UINT32_MAX / ElementSize); - uint32_t byteSrc = from * ElementSize; - - MOZ_ASSERT(count <= UINT32_MAX / ElementSize); - uint32_t byteSize = count * ElementSize; - - -#ifdef DEBUG - uint32_t viewByteLength = obj->byteLength(); - MOZ_ASSERT(byteSize <= viewByteLength); - MOZ_ASSERT(byteDest <= viewByteLength); - MOZ_ASSERT(byteSrc <= viewByteLength); - MOZ_ASSERT(byteDest <= viewByteLength - byteSize); - MOZ_ASSERT(byteSrc <= viewByteLength - byteSize); -#endif - - SharedMem data = - obj->template as().viewDataEither().template cast(); - SharedOps::memmove(data + byteDest, data + byteSrc, byteSize); - - // Step 19. - args.rval().set(args.thisv()); - return true; - } - /* set(array[, offset]) */ static bool set(JSContext* cx, const CallArgs& args)