Bug 1041495 - Handlify StructuredClone. r=jonco

This commit is contained in:
Tom Schuster 2014-07-22 12:18:24 +02:00
parent 1814d69318
commit 594e01a452

View File

@ -212,7 +212,7 @@ struct JSStructuredCloneReader {
callbacks(cb), closure(cbClosure) { }
SCInput &input() { return in; }
bool read(Value *vp);
bool read(MutableHandleValue vp);
private:
JSContext *context() { return in.context(); }
@ -224,10 +224,11 @@ struct JSStructuredCloneReader {
JSString *readString(uint32_t data);
bool checkDouble(double d);
bool readTypedArray(uint32_t arrayType, uint32_t nelems, Value *vp, bool v1Read = false);
bool readArrayBuffer(uint32_t nbytes, Value *vp);
bool readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems, Value *vp);
bool startRead(Value *vp);
bool readTypedArray(uint32_t arrayType, uint32_t nelems, MutableHandleValue vp,
bool v1Read = false);
bool readArrayBuffer(uint32_t nbytes, MutableHandleValue vp);
bool readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems, MutableHandleValue vp);
bool startRead(MutableHandleValue vp);
SCInput ∈
@ -261,7 +262,7 @@ struct JSStructuredCloneWriter {
bool init() { return memory.init() && parseTransferable() && writeTransferMap(); }
bool write(const Value &v);
bool write(HandleValue v);
SCOutput &output() { return out; }
@ -278,7 +279,7 @@ struct JSStructuredCloneWriter {
bool writeArrayBuffer(HandleObject obj);
bool writeTypedArray(HandleObject obj);
bool startObject(HandleObject obj, bool *backref);
bool startWrite(const Value &v);
bool startWrite(HandleValue v);
bool traverseObject(HandleObject obj);
bool traverseMap(HandleObject obj);
bool traverseSet(HandleObject obj);
@ -360,7 +361,7 @@ ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, MutableHandleV
{
SCInput in(cx, data, nbytes);
JSStructuredCloneReader r(in, cb, cbClosure);
return r.read(vp.address());
return r.read(vp);
}
// If the given buffer contains Transferables, free them. Note that custom
@ -974,19 +975,8 @@ JSStructuredCloneWriter::traverseSet(HandleObject obj)
return out.writePair(SCTAG_SET_OBJECT, 0);
}
static bool
PrimitiveToObject(JSContext *cx, Value *vp)
{
JSObject *obj = PrimitiveToObject(cx, *vp);
if (!obj)
return false;
vp->setObject(*obj);
return true;
}
bool
JSStructuredCloneWriter::startWrite(const Value &v)
JSStructuredCloneWriter::startWrite(HandleValue v)
{
assertSameCompartment(context(), v);
@ -1159,7 +1149,7 @@ JSStructuredCloneWriter::transferOwnership()
}
bool
JSStructuredCloneWriter::write(const Value &v)
JSStructuredCloneWriter::write(HandleValue v)
{
if (!startWrite(v))
return false;
@ -1293,7 +1283,7 @@ TagToV1ArrayType(uint32_t tag)
}
bool
JSStructuredCloneReader::readTypedArray(uint32_t arrayType, uint32_t nelems, Value *vp,
JSStructuredCloneReader::readTypedArray(uint32_t arrayType, uint32_t nelems, MutableHandleValue vp,
bool v1Read)
{
if (arrayType > Scalar::Uint8Clamped) {
@ -1304,7 +1294,7 @@ JSStructuredCloneReader::readTypedArray(uint32_t arrayType, uint32_t nelems, Val
// Push a placeholder onto the allObjs list to stand in for the typed array
uint32_t placeholderIndex = allObjs.length();
Value dummy = JSVAL_NULL;
Value dummy = UndefinedValue();
if (!allObjs.append(dummy))
return false;
@ -1312,11 +1302,11 @@ JSStructuredCloneReader::readTypedArray(uint32_t arrayType, uint32_t nelems, Val
RootedValue v(context());
uint32_t byteOffset;
if (v1Read) {
if (!readV1ArrayBuffer(arrayType, nelems, v.address()))
if (!readV1ArrayBuffer(arrayType, nelems, &v))
return false;
byteOffset = 0;
} else {
if (!startRead(v.address()))
if (!startRead(&v))
return false;
uint64_t n;
if (!in.read(&n))
@ -1360,20 +1350,20 @@ JSStructuredCloneReader::readTypedArray(uint32_t arrayType, uint32_t nelems, Val
if (!obj)
return false;
vp->setObject(*obj);
vp.setObject(*obj);
allObjs[placeholderIndex].set(*vp);
allObjs[placeholderIndex].set(vp);
return true;
}
bool
JSStructuredCloneReader::readArrayBuffer(uint32_t nbytes, Value *vp)
JSStructuredCloneReader::readArrayBuffer(uint32_t nbytes, MutableHandleValue vp)
{
JSObject *obj = ArrayBufferObject::create(context(), nbytes);
if (!obj)
return false;
vp->setObject(*obj);
vp.setObject(*obj);
ArrayBufferObject &buffer = obj->as<ArrayBufferObject>();
JS_ASSERT(buffer.byteLength() == nbytes);
return in.readArray(buffer.dataPointer(), nbytes);
@ -1384,7 +1374,8 @@ JSStructuredCloneReader::readArrayBuffer(uint32_t nbytes, Value *vp)
* endianness-conversion while reading.
*/
bool
JSStructuredCloneReader::readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems, Value *vp)
JSStructuredCloneReader::readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems,
MutableHandleValue vp)
{
JS_ASSERT(arrayType <= Scalar::Uint8Clamped);
@ -1392,7 +1383,7 @@ JSStructuredCloneReader::readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems,
JSObject *obj = ArrayBufferObject::create(context(), nbytes);
if (!obj)
return false;
vp->setObject(*obj);
vp.setObject(*obj);
ArrayBufferObject &buffer = obj->as<ArrayBufferObject>();
JS_ASSERT(buffer.byteLength() == nbytes);
@ -1415,29 +1406,41 @@ JSStructuredCloneReader::readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems,
}
}
static bool
PrimitiveToObject(JSContext *cx, MutableHandleValue vp)
{
JSObject *obj = js::PrimitiveToObject(cx, vp);
if (!obj)
return false;
vp.setObject(*obj);
return true;
}
bool
JSStructuredCloneReader::startRead(Value *vp)
JSStructuredCloneReader::startRead(MutableHandleValue vp)
{
uint32_t tag, data;
if (!in.readPair(&tag, &data))
return false;
switch (tag) {
case SCTAG_NULL:
vp->setNull();
vp.setNull();
break;
case SCTAG_UNDEFINED:
vp->setUndefined();
vp.setUndefined();
break;
case SCTAG_INT32:
vp->setInt32(data);
vp.setInt32(data);
break;
case SCTAG_BOOLEAN:
case SCTAG_BOOLEAN_OBJECT:
vp->setBoolean(!!data);
vp.setBoolean(!!data);
if (tag == SCTAG_BOOLEAN_OBJECT && !PrimitiveToObject(context(), vp))
return false;
break;
@ -1447,7 +1450,7 @@ JSStructuredCloneReader::startRead(Value *vp)
JSString *str = readString(data);
if (!str)
return false;
vp->setString(str);
vp.setString(str);
if (tag == SCTAG_STRING_OBJECT && !PrimitiveToObject(context(), vp))
return false;
break;
@ -1457,7 +1460,7 @@ JSStructuredCloneReader::startRead(Value *vp)
double d;
if (!in.readDouble(&d) || !checkDouble(d))
return false;
vp->setDouble(d);
vp.setDouble(d);
if (!PrimitiveToObject(context(), vp))
return false;
break;
@ -1475,7 +1478,7 @@ JSStructuredCloneReader::startRead(Value *vp)
JSObject *obj = js_NewDateObjectMsec(context(), d);
if (!obj)
return false;
vp->setObject(*obj);
vp.setObject(*obj);
break;
}
@ -1501,7 +1504,7 @@ JSStructuredCloneReader::startRead(Value *vp)
context()->tempLifoAlloc());
if (!reobj)
return false;
vp->setObject(*reobj);
vp.setObject(*reobj);
break;
}
@ -1512,7 +1515,7 @@ JSStructuredCloneReader::startRead(Value *vp)
: NewBuiltinClassInstance(context(), &JSObject::class_);
if (!obj || !objs.append(ObjectValue(*obj)))
return false;
vp->setObject(*obj);
vp.setObject(*obj);
break;
}
@ -1523,7 +1526,7 @@ JSStructuredCloneReader::startRead(Value *vp)
"invalid back reference in input");
return false;
}
*vp = allObjs[data];
vp.set(allObjs[data]);
return true;
}
@ -1551,7 +1554,7 @@ JSStructuredCloneReader::startRead(Value *vp)
JSObject *obj = MapObject::create(context());
if (!obj || !objs.append(ObjectValue(*obj)))
return false;
vp->setObject(*obj);
vp.setObject(*obj);
break;
}
@ -1559,7 +1562,7 @@ JSStructuredCloneReader::startRead(Value *vp)
JSObject *obj = SetObject::create(context());
if (!obj || !objs.append(ObjectValue(*obj)))
return false;
vp->setObject(*obj);
vp.setObject(*obj);
break;
}
@ -1568,7 +1571,7 @@ JSStructuredCloneReader::startRead(Value *vp)
double d = ReinterpretPairAsDouble(tag, data);
if (!checkDouble(d))
return false;
vp->setNumber(d);
vp.setNumber(d);
break;
}
@ -1586,11 +1589,11 @@ JSStructuredCloneReader::startRead(Value *vp)
JSObject *obj = callbacks->read(context(), this, tag, data, closure);
if (!obj)
return false;
vp->setObject(*obj);
vp.setObject(*obj);
}
}
if (vp->isObject() && !allObjs.append(*vp))
if (vp.isObject() && !allObjs.append(vp))
return false;
return true;
@ -1680,7 +1683,7 @@ JSStructuredCloneReader::readTransferMap()
}
bool
JSStructuredCloneReader::read(Value *vp)
JSStructuredCloneReader::read(MutableHandleValue vp)
{
if (!readTransferMap())
return false;
@ -1702,7 +1705,7 @@ JSStructuredCloneReader::read(Value *vp)
}
RootedValue key(context());
if (!startRead(key.address()))
if (!startRead(&key))
return false;
if (key.isNull() && !(obj->is<MapObject>() || obj->is<SetObject>())) {
@ -1719,7 +1722,7 @@ JSStructuredCloneReader::read(Value *vp)
}
RootedValue val(context());
if (!startRead(val.address()))
if (!startRead(&val))
return false;
if (obj->is<MapObject>()) {
@ -1973,12 +1976,12 @@ JS_ReadTypedArray(JSStructuredCloneReader *r, MutableHandleValue vp)
if (!r->input().readPair(&tag, &nelems))
return false;
if (tag >= SCTAG_TYPED_ARRAY_V1_MIN && tag <= SCTAG_TYPED_ARRAY_V1_MAX) {
return r->readTypedArray(TagToV1ArrayType(tag), nelems, vp.address(), true);
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.address());
return r->readTypedArray(arrayType, nelems, vp);
} else {
JS_ReportErrorNumber(r->context(), js_GetErrorMessage, nullptr,
JSMSG_SC_BAD_SERIALIZED_DATA, "expected type array");