Bug 929800 - Handlify the structured clone interface; r=sfink,smaug

--HG--
extra : rebase_source : 4f21dd799ad27dc665997d4912996a500ae8a2f2
This commit is contained in:
Terrence Cole 2013-10-22 17:18:32 -07:00
parent 11ebb1339c
commit 05b45c0c0f
15 changed files with 58 additions and 61 deletions

View File

@ -417,7 +417,8 @@ GetParamsForMessage(JSContext* aCx,
JSAutoStructuredCloneBuffer& aBuffer,
StructuredCloneClosure& aClosure)
{
if (WriteStructuredClone(aCx, aJSON, aBuffer, aClosure)) {
JS::Rooted<JS::Value> v(aCx, aJSON);
if (WriteStructuredClone(aCx, v, aBuffer, aClosure)) {
return true;
}
JS_ClearPendingException(aCx);
@ -427,7 +428,6 @@ GetParamsForMessage(JSContext* aCx,
// properly cases when interface is implemented in JS and used
// as a dictionary.
nsAutoString json;
JS::Rooted<JS::Value> v(aCx, aJSON);
NS_ENSURE_TRUE(JS_Stringify(aCx, &v, JS::NullPtr(), JS::NullHandleValue,
JSONCreator, &json), false);
NS_ENSURE_TRUE(!json.IsEmpty(), false);
@ -853,7 +853,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
JS::Rooted<JS::Value> json(ctx, JS::NullValue());
if (aCloneData && aCloneData->mDataLength &&
!ReadStructuredClone(ctx, *aCloneData, json.address())) {
!ReadStructuredClone(ctx, *aCloneData, &json)) {
JS_ClearPendingException(ctx);
return NS_OK;
}

View File

@ -245,8 +245,7 @@ PostMessageRunnable::Run()
scInfo.mEvent = this;
scInfo.mPort = mPort;
if (!buffer.read(cx, messageData.address(), &kPostMessageCallbacks,
&scInfo)) {
if (!buffer.read(cx, &messageData, &kPostMessageCallbacks, &scInfo)) {
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
}

View File

@ -6977,8 +6977,7 @@ PostMessageEvent::Run()
scInfo.event = this;
scInfo.window = targetWindow;
if (!buffer.read(cx, messageData.address(), &kPostMessageCallbacks,
&scInfo)) {
if (!buffer.read(cx, &messageData, &kPostMessageCallbacks, &scInfo)) {
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
}
@ -7128,7 +7127,9 @@ nsGlobalWindow::PostMessageMoz(const JS::Value& aMessage,
if (NS_FAILED(callerPrin->Subsumes(principal, &scInfo.subsumes)))
return NS_ERROR_DOM_DATA_CLONE_ERR;
if (!buffer.write(aCx, aMessage, aTransfer, &kPostMessageCallbacks, &scInfo))
JS::Rooted<JS::Value> message(aCx, aMessage);
JS::Rooted<JS::Value> transfer(aCx, aTransfer);
if (!buffer.write(aCx, message, transfer, &kPostMessageCallbacks, &scInfo))
return NS_ERROR_DOM_DATA_CLONE_ERR;
event->SetJSData(buffer);

View File

@ -52,7 +52,8 @@ nsStructuredCloneContainer::InitFromJSVal(const JS::Value & aData,
uint64_t* jsBytes = nullptr;
bool success = JS_WriteStructuredClone(aCx, jsData, &jsBytes, &mSize,
nullptr, nullptr, JSVAL_VOID);
nullptr, nullptr,
JS::UndefinedHandleValue);
NS_ENSURE_STATE(success);
NS_ENSURE_STATE(jsBytes);
@ -111,8 +112,7 @@ nsStructuredCloneContainer::DeserializeToVariant(JSContext *aCx,
JS::Rooted<JS::Value> jsStateObj(aCx);
bool hasTransferable = false;
bool success = JS_ReadStructuredClone(aCx, mData, mSize, mVersion,
jsStateObj.address(), nullptr,
nullptr) &&
&jsStateObj, nullptr, nullptr) &&
JS_StructuredCloneHasTransferables(mData, mSize,
&hasTransferable);
// We want to be sure that mData doesn't contain transferable objects

View File

@ -1340,7 +1340,7 @@ IDBObjectStore::DeserializeValue(JSContext* aCx,
nullptr
};
return buffer.read(aCx, aValue.address(), &callbacks, &aCloneReadInfo);
return buffer.read(aCx, aValue, &callbacks, &aCloneReadInfo);
}
// static
@ -4542,7 +4542,7 @@ CreateIndexHelper::InsertDataFromObjectStore(mozIStorageConnection* aConnection)
};
JS::Rooted<JS::Value> clone(cx);
if (!buffer.read(cx, clone.address(), &callbacks, &cloneReadInfo)) {
if (!buffer.read(cx, &clone, &callbacks, &cloneReadInfo)) {
NS_WARNING("Failed to deserialize structured clone data!");
return NS_ERROR_DOM_DATA_CLONE_ERR;
}

View File

@ -162,7 +162,8 @@ namespace dom {
bool
ReadStructuredClone(JSContext* aCx, uint64_t* aData, size_t aDataLength,
const StructuredCloneClosure& aClosure, JS::Value* aClone)
const StructuredCloneClosure& aClosure,
JS::MutableHandle<JS::Value> aClone)
{
void* closure = &const_cast<StructuredCloneClosure&>(aClosure);
return !!JS_ReadStructuredClone(aCx, aData, aDataLength,
@ -171,7 +172,7 @@ ReadStructuredClone(JSContext* aCx, uint64_t* aData, size_t aDataLength,
}
bool
WriteStructuredClone(JSContext* aCx, const JS::Value& aSource,
WriteStructuredClone(JSContext* aCx, JS::Handle<JS::Value> aSource,
JSAutoStructuredCloneBuffer& aBuffer,
StructuredCloneClosure& aClosure)
{

View File

@ -36,18 +36,19 @@ StructuredCloneData
bool
ReadStructuredClone(JSContext* aCx, uint64_t* aData, size_t aDataLength,
const StructuredCloneClosure& aClosure, JS::Value* aClone);
const StructuredCloneClosure& aClosure,
JS::MutableHandle<JS::Value> aClone);
inline bool
ReadStructuredClone(JSContext* aCx, const StructuredCloneData& aData,
JS::Value* aClone)
JS::MutableHandle<JS::Value> aClone)
{
return ReadStructuredClone(aCx, aData.mData, aData.mDataLength,
aData.mClosure, aClone);
}
bool
WriteStructuredClone(JSContext* aCx, const JS::Value& aSource,
WriteStructuredClone(JSContext* aCx, JS::Handle<JS::Value> aSource,
JSAutoStructuredCloneBuffer& aBuffer,
StructuredCloneClosure& aClosure);

View File

@ -584,7 +584,7 @@ private:
clonedObjects.SwapElements(event->mClonedObjects);
JS::Rooted<JS::Value> data(aCx);
if (!buffer.read(aCx, data.address(),
if (!buffer.read(aCx, &data,
WorkerStructuredCloneCallbacks(event->mMainRuntime))) {
return false;
}
@ -1166,4 +1166,4 @@ DispatchEventToTarget(JSContext* aCx, JS::Handle<JSObject*> aTarget,
} // namespace events
END_WORKERS_NAMESPACE
END_WORKERS_NAMESPACE

View File

@ -2636,7 +2636,7 @@ WorkerPrivateParent<Derived>::DispatchMessageEventToMessagePort(
JSAutoCompartment(cx, sgo->GetGlobalJSObject());
JS::Rooted<JS::Value> data(cx);
if (!buffer.read(cx, data.address(), WorkerStructuredCloneCallbacks(true))) {
if (!buffer.read(cx, &data, WorkerStructuredCloneCallbacks(true))) {
return false;
}

View File

@ -715,7 +715,7 @@ public:
clonedObjects.SwapElements(mClonedObjects);
JS::Rooted<JS::Value> response(aCx);
if (!responseBuffer.read(aCx, response.address(), callbacks, &clonedObjects)) {
if (!responseBuffer.read(aCx, &response, callbacks, &clonedObjects)) {
return false;
}
@ -1154,7 +1154,7 @@ public:
WorkerStructuredCloneCallbacks(true);
JS::Rooted<JS::Value> body(cx);
if (mBody.read(cx, body.address(), callbacks, &mClonedObjects)) {
if (mBody.read(cx, &body, callbacks, &mClonedObjects)) {
if (NS_FAILED(xpc->JSValToVariant(cx, body.address(),
getter_AddRefs(variant)))) {
rv = NS_ERROR_DOM_INVALID_STATE_ERR;
@ -1970,10 +1970,10 @@ XMLHttpRequest::Send(JSObject* aBody, ErrorResult& aRv)
JSContext* cx = GetJSContext();
jsval valToClone;
JS::Rooted<JS::Value> valToClone(cx);
if (JS_IsArrayBufferObject(aBody) || JS_IsArrayBufferViewObject(aBody) ||
file::GetDOMBlobFromJSObject(aBody)) {
valToClone = OBJECT_TO_JSVAL(aBody);
valToClone.setObject(*aBody);
}
else {
JSString* bodyStr = JS_ValueToString(cx, OBJECT_TO_JSVAL(aBody));
@ -1981,7 +1981,7 @@ XMLHttpRequest::Send(JSObject* aBody, ErrorResult& aRv)
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
valToClone = STRING_TO_JSVAL(bodyStr);
valToClone.setString(bodyStr);
}
JSStructuredCloneCallbacks* callbacks =

View File

@ -13,7 +13,9 @@
#include "jstypes.h"
#include "js/RootingAPI.h"
#include "js/TypeDecls.h"
#include "js/Value.h"
struct JSRuntime;
struct JSStructuredCloneReader;
@ -62,15 +64,15 @@ struct JSStructuredCloneCallbacks {
// Note: if the *data contains transferable objects, it can be read only once.
JS_PUBLIC_API(bool)
JS_ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, uint32_t version,
JS::Value *vp, const JSStructuredCloneCallbacks *optionalCallbacks,
void *closure);
JS::MutableHandleValue vp,
const JSStructuredCloneCallbacks *optionalCallbacks, void *closure);
// Note: On success, the caller is responsible for calling
// JS_ClearStructuredClone(*datap, nbytesp).
JS_PUBLIC_API(bool)
JS_WriteStructuredClone(JSContext *cx, JS::Value v, uint64_t **datap, size_t *nbytesp,
JS_WriteStructuredClone(JSContext *cx, JS::HandleValue v, uint64_t **datap, size_t *nbytesp,
const JSStructuredCloneCallbacks *optionalCallbacks,
void *closure, JS::Value transferable);
void *closure, JS::HandleValue transferable);
JS_PUBLIC_API(bool)
JS_ClearStructuredClone(const uint64_t *data, size_t nbytes);
@ -79,7 +81,7 @@ JS_PUBLIC_API(bool)
JS_StructuredCloneHasTransferables(const uint64_t *data, size_t nbytes, bool *hasTransferable);
JS_PUBLIC_API(bool)
JS_StructuredClone(JSContext *cx, JS::Value v, JS::Value *vp,
JS_StructuredClone(JSContext *cx, JS::HandleValue v, JS::MutableHandleValue vp,
const JSStructuredCloneCallbacks *optionalCallbacks, void *closure);
// RAII sugar for JS_WriteStructuredClone.
@ -112,13 +114,13 @@ class JS_PUBLIC_API(JSAutoStructuredCloneBuffer) {
// JSAutoStructuredCloneBuffer::adopt.
void steal(uint64_t **datap, size_t *nbytesp, uint32_t *versionp=nullptr);
bool read(JSContext *cx, JS::Value *vp,
bool read(JSContext *cx, JS::MutableHandleValue vp,
const JSStructuredCloneCallbacks *optionalCallbacks=nullptr, void *closure=nullptr);
bool write(JSContext *cx, JS::Value v,
bool write(JSContext *cx, JS::HandleValue v,
const JSStructuredCloneCallbacks *optionalCallbacks=nullptr, void *closure=nullptr);
bool write(JSContext *cx, JS::Value v, JS::Value transferable,
bool write(JSContext *cx, JS::HandleValue v, JS::HandleValue transferable,
const JSStructuredCloneCallbacks *optionalCallbacks=nullptr, void *closure=nullptr);
// Swap ownership with another JSAutoStructuredCloneBuffer.

View File

@ -1264,11 +1264,8 @@ 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))
if (!clonebuf.write(cx, args.get(0), args.get(1)))
return false;
RootedObject obj(cx, CloneBufferObject::Create(cx, &clonebuf));
@ -1309,7 +1306,7 @@ Deserialize(JSContext *cx, unsigned argc, jsval *vp)
RootedValue deserialized(cx);
if (!JS_ReadStructuredClone(cx, obj->data(), obj->nbytes(),
JS_STRUCTURED_CLONE_VERSION, deserialized.address(), NULL, NULL)) {
JS_STRUCTURED_CLONE_VERSION, &deserialized, NULL, NULL)) {
return false;
}
args.rval().set(deserialized);

View File

@ -28,7 +28,7 @@ BEGIN_TEST(testStructuredClone_object)
JSAutoCompartment ac(cx, g2);
JS::RootedValue v2(cx);
CHECK(JS_StructuredClone(cx, v1, v2.address(), nullptr, nullptr));
CHECK(JS_StructuredClone(cx, v1, &v2, nullptr, nullptr));
CHECK(v2.isObject());
JS::RootedValue prop(cx);
@ -64,10 +64,10 @@ BEGIN_TEST(testStructuredClone_string)
JSAutoCompartment ac(cx, g2);
JS::RootedValue v2(cx);
CHECK(JS_StructuredClone(cx, v1, v2.address(), nullptr, nullptr));
CHECK(JS_StructuredClone(cx, v1, &v2, nullptr, nullptr));
CHECK(v2.isString());
CHECK(v2.toString());
JS::RootedValue expected(cx, JS::StringValue(
JS_NewStringCopyZ(cx, "Hello World!")));
CHECK_SAME(v2, expected);

View File

@ -323,12 +323,12 @@ WriteStructuredClone(JSContext *cx, HandleValue v, uint64_t **bufp, size_t *nbyt
}
bool
ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, Value *vp,
ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, MutableHandleValue vp,
const JSStructuredCloneCallbacks *cb, void *cbClosure)
{
SCInput in(cx, data, nbytes);
JSStructuredCloneReader r(in, cb, cbClosure);
return r.read(vp);
return r.read(vp.address());
}
// This may acquire new ways of discarding transfer map entries as new
@ -1551,7 +1551,7 @@ using namespace js;
JS_PUBLIC_API(bool)
JS_ReadStructuredClone(JSContext *cx, uint64_t *buf, size_t nbytes,
uint32_t version, JS::Value *vp,
uint32_t version, JS::MutableHandleValue vp,
const JSStructuredCloneCallbacks *optionalCallbacks,
void *closure)
{
@ -1570,11 +1570,10 @@ JS_ReadStructuredClone(JSContext *cx, uint64_t *buf, size_t nbytes,
}
JS_PUBLIC_API(bool)
JS_WriteStructuredClone(JSContext *cx, JS::Value valueArg, uint64_t **bufp, size_t *nbytesp,
JS_WriteStructuredClone(JSContext *cx, JS::HandleValue value, uint64_t **bufp, size_t *nbytesp,
const JSStructuredCloneCallbacks *optionalCallbacks,
void *closure, JS::Value transferable)
void *closure, JS::HandleValue transferable)
{
RootedValue value(cx, valueArg);
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, value);
@ -1606,11 +1605,10 @@ JS_StructuredCloneHasTransferables(const uint64_t *data, size_t nbytes,
}
JS_PUBLIC_API(bool)
JS_StructuredClone(JSContext *cx, JS::Value valueArg, JS::Value *vp,
JS_StructuredClone(JSContext *cx, JS::HandleValue value, JS::MutableHandleValue vp,
const JSStructuredCloneCallbacks *optionalCallbacks,
void *closure)
{
RootedValue value(cx, valueArg);
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
@ -1621,7 +1619,7 @@ JS_StructuredClone(JSContext *cx, JS::Value valueArg, JS::Value *vp,
if (!cx->compartment()->wrap(cx, strValue.address())) {
return false;
}
*vp = JS::StringValue(strValue);
vp.setString(strValue);
return true;
}
@ -1700,7 +1698,7 @@ JSAutoStructuredCloneBuffer::steal(uint64_t **datap, size_t *nbytesp, uint32_t *
}
bool
JSAutoStructuredCloneBuffer::read(JSContext *cx, JS::Value *vp,
JSAutoStructuredCloneBuffer::read(JSContext *cx, JS::MutableHandleValue vp,
const JSStructuredCloneCallbacks *optionalCallbacks,
void *closure)
{
@ -1711,21 +1709,20 @@ JSAutoStructuredCloneBuffer::read(JSContext *cx, JS::Value *vp,
}
bool
JSAutoStructuredCloneBuffer::write(JSContext *cx, JS::Value valueArg,
JSAutoStructuredCloneBuffer::write(JSContext *cx, JS::HandleValue value,
const JSStructuredCloneCallbacks *optionalCallbacks,
void *closure)
{
JS::Value transferable = JSVAL_VOID;
return write(cx, valueArg, transferable, optionalCallbacks, closure);
JS::HandleValue transferable = JS::UndefinedHandleValue;
return write(cx, value, transferable, optionalCallbacks, closure);
}
bool
JSAutoStructuredCloneBuffer::write(JSContext *cx, JS::Value valueArg,
JS::Value transferable,
JSAutoStructuredCloneBuffer::write(JSContext *cx, JS::HandleValue value,
JS::HandleValue transferable,
const JSStructuredCloneCallbacks *optionalCallbacks,
void *closure)
{
RootedValue value(cx, valueArg);
clear();
bool ok = !!JS_WriteStructuredClone(cx, value, &data_, &nbytes_,
optionalCallbacks, closure,

View File

@ -421,8 +421,7 @@ CloneNonReflectors(JSContext *cx, MutableHandleValue val)
}
// Now recreate the clones in the target compartment.
RootedValue rval(cx);
if (!buffer.read(cx, val.address(),
if (!buffer.read(cx, val,
&gForwarderStructuredCloneCallbacks,
&rootedReflectors))
{
@ -1765,7 +1764,7 @@ xpc::SetSandboxMetadata(JSContext *cx, HandleObject sandbox, HandleValue metadat
RootedValue metadata(cx);
JSAutoCompartment ac(cx, sandbox);
if (!JS_StructuredClone(cx, metadataArg, metadata.address(), nullptr, nullptr))
if (!JS_StructuredClone(cx, metadataArg, &metadata, nullptr, nullptr))
return NS_ERROR_UNEXPECTED;
JS_SetReservedSlot(sandbox, XPCONNECT_SANDBOX_CLASS_METADATA_SLOT, metadata);