mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 03:35:33 +00:00
Bug 1165053 - Part 1: Handle when ArrayBuffer species constructor returns wrapped ArrayBuffer. r=jwalden
This commit is contained in:
parent
6e95072f22
commit
f28ae392ef
@ -1308,7 +1308,7 @@ function TypedArrayStaticOf(/*...items*/) {
|
|||||||
return newObj;
|
return newObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ES 2016 draft Dec 10, 2015 24.1.4.3.
|
// ES 2016 draft Mar 25, 2016 24.1.4.3.
|
||||||
function ArrayBufferSlice(start, end) {
|
function ArrayBufferSlice(start, end) {
|
||||||
// Step 1.
|
// Step 1.
|
||||||
var O = this;
|
var O = this;
|
||||||
@ -1351,33 +1351,47 @@ function ArrayBufferSlice(start, end) {
|
|||||||
// Step 12.
|
// Step 12.
|
||||||
var new_ = new ctor(newLen);
|
var new_ = new ctor(newLen);
|
||||||
|
|
||||||
// Step 13.
|
var isWrapped = false;
|
||||||
if (!IsArrayBuffer(new_))
|
if (IsArrayBuffer(new_)) {
|
||||||
ThrowTypeError(JSMSG_NON_ARRAY_BUFFER_RETURNED);
|
// Step 14.
|
||||||
|
if (IsDetachedBuffer(new_))
|
||||||
|
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
|
||||||
|
} else {
|
||||||
|
// Step 13.
|
||||||
|
if (!IsWrappedArrayBuffer(new_))
|
||||||
|
ThrowTypeError(JSMSG_NON_ARRAY_BUFFER_RETURNED);
|
||||||
|
|
||||||
// Step 14.
|
isWrapped = true;
|
||||||
if (IsDetachedBuffer(new_))
|
|
||||||
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
|
// Step 14.
|
||||||
|
if (callFunction(CallArrayBufferMethodIfWrapped, new_, "IsDetachedBufferThis"))
|
||||||
|
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
|
||||||
|
}
|
||||||
|
|
||||||
// Step 15.
|
// Step 15.
|
||||||
if (new_ == O)
|
if (new_ === O)
|
||||||
ThrowTypeError(JSMSG_SAME_ARRAY_BUFFER_RETURNED);
|
ThrowTypeError(JSMSG_SAME_ARRAY_BUFFER_RETURNED);
|
||||||
|
|
||||||
// Step 16.
|
// Step 16.
|
||||||
if (ArrayBufferByteLength(new_) < newLen)
|
var actualLen = PossiblyWrappedArrayBufferByteLength(new_);
|
||||||
ThrowTypeError(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, newLen, ArrayBufferByteLength(new_));
|
if (actualLen < newLen)
|
||||||
|
ThrowTypeError(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, newLen, actualLen);
|
||||||
|
|
||||||
// Step 18.
|
// Step 18.
|
||||||
if (IsDetachedBuffer(O))
|
if (IsDetachedBuffer(O))
|
||||||
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
|
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
|
||||||
|
|
||||||
// Steps 19-21.
|
// Steps 19-21.
|
||||||
ArrayBufferCopyData(new_, O, first | 0, newLen | 0);
|
ArrayBufferCopyData(new_, O, first | 0, newLen | 0, isWrapped);
|
||||||
|
|
||||||
// Step 22.
|
// Step 22.
|
||||||
return new_;
|
return new_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function IsDetachedBufferThis() {
|
||||||
|
return IsDetachedBuffer(this);
|
||||||
|
}
|
||||||
|
|
||||||
function ArrayBufferStaticSlice(buf, start, end) {
|
function ArrayBufferStaticSlice(buf, start, end) {
|
||||||
if (arguments.length < 1)
|
if (arguments.length < 1)
|
||||||
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'ArrayBuffer.slice');
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'ArrayBuffer.slice');
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "vm/Interpreter.h"
|
#include "vm/Interpreter.h"
|
||||||
#include "vm/String.h"
|
#include "vm/String.h"
|
||||||
#include "vm/TypedArrayCommon.h"
|
#include "vm/TypedArrayCommon.h"
|
||||||
|
#include "vm/WrapperObject.h"
|
||||||
|
|
||||||
#include "jsfuninlines.h"
|
#include "jsfuninlines.h"
|
||||||
#include "jsobjinlines.h"
|
#include "jsobjinlines.h"
|
||||||
@ -868,6 +869,33 @@ intrinsic_GeneratorSetClosed(JSContext* cx, unsigned argc, Value* vp)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
intrinsic_IsWrappedArrayBuffer(JSContext* cx, unsigned argc, Value* vp)
|
||||||
|
{
|
||||||
|
CallArgs args = CallArgsFromVp(argc, vp);
|
||||||
|
MOZ_ASSERT(args.length() == 1);
|
||||||
|
|
||||||
|
if (!args[0].isObject()) {
|
||||||
|
args.rval().setBoolean(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject* obj = &args[0].toObject();
|
||||||
|
if (!obj->is<WrapperObject>()) {
|
||||||
|
args.rval().setBoolean(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject* unwrapped = CheckedUnwrap(obj);
|
||||||
|
if (!unwrapped) {
|
||||||
|
JS_ReportError(cx, "Permission denied to access object");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.rval().setBoolean(unwrapped->is<ArrayBufferObject>());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
intrinsic_ArrayBufferByteLength(JSContext* cx, unsigned argc, Value* vp)
|
intrinsic_ArrayBufferByteLength(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
@ -902,15 +930,22 @@ static bool
|
|||||||
intrinsic_ArrayBufferCopyData(JSContext* cx, unsigned argc, Value* vp)
|
intrinsic_ArrayBufferCopyData(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
CallArgs args = CallArgsFromVp(argc, vp);
|
CallArgs args = CallArgsFromVp(argc, vp);
|
||||||
MOZ_ASSERT(args.length() == 4);
|
MOZ_ASSERT(args.length() == 5);
|
||||||
MOZ_ASSERT(args[0].isObject());
|
|
||||||
MOZ_ASSERT(args[0].toObject().is<ArrayBufferObject>());
|
|
||||||
MOZ_ASSERT(args[1].isObject());
|
|
||||||
MOZ_ASSERT(args[1].toObject().is<ArrayBufferObject>());
|
|
||||||
MOZ_ASSERT(args[2].isInt32());
|
|
||||||
MOZ_ASSERT(args[3].isInt32());
|
|
||||||
|
|
||||||
Rooted<ArrayBufferObject*> toBuffer(cx, &args[0].toObject().as<ArrayBufferObject>());
|
bool isWrapped = args[4].toBoolean();
|
||||||
|
Rooted<ArrayBufferObject*> toBuffer(cx);
|
||||||
|
if (!isWrapped) {
|
||||||
|
toBuffer = &args[0].toObject().as<ArrayBufferObject>();
|
||||||
|
} else {
|
||||||
|
JSObject* wrapped = &args[0].toObject();
|
||||||
|
MOZ_ASSERT(wrapped->is<WrapperObject>());
|
||||||
|
RootedObject toBufferObj(cx, CheckedUnwrap(wrapped));
|
||||||
|
if (!toBufferObj) {
|
||||||
|
JS_ReportError(cx, "Permission denied to access object");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
toBuffer = toBufferObj.as<ArrayBufferObject>();
|
||||||
|
}
|
||||||
Rooted<ArrayBufferObject*> fromBuffer(cx, &args[1].toObject().as<ArrayBufferObject>());
|
Rooted<ArrayBufferObject*> fromBuffer(cx, &args[1].toObject().as<ArrayBufferObject>());
|
||||||
uint32_t fromIndex = uint32_t(args[2].toInt32());
|
uint32_t fromIndex = uint32_t(args[2].toInt32());
|
||||||
uint32_t count = uint32_t(args[3].toInt32());
|
uint32_t count = uint32_t(args[3].toInt32());
|
||||||
@ -2167,12 +2202,13 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
|||||||
intrinsic_IsInstanceOfBuiltin<ArrayBufferObject>, 1,0),
|
intrinsic_IsInstanceOfBuiltin<ArrayBufferObject>, 1,0),
|
||||||
JS_FN("IsSharedArrayBuffer",
|
JS_FN("IsSharedArrayBuffer",
|
||||||
intrinsic_IsInstanceOfBuiltin<SharedArrayBufferObject>, 1,0),
|
intrinsic_IsInstanceOfBuiltin<SharedArrayBufferObject>, 1,0),
|
||||||
|
JS_FN("IsWrappedArrayBuffer", intrinsic_IsWrappedArrayBuffer, 1,0),
|
||||||
|
|
||||||
JS_INLINABLE_FN("ArrayBufferByteLength", intrinsic_ArrayBufferByteLength, 1,0,
|
JS_INLINABLE_FN("ArrayBufferByteLength", intrinsic_ArrayBufferByteLength, 1,0,
|
||||||
IntrinsicArrayBufferByteLength),
|
IntrinsicArrayBufferByteLength),
|
||||||
JS_INLINABLE_FN("PossiblyWrappedArrayBufferByteLength", intrinsic_PossiblyWrappedArrayBufferByteLength, 1,0,
|
JS_INLINABLE_FN("PossiblyWrappedArrayBufferByteLength", intrinsic_PossiblyWrappedArrayBufferByteLength, 1,0,
|
||||||
IntrinsicPossiblyWrappedArrayBufferByteLength),
|
IntrinsicPossiblyWrappedArrayBufferByteLength),
|
||||||
JS_FN("ArrayBufferCopyData", intrinsic_ArrayBufferCopyData, 4,0),
|
JS_FN("ArrayBufferCopyData", intrinsic_ArrayBufferCopyData, 5,0),
|
||||||
|
|
||||||
JS_FN("IsUint8TypedArray", intrinsic_IsUint8TypedArray, 1,0),
|
JS_FN("IsUint8TypedArray", intrinsic_IsUint8TypedArray, 1,0),
|
||||||
JS_FN("IsInt8TypedArray", intrinsic_IsInt8TypedArray, 1,0),
|
JS_FN("IsInt8TypedArray", intrinsic_IsInt8TypedArray, 1,0),
|
||||||
|
Loading…
Reference in New Issue
Block a user