зеркало из https://github.com/mozilla/gecko-dev.git
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)
This commit is contained in:
Родитель
46c49c4b98
Коммит
1a01f63e42
|
@ -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 {
|
||||
|
|
|
@ -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<CloneBufferObject>();
|
||||
}
|
||||
|
||||
static CloneBufferObject *Create(JSContext *cx, JSAutoStructuredCloneBuffer *buffer) {
|
||||
Rooted<CloneBufferObject*> 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<uint64_t*>(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<CloneBufferObject*> obj(cx, &args.thisv().toObject().as<CloneBufferObject>());
|
||||
obj->discard();
|
||||
|
||||
char *str = JS_EncodeString(cx, args[0].toString());
|
||||
if (!str)
|
||||
return false;
|
||||
obj->setData(reinterpret_cast<uint64_t*>(str));
|
||||
obj->setNBytes(JS_GetStringLength(args[0].toString()));
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
is(HandleValue v) {
|
||||
return v.isObject() && v.toObject().is<CloneBufferObject>();
|
||||
}
|
||||
|
||||
static bool
|
||||
setCloneBuffer(JSContext* cx, unsigned int argc, JS::Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<is, setCloneBuffer_impl>(cx, args);
|
||||
}
|
||||
|
||||
static bool
|
||||
getCloneBuffer_impl(JSContext* cx, CallArgs args) {
|
||||
Rooted<CloneBufferObject*> obj(cx, &args.thisv().toObject().as<CloneBufferObject>());
|
||||
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<char*>(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<is, getCloneBuffer_impl>(cx, args);
|
||||
}
|
||||
|
||||
static void Finalize(FreeOp *fop, JSObject *obj) {
|
||||
obj->as<CloneBufferObject>().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<CloneBufferObject>()) {
|
||||
JS_ReportError(cx, "deserialize requires a clonebuffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<CloneBufferObject*> obj(cx, &args[0].toObject().as<CloneBufferObject>());
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, "")
|
||||
|
|
|
@ -224,12 +224,6 @@ class AutoArrayRooter : private AutoGCRooter {
|
|||
template<class T>
|
||||
class AutoVectorRooter : protected AutoGCRooter
|
||||
{
|
||||
typedef js::Vector<T, 8> 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<T, 8> 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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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<TypedArrayObject>();
|
||||
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<jsval> v(cx, argc > 0 ? JS_ARGV(cx, vp)[0] : UndefinedValue());
|
||||
JSObject *obj;
|
||||
if (JSVAL_IS_PRIMITIVE(v) || !(obj = JSVAL_TO_OBJECT(v))->is<TypedArrayObject>()) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "deserialize");
|
||||
return false;
|
||||
}
|
||||
TypedArrayObject *tarr = &obj->as<TypedArrayObject>();
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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');
|
|
@ -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]);
|
||||
|
|
|
@ -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() + ");");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
#include "mozilla/Endian.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#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 <class T>
|
||||
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<void*>(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--) {
|
||||
if (tag == SCTAG_TRANSFER_MAP_HEADER) {
|
||||
if ((TransferableMapHeader)uint32_t(u) == SCTAG_TM_NOT_MARKED) {
|
||||
while (point != end) {
|
||||
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
|
||||
uint32_t tag = uint32_t(u >> 32);
|
||||
if (tag == SCTAG_TRANSFER_MAP) {
|
||||
u = LittleEndian::readUint64(point++);
|
||||
js_free(reinterpret_cast<void*>(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<uint64_t*>(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,7 +451,6 @@ template <typename T>
|
|||
static void
|
||||
copyAndSwapFromLittleEndian(T *dest, const void *src, size_t nelems)
|
||||
{
|
||||
if (nelems > 0)
|
||||
NativeEndian::copyAndSwapFromLittleEndian(dest, src, nelems);
|
||||
}
|
||||
|
||||
|
@ -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,7 +565,6 @@ template <typename T>
|
|||
static void
|
||||
copyAndSwapToLittleEndian(void *dest, const T *src, size_t nelems)
|
||||
{
|
||||
if (nelems > 0)
|
||||
NativeEndian::copyAndSwapToLittleEndian(dest, src, nelems);
|
||||
}
|
||||
|
||||
|
@ -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<ArrayBufferObject>()) {
|
||||
|
@ -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,29 +894,23 @@ 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))
|
||||
if (!transferableObjects.empty()) {
|
||||
if (!out.writePair(SCTAG_TRANSFER_MAP_HEADER, (uint32_t)SCTAG_TM_NOT_MARKED))
|
||||
return false;
|
||||
|
||||
if (!out.write(transferableObjects.length()))
|
||||
return false;
|
||||
|
||||
for (JS::AutoObjectVector::Range tr = transferableObjects.all();
|
||||
!tr.empty(); tr.popFront())
|
||||
{
|
||||
JSObject *obj = tr.front();
|
||||
for (HashSet<JSObject*>::Range r = transferableObjects.all();
|
||||
!r.empty(); r.popFront()) {
|
||||
JSObject *obj = r.front();
|
||||
|
||||
if (!memory.put(obj, memory.count()))
|
||||
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))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -981,43 +918,6 @@ JSStructuredCloneWriter::writeTransferMap()
|
|||
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<uint64_t>(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;
|
||||
JS_ASSERT(tag == SCTAG_TRANSFER_MAP_ENTRY);
|
||||
JS_ASSERT(data == SCTAG_TM_ALLOC_DATA);
|
||||
|
||||
void *content;
|
||||
if (!in.readPtr(&content))
|
||||
while (1) {
|
||||
if (!in.getPair(&tag, &data))
|
||||
return false;
|
||||
|
||||
uint64_t userdata;
|
||||
if (!in.read(&userdata))
|
||||
if (tag != SCTAG_TRANSFER_MAP)
|
||||
break;
|
||||
|
||||
void *content;
|
||||
|
||||
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)
|
||||
|
|
|
@ -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<ArrayBufferViewObject> views;
|
||||
};
|
||||
|
@ -329,24 +329,6 @@ GetViewListRef(ArrayBufferObject *obj)
|
|||
return reinterpret_cast<OldObjectRepresentationHack*>(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)
|
||||
{
|
||||
|
@ -366,35 +348,20 @@ ArrayBufferObject::changeContents(JSContext *maybecx, ObjectElements *newHeader)
|
|||
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();
|
||||
|
||||
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)
|
||||
{
|
||||
if (hasDynamicElements())
|
||||
return true;
|
||||
|
||||
ObjectElements *newHeader = AllocateArrayBufferContents(maybecx, byteLength(), dataPointer());
|
||||
if (!newHeader)
|
||||
return false;
|
||||
|
@ -403,36 +370,6 @@ ArrayBufferObject::copyData(JSContext *maybecx)
|
|||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#if defined(JS_ION) && defined(JS_CPU_X64)
|
||||
// To avoid dynamically checking bounds on each load/store, asm.js code relies
|
||||
// on the SIGSEGV handler in AsmJSSignalHandlers.cpp. However, this only works
|
||||
|
@ -542,9 +479,8 @@ ArrayBufferObject::neuterAsmJSArrayBuffer(ArrayBufferObject &buffer)
|
|||
bool
|
||||
ArrayBufferObject::prepareForAsmJS(JSContext *cx, Handle<ArrayBufferObject*> 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<ArrayBufferObject>();
|
||||
|
||||
// Make the data stealable
|
||||
bool own;
|
||||
ObjectElements *header = reinterpret_cast<ObjectElements*>(buffer.getTransferableContents(cx, &own));
|
||||
if (!header)
|
||||
return false;
|
||||
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 = reinterpret_cast<uint8_t *>(header + 1);
|
||||
*data = buffer.dataPointer();
|
||||
|
||||
// Neuter the views, which may also mprotect(PROT_NONE) the buffer. So do
|
||||
// it after copying out the data.
|
||||
buffer.neuterViews(cx);
|
||||
|
||||
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()));
|
||||
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;
|
||||
}
|
||||
buffer.neuter(cx);
|
||||
|
||||
ArrayBufferObject::setElementsHeader(newheader, length);
|
||||
*contents = newheader;
|
||||
*data = reinterpret_cast<uint8_t *>(newheader + 1);
|
||||
|
||||
if (buffer.isAsmJSArrayBuffer())
|
||||
ArrayBufferObject::neuterAsmJSArrayBuffer(buffer);
|
||||
}
|
||||
|
||||
// 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<ArrayBufferObject>();
|
||||
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<ArrayBufferObject>();
|
||||
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<uint8_t*>(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<uint8_t*>(header->elements());
|
||||
|
|
|
@ -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<DataViewObject*> obj,
|
||||
CallArgs args, size_t typeSize, uint8_t **data);
|
||||
template<typename NativeType>
|
||||
|
|
Загрузка…
Ссылка в новой задаче