Bug 789593 - Clone typed arrays by cloning their buffers and only saving construction parameters. r=jorendorff, bent

Also enters a compartment where needed, and bumps both the structured clone and IndexedDB schema versions
This commit is contained in:
Steve Fink 2013-02-22 13:43:28 -08:00
Родитель 7b3fdd386a
Коммит a3f269557f
8 изменённых файлов: 403 добавлений и 97 удалений

Просмотреть файл

@ -3530,12 +3530,13 @@ NS_DOMWriteStructuredClone(JSContext* cx,
// Prepare the ImageData internals.
uint32_t width = imageData->Width();
uint32_t height = imageData->Height();
JS::Value dataArray = JS::ObjectValue(*imageData->GetDataObject());
JSObject *dataArray = imageData->GetDataObject();
// Write the internals to the stream.
JSAutoCompartment ac(cx, dataArray);
return JS_WriteUint32Pair(writer, SCTAG_DOM_IMAGEDATA, 0) &&
JS_WriteUint32Pair(writer, width, height) &&
JS_WriteTypedArray(writer, dataArray);
JS_WriteTypedArray(writer, JS::ObjectValue(*dataArray));
}
void

Просмотреть файл

@ -32,11 +32,11 @@ namespace {
// If JS_STRUCTURED_CLONE_VERSION changes then we need to update our major
// schema version.
MOZ_STATIC_ASSERT(JS_STRUCTURED_CLONE_VERSION == 1,
MOZ_STATIC_ASSERT(JS_STRUCTURED_CLONE_VERSION == 2,
"Need to update the major schema version.");
// Major schema version. Bump for almost everything.
const uint32_t kMajorSchemaVersion = 13;
const uint32_t kMajorSchemaVersion = 14;
// Minor schema version. Should almost always be 0 (maybe bump on release
// branches if we have to).
@ -1350,6 +1350,17 @@ UpgradeSchemaFrom12_0To13_0(mozIStorageConnection* aConnection,
return NS_OK;
}
nsresult
UpgradeSchemaFrom13_0To14_0(mozIStorageConnection* aConnection)
{
// The only change between 13 and 14 was a different structured
// clone format, but it's backwards-compatible.
nsresult rv = aConnection->SetSchemaVersion(MakeSchemaVersion(14, 0));
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
class VersionChangeEventsRunnable;
class SetVersionHelper : public AsyncConnectionHelper,
@ -1904,7 +1915,7 @@ OpenDatabaseHelper::CreateDatabaseConnection(
}
else {
// This logic needs to change next time we change the schema!
MOZ_STATIC_ASSERT(kSQLiteSchemaVersion == int32_t((13 << 4) + 0),
MOZ_STATIC_ASSERT(kSQLiteSchemaVersion == int32_t((14 << 4) + 0),
"Need upgrade code from schema version increase.");
while (schemaVersion != kSQLiteSchemaVersion) {
@ -1936,6 +1947,9 @@ OpenDatabaseHelper::CreateDatabaseConnection(
else if (schemaVersion == MakeSchemaVersion(12, 0)) {
rv = UpgradeSchemaFrom12_0To13_0(connection, &vacuumNeeded);
}
else if (schemaVersion == MakeSchemaVersion(13, 0)) {
rv = UpgradeSchemaFrom13_0To14_0(connection);
}
else {
NS_WARNING("Unable to open IndexedDB database, no upgrade path is "
"available!");

Просмотреть файл

@ -4404,7 +4404,7 @@ JS_ParseJSONWithReviver(JSContext *cx, const jschar *chars, uint32_t len, jsval
/* API for the HTML5 internal structured cloning algorithm. */
/* The maximum supported structured-clone serialization format version. */
#define JS_STRUCTURED_CLONE_VERSION 1
#define JS_STRUCTURED_CLONE_VERSION 2
struct JSStructuredCloneCallbacks {
ReadStructuredCloneOp read;

Просмотреть файл

@ -4,6 +4,29 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Endian.h"
/*
* This file implements the structured clone algorithm of
* http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#safe-passing-of-structured-data
*
* The implementation differs slightly in that it uses an explicit stack, and
* the "memory" maps source objects to sequential integer indexes rather than
* directly pointing to destination objects. As a result, the order in which
* things are added to the memory must exactly match the order in which they
* are placed into 'allObjs', an analogous array of back-referenceable
* destination objects constructed while reading.
*
* For the most part, this is easy: simply add objects to the memory when first
* encountering them. But reading in a typed array requires an ArrayBuffer for
* construction, so objects cannot just be added to 'allObjs' in the order they
* are created. If they were, ArrayBuffers would come before typed arrays when
* in fact the typed array was added to 'memory' first.
*
* So during writing, we add objects to the memory when first encountering
* them. When reading a typed array, a placeholder is pushed onto allObjs until
* the ArrayBuffer has been read, then it is updated with the actual typed
* array object.
*/
#include "mozilla/FloatingPoint.h"
#include "jsclone.h"
@ -40,17 +63,18 @@ enum StructuredDataType {
SCTAG_BACK_REFERENCE_OBJECT,
SCTAG_TRANSFER_MAP_HEADER,
SCTAG_TRANSFER_MAP,
SCTAG_TYPED_ARRAY_MIN = 0xFFFF0100,
SCTAG_TYPED_ARRAY_INT8 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_INT8,
SCTAG_TYPED_ARRAY_UINT8 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_UINT8,
SCTAG_TYPED_ARRAY_INT16 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_INT16,
SCTAG_TYPED_ARRAY_UINT16 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_UINT16,
SCTAG_TYPED_ARRAY_INT32 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_INT32,
SCTAG_TYPED_ARRAY_UINT32 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_UINT32,
SCTAG_TYPED_ARRAY_FLOAT32 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_FLOAT32,
SCTAG_TYPED_ARRAY_FLOAT64 = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_FLOAT64,
SCTAG_TYPED_ARRAY_UINT8_CLAMPED = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_UINT8_CLAMPED,
SCTAG_TYPED_ARRAY_MAX = SCTAG_TYPED_ARRAY_MIN + TypedArray::TYPE_MAX - 1,
SCTAG_TYPED_ARRAY_OBJECT,
SCTAG_TYPED_ARRAY_V1_MIN = 0xFFFF0100,
SCTAG_TYPED_ARRAY_V1_INT8 = SCTAG_TYPED_ARRAY_V1_MIN + TypedArray::TYPE_INT8,
SCTAG_TYPED_ARRAY_V1_UINT8 = SCTAG_TYPED_ARRAY_V1_MIN + TypedArray::TYPE_UINT8,
SCTAG_TYPED_ARRAY_V1_INT16 = SCTAG_TYPED_ARRAY_V1_MIN + TypedArray::TYPE_INT16,
SCTAG_TYPED_ARRAY_V1_UINT16 = SCTAG_TYPED_ARRAY_V1_MIN + TypedArray::TYPE_UINT16,
SCTAG_TYPED_ARRAY_V1_INT32 = SCTAG_TYPED_ARRAY_V1_MIN + TypedArray::TYPE_INT32,
SCTAG_TYPED_ARRAY_V1_UINT32 = SCTAG_TYPED_ARRAY_V1_MIN + TypedArray::TYPE_UINT32,
SCTAG_TYPED_ARRAY_V1_FLOAT32 = SCTAG_TYPED_ARRAY_V1_MIN + TypedArray::TYPE_FLOAT32,
SCTAG_TYPED_ARRAY_V1_FLOAT64 = SCTAG_TYPED_ARRAY_V1_MIN + TypedArray::TYPE_FLOAT64,
SCTAG_TYPED_ARRAY_V1_UINT8_CLAMPED = SCTAG_TYPED_ARRAY_V1_MIN + TypedArray::TYPE_UINT8_CLAMPED,
SCTAG_TYPED_ARRAY_V1_MAX = SCTAG_TYPED_ARRAY_V1_MIN + TypedArray::TYPE_MAX - 1,
SCTAG_END_OF_BUILTIN_TYPES
};
@ -66,13 +90,6 @@ js_GetSCOffset(JSStructuredCloneWriter* writer)
return writer->output().count() * sizeof(uint64_t);
}
static StructuredDataType
ArrayTypeToTag(uint32_t type)
{
JS_ASSERT(type < TypedArray::TYPE_MAX);
return static_cast<StructuredDataType>(uint32_t(SCTAG_TYPED_ARRAY_MIN) + type);
}
JS_STATIC_ASSERT(SCTAG_END_OF_BUILTIN_TYPES <= JS_SCTAG_USER_MIN);
JS_STATIC_ASSERT(JS_SCTAG_USER_MIN <= JS_SCTAG_USER_MAX);
JS_STATIC_ASSERT(TypedArray::TYPE_INT8 == 0);
@ -539,6 +556,7 @@ JS_PUBLIC_API(JSBool)
JS_WriteTypedArray(JSStructuredCloneWriter *w, jsval v)
{
JS_ASSERT(v.isObject());
assertSameCompartment(w->context(), v);
RootedObject obj(w->context(), &v.toObject());
// If the object is a security wrapper, see if we're allowed to unwrap it.
@ -552,30 +570,29 @@ JS_WriteTypedArray(JSStructuredCloneWriter *w, jsval v)
return w->writeTypedArray(obj);
}
/*
* Write out a typed array. Note that post-v1 structured clone buffers do not
* perform endianness conversion on stored data, so multibyte typed arrays
* cannot be deserialized into a different endianness machine. Endianness
* conversion would prevent sharing ArrayBuffers: if you have Int8Array and
* Int16Array views of the same ArrayBuffer, should the data bytes be
* byte-swapped when writing or not? The Int8Array requires them to not be
* swapped; the Int16Array requires that they are.
*/
bool
JSStructuredCloneWriter::writeTypedArray(HandleObject arr)
{
if (!out.writePair(ArrayTypeToTag(TypedArray::type(arr)), TypedArray::length(arr)))
if (!out.writePair(SCTAG_TYPED_ARRAY_OBJECT, TypedArray::length(arr)))
return false;
uint64_t type = TypedArray::type(arr);
if (!out.write(type))
return false;
switch (TypedArray::type(arr)) {
case TypedArray::TYPE_INT8:
case TypedArray::TYPE_UINT8:
case TypedArray::TYPE_UINT8_CLAMPED:
return out.writeArray((const uint8_t *) TypedArray::viewData(arr), TypedArray::length(arr));
case TypedArray::TYPE_INT16:
case TypedArray::TYPE_UINT16:
return out.writeArray((const uint16_t *) TypedArray::viewData(arr), TypedArray::length(arr));
case TypedArray::TYPE_INT32:
case TypedArray::TYPE_UINT32:
case TypedArray::TYPE_FLOAT32:
return out.writeArray((const uint32_t *) TypedArray::viewData(arr), TypedArray::length(arr));
case TypedArray::TYPE_FLOAT64:
return out.writeArray((const uint64_t *) TypedArray::viewData(arr), TypedArray::length(arr));
default:
JS_NOT_REACHED("unknown TypedArray type");
// Write out the ArrayBuffer tag and contents
if (!startWrite(TypedArray::bufferValue(arr)))
return false;
}
return out.write(TypedArray::byteOffset(arr));
}
bool
@ -818,48 +835,94 @@ JSStructuredCloneReader::readString(uint32_t nchars)
return str;
}
static uint32_t
TagToV1ArrayType(uint32_t tag)
{
JS_ASSERT(tag >= SCTAG_TYPED_ARRAY_V1_MIN && tag <= SCTAG_TYPED_ARRAY_V1_MAX);
return tag - SCTAG_TYPED_ARRAY_V1_MIN;
}
JS_PUBLIC_API(JSBool)
JS_ReadTypedArray(JSStructuredCloneReader *r, jsval *vp)
{
uint32_t tag, nelems;
if (!r->input().readPair(&tag, &nelems))
return false;
JS_ASSERT(tag >= SCTAG_TYPED_ARRAY_MIN && tag <= SCTAG_TYPED_ARRAY_MAX);
return r->readTypedArray(tag, nelems, vp);
if (tag >= SCTAG_TYPED_ARRAY_V1_MIN && tag <= SCTAG_TYPED_ARRAY_V1_MAX) {
return r->readTypedArray(TagToV1ArrayType(tag), nelems, vp, true);
} else if (tag == SCTAG_TYPED_ARRAY_OBJECT) {
uint64_t arrayType;
if (!r->input().read(&arrayType))
return false;
return r->readTypedArray(arrayType, nelems, vp);
} else {
JS_ReportErrorNumber(r->context(), js_GetErrorMessage, NULL,
JSMSG_SC_BAD_SERIALIZED_DATA, "expected type array");
return false;
}
}
bool
JSStructuredCloneReader::readTypedArray(uint32_t tag, uint32_t nelems, Value *vp)
JSStructuredCloneReader::readTypedArray(uint32_t arrayType, uint32_t nelems, Value *vp,
bool v1Read)
{
if (arrayType > TypedArray::TYPE_UINT8_CLAMPED) {
JS_ReportErrorNumber(context(), js_GetErrorMessage, NULL,
JSMSG_SC_BAD_SERIALIZED_DATA, "unhandled typed array element type");
return false;
}
// Push a placeholder onto the allObjs list to stand in for the typed array
uint32_t placeholderIndex = allObjs.length();
Value dummy = JSVAL_NULL;
if (!allObjs.append(dummy))
return false;
// Read the ArrayBuffer object and its contents (but no properties)
Value v;
uint32_t byteOffset;
if (v1Read) {
if (!readV1ArrayBuffer(arrayType, nelems, &v))
return false;
byteOffset = 0;
} else {
if (!startRead(&v))
return false;
uint64_t n;
if (!in.read(&n))
return false;
byteOffset = n;
}
RootedObject buffer(context(), &v.toObject());
RootedObject obj(context(), NULL);
switch (tag) {
case SCTAG_TYPED_ARRAY_INT8:
obj = JS_NewInt8Array(context(), nelems);
switch (arrayType) {
case TypedArray::TYPE_INT8:
obj = JS_NewInt8ArrayWithBuffer(context(), buffer, byteOffset, nelems);
break;
case SCTAG_TYPED_ARRAY_UINT8:
obj = JS_NewUint8Array(context(), nelems);
case TypedArray::TYPE_UINT8:
obj = JS_NewUint8ArrayWithBuffer(context(), buffer, byteOffset, nelems);
break;
case SCTAG_TYPED_ARRAY_INT16:
obj = JS_NewInt16Array(context(), nelems);
case TypedArray::TYPE_INT16:
obj = JS_NewInt16ArrayWithBuffer(context(), buffer, byteOffset, nelems);
break;
case SCTAG_TYPED_ARRAY_UINT16:
obj = JS_NewUint16Array(context(), nelems);
case TypedArray::TYPE_UINT16:
obj = JS_NewUint16ArrayWithBuffer(context(), buffer, byteOffset, nelems);
break;
case SCTAG_TYPED_ARRAY_INT32:
obj = JS_NewInt32Array(context(), nelems);
case TypedArray::TYPE_INT32:
obj = JS_NewInt32ArrayWithBuffer(context(), buffer, byteOffset, nelems);
break;
case SCTAG_TYPED_ARRAY_UINT32:
obj = JS_NewUint32Array(context(), nelems);
case TypedArray::TYPE_UINT32:
obj = JS_NewUint32ArrayWithBuffer(context(), buffer, byteOffset, nelems);
break;
case SCTAG_TYPED_ARRAY_FLOAT32:
obj = JS_NewFloat32Array(context(), nelems);
case TypedArray::TYPE_FLOAT32:
obj = JS_NewFloat32ArrayWithBuffer(context(), buffer, byteOffset, nelems);
break;
case SCTAG_TYPED_ARRAY_FLOAT64:
obj = JS_NewFloat64Array(context(), nelems);
case TypedArray::TYPE_FLOAT64:
obj = JS_NewFloat64ArrayWithBuffer(context(), buffer, byteOffset, nelems);
break;
case SCTAG_TYPED_ARRAY_UINT8_CLAMPED:
obj = JS_NewUint8ClampedArray(context(), nelems);
case TypedArray::TYPE_UINT8_CLAMPED:
obj = JS_NewUint8ClampedArrayWithBuffer(context(), buffer, byteOffset, nelems);
break;
default:
JS_NOT_REACHED("unknown TypedArray type");
@ -870,30 +933,9 @@ JSStructuredCloneReader::readTypedArray(uint32_t tag, uint32_t nelems, Value *vp
return false;
vp->setObject(*obj);
JS_ASSERT(TypedArray::length(obj) == nelems);
switch (tag) {
case SCTAG_TYPED_ARRAY_INT8:
return in.readArray((uint8_t*) JS_GetInt8ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_UINT8:
return in.readArray(JS_GetUint8ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_INT16:
return in.readArray((uint16_t*) JS_GetInt16ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_UINT16:
return in.readArray(JS_GetUint16ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_INT32:
return in.readArray((uint32_t*) JS_GetInt32ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_UINT32:
return in.readArray(JS_GetUint32ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_FLOAT32:
return in.readArray((uint32_t*) JS_GetFloat32ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_FLOAT64:
return in.readArray((uint64_t*) JS_GetFloat64ArrayData(obj), nelems);
case SCTAG_TYPED_ARRAY_UINT8_CLAMPED:
return in.readArray(JS_GetUint8ClampedArrayData(obj), nelems);
default:
JS_NOT_REACHED("unknown TypedArray type");
return false;
}
allObjs[placeholderIndex] = *vp;
return true;
}
bool
@ -908,6 +950,66 @@ JSStructuredCloneReader::readArrayBuffer(uint32_t nbytes, Value *vp)
return in.readArray(buffer.dataPointer(), nbytes);
}
static size_t
bytesPerTypedArrayElement(uint32_t arrayType)
{
switch (arrayType) {
case TypedArray::TYPE_INT8:
case TypedArray::TYPE_UINT8:
case TypedArray::TYPE_UINT8_CLAMPED:
return sizeof(uint8_t);
case TypedArray::TYPE_INT16:
case TypedArray::TYPE_UINT16:
return sizeof(uint16_t);
case TypedArray::TYPE_INT32:
case TypedArray::TYPE_UINT32:
case TypedArray::TYPE_FLOAT32:
return sizeof(uint32_t);
case TypedArray::TYPE_FLOAT64:
return sizeof(uint64_t);
default:
JS_NOT_REACHED("unknown TypedArray type");
return 0;
}
}
/*
* Read in the data for a structured clone version 1 ArrayBuffer, performing
* endianness-conversion while reading.
*/
bool
JSStructuredCloneReader::readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems, Value *vp)
{
JS_ASSERT(arrayType <= TypedArray::TYPE_UINT8_CLAMPED);
uint32_t nbytes = nelems * bytesPerTypedArrayElement(arrayType);
JSObject *obj = ArrayBufferObject::create(context(), nbytes);
if (!obj)
return false;
vp->setObject(*obj);
ArrayBufferObject &buffer = obj->asArrayBuffer();
JS_ASSERT(buffer.byteLength() == nbytes);
switch (arrayType) {
case TypedArray::TYPE_INT8:
case TypedArray::TYPE_UINT8:
case TypedArray::TYPE_UINT8_CLAMPED:
return in.readArray((uint8_t*) buffer.dataPointer(), nelems);
case TypedArray::TYPE_INT16:
case TypedArray::TYPE_UINT16:
return in.readArray((uint16_t*) buffer.dataPointer(), nelems);
case TypedArray::TYPE_INT32:
case TypedArray::TYPE_UINT32:
case TypedArray::TYPE_FLOAT32:
return in.readArray((uint32_t*) buffer.dataPointer(), nelems);
case TypedArray::TYPE_FLOAT64:
return in.readArray((uint64_t*) buffer.dataPointer(), nelems);
default:
JS_NOT_REACHED("unknown TypedArray type");
return false;
}
}
bool
JSStructuredCloneReader::startRead(Value *vp)
{
@ -1035,6 +1137,14 @@ JSStructuredCloneReader::startRead(Value *vp)
return false;
break;
case SCTAG_TYPED_ARRAY_OBJECT:
// readTypedArray adds the array to allObjs
uint64_t arrayType;
if (!in.read(&arrayType))
return false;
return readTypedArray(arrayType, data, vp);
break;
default: {
if (tag <= SCTAG_FLOAT_MAX) {
double d = ReinterpretPairAsDouble(tag, data);
@ -1044,10 +1154,10 @@ JSStructuredCloneReader::startRead(Value *vp)
break;
}
if (SCTAG_TYPED_ARRAY_MIN <= tag && tag <= SCTAG_TYPED_ARRAY_MAX) {
if (!readTypedArray(tag, data, vp))
return false;
break;
if (SCTAG_TYPED_ARRAY_V1_MIN <= tag && tag <= SCTAG_TYPED_ARRAY_V1_MAX) {
// A v1-format typed array
// readTypedArray adds the array to allObjs
return readTypedArray(TagToV1ArrayType(tag), data, vp, true);
}
if (!callbacks || !callbacks->read) {

Просмотреть файл

@ -110,8 +110,9 @@ struct JSStructuredCloneReader {
bool checkDouble(double d);
JSString *readString(uint32_t nchars);
bool readTypedArray(uint32_t tag, uint32_t nelems, js::Value *vp);
bool readTypedArray(uint32_t arrayType, uint32_t nelems, js::Value *vp, bool v1Read = false);
bool readArrayBuffer(uint32_t nbytes, js::Value *vp);
bool readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems, js::Value *vp);
bool readId(jsid *idp);
bool startRead(js::Value *vp);

Просмотреть файл

@ -65,9 +65,9 @@ function test() {
checkPrototype(ctor);
}
// Cloning should separately copy two TypedArrays backed by the same
// ArrayBuffer. This also tests cloning TypedArrays where the arr->data
// pointer is not 8-byte-aligned.
// Two TypedArrays backed by the same ArrayBuffer should be cloned into two
// TypedArrays still sharing a buffer. This also tests cloning TypedArrays
// where the arr->data pointer is not 8-byte-aligned.
var base = Int8Array([0, 1, 2, 3]);
b = [Int8Array(base.buffer, 0, 3), Int8Array(base.buffer, 1, 3)];
@ -77,7 +77,27 @@ function test() {
assertArraysEqual(b[0], Int8Array([0, -1, 2])); // shared with base
assertArraysEqual(b[1], Int8Array([-1, 2, 3])); // shared with base
assertArraysEqual(a[0], Int8Array([0, 1, -2])); // not shared with base
assertArraysEqual(a[1], Int8Array([1, 2, 3])); // not shared with base or a[0]
assertArraysEqual(a[1], Int8Array([1, -2, 3])); // not shared with base, shared with a[0]
assertEq(b[0].buffer, b[1].buffer);
assertEq(b[1].byteOffset, 1);
assertEq(b[1].byteLength, 3);
assertEq(b[1].buffer.byteLength, 4);
// ArrayBuffer clones do not preserve properties
base = Int8Array([0, 1, 2, 3]);
b = [Int8Array(base.buffer, 0, 3), Int8Array(base.buffer, 1, 3)];
base.buffer.prop = "yes";
base.buffer.loop = b[0];
base.buffer.loops = [ b[0], b[1] ];
a = deserialize(serialize(b));
assertEq("prop" in a[0].buffer, false);
assertEq("prop" in a[1].buffer, false);
assertEq("loop" in a[0].buffer, false);
assertEq("loop" in a[1].buffer, false);
assertEq("loops" in a[0].buffer, false);
assertEq("loops" in a[1].buffer, false);
}
test();

Просмотреть файл

@ -0,0 +1,32 @@
var captured = [];
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] = 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] = 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] = 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] = 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] = 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] = 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] = 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] = 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] = 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] = 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]);

Просмотреть файл

@ -0,0 +1,128 @@
// |reftest| skip-if(!xulRuntime.shell)
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
// This file is a copy of clone-typed-array.js from before v2 structured clone
// was implemented. If you run this test under a v1-writing engine with the
// environment variable JS_RECORD_RESULTS set, then it will output a log of
// structured clone buffers resulting from running this test. You can then use
// that log as input to another run of this same test on a newer engine, to
// verify that older-format structured clone data can be deserialized properly.
var old_serialize = serialize;
var captured = [];
if ("JS_RECORD_RESULTS" in environment) {
serialize = function(o) {
var data;
try {
data = old_serialize(o);
captured.push(data);
return data;
} catch(e) {
captured.push(e);
throw(e);
}
};
} else {
loadRelativeToScript("clone-v1-typed-array-data.dat");
serialize = function(d) {
var data = captured.shift();
if (data instanceof Error)
throw(data);
else
return data;
};
}
function assertArraysEqual(a, b) {
assertEq(a.constructor, b.constructor);
assertEq(a.length, b.length);
for (var i = 0; i < a.length; i++)
assertEq(a[i], b[i]);
}
function check(b) {
var a = deserialize(serialize(b));
assertArraysEqual(a, b);
}
function checkPrototype(ctor) {
var threw = false;
try {
serialize(ctor.prototype);
throw new Error("serializing " + ctor.name + ".prototype should throw a TypeError");
} catch (exc) {
if (!(exc instanceof TypeError))
throw exc;
}
}
function test() {
// Test cloning ArrayBuffer objects.
check(ArrayBuffer(0));
check(ArrayBuffer(7));
checkPrototype(ArrayBuffer);
// Test cloning typed array objects.
var ctors = [
Int8Array,
Uint8Array,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array,
Uint8ClampedArray];
var b;
for (var i = 0; i < ctors.length; i++) {
var ctor = ctors[i];
// check empty array
b = ctor(0);
check(b);
// check array with some elements
b = ctor(100);
var v = 1;
for (var j = 0; j < 100; j++) {
b[j] = v;
v *= 7;
}
b[99] = NaN; // check serializing NaNs too
check(b);
// try the prototype
checkPrototype(ctor);
}
// Cloning should separately copy two TypedArrays backed by the same
// ArrayBuffer. This also tests cloning TypedArrays where the arr->data
// pointer is not 8-byte-aligned.
var base = Int8Array([0, 1, 2, 3]);
b = [Int8Array(base.buffer, 0, 3), Int8Array(base.buffer, 1, 3)];
var a = deserialize(serialize(b));
base[1] = -1;
a[0][2] = -2;
assertArraysEqual(b[0], Int8Array([0, -1, 2])); // shared with base
assertArraysEqual(b[1], Int8Array([-1, 2, 3])); // shared with base
assertArraysEqual(a[0], Int8Array([0, 1, -2])); // not shared with base
assertArraysEqual(a[1], Int8Array([1, 2, 3])); // not shared with base or a[0]
}
test();
reportCompare(0, 0, 'ok');
if ("JS_RECORD_RESULTS" in environment) {
print("var captured = [];");
for (var i in captured) {
var s = "captured[" + i + "] = ";
if (captured[i] instanceof Error)
print(s + captured[i].toSource() + ";");
else
print(s + "new Uint8Array(" + [...captured[i]].toSource() + ");");
}
}