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