mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-02 22:37:50 +00:00
Bug 1041495 - Handlify StructuredClone. r=jonco
This commit is contained in:
parent
1814d69318
commit
594e01a452
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user