TransformerCallbackHelpers.cpp (4910B)
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/. */ 6 7 #include "TransformerCallbackHelpers.h" 8 9 #include "StreamUtils.h" 10 #include "mozilla/dom/Promise.h" 11 #include "mozilla/dom/TransformStreamDefaultController.h" 12 13 using namespace mozilla::dom; 14 15 NS_IMPL_CYCLE_COLLECTION(TransformerAlgorithmsBase) 16 NS_IMPL_CYCLE_COLLECTING_ADDREF(TransformerAlgorithmsBase) 17 NS_IMPL_CYCLE_COLLECTING_RELEASE(TransformerAlgorithmsBase) 18 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TransformerAlgorithmsBase) 19 NS_INTERFACE_MAP_ENTRY(nsISupports) 20 NS_INTERFACE_MAP_END 21 22 NS_IMPL_CYCLE_COLLECTION_INHERITED_WITH_JS_MEMBERS( 23 TransformerAlgorithms, TransformerAlgorithmsBase, 24 (mGlobal, mTransformCallback, mFlushCallback), (mTransformer)) 25 NS_IMPL_ADDREF_INHERITED(TransformerAlgorithms, TransformerAlgorithmsBase) 26 NS_IMPL_RELEASE_INHERITED(TransformerAlgorithms, TransformerAlgorithmsBase) 27 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TransformerAlgorithms) 28 NS_INTERFACE_MAP_END_INHERITING(TransformerAlgorithmsBase) 29 30 // https://streams.spec.whatwg.org/#set-up-transform-stream-default-controller-from-transformer 31 already_AddRefed<Promise> TransformerAlgorithms::TransformCallback( 32 JSContext* aCx, JS::Handle<JS::Value> aChunk, 33 TransformStreamDefaultController& aController, ErrorResult& aRv) { 34 if (!mTransformCallback) { 35 // Step 2.1. Let result be 36 // TransformStreamDefaultControllerEnqueue(controller, chunk). 37 aController.Enqueue(aCx, aChunk, aRv); 38 39 // Step 2.2. If result is an abrupt completion, return a promise rejected 40 // with result.[[Value]]. 41 if (aRv.MaybeSetPendingException(aCx)) { 42 JS::Rooted<JS::Value> error(aCx); 43 if (!JS_GetPendingException(aCx, &error)) { 44 // Uncatchable exception; we should mark aRv and return. 45 aRv.StealExceptionFromJSContext(aCx); 46 return nullptr; 47 } 48 JS_ClearPendingException(aCx); 49 50 return Promise::CreateRejected(aController.GetParentObject(), error, aRv); 51 } 52 53 // Step 2.3. Otherwise, return a promise resolved with undefined. 54 return Promise::CreateResolvedWithUndefined(aController.GetParentObject(), 55 aRv); 56 } 57 // Step 4. If transformerDict["transform"] exists, set transformAlgorithm to 58 // an algorithm which takes an argument chunk and returns the result of 59 // invoking transformerDict["transform"] with argument list « chunk, 60 // controller » and callback this value transformer. 61 JS::Rooted<JSObject*> thisObj(aCx, mTransformer); 62 return MOZ_KnownLive(mTransformCallback) 63 ->Call(thisObj, aChunk, aController, aRv, 64 "TransformStreamDefaultController.[[transformAlgorithm]]", 65 CallbackObject::eRethrowExceptions); 66 } 67 68 // https://streams.spec.whatwg.org/#set-up-transform-stream-default-controller-from-transformer 69 already_AddRefed<Promise> TransformerAlgorithms::FlushCallback( 70 JSContext* aCx, TransformStreamDefaultController& aController, 71 ErrorResult& aRv) { 72 if (!mFlushCallback) { 73 // Step 3. Let flushAlgorithm be an algorithm which returns a promise 74 // resolved with undefined. 75 return Promise::CreateResolvedWithUndefined(aController.GetParentObject(), 76 aRv); 77 } 78 // Step 5. If transformerDict["flush"] exists, set flushAlgorithm to an 79 // algorithm which returns the result of invoking transformerDict["flush"] 80 // with argument list « controller » and callback this value transformer. 81 JS::Rooted<JSObject*> thisObj(aCx, mTransformer); 82 return MOZ_KnownLive(mFlushCallback) 83 ->Call(thisObj, aController, aRv, 84 "TransformStreamDefaultController.[[flushAlgorithm]]", 85 CallbackObject::eRethrowExceptions); 86 } 87 88 already_AddRefed<Promise> TransformerAlgorithmsWrapper::TransformCallback( 89 JSContext*, JS::Handle<JS::Value> aChunk, 90 TransformStreamDefaultController& aController, ErrorResult& aRv) { 91 nsCOMPtr<nsIGlobalObject> global = aController.GetParentObject(); 92 return PromisifyAlgorithm( 93 global, 94 [this, &aChunk, &aController](ErrorResult& aRv) 95 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { 96 return TransformCallbackImpl(aChunk, aController, aRv); 97 }, 98 aRv); 99 } 100 101 already_AddRefed<Promise> TransformerAlgorithmsWrapper::FlushCallback( 102 JSContext*, TransformStreamDefaultController& aController, 103 ErrorResult& aRv) { 104 nsCOMPtr<nsIGlobalObject> global = aController.GetParentObject(); 105 return PromisifyAlgorithm( 106 global, 107 [this, &aController](ErrorResult& aRv) MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { 108 return FlushCallbackImpl(aController, aRv); 109 }, 110 aRv); 111 }