Skip to content

Commit

Permalink
Bug 1605566 - MessagePort + wasm - part 2 - implement JS::StructuredC…
Browse files Browse the repository at this point in the history
…loneScope::UnknownDestination, r=sfink

Differential Revision: https://phabricator.services.mozilla.com/D59613

--HG--
extra : moz-landing-system : lando
  • Loading branch information
bakulf committed Jan 22, 2020
1 parent f27a63d commit 14b6fd8
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 56 deletions.
105 changes: 66 additions & 39 deletions dom/base/StructuredCloneHolder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,14 @@ JSObject* StructuredCloneCallbacksRead(JSContext* aCx,

bool StructuredCloneCallbacksWrite(JSContext* aCx,
JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj, void* aClosure) {
JS::Handle<JSObject*> aObj,
bool* aSameProcessScopeRequired,
void* aClosure) {
StructuredCloneHolderBase* holder =
static_cast<StructuredCloneHolderBase*>(aClosure);
MOZ_ASSERT(holder);
return holder->CustomWriteHandler(aCx, aWriter, aObj);
return holder->CustomWriteHandler(aCx, aWriter, aObj,
aSameProcessScopeRequired);
}

bool StructuredCloneCallbacksReadTransfer(
Expand Down Expand Up @@ -100,11 +103,13 @@ void StructuredCloneCallbacksFreeTransfer(uint32_t aTag,

bool StructuredCloneCallbacksCanTransfer(JSContext* aCx,
JS::Handle<JSObject*> aObject,
bool* aSameProcessScopeRequired,
void* aClosure) {
StructuredCloneHolderBase* holder =
static_cast<StructuredCloneHolderBase*>(aClosure);
MOZ_ASSERT(holder);
return holder->CustomCanTransferHandler(aCx, aObject);
return holder->CustomCanTransferHandler(aCx, aObject,
aSameProcessScopeRequired);
}

void StructuredCloneCallbacksError(JSContext* aCx, uint32_t aErrorId) {
Expand Down Expand Up @@ -229,7 +234,8 @@ void StructuredCloneHolderBase::CustomFreeTransferHandler(
}

bool StructuredCloneHolderBase::CustomCanTransferHandler(
JSContext* aCx, JS::Handle<JSObject*> aObj) {
JSContext* aCx, JS::Handle<JSObject*> aObj,
bool* aSameProcessScopeRequired) {
return false;
}

Expand Down Expand Up @@ -321,9 +327,9 @@ void StructuredCloneHolder::ReadFromBuffer(nsIGlobalObject* aGlobal,
mozilla::AutoRestore<nsIGlobalObject*> guard(mGlobal);
mGlobal = aGlobal;

if (!JS_ReadStructuredClone(aCx, aBuffer, aAlgorithmVersion,
mStructuredCloneScope, aValue,
JS::CloneDataPolicy(), &sCallbacks, this)) {
if (!JS_ReadStructuredClone(aCx, aBuffer, aAlgorithmVersion, CloneScope(),
aValue, JS::CloneDataPolicy(), &sCallbacks,
this)) {
JS_ClearPendingException(aCx);
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
}
Expand Down Expand Up @@ -884,7 +890,7 @@ JSObject* StructuredCloneHolder::CustomReadHandler(
}

if (aTag == SCTAG_DOM_IMAGEBITMAP &&
mStructuredCloneScope == StructuredCloneScope::SameProcess) {
CloneScope() == StructuredCloneScope::SameProcess) {
// Get the current global object.
// This can be null.
JS::RootedObject result(aCx);
Expand All @@ -901,7 +907,7 @@ JSObject* StructuredCloneHolder::CustomReadHandler(
}

if (aTag == SCTAG_DOM_WASM &&
mStructuredCloneScope == StructuredCloneScope::SameProcess) {
CloneScope() == StructuredCloneScope::SameProcess) {
return ReadWasmModule(aCx, aIndex, this);
}

Expand All @@ -920,9 +926,9 @@ JSObject* StructuredCloneHolder::CustomReadHandler(
return ReadFullySerializableObjects(aCx, aReader, aTag);
}

bool StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj) {
bool StructuredCloneHolder::CustomWriteHandler(
JSContext* aCx, JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj, bool* aSameProcessScopeRequired) {
if (!mSupportsCloning) {
return false;
}
Expand Down Expand Up @@ -962,11 +968,16 @@ bool StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
}

// See if this is an ImageBitmap object.
if (mStructuredCloneScope == StructuredCloneScope::SameProcess) {
{
ImageBitmap* imageBitmap = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageBitmap, &obj, imageBitmap))) {
return ImageBitmap::WriteStructuredClone(aWriter, GetSurfaces(),
imageBitmap);
SameProcessScopeRequired(aSameProcessScopeRequired);

if (CloneScope() == StructuredCloneScope::SameProcess) {
return ImageBitmap::WriteStructuredClone(aWriter, GetSurfaces(),
imageBitmap);
}
return false;
}
}

Expand All @@ -979,8 +990,7 @@ bool StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
}

// See if this is a BrowsingContext object.
if (mStructuredCloneScope == StructuredCloneScope::SameProcess ||
mStructuredCloneScope == StructuredCloneScope::DifferentProcess) {
{
BrowsingContext* holder = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(BrowsingContext, &obj, holder))) {
return holder->WriteStructuredClone(aCx, aWriter, this);
Expand All @@ -996,12 +1006,15 @@ bool StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
}

// See if this is a WasmModule.
if (mStructuredCloneScope == StructuredCloneScope::SameProcess &&
JS::IsWasmModuleObject(obj)) {
RefPtr<JS::WasmModule> module = JS::GetWasmModule(obj);
MOZ_ASSERT(module);
if (JS::IsWasmModuleObject(obj)) {
SameProcessScopeRequired(aSameProcessScopeRequired);
if (CloneScope() == StructuredCloneScope::SameProcess) {
RefPtr<JS::WasmModule> module = JS::GetWasmModule(obj);
MOZ_ASSERT(module);

return WriteWasmModule(aWriter, module, this);
return WriteWasmModule(aWriter, module, this);
}
return false;
}

{
Expand Down Expand Up @@ -1051,7 +1064,7 @@ bool StructuredCloneHolder::CustomReadTransferHandler(
}

if (aTag == SCTAG_DOM_CANVAS &&
mStructuredCloneScope == StructuredCloneScope::SameProcess) {
CloneScope() == StructuredCloneScope::SameProcess) {
MOZ_ASSERT(aContent);
OffscreenCanvasCloneData* data =
static_cast<OffscreenCanvasCloneData*>(aContent);
Expand All @@ -1070,7 +1083,7 @@ bool StructuredCloneHolder::CustomReadTransferHandler(
}

if (aTag == SCTAG_DOM_IMAGEBITMAP &&
mStructuredCloneScope == StructuredCloneScope::SameProcess) {
CloneScope() == StructuredCloneScope::SameProcess) {
MOZ_ASSERT(aContent);
ImageBitmapCloneData* data = static_cast<ImageBitmapCloneData*>(aContent);
RefPtr<ImageBitmap> bitmap =
Expand Down Expand Up @@ -1122,7 +1135,7 @@ bool StructuredCloneHolder::CustomWriteTransferHandler(
return true;
}

if (mStructuredCloneScope == StructuredCloneScope::SameProcess) {
if (CloneScope() == StructuredCloneScope::SameProcess) {
OffscreenCanvas* canvas = nullptr;
rv = UNWRAP_OBJECT(OffscreenCanvas, &obj, canvas);
if (NS_SUCCEEDED(rv)) {
Expand Down Expand Up @@ -1186,7 +1199,7 @@ void StructuredCloneHolder::CustomFreeTransferHandler(
}

if (aTag == SCTAG_DOM_CANVAS &&
mStructuredCloneScope == StructuredCloneScope::SameProcess) {
CloneScope() == StructuredCloneScope::SameProcess) {
MOZ_ASSERT(aContent);
OffscreenCanvasCloneData* data =
static_cast<OffscreenCanvasCloneData*>(aContent);
Expand All @@ -1195,7 +1208,7 @@ void StructuredCloneHolder::CustomFreeTransferHandler(
}

if (aTag == SCTAG_DOM_IMAGEBITMAP &&
mStructuredCloneScope == StructuredCloneScope::SameProcess) {
CloneScope() == StructuredCloneScope::SameProcess) {
MOZ_ASSERT(aContent);
ImageBitmapCloneData* data = static_cast<ImageBitmapCloneData*>(aContent);
delete data;
Expand All @@ -1204,7 +1217,8 @@ void StructuredCloneHolder::CustomFreeTransferHandler(
}

bool StructuredCloneHolder::CustomCanTransferHandler(
JSContext* aCx, JS::Handle<JSObject*> aObj) {
JSContext* aCx, JS::Handle<JSObject*> aObj,
bool* aSameProcessScopeRequired) {
if (!mSupportsTransferring) {
return false;
}
Expand All @@ -1217,19 +1231,23 @@ bool StructuredCloneHolder::CustomCanTransferHandler(
if (NS_SUCCEEDED(rv)) {
return true;
}
}

if (mStructuredCloneScope == StructuredCloneScope::SameProcess) {
OffscreenCanvas* canvas = nullptr;
rv = UNWRAP_OBJECT(OffscreenCanvas, &obj, canvas);
if (NS_SUCCEEDED(rv)) {
return true;
}
{
OffscreenCanvas* canvas = nullptr;
nsresult rv = UNWRAP_OBJECT(OffscreenCanvas, &obj, canvas);
if (NS_SUCCEEDED(rv)) {
SameProcessScopeRequired(aSameProcessScopeRequired);
return CloneScope() == StructuredCloneScope::SameProcess;
}
}

ImageBitmap* bitmap = nullptr;
rv = UNWRAP_OBJECT(ImageBitmap, &obj, bitmap);
if (NS_SUCCEEDED(rv)) {
return true;
}
{
ImageBitmap* bitmap = nullptr;
nsresult rv = UNWRAP_OBJECT(ImageBitmap, &obj, bitmap);
if (NS_SUCCEEDED(rv)) {
SameProcessScopeRequired(aSameProcessScopeRequired);
return CloneScope() == StructuredCloneScope::SameProcess;
}
}

Expand All @@ -1250,5 +1268,14 @@ bool StructuredCloneHolder::TakeTransferredPortsAsSequence(
return true;
}

void StructuredCloneHolder::SameProcessScopeRequired(
bool* aSameProcessScopeRequired) {
MOZ_ASSERT(aSameProcessScopeRequired);
if (mStructuredCloneScope == StructuredCloneScope::UnknownDestination) {
mStructuredCloneScope = StructuredCloneScope::SameProcess;
*aSameProcessScopeRequired = true;
}
}

} // namespace dom
} // namespace mozilla
25 changes: 19 additions & 6 deletions dom/base/StructuredCloneHolder.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ class StructuredCloneHolderBase {

virtual bool CustomWriteHandler(JSContext* aCx,
JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj) = 0;
JS::Handle<JSObject*> aObj,
bool* aSameProcessScopeRequired) = 0;

// This method has to be called when this object is not needed anymore.
// It will free memory and the buffer. This has to be called because
Expand Down Expand Up @@ -87,7 +88,8 @@ class StructuredCloneHolderBase {
void* aContent, uint64_t aExtraData);

virtual bool CustomCanTransferHandler(JSContext* aCx,
JS::Handle<JSObject*> aObj);
JS::Handle<JSObject*> aObj,
bool* aSameProcessScopeRequired);

// These methods are what you should use to read/write data.

Expand Down Expand Up @@ -198,7 +200,14 @@ class StructuredCloneHolder : public StructuredCloneHolderBase {
return mInputStreamArray;
}

StructuredCloneScope CloneScope() const { return mStructuredCloneScope; }
// This method returns the final scope. If the final scope is unknown,
// DifferentProcess is returned because it's the most restrictive one.
StructuredCloneScope CloneScope() const {
if (mStructuredCloneScope == StructuredCloneScope::UnknownDestination) {
return StructuredCloneScope::DifferentProcess;
}
return mStructuredCloneScope;
}

// The global object is set internally just during the Read(). This method
// can be used by read functions to retrieve it.
Expand Down Expand Up @@ -235,7 +244,8 @@ class StructuredCloneHolder : public StructuredCloneHolderBase {

virtual bool CustomWriteHandler(JSContext* aCx,
JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj) override;
JS::Handle<JSObject*> aObj,
bool* aSameProcessScopeRequired) override;

virtual bool CustomReadTransferHandler(
JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
Expand All @@ -254,8 +264,9 @@ class StructuredCloneHolder : public StructuredCloneHolderBase {
void* aContent,
uint64_t aExtraData) override;

virtual bool CustomCanTransferHandler(JSContext* aCx,
JS::Handle<JSObject*> aObj) override;
virtual bool CustomCanTransferHandler(
JSContext* aCx, JS::Handle<JSObject*> aObj,
bool* aSameProcessScopeRequired) override;

// These 2 static methods are useful to read/write fully serializable objects.
// They can be used by custom StructuredCloneHolderBase classes to
Expand Down Expand Up @@ -288,6 +299,8 @@ class StructuredCloneHolder : public StructuredCloneHolderBase {
uint32_t aAlgorithmVersion,
JS::MutableHandle<JS::Value> aValue, ErrorResult& aRv);

void SameProcessScopeRequired(bool* aSameProcessScopeRequired);

bool mSupportsCloning;
bool mSupportsTransferring;

Expand Down
3 changes: 2 additions & 1 deletion dom/console/Console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,8 @@ class ConsoleRunnable : public StructuredCloneHolderBase {
}

bool CustomWriteHandler(JSContext* aCx, JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj) override {
JS::Handle<JSObject*> aObj,
bool* aSameProcessScopeRequired) override {
RefPtr<Blob> blob;
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob))) {
if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, CONSOLE_TAG_BLOB,
Expand Down
4 changes: 3 additions & 1 deletion dom/indexedDB/IDBObjectStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ RefPtr<IDBRequest> GenerateRequest(JSContext* aCx,

bool StructuredCloneWriteCallback(JSContext* aCx,
JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj, void* aClosure) {
JS::Handle<JSObject*> aObj,
bool* aSameProcessRequired, void* aClosure) {
MOZ_ASSERT(aCx);
MOZ_ASSERT(aWriter);
MOZ_ASSERT(aClosure);
Expand Down Expand Up @@ -352,6 +353,7 @@ bool StructuredCloneWriteCallback(JSContext* aCx,
bool CopyingStructuredCloneWriteCallback(JSContext* aCx,
JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj,
bool* aSameProcessRequired,
void* aClosure) {
MOZ_ASSERT(aCx);
MOZ_ASSERT(aWriter);
Expand Down
3 changes: 2 additions & 1 deletion dom/promise/Promise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,8 @@ JSObject* PromiseWorkerProxy::CustomReadHandler(

bool PromiseWorkerProxy::CustomWriteHandler(JSContext* aCx,
JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj) {
JS::Handle<JSObject*> aObj,
bool* aSameProcessScopeRequired) {
if (NS_WARN_IF(!mCallbacks)) {
return false;
}
Expand Down
3 changes: 2 additions & 1 deletion dom/promise/PromiseWorkerProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ class PromiseWorkerProxy : public PromiseNativeHandler,
uint32_t aTag, uint32_t aIndex) override;

bool CustomWriteHandler(JSContext* aCx, JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj) override;
JS::Handle<JSObject*> aObj,
bool* aSameProcessScopeRequired) override;

protected:
virtual void ResolvedCallback(JSContext* aCx,
Expand Down
Loading

0 comments on commit 14b6fd8

Please sign in to comment.