From dd25f949c610616c55cf89501367d635fcb4766c Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Tue, 15 Oct 2013 18:51:50 -0700 Subject: [PATCH] Backed out 5 changesets (bug 861925) so I can backout bug 900669 cleanly Backed out changeset 8febf2f0e35d (bug 861925) Backed out changeset e646195f32ae (bug 861925) Backed out changeset 015a92e94c07 (bug 861925) Backed out changeset 4546406915c1 (bug 861925) Backed out changeset 63321a464309 (bug 861925) --- js/public/StructuredClone.h | 4 +- js/src/builtin/TestingFunctions.cpp | 241 +-------------- js/src/builtin/TestingFunctions.h | 2 +- js/src/js.msg | 4 +- js/src/jsapi.h | 16 +- js/src/jsfriendapi.cpp | 2 +- js/src/jsfriendapi.h | 6 - js/src/shell/js.cpp | 62 +++- .../tests/js1_8_5/extensions/clone-forge.js | 13 +- .../tests/js1_8_5/extensions/clone-object.js | 2 +- .../js1_8_5/extensions/clone-transferables.js | 87 ------ .../extensions/clone-v1-typed-array-data.dat | 42 +-- .../extensions/clone-v1-typed-array.js | 8 +- js/src/tests/js1_8_5/extensions/shell.js | 13 - js/src/vm/StructuredClone.cpp | 274 +++++------------- js/src/vm/TypedArrayObject.cpp | 187 ++++-------- js/src/vm/TypedArrayObject.h | 39 +-- 17 files changed, 244 insertions(+), 758 deletions(-) delete mode 100644 js/src/tests/js1_8_5/extensions/clone-transferables.js diff --git a/js/public/StructuredClone.h b/js/public/StructuredClone.h index 2ad3b769d17..1095f483f4d 100644 --- a/js/public/StructuredClone.h +++ b/js/public/StructuredClone.h @@ -48,9 +48,7 @@ typedef bool (*WriteStructuredCloneOp)(JSContext *cx, JSStructuredCloneWriter *w // with error set to one of the JS_SCERR_* values. typedef void (*StructuredCloneErrorOp)(JSContext *cx, uint32_t errorid); -// The maximum supported structured-clone serialization format version. Note -// that this does not need to be bumped for Transferable-only changes, since -// they are never saved to persistent storage. +// The maximum supported structured-clone serialization format version. #define JS_STRUCTURED_CLONE_VERSION 2 struct JSStructuredCloneCallbacks { diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 2a0d08d574d..329f8127f96 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -18,7 +18,6 @@ #include "jit/AsmJS.h" #include "jit/AsmJSLink.h" -#include "js/StructuredClone.h" #include "vm/ForkJoin.h" #include "vm/GlobalObject.h" #include "vm/Interpreter.h" @@ -31,10 +30,6 @@ using namespace JS; using mozilla::ArrayLength; -// If fuzzingSafe is set, remove functionality that could cause problems with -// fuzzers. Set this via the environment variable MOZ_FUZZING_SAFE. -static bool fuzzingSafe = false; - static bool GetBuildConfiguration(JSContext *cx, unsigned argc, jsval *vp) { @@ -1096,228 +1091,6 @@ SetIonAssertGraphCoherency(JSContext *cx, unsigned argc, jsval *vp) return true; } -class CloneBufferObject : public JSObject { - static const JSPropertySpec props_[2]; - static const size_t DATA_SLOT = 0; - static const size_t LENGTH_SLOT = 1; - static const size_t NUM_SLOTS = 2; - - public: - static const Class class_; - - static CloneBufferObject *Create(JSContext *cx) { - RootedObject obj(cx, JS_NewObject(cx, Jsvalify(&class_), nullptr, nullptr)); - if (!obj) - return nullptr; - obj->setReservedSlot(DATA_SLOT, PrivateValue(nullptr)); - obj->setReservedSlot(LENGTH_SLOT, Int32Value(0)); - - if (!JS_DefineProperties(cx, obj, props_)) - return nullptr; - - return &obj->as(); - } - - static CloneBufferObject *Create(JSContext *cx, JSAutoStructuredCloneBuffer *buffer) { - Rooted obj(cx, Create(cx)); - if (!obj) - return nullptr; - uint64_t *datap; - size_t nbytes; - buffer->steal(&datap, &nbytes); - obj->setData(datap); - obj->setNBytes(nbytes); - return obj; - } - - uint64_t *data() const { - return static_cast(getReservedSlot(0).toPrivate()); - } - - void setData(uint64_t *aData) { - JS_ASSERT(!data()); - setReservedSlot(DATA_SLOT, PrivateValue(aData)); - } - - size_t nbytes() const { - return getReservedSlot(LENGTH_SLOT).toInt32(); - } - - void setNBytes(size_t nbytes) { - JS_ASSERT(nbytes <= UINT32_MAX); - setReservedSlot(LENGTH_SLOT, Int32Value(nbytes)); - } - - // Discard an owned clone buffer. - void discard() { - if (data()) - JS_ClearStructuredClone(data(), nbytes()); - setReservedSlot(DATA_SLOT, PrivateValue(nullptr)); - } - - static bool - setCloneBuffer_impl(JSContext* cx, CallArgs args) { - if (args.length() != 1 || !args[0].isString()) { - JS_ReportError(cx, - "the first argument argument must be maxBytes, " - "maxMallocBytes, gcStackpoolLifespan, gcBytes or " - "gcNumber"); - JS_ReportError(cx, "clonebuffer setter requires a single string argument"); - return false; - } - - if (fuzzingSafe) { - // A manually-created clonebuffer could easily trigger a crash - args.rval().setUndefined(); - return true; - } - - Rooted obj(cx, &args.thisv().toObject().as()); - obj->discard(); - - char *str = JS_EncodeString(cx, args[0].toString()); - if (!str) - return false; - obj->setData(reinterpret_cast(str)); - obj->setNBytes(JS_GetStringLength(args[0].toString())); - - args.rval().setUndefined(); - return true; - } - - static bool - is(HandleValue v) { - return v.isObject() && v.toObject().is(); - } - - static bool - setCloneBuffer(JSContext* cx, unsigned int argc, JS::Value* vp) { - CallArgs args = CallArgsFromVp(argc, vp); - return CallNonGenericMethod(cx, args); - } - - static bool - getCloneBuffer_impl(JSContext* cx, CallArgs args) { - Rooted obj(cx, &args.thisv().toObject().as()); - JS_ASSERT(args.length() == 0); - - if (!obj->data()) { - args.rval().setUndefined(); - return true; - } - - bool hasTransferable; - if (!JS_StructuredCloneHasTransferables(obj->data(), obj->nbytes(), &hasTransferable)) - return false; - - if (hasTransferable) { - JS_ReportError(cx, "cannot retrieve structured clone buffer with transferables"); - return false; - } - - JSString *str = JS_NewStringCopyN(cx, reinterpret_cast(obj->data()), obj->nbytes()); - if (!str) - return false; - args.rval().setString(str); - return true; - } - - static bool - getCloneBuffer(JSContext* cx, unsigned int argc, JS::Value* vp) { - CallArgs args = CallArgsFromVp(argc, vp); - return CallNonGenericMethod(cx, args); - } - - static void Finalize(FreeOp *fop, JSObject *obj) { - obj->as().discard(); - } -}; - -const Class CloneBufferObject::class_ = { - "CloneBuffer", JSCLASS_HAS_RESERVED_SLOTS(CloneBufferObject::NUM_SLOTS), - JS_PropertyStub, /* addProperty */ - JS_DeletePropertyStub, /* delProperty */ - JS_PropertyStub, /* getProperty */ - JS_StrictPropertyStub, /* setProperty */ - JS_EnumerateStub, - JS_ResolveStub, - JS_ConvertStub, - Finalize, - nullptr, /* checkAccess */ - nullptr, /* call */ - nullptr, /* hasInstance */ - nullptr, /* construct */ - nullptr, /* trace */ - JS_NULL_CLASS_EXT, - JS_NULL_OBJECT_OPS -}; - -const JSPropertySpec CloneBufferObject::props_[] = { - JS_PSGS("clonebuffer", getCloneBuffer, setCloneBuffer, 0), - JS_PS_END -}; - -static bool -Serialize(JSContext *cx, unsigned argc, jsval *vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - - Value v = args.length() > 0 ? args[0] : UndefinedValue(); - Value transferables = args.length() > 1 ? args[1] : UndefinedValue(); - - JSAutoStructuredCloneBuffer clonebuf; - if (!clonebuf.write(cx, v, transferables)) - return false; - - RootedObject obj(cx, CloneBufferObject::Create(cx, &clonebuf)); - if (!obj) - return false; - - args.rval().setObject(*obj); - return true; -} - -static bool -Deserialize(JSContext *cx, unsigned argc, jsval *vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - - if (args.length() != 1 || !args[0].isObject()) { - JS_ReportError(cx, "deserialize requires a single clonebuffer argument"); - return false; - } - - if (!args[0].toObject().is()) { - JS_ReportError(cx, "deserialize requires a clonebuffer"); - return false; - } - - Rooted obj(cx, &args[0].toObject().as()); - - // Clone buffer was already consumed? - if (!obj->data()) { - JS_ReportError(cx, "deserialize given invalid clone buffer " - "(transferables already consumed?)"); - return false; - } - - bool hasTransferable; - if (!JS_StructuredCloneHasTransferables(obj->data(), obj->nbytes(), &hasTransferable)) - return false; - - RootedValue deserialized(cx); - if (!JS_ReadStructuredClone(cx, obj->data(), obj->nbytes(), - JS_STRUCTURED_CLONE_VERSION, deserialized.address(), NULL, NULL)) { - return false; - } - args.rval().set(deserialized); - - if (hasTransferable) - obj->discard(); - - return true; -} - static const JSFunctionSpecWithHelp TestingFunctions[] = { JS_FN_HELP("gc", ::GC, 0, 0, "gc([obj] | 'compartment')", @@ -1523,23 +1296,11 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = { " are valuable and should be generally enabled, however they can be very expensive for large\n" " (asm.js) programs."), - JS_FN_HELP("serialize", Serialize, 1, 0, -"serialize(data, [transferables])", -" Serialize 'data' using JS_WriteStructuredClone. Returns a structured\n" -" clone buffer object."), - - JS_FN_HELP("deserialize", Deserialize, 1, 0, -"deserialize(clonebuffer)", -" Deserialize data generated by serialize."), - JS_FS_HELP_END }; bool -js::DefineTestingFunctions(JSContext *cx, HandleObject obj, bool fuzzingSafe_) +js::DefineTestingFunctions(JSContext *cx, HandleObject obj) { - fuzzingSafe = fuzzingSafe_; - if (getenv("MOZ_FUZZING_SAFE") && getenv("MOZ_FUZZING_SAFE")[0] != '0') - fuzzingSafe = true; return JS_DefineFunctionsWithHelp(cx, obj, TestingFunctions); } diff --git a/js/src/builtin/TestingFunctions.h b/js/src/builtin/TestingFunctions.h index acaf2c4856b..6b88f40ed59 100644 --- a/js/src/builtin/TestingFunctions.h +++ b/js/src/builtin/TestingFunctions.h @@ -12,7 +12,7 @@ namespace js { bool -DefineTestingFunctions(JSContext *cx, HandleObject obj, bool fuzzingSafe); +DefineTestingFunctions(JSContext *cx, HandleObject obj); bool testingFunc_inParallelSection(JSContext *cx, unsigned argc, Value *vp); diff --git a/js/src/js.msg b/js/src/js.msg index 20eb96d1721..b689b2dbee2 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -233,8 +233,8 @@ MSG_DEF(JSMSG_UNUSED179, 179, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED180, 180, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED181, 181, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_BAD_GENERATOR_SEND, 182, 1, JSEXN_TYPEERR, "attempt to send {0} to newborn generator") -MSG_DEF(JSMSG_SC_NOT_TRANSFERABLE, 183, 0, JSEXN_TYPEERR, "invalid transferable array for structured clone") -MSG_DEF(JSMSG_SC_DUP_TRANSFERABLE, 184, 0, JSEXN_TYPEERR, "duplicate transferable for structured clone") +MSG_DEF(JSMSG_UNUSED183, 183, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_UNUSED184, 184, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE, 185, 0, JSEXN_TYPEERR, "proxy can't report an extensible object as non-extensible") MSG_DEF(JSMSG_UNUSED186, 186, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED187, 187, 0, JSEXN_NONE, "") diff --git a/js/src/jsapi.h b/js/src/jsapi.h index e4ed8c5d831..cb2aed18575 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -224,12 +224,6 @@ class AutoArrayRooter : private AutoGCRooter { template class AutoVectorRooter : protected AutoGCRooter { - typedef js::Vector VectorImpl; - VectorImpl vector; - - /* Prevent overwriting of inline elements in vector. */ - js::SkipRoot vectorRoot; - public: explicit AutoVectorRooter(JSContext *cx, ptrdiff_t tag MOZ_GUARD_OBJECT_NOTIFIER_PARAM) @@ -246,7 +240,6 @@ class AutoVectorRooter : protected AutoGCRooter } typedef T ElementType; - typedef typename VectorImpl::Range Range; size_t length() const { return vector.length(); } bool empty() const { return vector.empty(); } @@ -306,8 +299,6 @@ class AutoVectorRooter : protected AutoGCRooter const T *end() const { return vector.end(); } T *end() { return vector.end(); } - Range all() { return vector.all(); } - const T &back() const { return vector.back(); } friend void AutoGCRooter::trace(JSTracer *trc); @@ -319,6 +310,12 @@ class AutoVectorRooter : protected AutoGCRooter memset(t, 0, sizeof(T)); } + typedef js::Vector VectorImpl; + VectorImpl vector; + + /* Prevent overwriting of inline elements in vector. */ + js::SkipRoot vectorRoot; + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; @@ -338,7 +335,6 @@ class AutoHashMapRooter : protected AutoGCRooter typedef Key KeyType; typedef Value ValueType; - typedef typename HashMapImpl::Entry Entry; typedef typename HashMapImpl::Lookup Lookup; typedef typename HashMapImpl::Ptr Ptr; typedef typename HashMapImpl::AddPtr AddPtr; diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 8d7ae68c94b..58eb6427c5e 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -1018,7 +1018,7 @@ js::GetTestingFunctions(JSContext *cx) if (!obj) return nullptr; - if (!DefineTestingFunctions(cx, obj, false)) + if (!DefineTestingFunctions(cx, obj)) return nullptr; return obj; diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 41db6a21651..446be8bf703 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -1240,12 +1240,6 @@ JS_GetArrayBufferViewData(JSObject *obj); extern JS_FRIEND_API(JSObject *) JS_GetArrayBufferViewBuffer(JSObject *obj); -/* - * Set an ArrayBuffer's length to 0 and neuter all of its views. - */ -extern JS_FRIEND_API(void) -JS_NeuterArrayBuffer(JSObject *obj, JSContext *cx); - /* * Check whether obj supports JS_GetDataView* APIs. */ diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 5440238894d..3433177fd44 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -3833,6 +3833,56 @@ WrapWithProto(JSContext *cx, unsigned argc, jsval *vp) return true; } +static bool +Serialize(JSContext *cx, unsigned argc, jsval *vp) +{ + jsval v = argc > 0 ? JS_ARGV(cx, vp)[0] : UndefinedValue(); + uint64_t *datap; + size_t nbytes; + if (!JS_WriteStructuredClone(cx, v, &datap, &nbytes, nullptr, nullptr, UndefinedValue())) + return false; + + JSObject *obj = JS_NewUint8Array(cx, nbytes); + if (!obj) { + JS_free(cx, datap); + return false; + } + TypedArrayObject *tarr = &obj->as(); + JS_ASSERT((uintptr_t(tarr->viewData()) & 7) == 0); + js_memcpy(tarr->viewData(), datap, nbytes); + + JS_ClearStructuredClone(datap, nbytes); + JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(tarr)); + return true; +} + +static bool +Deserialize(JSContext *cx, unsigned argc, jsval *vp) +{ + Rooted v(cx, argc > 0 ? JS_ARGV(cx, vp)[0] : UndefinedValue()); + JSObject *obj; + if (JSVAL_IS_PRIMITIVE(v) || !(obj = JSVAL_TO_OBJECT(v))->is()) { + JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "deserialize"); + return false; + } + TypedArrayObject *tarr = &obj->as(); + if ((tarr->byteLength() & 7) != 0) { + JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "deserialize"); + return false; + } + if ((uintptr_t(tarr->viewData()) & 7) != 0) { + JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_BAD_ALIGNMENT); + return false; + } + + if (!JS_ReadStructuredClone(cx, (uint64_t *) tarr->viewData(), tarr->byteLength(), + JS_STRUCTURED_CLONE_VERSION, v.address(), nullptr, nullptr)) { + return false; + } + JS_SET_RVAL(cx, vp, v); + return true; +} + static JSObject * NewGlobalObject(JSContext *cx, JS::CompartmentOptions &options); @@ -4309,6 +4359,14 @@ static const JSFunctionSpecWithHelp shell_functions[] = { "wrapWithProto(obj)", " Wrap an object into a noop wrapper with prototype semantics."), + JS_FN_HELP("serialize", Serialize, 1, 0, +"serialize(sd)", +" Serialize sd using JS_WriteStructuredClone. Returns a TypedArray."), + + JS_FN_HELP("deserialize", Deserialize, 1, 0, +"deserialize(a)", +" Deserialize data generated by serialize."), + JS_FN_HELP("newGlobal", NewGlobal, 1, 0, "newGlobal([options])", " Return a new global object in a new compartment. If options\n" @@ -5336,7 +5394,7 @@ NewGlobalObject(JSContext *cx, JS::CompartmentOptions &options) { return nullptr; } - if (!js::DefineTestingFunctions(cx, glob, fuzzingSafe)) + if (!js::DefineTestingFunctions(cx, glob)) return nullptr; if (!fuzzingSafe && !JS_DefineFunctionsWithHelp(cx, glob, fuzzing_unsafe_functions)) @@ -5641,8 +5699,6 @@ Shell(JSContext *cx, OptionParser *op, char **envp) if (op->getBoolOption("fuzzing-safe")) fuzzingSafe = true; - else - fuzzingSafe = (getenv("MOZ_FUZZING_SAFE") && getenv("MOZ_FUZZING_SAFE")[0] != '0'); RootedObject glob(cx); JS::CompartmentOptions options; diff --git a/js/src/tests/js1_8_5/extensions/clone-forge.js b/js/src/tests/js1_8_5/extensions/clone-forge.js index ad8e7ec5ce6..970d61286df 100644 --- a/js/src/tests/js1_8_5/extensions/clone-forge.js +++ b/js/src/tests/js1_8_5/extensions/clone-forge.js @@ -14,13 +14,8 @@ function assertThrows(f) { throw new TypeError("Assertion failed: " + f + " did not throw as expected"); } -function byteArray(str) { - return [ c.charCodeAt(0) for (c of str.split('')) ]; -} - // Don't allow forging bogus Date objects. -var mutated = byteArray(serialize(new Date(NaN)).clonebuffer); - +var buf = serialize(new Date(NaN)); var a = [1/0, -1/0, Number.MIN_VALUE, -Number.MIN_VALUE, Math.PI, 1286523948674.5, @@ -29,11 +24,9 @@ var a = [1/0, -1/0, for (var i = 0; i < a.length; i++) { var n = a[i]; var nbuf = serialize(n); - var data = byteArray(nbuf.clonebuffer); for (var j = 0; j < 8; j++) - mutated[j+8] = data[j]; - nbuf.clonebuffer = String.fromCharCode.apply(null, mutated); - assertThrows(function () { deserialize(nbuf); }); + buf[j + 8] = nbuf[j]; + assertThrows(function () { deserialize(buf); }); } reportCompare(0, 0); diff --git a/js/src/tests/js1_8_5/extensions/clone-object.js b/js/src/tests/js1_8_5/extensions/clone-object.js index 16af40b072d..fbd900187d4 100644 --- a/js/src/tests/js1_8_5/extensions/clone-object.js +++ b/js/src/tests/js1_8_5/extensions/clone-object.js @@ -208,7 +208,7 @@ function test() { b = []; b[255] = 1; check(b); - assertEq(serialize(b).clonebuffer.length < 255, true); + assertEq(serialize(b).length < 255, true); // Self-modifying object. // This should never read through to b's prototype. diff --git a/js/src/tests/js1_8_5/extensions/clone-transferables.js b/js/src/tests/js1_8_5/extensions/clone-transferables.js deleted file mode 100644 index 18eac7feabe..00000000000 --- a/js/src/tests/js1_8_5/extensions/clone-transferables.js +++ /dev/null @@ -1,87 +0,0 @@ -// |reftest| skip-if(!xulRuntime.shell) -// Any copyright is dedicated to the Public Domain. -// http://creativecommons.org/licenses/publicdomain/ - -function test() { - // Note: -8 and -200 will trigger asm.js link failures because 8 and 200 - // bytes are below the minimum allowed size, and the buffer will not - // actually be converted to an asm.js buffer. - for (var size of [0, 8, 16, 200, 1000, 4096, -8, -200, -8192, -65536]) { - var buffer_ctor = (size < 0) ? AsmJSArrayBuffer : ArrayBuffer; - size = Math.abs(size); - - var old = buffer_ctor(size); - var copy = deserialize(serialize(old, [old])); - assertEq(old.byteLength, 0); - assertEq(copy.byteLength, size); - - var constructors = [ Int8Array, - Uint8Array, - Int16Array, - Uint16Array, - Int32Array, - Uint32Array, - Float32Array, - Float64Array, - Uint8ClampedArray ]; - - for (var ctor of constructors) { - var buf = buffer_ctor(size); - var old_arr = ctor(buf); - assertEq(buf.byteLength, size); - assertEq(buf, old_arr.buffer); - assertEq(old_arr.length, size / old_arr.BYTES_PER_ELEMENT); - - var copy_arr = deserialize(serialize(old_arr, [ buf ])); - assertEq(buf.byteLength, 0, "donor array buffer should be neutered"); - assertEq(old_arr.length, 0, "donor typed array should be neutered"); - assertEq(copy_arr.buffer.byteLength == size, true); - assertEq(copy_arr.length, size / old_arr.BYTES_PER_ELEMENT); - - buf = null; - old_arr = null; - gc(); // Tickle the ArrayBuffer -> view management - } - - for (var ctor of constructors) { - var buf = buffer_ctor(size); - var old_arr = ctor(buf); - var dv = DataView(buf); // Second view - var copy_arr = deserialize(serialize(old_arr, [ buf ])); - assertEq(buf.byteLength, 0, "donor array buffer should be neutered"); - assertEq(old_arr.length, 0, "donor typed array should be neutered"); - assertEq(dv.byteLength, 0, "all views of donor array buffer should be neutered"); - - buf = null; - old_arr = null; - gc(); // Tickle the ArrayBuffer -> view management - } - - // Mutate the buffer during the clone operation. The modifications should be visible. - if (size >= 4) { - old = buffer_ctor(size); - var view = Int32Array(old); - view[0] = 1; - var mutator = { get foo() { view[0] = 2; } }; - var copy = deserialize(serialize([ old, mutator ], [old])); - var viewCopy = Int32Array(copy[0]); - assertEq(view.length, 0); // Neutered - assertEq(viewCopy[0], 2); - } - - // Neuter the buffer during the clone operation. Should throw an exception. - if (size >= 4) { - old = buffer_ctor(size); - var mutator = { - get foo() { - deserialize(serialize(old, [old])); - } - }; - // The throw is not yet implemented, bug 919259. - //var copy = deserialize(serialize([ old, mutator ], [old])); - } - } -} - -test(); -reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/clone-v1-typed-array-data.dat b/js/src/tests/js1_8_5/extensions/clone-v1-typed-array-data.dat index 9ced3410090..c6b263eb108 100644 --- a/js/src/tests/js1_8_5/extensions/clone-v1-typed-array-data.dat +++ b/js/src/tests/js1_8_5/extensions/clone-v1-typed-array-data.dat @@ -1,32 +1,32 @@ var captured = []; -captured[0] = serialize(0); captured[0].clonebuffer = String.fromCharCode(0, 0, 0, 0, 9, 0, 255, 255); -captured[1] = serialize(0); captured[1].clonebuffer = String.fromCharCode(7, 0, 0, 0, 9, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0); +captured[0] = new Uint8Array([0, 0, 0, 0, 9, 0, 255, 255]); +captured[1] = new Uint8Array([7, 0, 0, 0, 9, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0]); captured[2] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); -captured[3] = serialize(0); captured[3].clonebuffer = String.fromCharCode(0, 0, 0, 0, 0, 1, 255, 255); -captured[4] = serialize(0); captured[4].clonebuffer = String.fromCharCode(100, 0, 0, 0, 0, 1, 255, 255, 1, 7, 49, 87, 97, 167, 145, 247, 193, 71, 241, 151, 33, 231, 81, 55, 129, 135, 177, 216, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[3] = new Uint8Array([0, 0, 0, 0, 0, 1, 255, 255]); +captured[4] = new Uint8Array([100, 0, 0, 0, 0, 1, 255, 255, 1, 7, 49, 87, 97, 167, 145, 247, 193, 71, 241, 151, 33, 231, 81, 55, 129, 135, 177, 216, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); captured[5] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); -captured[6] = serialize(0); captured[6].clonebuffer = String.fromCharCode(0, 0, 0, 0, 1, 1, 255, 255); -captured[7] = serialize(0); captured[7].clonebuffer = String.fromCharCode(100, 0, 0, 0, 1, 1, 255, 255, 1, 7, 49, 87, 97, 167, 145, 247, 193, 71, 241, 151, 33, 231, 81, 55, 129, 135, 177, 216, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[6] = new Uint8Array([0, 0, 0, 0, 1, 1, 255, 255]); +captured[7] = new Uint8Array([100, 0, 0, 0, 1, 1, 255, 255, 1, 7, 49, 87, 97, 167, 145, 247, 193, 71, 241, 151, 33, 231, 81, 55, 129, 135, 177, 216, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); captured[8] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); -captured[9] = serialize(0); captured[9].clonebuffer = String.fromCharCode(0, 0, 0, 0, 2, 1, 255, 255); -captured[10] = serialize(0); captured[10].clonebuffer = String.fromCharCode(100, 0, 0, 0, 2, 1, 255, 255, 1, 0, 7, 0, 49, 0, 87, 1, 97, 9, 167, 65, 145, 203, 247, 144, 193, 246, 71, 191, 241, 58, 151, 156, 33, 72, 231, 248, 81, 206, 55, 164, 129, 125, 135, 110, 177, 5, 216, 39, 224, 22, 0, 160, 0, 96, 0, 160, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[9] = new Uint8Array([0, 0, 0, 0, 2, 1, 255, 255]); +captured[10] = new Uint8Array([100, 0, 0, 0, 2, 1, 255, 255, 1, 0, 7, 0, 49, 0, 87, 1, 97, 9, 167, 65, 145, 203, 247, 144, 193, 246, 71, 191, 241, 58, 151, 156, 33, 72, 231, 248, 81, 206, 55, 164, 129, 125, 135, 110, 177, 5, 216, 39, 224, 22, 0, 160, 0, 96, 0, 160, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); captured[11] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); -captured[12] = serialize(0); captured[12].clonebuffer = String.fromCharCode(0, 0, 0, 0, 3, 1, 255, 255); -captured[13] = serialize(0); captured[13].clonebuffer = String.fromCharCode(100, 0, 0, 0, 3, 1, 255, 255, 1, 0, 7, 0, 49, 0, 87, 1, 97, 9, 167, 65, 145, 203, 247, 144, 193, 246, 71, 191, 241, 58, 151, 156, 33, 72, 231, 248, 81, 206, 55, 164, 129, 125, 135, 110, 177, 5, 216, 39, 224, 22, 0, 160, 0, 96, 0, 160, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[12] = new Uint8Array([0, 0, 0, 0, 3, 1, 255, 255]); +captured[13] = new Uint8Array([100, 0, 0, 0, 3, 1, 255, 255, 1, 0, 7, 0, 49, 0, 87, 1, 97, 9, 167, 65, 145, 203, 247, 144, 193, 246, 71, 191, 241, 58, 151, 156, 33, 72, 231, 248, 81, 206, 55, 164, 129, 125, 135, 110, 177, 5, 216, 39, 224, 22, 0, 160, 0, 96, 0, 160, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); captured[14] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); -captured[15] = serialize(0); captured[15].clonebuffer = String.fromCharCode(0, 0, 0, 0, 4, 1, 255, 255); -captured[16] = serialize(0); captured[16].clonebuffer = String.fromCharCode(100, 0, 0, 0, 4, 1, 255, 255, 1, 0, 0, 0, 7, 0, 0, 0, 49, 0, 0, 0, 87, 1, 0, 0, 97, 9, 0, 0, 167, 65, 0, 0, 145, 203, 1, 0, 247, 144, 12, 0, 193, 246, 87, 0, 71, 191, 103, 2, 241, 58, 214, 16, 151, 156, 219, 117, 33, 72, 1, 57, 231, 248, 8, 143, 81, 206, 62, 233, 55, 164, 183, 96, 129, 125, 5, 165, 135, 110, 38, 131, 177, 5, 13, 150, 216, 39, 91, 26, 224, 22, 126, 184, 0, 160, 114, 11, 0, 96, 34, 80, 0, 160, 240, 48, 0, 128, 148, 86, 0, 0, 16, 94, 0, 0, 112, 146, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[15] = new Uint8Array([0, 0, 0, 0, 4, 1, 255, 255]); +captured[16] = new Uint8Array([100, 0, 0, 0, 4, 1, 255, 255, 1, 0, 0, 0, 7, 0, 0, 0, 49, 0, 0, 0, 87, 1, 0, 0, 97, 9, 0, 0, 167, 65, 0, 0, 145, 203, 1, 0, 247, 144, 12, 0, 193, 246, 87, 0, 71, 191, 103, 2, 241, 58, 214, 16, 151, 156, 219, 117, 33, 72, 1, 57, 231, 248, 8, 143, 81, 206, 62, 233, 55, 164, 183, 96, 129, 125, 5, 165, 135, 110, 38, 131, 177, 5, 13, 150, 216, 39, 91, 26, 224, 22, 126, 184, 0, 160, 114, 11, 0, 96, 34, 80, 0, 160, 240, 48, 0, 128, 148, 86, 0, 0, 16, 94, 0, 0, 112, 146, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); captured[17] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); -captured[18] = serialize(0); captured[18].clonebuffer = String.fromCharCode(0, 0, 0, 0, 5, 1, 255, 255); -captured[19] = serialize(0); captured[19].clonebuffer = String.fromCharCode(100, 0, 0, 0, 5, 1, 255, 255, 1, 0, 0, 0, 7, 0, 0, 0, 49, 0, 0, 0, 87, 1, 0, 0, 97, 9, 0, 0, 167, 65, 0, 0, 145, 203, 1, 0, 247, 144, 12, 0, 193, 246, 87, 0, 71, 191, 103, 2, 241, 58, 214, 16, 151, 156, 219, 117, 33, 72, 1, 57, 231, 248, 8, 143, 81, 206, 62, 233, 55, 164, 183, 96, 129, 125, 5, 165, 135, 110, 38, 131, 177, 5, 13, 150, 216, 39, 91, 26, 224, 22, 126, 184, 0, 160, 114, 11, 0, 96, 34, 80, 0, 160, 240, 48, 0, 128, 148, 86, 0, 0, 16, 94, 0, 0, 112, 146, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[18] = new Uint8Array([0, 0, 0, 0, 5, 1, 255, 255]); +captured[19] = new Uint8Array([100, 0, 0, 0, 5, 1, 255, 255, 1, 0, 0, 0, 7, 0, 0, 0, 49, 0, 0, 0, 87, 1, 0, 0, 97, 9, 0, 0, 167, 65, 0, 0, 145, 203, 1, 0, 247, 144, 12, 0, 193, 246, 87, 0, 71, 191, 103, 2, 241, 58, 214, 16, 151, 156, 219, 117, 33, 72, 1, 57, 231, 248, 8, 143, 81, 206, 62, 233, 55, 164, 183, 96, 129, 125, 5, 165, 135, 110, 38, 131, 177, 5, 13, 150, 216, 39, 91, 26, 224, 22, 126, 184, 0, 160, 114, 11, 0, 96, 34, 80, 0, 160, 240, 48, 0, 128, 148, 86, 0, 0, 16, 94, 0, 0, 112, 146, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); captured[20] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); -captured[21] = serialize(0); captured[21].clonebuffer = String.fromCharCode(0, 0, 0, 0, 6, 1, 255, 255); -captured[22] = serialize(0); captured[22].clonebuffer = String.fromCharCode(100, 0, 0, 0, 6, 1, 255, 255, 0, 0, 128, 63, 0, 0, 224, 64, 0, 0, 68, 66, 0, 128, 171, 67, 0, 16, 22, 69, 0, 78, 131, 70, 128, 200, 229, 71, 112, 15, 73, 73, 130, 237, 175, 74, 210, 239, 25, 76, 216, 177, 134, 77, 57, 183, 235, 78, 82, 64, 78, 80, 72, 120, 180, 81, 63, 233, 29, 83, 23, 44, 138, 84, 40, 205, 241, 85, 131, 147, 83, 87, 19, 33, 185, 88, 240, 252, 33, 90, 82, 189, 141, 91, 80, 11, 248, 92, 230, 9, 89, 94, 169, 232, 189, 95, 148, 43, 38, 97, 34, 102, 145, 98, 187, 114, 254, 99, 100, 164, 94, 101, 215, 207, 194, 102, 220, 117, 42, 104, 33, 39, 149, 105, 61, 130, 2, 107, 234, 99, 100, 108, 109, 215, 199, 109, 127, 220, 46, 111, 239, 0, 153, 112, 209, 224, 5, 114, 110, 73, 106, 115, 65, 0, 205, 116, 57, 96, 51, 118, 49, 244, 156, 119, 171, 85, 9, 121, 236, 85, 112, 122, 46, 75, 210, 123, 200, 1, 56, 125, 143, 1, 161, 126, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 192, 127); +captured[21] = new Uint8Array([0, 0, 0, 0, 6, 1, 255, 255]); +captured[22] = new Uint8Array([100, 0, 0, 0, 6, 1, 255, 255, 0, 0, 128, 63, 0, 0, 224, 64, 0, 0, 68, 66, 0, 128, 171, 67, 0, 16, 22, 69, 0, 78, 131, 70, 128, 200, 229, 71, 112, 15, 73, 73, 130, 237, 175, 74, 210, 239, 25, 76, 216, 177, 134, 77, 57, 183, 235, 78, 82, 64, 78, 80, 72, 120, 180, 81, 63, 233, 29, 83, 23, 44, 138, 84, 40, 205, 241, 85, 131, 147, 83, 87, 19, 33, 185, 88, 240, 252, 33, 90, 82, 189, 141, 91, 80, 11, 248, 92, 230, 9, 89, 94, 169, 232, 189, 95, 148, 43, 38, 97, 34, 102, 145, 98, 187, 114, 254, 99, 100, 164, 94, 101, 215, 207, 194, 102, 220, 117, 42, 104, 33, 39, 149, 105, 61, 130, 2, 107, 234, 99, 100, 108, 109, 215, 199, 109, 127, 220, 46, 111, 239, 0, 153, 112, 209, 224, 5, 114, 110, 73, 106, 115, 65, 0, 205, 116, 57, 96, 51, 118, 49, 244, 156, 119, 171, 85, 9, 121, 236, 85, 112, 122, 46, 75, 210, 123, 200, 1, 56, 125, 143, 1, 161, 126, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 192, 127]); captured[23] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); -captured[24] = serialize(0); captured[24].clonebuffer = String.fromCharCode(0, 0, 0, 0, 7, 1, 255, 255); -captured[25] = serialize(0); captured[25].clonebuffer = String.fromCharCode(100, 0, 0, 0, 7, 1, 255, 255, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 28, 64, 0, 0, 0, 0, 0, 128, 72, 64, 0, 0, 0, 0, 0, 112, 117, 64, 0, 0, 0, 0, 0, 194, 162, 64, 0, 0, 0, 0, 192, 105, 208, 64, 0, 0, 0, 0, 16, 185, 252, 64, 0, 0, 0, 0, 238, 33, 41, 65, 0, 0, 0, 64, 176, 253, 85, 65, 0, 0, 0, 56, 250, 61, 131, 65, 0, 0, 0, 241, 58, 214, 176, 65, 0, 0, 192, 37, 231, 118, 221, 65, 0, 0, 8, 65, 10, 200, 9, 66, 0, 0, 231, 248, 8, 143, 54, 66, 0, 32, 202, 217, 39, 189, 99, 66, 0, 220, 144, 222, 130, 69, 145, 66, 0, 129, 125, 5, 165, 57, 190, 66, 224, 208, 205, 100, 112, 114, 234, 66, 196, 22, 52, 88, 34, 36, 23, 67, 236, 147, 45, 13, 158, 63, 68, 67, 110, 225, 135, 75, 170, 183, 113, 67, 128, 202, 45, 4, 106, 1, 159, 67, 48, 17, 168, 195, 60, 33, 203, 67, 10, 15, 51, 43, 21, 189, 247, 67, 41, 173, 204, 133, 114, 197, 36, 68, 132, 23, 19, 53, 196, 44, 82, 68, 39, 105, 225, 92, 87, 206, 127, 68, 2, 60, 69, 113, 140, 212, 171, 68, 130, 148, 28, 227, 250, 89, 216, 68, 242, 1, 185, 134, 187, 78, 5, 69, 180, 225, 225, 21, 228, 164, 50, 69, 126, 165, 37, 147, 71, 80, 96, 69, 156, 225, 129, 65, 125, 140, 140, 69, 104, 165, 81, 153, 237, 250, 184, 69, 187, 112, 39, 230, 143, 219, 229, 69, 164, 130, 98, 233, 29, 32, 19, 70, 80, 50, 54, 44, 26, 188, 64, 70, 12, 216, 94, 205, 45, 73, 109, 70, 10, 253, 178, 19, 8, 160, 153, 70, 105, 157, 60, 17, 7, 108, 198, 70, 188, 9, 21, 47, 134, 158, 243, 70, 132, 104, 50, 105, 181, 42, 33, 71, 231, 54, 24, 120, 189, 10, 78, 71, 10, 48, 21, 201, 101, 73, 122, 71, 9, 138, 242, 15, 57, 0, 167, 71, 200, 56, 244, 237, 49, 32, 212, 71, 175, 177, 53, 176, 43, 156, 1, 72, 242, 246, 93, 116, 76, 209, 46, 72, 20, 56, 210, 229, 34, 247, 90, 72, 18, 241, 23, 137, 62, 152, 135, 72, 240, 242, 244, 183, 54, 165, 180, 72, 146, 84, 246, 224, 143, 16, 226, 72, 0, 20, 175, 201, 251, 156, 15, 73, 128, 49, 121, 80, 92, 169, 59, 73, 80, 11, 106, 198, 48, 52, 104, 73, 230, 201, 156, 173, 170, 45, 149, 73, 169, 48, 233, 87, 245, 135, 194, 73, 148, 10, 236, 172, 246, 54, 240, 73, 131, 18, 157, 174, 47, 96, 28, 74, 51, 112, 201, 184, 41, 212, 72, 74, 45, 66, 176, 129, 164, 185, 117, 74, 231, 57, 122, 241, 111, 2, 163, 74, 170, 242, 74, 243, 33, 162, 208, 74, 170, 40, 195, 105, 187, 27, 253, 74, 149, 195, 138, 252, 67, 120, 41, 75, 34, 107, 249, 124, 59, 73, 86, 75, 190, 61, 90, 13, 20, 128, 131, 75, 6, 246, 174, 139, 17, 16, 177, 75, 138, 46, 114, 180, 30, 220, 221, 75, 185, 232, 227, 221, 154, 32, 10, 76, 162, 107, 39, 130, 135, 220, 54, 76, 46, 126, 226, 145, 246, 0, 100, 76, 104, 46, 166, 191, 215, 128, 145, 76, 54, 209, 98, 143, 121, 161, 190, 76, 15, 119, 118, 93, 74, 205, 234, 76, 45, 168, 199, 17, 161, 115, 23, 77, 39, 179, 142, 239, 44, 133, 68, 77, 194, 220, 156, 81, 135, 244, 113, 77, 84, 130, 210, 206, 236, 107, 159, 77, 10, 50, 248, 52, 111, 126, 203, 77, 201, 43, 89, 78, 161, 14, 248, 77, 80, 6, 142, 36, 205, 12, 37, 78, 134, 69, 252, 127, 51, 107, 82, 78, 213, 188, 252, 15, 205, 29, 128, 78, 117, 74, 250, 219, 38, 52, 172, 78, 38, 1, 123, 0, 162, 173, 216, 78, 1, 161, 107, 192, 237, 151, 5, 79, 225, 44, 94, 8, 240, 228, 50, 79, 69, 103, 82, 7, 82, 136, 96, 79, 185, 52, 208, 140, 143, 238, 140, 79, 34, 46, 54, 155, 189, 80, 185, 79, 94, 104, 207, 231, 165, 38, 230, 79, 82, 123, 213, 42, 209, 97, 19, 80, 232, 203, 122, 5, 151, 245, 64, 80, 214, 228, 150, 73, 200, 173, 109, 80, 59, 8, 100, 64, 15, 248, 153, 80, 52, 135, 87, 88, 13, 185, 198, 80, 78, 150, 76, 173, 235, 225, 243, 80, 132, 3, 163, 55, 174, 101, 33, 81, 0, 0, 0, 0, 0, 0, 248, 127); +captured[24] = new Uint8Array([0, 0, 0, 0, 7, 1, 255, 255]); +captured[25] = new Uint8Array([100, 0, 0, 0, 7, 1, 255, 255, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 28, 64, 0, 0, 0, 0, 0, 128, 72, 64, 0, 0, 0, 0, 0, 112, 117, 64, 0, 0, 0, 0, 0, 194, 162, 64, 0, 0, 0, 0, 192, 105, 208, 64, 0, 0, 0, 0, 16, 185, 252, 64, 0, 0, 0, 0, 238, 33, 41, 65, 0, 0, 0, 64, 176, 253, 85, 65, 0, 0, 0, 56, 250, 61, 131, 65, 0, 0, 0, 241, 58, 214, 176, 65, 0, 0, 192, 37, 231, 118, 221, 65, 0, 0, 8, 65, 10, 200, 9, 66, 0, 0, 231, 248, 8, 143, 54, 66, 0, 32, 202, 217, 39, 189, 99, 66, 0, 220, 144, 222, 130, 69, 145, 66, 0, 129, 125, 5, 165, 57, 190, 66, 224, 208, 205, 100, 112, 114, 234, 66, 196, 22, 52, 88, 34, 36, 23, 67, 236, 147, 45, 13, 158, 63, 68, 67, 110, 225, 135, 75, 170, 183, 113, 67, 128, 202, 45, 4, 106, 1, 159, 67, 48, 17, 168, 195, 60, 33, 203, 67, 10, 15, 51, 43, 21, 189, 247, 67, 41, 173, 204, 133, 114, 197, 36, 68, 132, 23, 19, 53, 196, 44, 82, 68, 39, 105, 225, 92, 87, 206, 127, 68, 2, 60, 69, 113, 140, 212, 171, 68, 130, 148, 28, 227, 250, 89, 216, 68, 242, 1, 185, 134, 187, 78, 5, 69, 180, 225, 225, 21, 228, 164, 50, 69, 126, 165, 37, 147, 71, 80, 96, 69, 156, 225, 129, 65, 125, 140, 140, 69, 104, 165, 81, 153, 237, 250, 184, 69, 187, 112, 39, 230, 143, 219, 229, 69, 164, 130, 98, 233, 29, 32, 19, 70, 80, 50, 54, 44, 26, 188, 64, 70, 12, 216, 94, 205, 45, 73, 109, 70, 10, 253, 178, 19, 8, 160, 153, 70, 105, 157, 60, 17, 7, 108, 198, 70, 188, 9, 21, 47, 134, 158, 243, 70, 132, 104, 50, 105, 181, 42, 33, 71, 231, 54, 24, 120, 189, 10, 78, 71, 10, 48, 21, 201, 101, 73, 122, 71, 9, 138, 242, 15, 57, 0, 167, 71, 200, 56, 244, 237, 49, 32, 212, 71, 175, 177, 53, 176, 43, 156, 1, 72, 242, 246, 93, 116, 76, 209, 46, 72, 20, 56, 210, 229, 34, 247, 90, 72, 18, 241, 23, 137, 62, 152, 135, 72, 240, 242, 244, 183, 54, 165, 180, 72, 146, 84, 246, 224, 143, 16, 226, 72, 0, 20, 175, 201, 251, 156, 15, 73, 128, 49, 121, 80, 92, 169, 59, 73, 80, 11, 106, 198, 48, 52, 104, 73, 230, 201, 156, 173, 170, 45, 149, 73, 169, 48, 233, 87, 245, 135, 194, 73, 148, 10, 236, 172, 246, 54, 240, 73, 131, 18, 157, 174, 47, 96, 28, 74, 51, 112, 201, 184, 41, 212, 72, 74, 45, 66, 176, 129, 164, 185, 117, 74, 231, 57, 122, 241, 111, 2, 163, 74, 170, 242, 74, 243, 33, 162, 208, 74, 170, 40, 195, 105, 187, 27, 253, 74, 149, 195, 138, 252, 67, 120, 41, 75, 34, 107, 249, 124, 59, 73, 86, 75, 190, 61, 90, 13, 20, 128, 131, 75, 6, 246, 174, 139, 17, 16, 177, 75, 138, 46, 114, 180, 30, 220, 221, 75, 185, 232, 227, 221, 154, 32, 10, 76, 162, 107, 39, 130, 135, 220, 54, 76, 46, 126, 226, 145, 246, 0, 100, 76, 104, 46, 166, 191, 215, 128, 145, 76, 54, 209, 98, 143, 121, 161, 190, 76, 15, 119, 118, 93, 74, 205, 234, 76, 45, 168, 199, 17, 161, 115, 23, 77, 39, 179, 142, 239, 44, 133, 68, 77, 194, 220, 156, 81, 135, 244, 113, 77, 84, 130, 210, 206, 236, 107, 159, 77, 10, 50, 248, 52, 111, 126, 203, 77, 201, 43, 89, 78, 161, 14, 248, 77, 80, 6, 142, 36, 205, 12, 37, 78, 134, 69, 252, 127, 51, 107, 82, 78, 213, 188, 252, 15, 205, 29, 128, 78, 117, 74, 250, 219, 38, 52, 172, 78, 38, 1, 123, 0, 162, 173, 216, 78, 1, 161, 107, 192, 237, 151, 5, 79, 225, 44, 94, 8, 240, 228, 50, 79, 69, 103, 82, 7, 82, 136, 96, 79, 185, 52, 208, 140, 143, 238, 140, 79, 34, 46, 54, 155, 189, 80, 185, 79, 94, 104, 207, 231, 165, 38, 230, 79, 82, 123, 213, 42, 209, 97, 19, 80, 232, 203, 122, 5, 151, 245, 64, 80, 214, 228, 150, 73, 200, 173, 109, 80, 59, 8, 100, 64, 15, 248, 153, 80, 52, 135, 87, 88, 13, 185, 198, 80, 78, 150, 76, 173, 235, 225, 243, 80, 132, 3, 163, 55, 174, 101, 33, 81, 0, 0, 0, 0, 0, 0, 248, 127]); captured[26] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); -captured[27] = serialize(0); captured[27].clonebuffer = String.fromCharCode(0, 0, 0, 0, 8, 1, 255, 255); -captured[28] = serialize(0); captured[28].clonebuffer = String.fromCharCode(100, 0, 0, 0, 8, 1, 255, 255, 1, 7, 49, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0); +captured[27] = new Uint8Array([0, 0, 0, 0, 8, 1, 255, 255]); +captured[28] = new Uint8Array([100, 0, 0, 0, 8, 1, 255, 255, 1, 7, 49, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0]); captured[29] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); -captured[30] = serialize(0); captured[30].clonebuffer = String.fromCharCode(0, 0, 0, 0, 7, 0, 255, 255, 0, 0, 0, 0, 3, 0, 255, 255, 3, 0, 0, 0, 0, 1, 255, 255, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 255, 255, 3, 0, 0, 0, 0, 1, 255, 255, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255); +captured[30] = new Uint8Array([0, 0, 0, 0, 7, 0, 255, 255, 0, 0, 0, 0, 3, 0, 255, 255, 3, 0, 0, 0, 0, 1, 255, 255, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 255, 255, 3, 0, 0, 0, 0, 1, 255, 255, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255]); diff --git a/js/src/tests/js1_8_5/extensions/clone-v1-typed-array.js b/js/src/tests/js1_8_5/extensions/clone-v1-typed-array.js index e0f8ff24ef1..f79f483fdef 100644 --- a/js/src/tests/js1_8_5/extensions/clone-v1-typed-array.js +++ b/js/src/tests/js1_8_5/extensions/clone-v1-typed-array.js @@ -120,11 +120,9 @@ if ("JS_RECORD_RESULTS" in environment) { print("var captured = [];"); for (var i in captured) { var s = "captured[" + i + "] = "; - if (captured[i] instanceof Error) { + if (captured[i] instanceof Error) print(s + captured[i].toSource() + ";"); - } else { - data = [ c.charCodeAt(0) for (c of captured[i].clonebuffer.split('')) ]; - print(s + "serialize(0); captured[" + i + "].clonebuffer = String.fromCharCode(" + data.join(", ") + ");"); - } + else + print(s + "new Uint8Array(" + [...captured[i]].toSource() + ");"); } } diff --git a/js/src/tests/js1_8_5/extensions/shell.js b/js/src/tests/js1_8_5/extensions/shell.js index ad9fa67eff6..e4b4493486f 100644 --- a/js/src/tests/js1_8_5/extensions/shell.js +++ b/js/src/tests/js1_8_5/extensions/shell.js @@ -197,16 +197,3 @@ function referencesVia(from, edge, to) { print(e); return false; } - -// Note that AsmJS ArrayBuffers have a minimum size, currently 4096 bytes. If a -// smaller size is given, a regular ArrayBuffer will be returned instead. -function AsmJSArrayBuffer(size) { - var ab = new ArrayBuffer(size); - (new Function('global', 'foreign', 'buffer', '' + -' "use asm";' + -' var i32 = new global.Int32Array(buffer);' + -' function g() {};' + -' return g;' + -''))(this,null,ab); - return ab; -} diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 3a1ae254e51..9871f58d52e 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -32,8 +32,6 @@ #include "mozilla/Endian.h" #include "mozilla/FloatingPoint.h" -#include - #include "jsapi.h" #include "jscntxt.h" #include "jsdate.h" @@ -68,8 +66,8 @@ enum StructuredDataType { SCTAG_STRING_OBJECT, SCTAG_NUMBER_OBJECT, SCTAG_BACK_REFERENCE_OBJECT, - SCTAG_DO_NOT_USE_1, - SCTAG_DO_NOT_USE_2, + SCTAG_TRANSFER_MAP_HEADER, + SCTAG_TRANSFER_MAP, SCTAG_TYPED_ARRAY_OBJECT, SCTAG_TYPED_ARRAY_V1_MIN = 0xFFFF0100, SCTAG_TYPED_ARRAY_V1_INT8 = SCTAG_TYPED_ARRAY_V1_MIN + ScalarTypeRepresentation::TYPE_INT8, @@ -82,37 +80,12 @@ enum StructuredDataType { SCTAG_TYPED_ARRAY_V1_FLOAT64 = SCTAG_TYPED_ARRAY_V1_MIN + ScalarTypeRepresentation::TYPE_FLOAT64, SCTAG_TYPED_ARRAY_V1_UINT8_CLAMPED = SCTAG_TYPED_ARRAY_V1_MIN + ScalarTypeRepresentation::TYPE_UINT8_CLAMPED, SCTAG_TYPED_ARRAY_V1_MAX = SCTAG_TYPED_ARRAY_V1_MIN + ScalarTypeRepresentation::TYPE_MAX - 1, - - /* - * Define a separate range of numbers for Transferable-only tags, since - * they are not used for persistent clone buffers and therefore do not - * require bumping JS_STRUCTURED_CLONE_VERSION. - */ - SCTAG_TRANSFER_MAP_HEADER = 0xFFFF0200, - SCTAG_TRANSFER_MAP_ENTRY, - SCTAG_END_OF_BUILTIN_TYPES }; -// Data associated with an SCTAG_TRANSFER_MAP_HEADER that tells whether the -// contents have been read out yet or not. enum TransferableMapHeader { - SCTAG_TM_UNREAD = 0, - SCTAG_TM_TRANSFERRED -}; - -enum TransferableObjectType { - // Transferable data has not been filled in yet - SCTAG_TM_UNFILLED = 0, - - // Structured clone buffer does not yet own the data - SCTAG_TM_UNOWNED = 1, - - // All values at least this large are owned by the clone buffer - SCTAG_TM_FIRST_OWNED = 2, - - // Data is a pointer that can be freed - SCTAG_TM_ALLOC_DATA = 2, + SCTAG_TM_NOT_MARKED = 0, + SCTAG_TM_MARKED }; namespace js { @@ -120,7 +93,6 @@ namespace js { struct SCOutput { public: explicit SCOutput(JSContext *cx); - ~SCOutput(); JSContext *context() const { return cx; } @@ -136,8 +108,7 @@ struct SCOutput { bool extractBuffer(uint64_t **datap, size_t *sizep); - uint64_t count() const { return buf.length(); } - uint64_t *rawBuffer() { return buf.begin(); } + uint64_t count() { return buf.length(); } private: JSContext *cx; @@ -163,12 +134,6 @@ struct SCInput { bool replace(uint64_t u); bool replacePair(uint32_t tag, uint32_t data); - uint64_t *tell() const { return point; } - void seek(uint64_t *pos) { - JS_ASSERT(pos <= end); - point = pos; - } - template bool readArray(T *p, size_t nelems); @@ -239,7 +204,8 @@ struct JSStructuredCloneWriter { memory(out.context()), callbacks(cb), closure(cbClosure), transferable(out.context(), tVal), transferableObjects(out.context()) { } - bool init() { return parseTransferable() && memory.init() && writeTransferMap(); } + bool init() { return transferableObjects.init() && parseTransferable() && + memory.init() && writeTransferMap(); } bool write(const js::Value &v); @@ -260,7 +226,6 @@ struct JSStructuredCloneWriter { bool parseTransferable(); void reportErrorTransferable(); - bool transferOwnership(); inline void checkStack(); @@ -293,7 +258,7 @@ struct JSStructuredCloneWriter { // List of transferable objects JS::RootedValue transferable; - JS::AutoObjectVector transferableObjects; + js::AutoObjectHashSet transferableObjects; friend bool JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::Value v); }; @@ -330,47 +295,35 @@ ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, Value *vp, return r.read(vp); } -// This may acquire new ways of discarding transfer map entries as new -// Transferables are implemented. -static void -DiscardEntry(uint32_t mapEntryDescriptor, const uint64_t *ptr) +bool +ClearStructuredClone(const uint64_t *data, size_t nbytes) { - JS_ASSERT(mapEntryDescriptor == SCTAG_TM_ALLOC_DATA); - uint64_t u = LittleEndian::readUint64(ptr); - js_free(reinterpret_cast(u)); -} - -static void -Discard(const uint64_t *begin, const uint64_t *end) -{ - const uint64_t *point = begin; + const uint64_t *point = data; + const uint64_t *end = data + nbytes / 8; uint64_t u = LittleEndian::readUint64(point++); uint32_t tag = uint32_t(u >> 32); - if (tag != SCTAG_TRANSFER_MAP_HEADER) - return; - - if (TransferableMapHeader(u) == SCTAG_TM_TRANSFERRED) - return; - - uint64_t numTransferables = LittleEndian::readUint64(point++); - while (numTransferables--) { - uint64_t u = LittleEndian::readUint64(point++); - JS_ASSERT(uint32_t(u >> 32) == SCTAG_TRANSFER_MAP_ENTRY); - uint32_t mapEntryDescriptor = uint32_t(u); - if (mapEntryDescriptor >= SCTAG_TM_FIRST_OWNED) { - DiscardEntry(mapEntryDescriptor, point); - point += 2; // Pointer and userdata + if (tag == SCTAG_TRANSFER_MAP_HEADER) { + if ((TransferableMapHeader)uint32_t(u) == SCTAG_TM_NOT_MARKED) { + while (point != end) { + uint64_t u = LittleEndian::readUint64(point++); + uint32_t tag = uint32_t(u >> 32); + if (tag == SCTAG_TRANSFER_MAP) { + u = LittleEndian::readUint64(point++); + js_free(reinterpret_cast(u)); + } else { + // The only things in the transfer map should be + // SCTAG_TRANSFER_MAP tags paired with pointers. If we find + // any other tag, we've walked off the end of the transfer + // map. + break; + } + } } } -} -static void -ClearStructuredClone(const uint64_t *data, size_t nbytes) -{ - JS_ASSERT(nbytes % 8 == 0); - Discard(data, data + nbytes / 8); - js_free(const_cast(data)); + js_free((void *)data); + return true; } bool @@ -381,14 +334,15 @@ StructuredCloneHasTransferObjects(const uint64_t *data, size_t nbytes, bool *has if (data) { uint64_t u = LittleEndian::readUint64(data); uint32_t tag = uint32_t(u >> 32); - if (tag == SCTAG_TRANSFER_MAP_HEADER) + if (tag == SCTAG_TRANSFER_MAP_HEADER) { *hasTransferable = true; + } } return true; } -} /* namespace js */ +} static inline uint64_t PairToUInt64(uint32_t tag, uint32_t data) @@ -497,8 +451,7 @@ template static void copyAndSwapFromLittleEndian(T *dest, const void *src, size_t nelems) { - if (nelems > 0) - NativeEndian::copyAndSwapFromLittleEndian(dest, src, nelems); + NativeEndian::copyAndSwapFromLittleEndian(dest, src, nelems); } template <> @@ -553,12 +506,6 @@ SCInput::readPtr(void **p) SCOutput::SCOutput(JSContext *cx) : cx(cx), buf(cx) {} -SCOutput::~SCOutput() -{ - // Free any transferable data left lying around in the buffer - Discard(rawBuffer(), rawBuffer() + count()); -} - bool SCOutput::write(uint64_t u) { @@ -618,8 +565,7 @@ template static void copyAndSwapToLittleEndian(void *dest, const T *src, size_t nelems) { - if (nelems > 0) - NativeEndian::copyAndSwapToLittleEndian(dest, src, nelems); + NativeEndian::copyAndSwapToLittleEndian(dest, src, nelems); } template <> @@ -686,7 +632,7 @@ JS_STATIC_ASSERT(JSString::MAX_LENGTH < UINT32_MAX); bool JSStructuredCloneWriter::parseTransferable() { - MOZ_ASSERT(transferableObjects.empty(), "parseTransferable called with stale data"); + transferableObjects.clear(); if (JSVAL_IS_NULL(transferable) || JSVAL_IS_VOID(transferable)) return true; @@ -696,22 +642,21 @@ JSStructuredCloneWriter::parseTransferable() return false; } - JSContext *cx = context(); - RootedObject array(cx, &transferable.toObject()); - if (!JS_IsArrayObject(cx, array)) { + RootedObject array(context(), &transferable.toObject()); + if (!JS_IsArrayObject(context(), array)) { reportErrorTransferable(); return false; } uint32_t length; - if (!JS_GetArrayLength(cx, array, &length)) { + if (!JS_GetArrayLength(context(), array, &length)) { return false; } RootedValue v(context()); for (uint32_t i = 0; i < length; ++i) { - if (!JS_GetElement(cx, array, i, &v)) { + if (!JS_GetElement(context(), array, i, &v)) { return false; } @@ -722,7 +667,7 @@ JSStructuredCloneWriter::parseTransferable() JSObject* tObj = CheckedUnwrap(&v.toObject()); if (!tObj) { - JS_ReportErrorNumber(context(), js_GetErrorMessage, NULL, JSMSG_UNWRAP_DENIED); + JS_ReportError(context(), "Permission denied to access object"); return false; } if (!tObj->is()) { @@ -730,13 +675,13 @@ JSStructuredCloneWriter::parseTransferable() return false; } - // No duplicates allowed - if (std::find(transferableObjects.begin(), transferableObjects.end(), tObj) != transferableObjects.end()) { - JS_ReportErrorNumber(context(), js_GetErrorMessage, NULL, JSMSG_SC_DUP_TRANSFERABLE); + // No duplicate: + if (transferableObjects.has(tObj)) { + reportErrorTransferable(); return false; } - if (!transferableObjects.append(tObj)) + if (!transferableObjects.putNew(tObj)) return false; } @@ -748,8 +693,6 @@ JSStructuredCloneWriter::reportErrorTransferable() { if (callbacks && callbacks->reportError) return callbacks->reportError(context(), JS_SCERR_TRANSFERABLE); - else - JS_ReportErrorNumber(context(), js_GetErrorMessage, NULL, JSMSG_SC_NOT_TRANSFERABLE); } bool @@ -951,73 +894,30 @@ JSStructuredCloneWriter::startWrite(const Value &v) bool JSStructuredCloneWriter::writeTransferMap() { - if (transferableObjects.empty()) - return true; - - if (!out.writePair(SCTAG_TRANSFER_MAP_HEADER, (uint32_t)SCTAG_TM_UNREAD)) - return false; - - if (!out.write(transferableObjects.length())) - return false; - - for (JS::AutoObjectVector::Range tr = transferableObjects.all(); - !tr.empty(); tr.popFront()) - { - JSObject *obj = tr.front(); - - if (!memory.put(obj, memory.count())) + if (!transferableObjects.empty()) { + if (!out.writePair(SCTAG_TRANSFER_MAP_HEADER, (uint32_t)SCTAG_TM_NOT_MARKED)) return false; - // Emit a placeholder pointer. We will steal the data and neuter the - // transferable later. - if (!out.writePair(SCTAG_TRANSFER_MAP_ENTRY, SCTAG_TM_UNFILLED) || - !out.writePtr(NULL) || - !out.write(0)) - { - return false; + for (HashSet::Range r = transferableObjects.all(); + !r.empty(); r.popFront()) { + JSObject *obj = r.front(); + + if (!memory.put(obj, memory.count())) + return false; + + void *content; + uint8_t *data; + if (!JS_StealArrayBufferContents(context(), obj, &content, &data)) + return false; + + if (!out.writePair(SCTAG_TRANSFER_MAP, 0) || !out.writePtr(content)) + return false; } } return true; } -bool -JSStructuredCloneWriter::transferOwnership() -{ - if (transferableObjects.empty()) - return true; - - // Walk along the transferables and the transfer map at the same time, - // grabbing out pointers from the transferables and stuffing them into the - // transfer map. - uint64_t *point = out.rawBuffer(); - JS_ASSERT(uint32_t(LittleEndian::readUint64(point) >> 32) == SCTAG_TRANSFER_MAP_HEADER); - point++; - JS_ASSERT(LittleEndian::readUint64(point) == transferableObjects.length()); - point++; - - for (JS::AutoObjectVector::Range tr = transferableObjects.all(); - !tr.empty(); - tr.popFront()) - { - void *content; - uint8_t *data; - if (!JS_StealArrayBufferContents(context(), tr.front(), &content, &data)) - return false; // Destructor will clean up the already-transferred data - - MOZ_ASSERT(uint32_t(LittleEndian::readUint64(point) >> 32) == SCTAG_TRANSFER_MAP_ENTRY); - LittleEndian::writeUint64(point++, PairToUInt64(SCTAG_TRANSFER_MAP_ENTRY, SCTAG_TM_ALLOC_DATA)); - LittleEndian::writeUint64(point++, reinterpret_cast(content)); - LittleEndian::writeUint64(point++, 0); - } - - JS_ASSERT(point <= out.rawBuffer() + out.count()); - JS_ASSERT_IF(point < out.rawBuffer() + out.count(), - uint32_t(LittleEndian::readUint64(point) >> 32) != SCTAG_TRANSFER_MAP_ENTRY); - - return true; -} - bool JSStructuredCloneWriter::write(const Value &v) { @@ -1061,7 +961,8 @@ JSStructuredCloneWriter::write(const Value &v) } memory.clear(); - return transferOwnership(); + + return true; } bool @@ -1387,7 +1288,7 @@ JSStructuredCloneReader::startRead(Value *vp) "invalid input"); return false; - case SCTAG_TRANSFER_MAP_ENTRY: + case SCTAG_TRANSFER_MAP: // A map cannot be here but just at the beginning of the buffer. JS_ReportErrorNumber(context(), js_GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA, @@ -1473,57 +1374,37 @@ JSStructuredCloneReader::readId(jsid *idp) bool JSStructuredCloneReader::readTransferMap() { - uint64_t *headerPos = in.tell(); - uint32_t tag, data; if (!in.getPair(&tag, &data)) return false; - if (tag != SCTAG_TRANSFER_MAP_HEADER || TransferableMapHeader(data) == SCTAG_TM_TRANSFERRED) + if (tag != SCTAG_TRANSFER_MAP_HEADER || + (TransferableMapHeader)data == SCTAG_TM_MARKED) return true; - uint64_t numTransferables; - MOZ_ALWAYS_TRUE(in.readPair(&tag, &data)); - if (!in.read(&numTransferables)) + if (!in.replacePair(SCTAG_TRANSFER_MAP_HEADER, SCTAG_TM_MARKED)) return false; - for (uint64_t i = 0; i < numTransferables; i++) { - uint64_t *pos = in.tell(); + if (!in.readPair(&tag, &data)) + return false; - if (!in.readPair(&tag, &data)) + while (1) { + if (!in.getPair(&tag, &data)) return false; - JS_ASSERT(tag == SCTAG_TRANSFER_MAP_ENTRY); - JS_ASSERT(data == SCTAG_TM_ALLOC_DATA); + + if (tag != SCTAG_TRANSFER_MAP) + break; void *content; - if (!in.readPtr(&content)) - return false; - uint64_t userdata; - if (!in.read(&userdata)) + if (!in.readPair(&tag, &data) || !in.readPtr(&content)) return false; JSObject *obj = JS_NewArrayBufferWithContents(context(), content); - if (!obj) - return false; - - // Rewind to the SCTAG_TRANSFER_MAP_ENTRY and mark this entry as unowned by - // the input buffer. - uint64_t *next = in.tell(); - in.seek(pos); - MOZ_ALWAYS_TRUE(in.replacePair(SCTAG_TRANSFER_MAP_ENTRY, SCTAG_TM_UNOWNED)); - in.seek(next); - - if (!allObjs.append(ObjectValue(*obj))) + if (!obj || !allObjs.append(ObjectValue(*obj))) return false; } - // Mark the whole transfer map as consumed - uint64_t *endPos = in.tell(); - in.seek(headerPos); - MOZ_ALWAYS_TRUE(in.replacePair(SCTAG_TRANSFER_MAP_HEADER, SCTAG_TM_TRANSFERRED)); - in.seek(endPos); - return true; } @@ -1598,8 +1479,7 @@ JS_WriteStructuredClone(JSContext *cx, JS::Value valueArg, uint64_t **bufp, size JS_PUBLIC_API(bool) JS_ClearStructuredClone(const uint64_t *data, size_t nbytes) { - ClearStructuredClone(data, nbytes); - return true; + return ClearStructuredClone(data, nbytes); } JS_PUBLIC_API(bool) diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 59b67f1552d..6430dea1c5d 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -244,7 +244,7 @@ AllocateArrayBufferContents(JSContext *maybecx, uint32_t nbytes, uint8_t *initda memcpy(newheader->elements(), initdata, nbytes); // we rely on this being correct - ArrayBufferObject::updateElementsHeader(newheader, nbytes); + ArrayBufferObject::setElementsHeader(newheader, nbytes); return newheader; } @@ -274,7 +274,7 @@ ArrayBufferObject::allocateSlots(JSContext *maybecx, uint32_t bytes, uint8_t *co memset(elements, 0, bytes); } - initElementsHeader(getElementsHeader(), bytes); + setElementsHeader(getElementsHeader(), bytes); return true; } @@ -297,7 +297,7 @@ PostBarrierTypedArrayObject(JSObject *obj) // JS_USE_NEW_OBJECT_REPRESENTATION pending, since it will solve this much // more cleanly. struct OldObjectRepresentationHack { - uint32_t flags; + uint32_t capacity; uint32_t initializedLength; EncapsulatedPtr views; }; @@ -329,108 +329,45 @@ GetViewListRef(ArrayBufferObject *obj) return reinterpret_cast(obj->getElementsHeader())->views; } -void -ArrayBufferObject::neuterViews(JSContext *maybecx) -{ - ArrayBufferViewObject *view; - for (view = GetViewList(this); view; view = view->nextView()) { - view->neuter(); - - // Notify compiled jit code that the base pointer has moved. - if (maybecx) - MarkObjectStateChange(maybecx, view); - } - - // neuterAsmJSArrayBuffer adjusts state specific to the ArrayBuffer data - // itself, but it only affects the behavior of views - if (isAsmJSArrayBuffer()) - ArrayBufferObject::neuterAsmJSArrayBuffer(*this); -} - void ArrayBufferObject::changeContents(JSContext *maybecx, ObjectElements *newHeader) { - // Grab out data before invalidating it. - uint32_t byteLengthCopy = byteLength(); - uintptr_t oldDataPointer = uintptr_t(dataPointer()); - ArrayBufferViewObject *viewListHead = GetViewList(this); + // Grab out data before invalidating it. + uint32_t byteLengthCopy = byteLength(); + uintptr_t oldDataPointer = uintptr_t(dataPointer()); + ArrayBufferViewObject *viewListHead = GetViewList(this); - // Update all views. - uintptr_t newDataPointer = uintptr_t(newHeader->elements()); - for (ArrayBufferViewObject *view = viewListHead; view; view = view->nextView()) { - uintptr_t newDataPtr = uintptr_t(view->getPrivate()) - oldDataPointer + newDataPointer; - view->setPrivate(reinterpret_cast(newDataPtr)); + // Update all views. + uintptr_t newDataPointer = uintptr_t(newHeader->elements()); + for (ArrayBufferViewObject *view = viewListHead; view; view = view->nextView()) { + uintptr_t newDataPtr = uintptr_t(view->getPrivate()) - oldDataPointer + newDataPointer; + view->setPrivate(reinterpret_cast(newDataPtr)); - // Notify compiled jit code that the base pointer has moved. - if (maybecx) - MarkObjectStateChange(maybecx, view); - } + // Notify compiled jit code that the base pointer has moved. + if (maybecx) + MarkObjectStateChange(maybecx, view); + } - // The list of views in the old header is reachable if the contents are - // being transferred, so NULL it out - SetViewList(this, NULL); + // Change to the new header (now, so we can use SetViewList). + elements = newHeader->elements(); - elements = newHeader->elements(); - - initElementsHeader(newHeader, byteLengthCopy); - InitViewList(this, viewListHead); -} - -void -ArrayBufferObject::neuter(JSContext *cx) -{ - JS_ASSERT(cx); - if (hasDynamicElements() && !isAsmJSArrayBuffer()) { - ObjectElements *oldHeader = getElementsHeader(); - changeContents(cx, ObjectElements::fromElements(fixedElements())); - - FreeOp fop(cx->runtime(), false); - fop.free_(oldHeader); - } - - uint32_t byteLen = 0; - updateElementsHeader(getElementsHeader(), byteLen); + // Initialize 'newHeader'. + ArrayBufferObject::setElementsHeader(newHeader, byteLengthCopy); + SetViewList(this, viewListHead); } bool -ArrayBufferObject::copyData(JSContext *maybecx) +ArrayBufferObject::uninlineData(JSContext *maybecx) { - ObjectElements *newHeader = AllocateArrayBufferContents(maybecx, byteLength(), dataPointer()); - if (!newHeader) - return false; + if (hasDynamicElements()) + return true; - changeContents(maybecx, newHeader); - return true; -} + ObjectElements *newHeader = AllocateArrayBufferContents(maybecx, byteLength(), dataPointer()); + if (!newHeader) + return false; -bool -ArrayBufferObject::ensureNonInline(JSContext *maybecx) -{ - if (hasDynamicElements()) - return true; - return copyData(maybecx); -} - -// If the ArrayBuffer already contains dynamic contents, hand them back. -// Otherwise, allocate some new contents and copy the data over, but in no case -// modify the original ArrayBuffer. (Also, any allocated contents will have no -// views linked to in its header.) -ObjectElements * -ArrayBufferObject::getTransferableContents(JSContext *maybecx, bool *callerOwns) -{ - if (hasDynamicElements() && !isAsmJSArrayBuffer()) { - *callerOwns = false; - return getElementsHeader(); - } - - uint32_t byteLen = byteLength(); - ObjectElements *newheader = AllocateArrayBufferContents(maybecx, byteLen, dataPointer()); - if (!newheader) - return NULL; - - initElementsHeader(newheader, byteLen); - *callerOwns = true; - return newheader; + changeContents(maybecx, newHeader); + return true; } #if defined(JS_ION) && defined(JS_CPU_X64) @@ -542,9 +479,8 @@ ArrayBufferObject::neuterAsmJSArrayBuffer(ArrayBufferObject &buffer) bool ArrayBufferObject::prepareForAsmJS(JSContext *cx, Handle buffer) { - if (!buffer->copyData(cx)) + if (!buffer->uninlineData(cx)) return false; - JS_ASSERT(buffer->hasDynamicElements()); buffer->getElementsHeader()->setIsAsmJSArrayBuffer(); return true; @@ -661,28 +597,41 @@ ArrayBufferObject::createDataViewForThis(JSContext *cx, unsigned argc, Value *vp } bool -ArrayBufferObject::stealContents(JSContext *cx, JSObject *obj, void **contents, uint8_t **data) +ArrayBufferObject::stealContents(JSContext *cx, JSObject *obj, void **contents, + uint8_t **data) { ArrayBufferObject &buffer = obj->as(); + ArrayBufferViewObject *views = GetViewList(&buffer); + js::ObjectElements *header = js::ObjectElements::fromElements((js::HeapSlot*)buffer.dataPointer()); + if (buffer.hasDynamicElements() && !buffer.isAsmJSArrayBuffer()) { + SetViewList(&buffer, nullptr); + *contents = header; + *data = buffer.dataPointer(); - // Make the data stealable - bool own; - ObjectElements *header = reinterpret_cast(buffer.getTransferableContents(cx, &own)); - if (!header) - return false; - *contents = header; - *data = reinterpret_cast(header + 1); + buffer.setFixedElements(); + header = js::ObjectElements::fromElements((js::HeapSlot*)buffer.dataPointer()); + } else { + uint32_t length = buffer.byteLength(); + js::ObjectElements *newheader = + AllocateArrayBufferContents(cx, length, buffer.dataPointer()); + if (!newheader) { + js_ReportOutOfMemory(cx); + return false; + } - // Neuter the views, which may also mprotect(PROT_NONE) the buffer. So do - // it after copying out the data. - buffer.neuterViews(cx); + ArrayBufferObject::setElementsHeader(newheader, length); + *contents = newheader; + *data = reinterpret_cast(newheader + 1); - if (!own) { - // If header has dynamically allocated elements, revert it back to - // fixed-element storage before neutering it. - buffer.changeContents(cx, ObjectElements::fromElements(buffer.fixedElements())); + if (buffer.isAsmJSArrayBuffer()) + ArrayBufferObject::neuterAsmJSArrayBuffer(buffer); } - buffer.neuter(cx); + + // Neuter the donor ArrayBufferObject and all views of it + ArrayBufferObject::setElementsHeader(header, 0); + InitViewList(&buffer, views); + for (ArrayBufferViewObject *view = views; view; view = view->nextView()) + view->neuter(); return true; } @@ -4017,19 +3966,11 @@ JS_GetArrayBufferData(JSObject *obj) if (!obj) return nullptr; ArrayBufferObject &buffer = obj->as(); - if (!buffer.ensureNonInline(NULL)) + if (!buffer.uninlineData(nullptr)) return nullptr; return buffer.dataPointer(); } -JS_FRIEND_API(void) -JS_NeuterArrayBuffer(JSObject *obj, JSContext *cx) -{ - ArrayBufferObject &buffer = obj->as(); - buffer.neuterViews(cx); - buffer.neuter(cx); -} - JS_FRIEND_API(JSObject *) JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes) { @@ -4056,7 +3997,7 @@ JS_AllocateArrayBufferContents(JSContext *cx, uint32_t nbytes, void **contents, if (!header) return false; - ArrayBufferObject::updateElementsHeader(header, nbytes); + ArrayBufferObject::setElementsHeader(header, nbytes); *contents = header; *data = reinterpret_cast(header->elements()); @@ -4070,7 +4011,7 @@ JS_ReallocateArrayBufferContents(JSContext *cx, uint32_t nbytes, void **contents if (!header) return false; - ArrayBufferObject::initElementsHeader(header, nbytes); + ArrayBufferObject::setElementsHeader(header, nbytes); *contents = header; *data = reinterpret_cast(header->elements()); @@ -4320,8 +4261,8 @@ JS_GetObjectAsArrayBufferView(JSObject *obj, uint32_t *length, uint8_t **data) JS_FRIEND_API(JSObject *) JS_GetObjectAsArrayBuffer(JSObject *obj, uint32_t *length, uint8_t **data) { - if (!(obj = CheckedUnwrap(obj))) - return nullptr; + if (!(obj = CheckedUnwrap(obj))) + return nullptr; if (!obj->is()) return nullptr; diff --git a/js/src/vm/TypedArrayObject.h b/js/src/vm/TypedArrayObject.h index dc1fdab3c57..ce13ea413f4 100644 --- a/js/src/vm/TypedArrayObject.h +++ b/js/src/vm/TypedArrayObject.h @@ -146,7 +146,8 @@ class ArrayBufferObject : public JSObject static bool stealContents(JSContext *cx, JSObject *obj, void **contents, uint8_t **data); - static void updateElementsHeader(js::ObjectElements *header, uint32_t bytes) { + static void setElementsHeader(js::ObjectElements *header, uint32_t bytes) { + header->flags = 0; header->initializedLength = bytes; // NB: one or both of these fields is clobbered by GetViewList to store @@ -156,11 +157,6 @@ class ArrayBufferObject : public JSObject header->capacity = 0; } - static void initElementsHeader(js::ObjectElements *header, uint32_t bytes) { - header->flags = 0; - updateElementsHeader(header, bytes); - } - static uint32_t headerInitializedLength(const js::ObjectElements *header) { return header->initializedLength; } @@ -168,48 +164,22 @@ class ArrayBufferObject : public JSObject void addView(ArrayBufferViewObject *view); bool allocateSlots(JSContext *cx, uint32_t size, uint8_t *contents = nullptr); - void changeContents(JSContext *cx, ObjectElements *newHeader); /* - * Copy the data into freshly-allocated memory. Used when un-inlining or - * when converting an ArrayBuffer to an AsmJS (MMU-assisted) ArrayBuffer. - */ - bool copyData(JSContext *maybecx); - - /* - * Ensure data is not stored inline in the object. Used when handing back a + * Ensure that the data is not stored inline. Used when handing back a * GC-safe pointer. */ - bool ensureNonInline(JSContext *maybecx); + bool uninlineData(JSContext *cx); uint32_t byteLength() const { return getElementsHeader()->initializedLength; } - /* - * Return the contents of an ArrayBuffer without modifying the ArrayBuffer - * itself. Set *callerOwns to true if the caller has the only pointer to - * the returned contents (which is the case for inline or asm.js buffers), - * and false if the ArrayBuffer still owns the pointer. - */ - ObjectElements *getTransferableContents(JSContext *maybecx, bool *callerOwns); - - /* - * Neuter all views of an ArrayBuffer. - */ - void neuterViews(JSContext *maybecx); - inline uint8_t * dataPointer() const { return (uint8_t *) elements; } - /* - * Discard the ArrayBuffer contents. For asm.js buffers, at least, should - * be called after neuterViews(). - */ - void neuter(JSContext *maybecx); - /* * Check if the arrayBuffer contains any data. This will return false for * ArrayBuffer.prototype and neutered ArrayBuffers. @@ -551,7 +521,6 @@ class DataViewObject : public ArrayBufferViewObject static bool fun_setFloat64(JSContext *cx, unsigned argc, Value *vp); static JSObject *initClass(JSContext *cx); - static void neuter(JSObject *view); static bool getDataPointer(JSContext *cx, Handle obj, CallArgs args, size_t typeSize, uint8_t **data); template