mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1800470, make it possible to extend WritableStream with another cycle collectable class, r=saschanaz
Differential Revision: https://phabricator.services.mozilla.com/D162287
This commit is contained in:
parent
b1055977ce
commit
73ed00444f
@ -116,7 +116,7 @@ FileSystemWritableFileStream::FileSystemWritableFileStream(
|
||||
RefPtr<FileSystemWritableFileStreamChild> aActor,
|
||||
const ::mozilla::ipc::FileDescriptor& aFileDescriptor,
|
||||
const fs::FileSystemEntryMetadata& aMetadata)
|
||||
: WritableStream(aGlobal),
|
||||
: WritableStream(aGlobal, HoldDropJSObjectsCaller::Explicit),
|
||||
mManager(aManager),
|
||||
mActor(std::move(aActor)),
|
||||
mFileDesc(nullptr),
|
||||
@ -125,12 +125,16 @@ FileSystemWritableFileStream::FileSystemWritableFileStream(
|
||||
auto rawFD = aFileDescriptor.ClonePlatformHandle();
|
||||
mFileDesc = PR_ImportFile(PROsfd(rawFD.release()));
|
||||
|
||||
mozilla::HoldJSObjects(this);
|
||||
|
||||
LOG(("Created WritableFileStream %p for fd %p", this, mFileDesc));
|
||||
}
|
||||
|
||||
FileSystemWritableFileStream::~FileSystemWritableFileStream() {
|
||||
MOZ_ASSERT(!mActor);
|
||||
MOZ_ASSERT(mClosed);
|
||||
|
||||
mozilla::DropJSObjects(this);
|
||||
}
|
||||
|
||||
// https://streams.spec.whatwg.org/#writablestream-set-up
|
||||
|
28
dom/fs/test/crashtests/1800470.html
Normal file
28
dom/fs/test/crashtests/1800470.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script id="worker1" type="javascript/worker">
|
||||
self.onmessage = async function (e) {
|
||||
const directory = await navigator.storage.getDirectory();
|
||||
const file = await directory.getFileHandle("500014c3-f683-4551-bb26-08025c9be332", {
|
||||
create: true,
|
||||
});
|
||||
const stream = await file.createWritable({});
|
||||
const regex = new RegExp(".*");
|
||||
await stream.abort(regex);
|
||||
self.postMessage("done");
|
||||
self.close();
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
var worker;
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const buffer = new ArrayBuffer(1);
|
||||
const blob = new Blob([document.querySelector('#worker1').textContent], { type: 'text/javascript' });
|
||||
worker = new Worker(window.URL.createObjectURL(blob));
|
||||
worker.postMessage([buffer], [buffer]);
|
||||
worker.onmessage = function() {document.documentElement.removeAttribute("class"); }
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
@ -1,3 +1,5 @@
|
||||
defaults pref(dom.fs.enabled,true)
|
||||
# StorageManager isn't enabled on Android
|
||||
defaults skip-if(Android) pref(dom.fs.enabled,true)
|
||||
|
||||
load 1798773.html
|
||||
load 1800470.html
|
||||
|
@ -833,7 +833,8 @@ bool ReadableStream::Transfer(JSContext* aCx, UniqueMessagePortId& aPortId) {
|
||||
}
|
||||
|
||||
// Step 5: Let writable be a new WritableStream in the current Realm.
|
||||
RefPtr<WritableStream> writable = new WritableStream(mGlobal);
|
||||
RefPtr<WritableStream> writable = new WritableStream(
|
||||
mGlobal, WritableStream::HoldDropJSObjectsCaller::Implicit);
|
||||
|
||||
// Step 6: Perform ! SetUpCrossRealmTransformWritable(writable, port1).
|
||||
// MOZ_KnownLive because Port1 never changes before CC
|
||||
@ -957,7 +958,8 @@ WritableStreamTransferReceivingStepsImpl(JSContext* aCx,
|
||||
// Step 2: Let port be a deserializedRecord.[[Deserialized]].
|
||||
|
||||
// Step 3: Perform ! SetUpCrossRealmTransformWritable(value, port).
|
||||
auto writable = MakeRefPtr<WritableStream>(aGlobal);
|
||||
auto writable = MakeRefPtr<WritableStream>(
|
||||
aGlobal, WritableStream::HoldDropJSObjectsCaller::Implicit);
|
||||
ErrorResult rv;
|
||||
SetUpCrossRealmTransformWritable(writable, &aPort, rv);
|
||||
if (rv.MaybeSetPendingException(aCx)) {
|
||||
|
@ -49,16 +49,28 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WritableStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
WritableStream::WritableStream(nsIGlobalObject* aGlobal) : mGlobal(aGlobal) {
|
||||
mozilla::HoldJSObjects(this);
|
||||
WritableStream::WritableStream(nsIGlobalObject* aGlobal,
|
||||
HoldDropJSObjectsCaller aHoldDropCaller)
|
||||
: mGlobal(aGlobal), mHoldDropCaller(aHoldDropCaller) {
|
||||
if (mHoldDropCaller == HoldDropJSObjectsCaller::Implicit) {
|
||||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
}
|
||||
|
||||
WritableStream::WritableStream(const GlobalObject& aGlobal)
|
||||
: mGlobal(do_QueryInterface(aGlobal.GetAsSupports())) {
|
||||
mozilla::HoldJSObjects(this);
|
||||
WritableStream::WritableStream(const GlobalObject& aGlobal,
|
||||
HoldDropJSObjectsCaller aHoldDropCaller)
|
||||
: mGlobal(do_QueryInterface(aGlobal.GetAsSupports())),
|
||||
mHoldDropCaller(aHoldDropCaller) {
|
||||
if (mHoldDropCaller == HoldDropJSObjectsCaller::Implicit) {
|
||||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
}
|
||||
|
||||
WritableStream::~WritableStream() { mozilla::DropJSObjects(this); }
|
||||
WritableStream::~WritableStream() {
|
||||
if (mHoldDropCaller == HoldDropJSObjectsCaller::Implicit) {
|
||||
mozilla::DropJSObjects(this);
|
||||
}
|
||||
}
|
||||
|
||||
JSObject* WritableStream::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
@ -458,7 +470,8 @@ already_AddRefed<WritableStream> WritableStream::Constructor(
|
||||
}
|
||||
|
||||
// Step 4. Perform ! InitializeWritableStream(this).
|
||||
RefPtr<WritableStream> writableStream = new WritableStream(aGlobal);
|
||||
RefPtr<WritableStream> writableStream =
|
||||
new WritableStream(aGlobal, HoldDropJSObjectsCaller::Implicit);
|
||||
|
||||
// Step 5. Let sizeAlgorithm be ! ExtractSizeAlgorithm(strategy).
|
||||
//
|
||||
@ -693,7 +706,8 @@ already_AddRefed<WritableStream> CreateWritableStream(
|
||||
|
||||
// Step 2: Let stream be a new WritableStream.
|
||||
// Step 3: Perform ! InitializeWritableStream(stream).
|
||||
auto stream = MakeRefPtr<WritableStream>(aGlobal);
|
||||
auto stream = MakeRefPtr<WritableStream>(
|
||||
aGlobal, WritableStream::HoldDropJSObjectsCaller::Implicit);
|
||||
|
||||
// Step 4: Let controller be a new WritableStreamDefaultController.
|
||||
auto controller =
|
||||
|
@ -39,8 +39,16 @@ class WritableStream : public nsISupports, public nsWrapperCache {
|
||||
virtual void LastRelease() {}
|
||||
|
||||
public:
|
||||
explicit WritableStream(const GlobalObject& aGlobal);
|
||||
explicit WritableStream(nsIGlobalObject* aGlobal);
|
||||
// If one extends WritableStream with another cycle collectable class,
|
||||
// calling HoldJSObjects and DropJSObjects should happen using 'this' of
|
||||
// that extending class. And in that case Explicit should be passed to the
|
||||
// constructor of WriteableStream so that it doesn't make those calls.
|
||||
// See also https://bugzilla.mozilla.org/show_bug.cgi?id=1801214.
|
||||
enum class HoldDropJSObjectsCaller { Implicit, Explicit };
|
||||
explicit WritableStream(const GlobalObject& aGlobal,
|
||||
HoldDropJSObjectsCaller aHoldDropCaller);
|
||||
explicit WritableStream(nsIGlobalObject* aGlobal,
|
||||
HoldDropJSObjectsCaller aHoldDropCaller);
|
||||
|
||||
enum class WriterState { Writable, Closed, Erroring, Errored };
|
||||
|
||||
@ -188,6 +196,7 @@ class WritableStream : public nsISupports, public nsWrapperCache {
|
||||
nsTArray<RefPtr<Promise>> mWriteRequests;
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
HoldDropJSObjectsCaller mHoldDropCaller;
|
||||
};
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT already_AddRefed<WritableStream> CreateWritableStream(
|
||||
|
Loading…
Reference in New Issue
Block a user