зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1303714 - Always Unwrap ArrayBuffer in TypedArray constructor. r=bholley
This commit is contained in:
Родитель
4c034fe691
Коммит
4e49d5103f
|
@ -765,15 +765,6 @@ class TypedArrayObjectTemplate : public TypedArrayObject
|
||||||
fromBufferWithProto(JSContext* cx, HandleObject bufobj, uint32_t byteOffset, int32_t lengthInt,
|
fromBufferWithProto(JSContext* cx, HandleObject bufobj, uint32_t byteOffset, int32_t lengthInt,
|
||||||
HandleObject proto)
|
HandleObject proto)
|
||||||
{
|
{
|
||||||
ESClass cls;
|
|
||||||
if (!GetBuiltinClass(cx, bufobj, &cls))
|
|
||||||
return nullptr;
|
|
||||||
if (cls != ESClass::ArrayBuffer && cls != ESClass::SharedArrayBuffer) {
|
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(IsArrayBuffer(bufobj) || IsSharedArrayBuffer(bufobj) || bufobj->is<ProxyObject>());
|
|
||||||
if (bufobj->is<ProxyObject>()) {
|
if (bufobj->is<ProxyObject>()) {
|
||||||
/*
|
/*
|
||||||
* Normally, NonGenericMethodGuard handles the case of transparent
|
* Normally, NonGenericMethodGuard handles the case of transparent
|
||||||
|
@ -791,44 +782,48 @@ class TypedArrayObjectTemplate : public TypedArrayObject
|
||||||
JS_ReportErrorASCII(cx, "Permission denied to access object");
|
JS_ReportErrorASCII(cx, "Permission denied to access object");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (IsArrayBuffer(wrapped) || IsSharedArrayBuffer(wrapped)) {
|
|
||||||
/*
|
|
||||||
* And for even more fun, the new view's prototype should be
|
|
||||||
* set to the origin compartment's prototype object, not the
|
|
||||||
* target's (specifically, the actual view in the target
|
|
||||||
* compartment will use as its prototype a wrapper around the
|
|
||||||
* origin compartment's view.prototype object).
|
|
||||||
*
|
|
||||||
* Rather than hack some crazy solution together, implement
|
|
||||||
* this all using a private helper function, created when
|
|
||||||
* ArrayBufferObject was initialized and cached in the global.
|
|
||||||
* This reuses all the existing cross-compartment crazy so we
|
|
||||||
* don't have to do anything *uniquely* crazy here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
RootedObject protoRoot(cx, proto);
|
if (!IsArrayBuffer(wrapped) && !IsSharedArrayBuffer(wrapped)) {
|
||||||
if (!protoRoot) {
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
|
||||||
if (!GetBuiltinPrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()), &protoRoot))
|
return nullptr; // must be arrayBuffer
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FixedInvokeArgs<3> args(cx);
|
|
||||||
|
|
||||||
args[0].setNumber(byteOffset);
|
|
||||||
args[1].setInt32(lengthInt);
|
|
||||||
args[2].setObject(*protoRoot);
|
|
||||||
|
|
||||||
RootedValue fval(cx);
|
|
||||||
if (!getOrCreateCreateArrayFromBufferFunction(cx, &fval))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
RootedValue thisv(cx, ObjectValue(*bufobj));
|
|
||||||
RootedValue rval(cx);
|
|
||||||
if (!js::Call(cx, fval, thisv, args, &rval))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return &rval.toObject();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* And for even more fun, the new view's prototype should be
|
||||||
|
* set to the origin compartment's prototype object, not the
|
||||||
|
* target's (specifically, the actual view in the target
|
||||||
|
* compartment will use as its prototype a wrapper around the
|
||||||
|
* origin compartment's view.prototype object).
|
||||||
|
*
|
||||||
|
* Rather than hack some crazy solution together, implement
|
||||||
|
* this all using a private helper function, created when
|
||||||
|
* ArrayBufferObject was initialized and cached in the global.
|
||||||
|
* This reuses all the existing cross-compartment crazy so we
|
||||||
|
* don't have to do anything *uniquely* crazy here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
RootedObject protoRoot(cx, proto);
|
||||||
|
if (!protoRoot) {
|
||||||
|
if (!GetBuiltinPrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()), &protoRoot))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
FixedInvokeArgs<3> args(cx);
|
||||||
|
|
||||||
|
args[0].setNumber(byteOffset);
|
||||||
|
args[1].setInt32(lengthInt);
|
||||||
|
args[2].setObject(*protoRoot);
|
||||||
|
|
||||||
|
RootedValue fval(cx);
|
||||||
|
if (!getOrCreateCreateArrayFromBufferFunction(cx, &fval))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
RootedValue thisv(cx, ObjectValue(*bufobj));
|
||||||
|
RootedValue rval(cx);
|
||||||
|
if (!js::Call(cx, fval, thisv, args, &rval))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &rval.toObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsArrayBuffer(bufobj) && !IsSharedArrayBuffer(bufobj)) {
|
if (!IsArrayBuffer(bufobj) && !IsSharedArrayBuffer(bufobj)) {
|
||||||
|
|
|
@ -753,6 +753,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
|
||||||
is(t.length, 10, "Length accessor works over Xrays")
|
is(t.length, 10, "Length accessor works over Xrays")
|
||||||
is(t.byteLength, t.length * window[c].prototype.BYTES_PER_ELEMENT, "byteLength accessor works over Xrays")
|
is(t.byteLength, t.length * window[c].prototype.BYTES_PER_ELEMENT, "byteLength accessor works over Xrays")
|
||||||
|
|
||||||
|
// Can create TypedArray from content ArrayBuffer
|
||||||
|
var buffer = new iwin.ArrayBuffer(8);
|
||||||
|
eval(`new ${c}(buffer);`);
|
||||||
|
|
||||||
var xray = new iwin[c](0);
|
var xray = new iwin[c](0);
|
||||||
var xrayTypedArrayProto = Object.getPrototypeOf(Object.getPrototypeOf(xray));
|
var xrayTypedArrayProto = Object.getPrototypeOf(Object.getPrototypeOf(xray));
|
||||||
testProtoCallables(inheritedCallables, new iwin[c](0), xrayTypedArrayProto, typedArrayProto);
|
testProtoCallables(inheritedCallables, new iwin[c](0), xrayTypedArrayProto, typedArrayProto);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче