☠☠ backed out by 62f4ddbaad18 ☠ ☠ | |
author | Lars T Hansen <lhansen@mozilla.com> |
Fri, 07 Feb 2020 15:42:37 +0000 | |
changeset 512906 | 1dc5c3074b57fb45d0a94188e69048da993360ca |
parent 512905 | ecb837a257f43805e27c5fc093391c490ac0fd27 |
child 512907 | bef203601b7f9476176fd7da4110b82a331e3dd3 |
push id | 37101 |
push user | nerli@mozilla.com |
push date | Sat, 08 Feb 2020 09:25:03 +0000 |
treeherder | mozilla-central@cb56699431a0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | luke |
bugs | 1609916 |
milestone | 74.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/base/StructuredCloneHolder.cpp +++ b/dom/base/StructuredCloneHolder.cpp @@ -138,17 +138,17 @@ void AssertTagValues() { } } // anonymous namespace const JSStructuredCloneCallbacks StructuredCloneHolder::sCallbacks = { StructuredCloneCallbacksRead, StructuredCloneCallbacksWrite, StructuredCloneCallbacksError, StructuredCloneCallbacksReadTransfer, StructuredCloneCallbacksWriteTransfer, StructuredCloneCallbacksFreeTransfer, - StructuredCloneCallbacksCanTransfer, + StructuredCloneCallbacksCanTransfer, nullptr, }; // StructuredCloneHolderBase class StructuredCloneHolderBase::StructuredCloneHolderBase( StructuredCloneScope aScope) : mStructuredCloneScope(aScope) #ifdef DEBUG
--- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -414,23 +414,20 @@ bool CopyingStructuredCloneWriteCallback } return StructuredCloneHolder::WriteFullySerializableObjects(aCx, aWriter, aObj); } nsresult GetAddInfoCallback(JSContext* aCx, void* aClosure) { static const JSStructuredCloneCallbacks kStructuredCloneCallbacks = { - nullptr /* read */, - StructuredCloneWriteCallback /* write */, - nullptr /* reportError */, - nullptr /* readTransfer */, - nullptr /* writeTransfer */, - nullptr /* freeTransfer */, - nullptr /* canTransfer */ + nullptr /* read */, StructuredCloneWriteCallback /* write */, + nullptr /* reportError */, nullptr /* readTransfer */, + nullptr /* writeTransfer */, nullptr /* freeTransfer */, + nullptr /* canTransfer */, nullptr /* sabCloned */ }; MOZ_ASSERT(aCx); auto* const data = static_cast<GetAddInfoClosure*>(aClosure); MOZ_ASSERT(data); data->mCloneWriteInfo.mOffsetToKeyProp = 0; @@ -1057,16 +1054,17 @@ bool IDBObjectStore::DeserializeValue(JS static const JSStructuredCloneCallbacks callbacks = { CommonStructuredCloneReadCallback, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr}; // FIXME: Consider to use StructuredCloneHolder here and in other // deserializing methods. return JS_ReadStructuredClone( aCx, aCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION, JS::StructuredCloneScope::DifferentProcessForIndexedDB, aValue, JS::CloneDataPolicy(), &callbacks, &aCloneReadInfo); @@ -1214,16 +1212,17 @@ class DeserializeIndexValueHelper final JS::MutableHandle<JS::Value> aValue) { static const JSStructuredCloneCallbacks callbacks = { CommonStructuredCloneReadCallback, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr}; if (!JS_ReadStructuredClone( aCx, mCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION, JS::StructuredCloneScope::DifferentProcessForIndexedDB, aValue, JS::CloneDataPolicy(), &callbacks, &mCloneReadInfo)) { return NS_ERROR_DOM_DATA_CLONE_ERR; } @@ -1320,16 +1319,17 @@ class DeserializeUpgradeValueHelper fina JS::MutableHandle<JS::Value> aValue) { static const JSStructuredCloneCallbacks callbacks = { CommonStructuredCloneReadCallback, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr}; if (!JS_ReadStructuredClone( aCx, mCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION, JS::StructuredCloneScope::DifferentProcessForIndexedDB, aValue, JS::CloneDataPolicy(), &callbacks, &mCloneReadInfo)) { return NS_ERROR_DOM_DATA_CLONE_ERR; } @@ -2566,17 +2566,18 @@ bool IDBObjectStore::ValueWrapper::Clone static const JSStructuredCloneCallbacks callbacks = { CopyingStructuredCloneReadCallback /* read */, CopyingStructuredCloneWriteCallback /* write */, nullptr /* reportError */, nullptr /* readTransfer */, nullptr /* writeTransfer */, nullptr /* freeTransfer */, - nullptr /* canTransfer */ + nullptr /* canTransfer */, + nullptr /* sabCloned */ }; StructuredCloneInfo cloneInfo; JS::Rooted<JS::Value> clonedValue(aCx); if (!JS_StructuredClone(aCx, mValue, &clonedValue, &callbacks, &cloneInfo)) { return false; }
--- a/js/public/StructuredClone.h +++ b/js/public/StructuredClone.h @@ -324,24 +324,38 @@ typedef void (*FreeTransferStructuredClo * Called when the transferring objects are checked. If this function returns * false, the serialization ends throwing a DataCloneError exception. */ typedef bool (*CanTransferStructuredCloneOp)(JSContext* cx, JS::Handle<JSObject*> obj, bool* sameProcessScopeRequired, void* closure); +/** + * Called when a SharedArrayBuffer (including one owned by a Wasm memory object) + * has been processed in context `cx` by structured cloning. If `receiving` is + * true then the SAB has been received from a channel and a new SAB object has + * been created; if false then an existing SAB has been serialized onto a + * channel. + * + * If the callback returns false then the clone operation (read or write) will + * signal a failure. + */ +typedef bool (*SharedArrayBufferClonedOp)(JSContext* cx, bool receiving, + void* closure); + struct JSStructuredCloneCallbacks { ReadStructuredCloneOp read; WriteStructuredCloneOp write; StructuredCloneErrorOp reportError; ReadTransferStructuredCloneOp readTransfer; TransferStructuredCloneOp writeTransfer; FreeTransferStructuredCloneOp freeTransfer; CanTransferStructuredCloneOp canTransfer; + SharedArrayBufferClonedOp sabCloned; }; enum OwnTransferablePolicy { /** * The buffer owns any Transferables that it might contain, and should * properly release them upon destruction. */ OwnsTransferablesIfAny,
--- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -465,16 +465,18 @@ struct JSStructuredCloneReader { struct JSStructuredCloneWriter { public: explicit JSStructuredCloneWriter(JSContext* cx, JS::StructuredCloneScope scope, const JS::CloneDataPolicy& cloneDataPolicy, const JSStructuredCloneCallbacks* cb, void* cbClosure, const Value& tVal) : out(cx, scope), + callbacks(cb), + closure(cbClosure), objs(out.context()), counts(out.context()), objectEntries(out.context()), otherEntries(out.context()), memory(out.context()), transferable(out.context(), tVal), transferableObjects(out.context(), TransferableObjectsSet(cx)), cloneDataPolicy(cloneDataPolicy) { @@ -522,16 +524,23 @@ struct JSStructuredCloneWriter { bool parseTransferable(); bool transferOwnership(); inline void checkStack(); SCOutput out; + // The user defined callbacks that will be used to signal cloning, in some + // cases. + const JSStructuredCloneCallbacks* callbacks; + + // Any value passed to the callbacks. + void* closure; + // Vector of objects with properties remaining to be written. // // NB: These can span multiple compartments, so the compartment must be // entered before any manipulation is performed. RootedValueVector objs; // counts[i] is the number of entries of objs[i] remaining to be written. // counts.length() == objs.length() and sum(counts) == entries.length(). @@ -1290,20 +1299,29 @@ bool JSStructuredCloneWriter::writeShare } // We must serialize the length so that the buffer object arrives in the // receiver with the same length, and not with the length read from the // rawbuf - that length can be different, and it can change at any time. intptr_t p = reinterpret_cast<intptr_t>(rawbuf); uint32_t byteLength = sharedArrayBuffer->byteLength(); - return out.writePair(SCTAG_SHARED_ARRAY_BUFFER_OBJECT, - static_cast<uint32_t>(sizeof(p))) && - out.writeBytes(&byteLength, sizeof(byteLength)) && - out.writeBytes(&p, sizeof(p)); + if (!out.writePair(SCTAG_SHARED_ARRAY_BUFFER_OBJECT, + static_cast<uint32_t>(sizeof(p))) && + out.writeBytes(&byteLength, sizeof(byteLength)) && + out.writeBytes(&p, sizeof(p))) { + return false; + } + + if (callbacks && callbacks->sabCloned && + !callbacks->sabCloned(context(), /*receiving=*/false, closure)) { + return false; + } + + return true; } bool JSStructuredCloneWriter::writeSharedWasmMemory(HandleObject obj) { MOZ_ASSERT(obj->canUnwrapAs<WasmMemoryObject>()); // Check the policy here so that we can report a sane error. if (!cloneDataPolicy.areSharedMemoryObjectsAllowed()) { auto errorMsg = @@ -2280,16 +2298,22 @@ bool JSStructuredCloneReader::readShared } JSObject* obj = SharedArrayBufferObject::New(context(), rawbuf, byteLength); if (!obj) { rawbuf->dropReference(); return false; } + if (callbacks && callbacks->sabCloned && + !callbacks->sabCloned(context(), /*receiving=*/true, closure)) { + rawbuf->dropReference(); + return false; + } + vp.setObject(*obj); return true; } bool JSStructuredCloneReader::readSharedWasmMemory(uint32_t nbytes, MutableHandleValue vp) { JSContext* cx = context(); if (nbytes != 0) {