Bug 1769952 - Fix running raptor on a Win10-64 VM r=sparky
[gecko.git] / dom / streams / TransformStreamDefaultController.cpp
blob570b66b471942cdd455608f9a1da2ae61c8da737
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/TransformStreamDefaultController.h"
9 #include "TransformerCallbackHelpers.h"
10 #include "mozilla/Attributes.h"
11 #include "mozilla/dom/Promise.h"
12 #include "mozilla/dom/ReadableStream.h"
13 #include "mozilla/dom/ReadableStreamDefaultController.h"
14 #include "mozilla/dom/TransformStream.h"
15 #include "mozilla/dom/TransformStreamDefaultControllerBinding.h"
16 #include "nsWrapperCache.h"
18 namespace mozilla::dom {
20 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TransformStreamDefaultController, mGlobal,
21 mStream, mTransformerAlgorithms)
22 NS_IMPL_CYCLE_COLLECTING_ADDREF(TransformStreamDefaultController)
23 NS_IMPL_CYCLE_COLLECTING_RELEASE(TransformStreamDefaultController)
24 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TransformStreamDefaultController)
25 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
26 NS_INTERFACE_MAP_ENTRY(nsISupports)
27 NS_INTERFACE_MAP_END
29 TransformStream* TransformStreamDefaultController::Stream() { return mStream; }
31 void TransformStreamDefaultController::SetStream(TransformStream& aStream) {
32 MOZ_ASSERT(!mStream);
33 mStream = &aStream;
36 TransformerAlgorithms* TransformStreamDefaultController::Algorithms() {
37 return mTransformerAlgorithms;
40 void TransformStreamDefaultController::SetAlgorithms(
41 TransformerAlgorithms* aTransformerAlgorithms) {
42 mTransformerAlgorithms = aTransformerAlgorithms;
45 TransformStreamDefaultController::TransformStreamDefaultController(
46 nsIGlobalObject* aGlobal)
47 : mGlobal(aGlobal) {
48 mozilla::HoldJSObjects(this);
51 TransformStreamDefaultController::~TransformStreamDefaultController() {
52 mozilla::DropJSObjects(this);
55 JSObject* TransformStreamDefaultController::WrapObject(
56 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
57 return TransformStreamDefaultController_Binding::Wrap(aCx, this, aGivenProto);
60 // https://streams.spec.whatwg.org/#ts-default-controller-desired-size
61 Nullable<double> TransformStreamDefaultController::GetDesiredSize() const {
62 // Step 1. Let readableController be
63 // this.[[stream]].[[readable]].[[controller]].
64 RefPtr<ReadableStreamDefaultController> readableController =
65 mStream->Readable()->Controller()->AsDefault();
67 // Step 2. Return !
68 // ReadableStreamDefaultControllerGetDesiredSize(readableController).
69 return ReadableStreamDefaultControllerGetDesiredSize(readableController);
72 // https://streams.spec.whatwg.org/#rs-default-controller-has-backpressure
73 // Looks like a readable stream thing but the spec explicitly says this is for
74 // TransformStream.
75 static bool ReadableStreamDefaultControllerHasBackpressure(
76 ReadableStreamDefaultController* aController) {
77 // Step 1: If ! ReadableStreamDefaultControllerShouldCallPull(controller) is
78 // true, return false.
79 // Step 2: Otherwise, return true.
80 return !ReadableStreamDefaultControllerShouldCallPull(aController);
83 void TransformStreamDefaultController::Enqueue(JSContext* aCx,
84 JS::Handle<JS::Value> aChunk,
85 ErrorResult& aRv) {
86 // Step 1: Perform ? TransformStreamDefaultControllerEnqueue(this, chunk).
88 // Inlining TransformStreamDefaultControllerEnqueue here.
89 // https://streams.spec.whatwg.org/#transform-stream-default-controller-enqueue
91 // Step 1: Let stream be controller.[[stream]].
92 RefPtr<TransformStream> stream = mStream;
94 // Step 2: Let readableController be stream.[[readable]].[[controller]].
95 RefPtr<ReadableStreamDefaultController> readableController =
96 stream->Readable()->Controller()->AsDefault();
98 // Step 3: If !
99 // ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController) is
100 // false, throw a TypeError exception.
101 if (!ReadableStreamDefaultControllerCanCloseOrEnqueueAndThrow(
102 readableController, CloseOrEnqueue::Enqueue, aRv)) {
103 return;
106 // Step 4: Let enqueueResult be
107 // ReadableStreamDefaultControllerEnqueue(readableController, chunk).
108 ErrorResult rv;
109 ReadableStreamDefaultControllerEnqueue(aCx, readableController, aChunk, rv);
111 // Step 5: If enqueueResult is an abrupt completion,
112 if (rv.MaybeSetPendingException(aCx)) {
113 JS::Rooted<JS::Value> error(aCx);
114 if (!JS_GetPendingException(aCx, &error)) {
115 // Uncatchable exception; we should mark aRv and return.
116 aRv.StealExceptionFromJSContext(aCx);
117 return;
119 JS_ClearPendingException(aCx);
121 // Step 5.1: Perform ! TransformStreamErrorWritableAndUnblockWrite(stream,
122 // enqueueResult.[[Value]]).
123 TransformStreamErrorWritableAndUnblockWrite(aCx, stream, error, aRv);
125 // Step 5.2: Throw stream.[[readable]].[[storedError]].
126 JS::Rooted<JS::Value> storedError(aCx, stream->Readable()->StoredError());
127 aRv.MightThrowJSException();
128 aRv.ThrowJSException(aCx, storedError);
129 return;
132 // Step 6: Let backpressure be !
133 // ReadableStreamDefaultControllerHasBackpressure(readableController).
134 bool backpressure =
135 ReadableStreamDefaultControllerHasBackpressure(readableController);
137 // Step 7: If backpressure is not stream.[[backpressure]],
138 if (backpressure != stream->Backpressure()) {
139 // Step 7.1: Assert: backpressure is true.
140 MOZ_ASSERT(backpressure);
142 // Step 7.2: Perform ! TransformStreamSetBackpressure(stream, true).
143 TransformStreamSetBackpressure(stream, true, aRv);
147 // https://streams.spec.whatwg.org/#ts-default-controller-error
148 void TransformStreamDefaultController::Error(JSContext* aCx,
149 JS::Handle<JS::Value> aError,
150 ErrorResult& aRv) {
151 // Step 1: Perform ? TransformStreamDefaultControllerError(this, e).
153 // Inlining TransformStreamDefaultControllerError here.
154 // https://streams.spec.whatwg.org/#transform-stream-default-controller-error
156 // Perform ! TransformStreamError(controller.[[stream]], e).
157 TransformStreamError(aCx, mStream, aError, aRv);
160 // https://streams.spec.whatwg.org/#ts-default-controller-terminate
162 void TransformStreamDefaultController::Terminate(JSContext* aCx,
163 ErrorResult& aRv) {
164 // Step 1: Perform ? TransformStreamDefaultControllerTerminate(this).
166 // Inlining TransformStreamDefaultControllerTerminate here.
167 // https://streams.spec.whatwg.org/#transform-stream-default-controller-terminate
169 // Step 1: Let stream be controller.[[stream]].
170 RefPtr<TransformStream> stream = mStream;
172 // Step 2: Let readableController be stream.[[readable]].[[controller]].
173 RefPtr<ReadableStreamDefaultController> readableController =
174 stream->Readable()->Controller()->AsDefault();
176 // Step 3: Perform ! ReadableStreamDefaultControllerClose(readableController).
177 ReadableStreamDefaultControllerClose(aCx, readableController, aRv);
179 // Step 4: Let error be a TypeError exception indicating that the stream has
180 // been terminated.
181 ErrorResult rv;
182 rv.ThrowTypeError("Terminating the stream");
183 JS::Rooted<JS::Value> error(aCx);
184 MOZ_ALWAYS_TRUE(ToJSValue(aCx, std::move(rv), &error));
186 // Step 5: Perform ! TransformStreamErrorWritableAndUnblockWrite(stream,
187 // error).
188 TransformStreamErrorWritableAndUnblockWrite(aCx, stream, error, aRv);
191 // https://streams.spec.whatwg.org/#set-up-transform-stream-default-controller
192 void SetUpTransformStreamDefaultController(
193 JSContext* aCx, TransformStream& aStream,
194 TransformStreamDefaultController& aController,
195 TransformerAlgorithms& aTransformerAlgorithms) {
196 // Step 1. Assert: stream implements TransformStream.
197 // Step 2. Assert: stream.[[controller]] is undefined.
198 MOZ_ASSERT(!aStream.Controller());
200 // Step 3. Set controller.[[stream]] to stream.
201 aController.SetStream(aStream);
203 // Step 4. Set stream.[[controller]] to controller.
204 aStream.SetController(aController);
206 // Step 5. Set controller.[[transformAlgorithm]] to transformAlgorithm.
207 // Step 6. Set controller.[[flushAlgorithm]] to flushAlgorithm.
208 aController.SetAlgorithms(&aTransformerAlgorithms);
211 // https://streams.spec.whatwg.org/#set-up-transform-stream-default-controller-from-transformer
212 void SetUpTransformStreamDefaultControllerFromTransformer(
213 JSContext* aCx, TransformStream& aStream,
214 JS::Handle<JSObject*> aTransformer, Transformer& aTransformerDict) {
215 // Step 1. Let controller be a new TransformStreamDefaultController.
216 auto controller =
217 MakeRefPtr<TransformStreamDefaultController>(aStream.GetParentObject());
219 // Step 2 - 5:
220 auto algorithms = MakeRefPtr<TransformerAlgorithms>(
221 aStream.GetParentObject(), aTransformer, aTransformerDict);
223 // Step 6: Perform ! SetUpTransformStreamDefaultController(stream, controller,
224 // transformAlgorithm, flushAlgorithm).
225 SetUpTransformStreamDefaultController(aCx, aStream, *controller, *algorithms);
228 } // namespace mozilla::dom