Copy as Markdown

Other Tools

/* THIS FILE IS AUTOGENERATED FROM UnderlyingSource.webidl BY Codegen.py - DO NOT EDIT */
#include <type_traits>
#include "AtomList.h"
#include "MainThreadUtils.h"
#include "UnderlyingSourceBinding.h"
#include "js/CallAndConstruct.h"
#include "js/Exception.h"
#include "js/MapAndSet.h"
#include "js/Object.h"
#include "js/PropertyAndElement.h"
#include "js/PropertyDescriptor.h"
#include "js/experimental/JitInfo.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ReadableByteStreamController.h"
#include "mozilla/dom/ReadableStreamDefaultController.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/ToJSValue.h"
namespace mozilla::dom {
namespace binding_detail {}; // Just to make sure it's known as a namespace
using namespace mozilla::dom::binding_detail;
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningReadableStreamDefaultControllerOrReadableByteStreamController& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsReadableStreamDefaultController()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsReadableStreamDefaultController(), "mReadableStreamDefaultController", aFlags);
} else if (aUnion.IsReadableByteStreamController()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsReadableByteStreamController(), "mReadableByteStreamController", aFlags);
}
}
void
ImplCycleCollectionUnlink(OwningReadableStreamDefaultControllerOrReadableByteStreamController& aUnion)
{
aUnion.Uninit();
}
bool
ReadableStreamDefaultControllerOrReadableByteStreamController::TrySetToReadableStreamDefaultController(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::ReadableStreamDefaultController>& memberSlot = RawSetAsReadableStreamDefaultController();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ReadableStreamDefaultController, mozilla::dom::ReadableStreamDefaultController>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyReadableStreamDefaultController();
tryNext = true;
return true;
}
}
}
return true;
}
bool
ReadableStreamDefaultControllerOrReadableByteStreamController::TrySetToReadableStreamDefaultController(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToReadableStreamDefaultController(cx, value, tryNext, passedToJSImpl);
}
bool
ReadableStreamDefaultControllerOrReadableByteStreamController::TrySetToReadableByteStreamController(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::ReadableByteStreamController>& memberSlot = RawSetAsReadableByteStreamController();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ReadableByteStreamController, mozilla::dom::ReadableByteStreamController>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyReadableByteStreamController();
tryNext = true;
return true;
}
}
}
return true;
}
bool
ReadableStreamDefaultControllerOrReadableByteStreamController::TrySetToReadableByteStreamController(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToReadableByteStreamController(cx, value, tryNext, passedToJSImpl);
}
bool
ReadableStreamDefaultControllerOrReadableByteStreamController::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToReadableStreamDefaultController(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToReadableByteStreamController(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ReadableStreamDefaultController, ReadableByteStreamController");
return false;
}
return true;
}
bool
ReadableStreamDefaultControllerOrReadableByteStreamController::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ReadableStreamDefaultControllerOrReadableByteStreamController::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eReadableStreamDefaultController: {
if (!GetOrCreateDOMReflector(cx, mValue.mReadableStreamDefaultController.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eReadableByteStreamController: {
if (!GetOrCreateDOMReflector(cx, mValue.mReadableByteStreamController.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningReadableStreamDefaultControllerOrReadableByteStreamController::OwningReadableStreamDefaultControllerOrReadableByteStreamController(OwningReadableStreamDefaultControllerOrReadableByteStreamController&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eReadableStreamDefaultController: {
mType = eReadableStreamDefaultController;
mValue.mReadableStreamDefaultController.SetValue(std::move(aOther.mValue.mReadableStreamDefaultController.Value()));
break;
}
case eReadableByteStreamController: {
mType = eReadableByteStreamController;
mValue.mReadableByteStreamController.SetValue(std::move(aOther.mValue.mReadableByteStreamController.Value()));
break;
}
}
}
bool
OwningReadableStreamDefaultControllerOrReadableByteStreamController::TrySetToReadableStreamDefaultController(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::ReadableStreamDefaultController>& memberSlot = RawSetAsReadableStreamDefaultController();
static_assert(IsRefcounted<mozilla::dom::ReadableStreamDefaultController>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ReadableStreamDefaultController, mozilla::dom::ReadableStreamDefaultController>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyReadableStreamDefaultController();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningReadableStreamDefaultControllerOrReadableByteStreamController::TrySetToReadableStreamDefaultController(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToReadableStreamDefaultController(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::ReadableStreamDefaultController>&
OwningReadableStreamDefaultControllerOrReadableByteStreamController::RawSetAsReadableStreamDefaultController()
{
if (mType == eReadableStreamDefaultController) {
return mValue.mReadableStreamDefaultController.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eReadableStreamDefaultController;
return mValue.mReadableStreamDefaultController.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::ReadableStreamDefaultController>&
OwningReadableStreamDefaultControllerOrReadableByteStreamController::SetAsReadableStreamDefaultController()
{
if (mType == eReadableStreamDefaultController) {
return mValue.mReadableStreamDefaultController.Value();
}
Uninit();
mType = eReadableStreamDefaultController;
return mValue.mReadableStreamDefaultController.SetValue();
}
void
OwningReadableStreamDefaultControllerOrReadableByteStreamController::DestroyReadableStreamDefaultController()
{
MOZ_RELEASE_ASSERT(IsReadableStreamDefaultController(), "Wrong type!");
mValue.mReadableStreamDefaultController.Destroy();
mType = eUninitialized;
}
bool
OwningReadableStreamDefaultControllerOrReadableByteStreamController::TrySetToReadableByteStreamController(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::ReadableByteStreamController>& memberSlot = RawSetAsReadableByteStreamController();
static_assert(IsRefcounted<mozilla::dom::ReadableByteStreamController>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ReadableByteStreamController, mozilla::dom::ReadableByteStreamController>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyReadableByteStreamController();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningReadableStreamDefaultControllerOrReadableByteStreamController::TrySetToReadableByteStreamController(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToReadableByteStreamController(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::ReadableByteStreamController>&
OwningReadableStreamDefaultControllerOrReadableByteStreamController::RawSetAsReadableByteStreamController()
{
if (mType == eReadableByteStreamController) {
return mValue.mReadableByteStreamController.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eReadableByteStreamController;
return mValue.mReadableByteStreamController.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::ReadableByteStreamController>&
OwningReadableStreamDefaultControllerOrReadableByteStreamController::SetAsReadableByteStreamController()
{
if (mType == eReadableByteStreamController) {
return mValue.mReadableByteStreamController.Value();
}
Uninit();
mType = eReadableByteStreamController;
return mValue.mReadableByteStreamController.SetValue();
}
void
OwningReadableStreamDefaultControllerOrReadableByteStreamController::DestroyReadableByteStreamController()
{
MOZ_RELEASE_ASSERT(IsReadableByteStreamController(), "Wrong type!");
mValue.mReadableByteStreamController.Destroy();
mType = eUninitialized;
}
bool
OwningReadableStreamDefaultControllerOrReadableByteStreamController::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToReadableStreamDefaultController(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToReadableByteStreamController(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ReadableStreamDefaultController, ReadableByteStreamController");
return false;
}
return true;
}
bool
OwningReadableStreamDefaultControllerOrReadableByteStreamController::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningReadableStreamDefaultControllerOrReadableByteStreamController::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eReadableStreamDefaultController: {
DestroyReadableStreamDefaultController();
break;
}
case eReadableByteStreamController: {
DestroyReadableByteStreamController();
break;
}
}
}
bool
OwningReadableStreamDefaultControllerOrReadableByteStreamController::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eReadableStreamDefaultController: {
if (!GetOrCreateDOMReflector(cx, mValue.mReadableStreamDefaultController.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eReadableByteStreamController: {
if (!GetOrCreateDOMReflector(cx, mValue.mReadableByteStreamController.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningReadableStreamDefaultControllerOrReadableByteStreamController&
OwningReadableStreamDefaultControllerOrReadableByteStreamController::operator=(OwningReadableStreamDefaultControllerOrReadableByteStreamController&& aOther)
{
this->~OwningReadableStreamDefaultControllerOrReadableByteStreamController();
new (this) OwningReadableStreamDefaultControllerOrReadableByteStreamController (std::move(aOther));
return *this;
}
OwningReadableStreamDefaultControllerOrReadableByteStreamController&
OwningReadableStreamDefaultControllerOrReadableByteStreamController::operator=(const OwningReadableStreamDefaultControllerOrReadableByteStreamController& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eReadableStreamDefaultController: {
SetAsReadableStreamDefaultController() = aOther.GetAsReadableStreamDefaultController();
break;
}
case eReadableByteStreamController: {
SetAsReadableByteStreamController() = aOther.GetAsReadableByteStreamController();
break;
}
}
return *this;
}
UnderlyingSource::UnderlyingSource()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
UnderlyingSource::InitIds(JSContext* cx, UnderlyingSourceAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->type_id.init(cx, "type") ||
!atomsCache->start_id.init(cx, "start") ||
!atomsCache->pull_id.init(cx, "pull") ||
!atomsCache->cancel_id.init(cx, "cancel") ||
!atomsCache->autoAllocateChunkSize_id.init(cx, "autoAllocateChunkSize")) {
return false;
}
return true;
}
bool
UnderlyingSource::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
UnderlyingSourceAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<UnderlyingSourceAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->autoAllocateChunkSize_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mAutoAllocateChunkSize.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'autoAllocateChunkSize' member of UnderlyingSource", &(mAutoAllocateChunkSize.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->cancel_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mCancel.Construct();
if (temp.ref().isObject()) {
if (JS::IsCallable(&temp.ref().toObject())) {
{ // scope for tempRoot and tempGlobalRoot if needed
JS::Rooted<JSObject*> tempRoot(cx, &temp.ref().toObject());
JS::Rooted<JSObject*> tempGlobalRoot(cx, JS::CurrentGlobalOrNull(cx));
(mCancel.Value()) = new UnderlyingSourceCancelCallback(cx, tempRoot, tempGlobalRoot, GetIncumbentGlobal());
}
} else {
cx.ThrowErrorMessage<MSG_NOT_CALLABLE>("'cancel' member of UnderlyingSource");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'cancel' member of UnderlyingSource");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->pull_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mPull.Construct();
if (temp.ref().isObject()) {
if (JS::IsCallable(&temp.ref().toObject())) {
{ // scope for tempRoot and tempGlobalRoot if needed
JS::Rooted<JSObject*> tempRoot(cx, &temp.ref().toObject());
JS::Rooted<JSObject*> tempGlobalRoot(cx, JS::CurrentGlobalOrNull(cx));
(mPull.Value()) = new UnderlyingSourcePullCallback(cx, tempRoot, tempGlobalRoot, GetIncumbentGlobal());
}
} else {
cx.ThrowErrorMessage<MSG_NOT_CALLABLE>("'pull' member of UnderlyingSource");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'pull' member of UnderlyingSource");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->start_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mStart.Construct();
if (temp.ref().isObject()) {
if (JS::IsCallable(&temp.ref().toObject())) {
{ // scope for tempRoot and tempGlobalRoot if needed
JS::Rooted<JSObject*> tempRoot(cx, &temp.ref().toObject());
JS::Rooted<JSObject*> tempGlobalRoot(cx, JS::CurrentGlobalOrNull(cx));
(mStart.Value()) = new UnderlyingSourceStartCallback(cx, tempRoot, tempGlobalRoot, GetIncumbentGlobal());
}
} else {
cx.ThrowErrorMessage<MSG_NOT_CALLABLE>("'start' member of UnderlyingSource");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'start' member of UnderlyingSource");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mType.Construct();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<ReadableStreamType>::Values,
"ReadableStreamType", "'type' member of UnderlyingSource",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
(mType.Value()) = static_cast<ReadableStreamType>(index);
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
UnderlyingSource::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
UnderlyingSource::TraceDictionary(JSTracer* trc)
{
}
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise>
UnderlyingSourceCancelCallback::Call(BindingCallContext& cx, JS::Handle<JS::Value> aThisVal, const Optional<JS::Handle<JS::Value>>& reason, ErrorResult& aRv)
{
JS::Rooted<JS::Value> rval(cx);
JS::RootedVector<JS::Value> argv(cx);
if (!argv.resize(1)) {
// That threw an exception on the JSContext, and our CallSetup will do
// the right thing with that.
return nullptr;
}
unsigned argc = 1;
do {
if (reason.WasPassed()) {
JS::ExposeValueToActiveJS(reason.Value());
argv[0].set(reason.Value());
if (!MaybeWrapValue(cx, argv[0])) {
// Convert exception to a rejected promise.
// step 10 and step 15.5.
return CreateRejectedPromiseFromThrownException(cx, aRv);
}
break;
} else if (argc == 1) {
// This is our current trailing argument; reduce argc
--argc;
} else {
argv[0].setUndefined();
}
} while (false);
JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
if (!JS::Call(cx, aThisVal, callable,
JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
// Convert exception to a rejected promise.
// step 12 and step 15.5.
return CreateRejectedPromiseFromThrownException(cx, aRv);
}
RefPtr<Promise> rvalDecl;
{ // Scope for our GlobalObject, FastErrorResult, JSAutoRealm,
// etc.
JS::Rooted<JSObject*> globalObj(cx);
// We basically want our entry global here. Play it safe
// and use GetEntryGlobal() to get it, with whatever
// principal-clamping it ends up doing.
globalObj = GetEntryGlobal()->GetGlobalJSObject();
JSAutoRealm ar(cx, globalObj);
GlobalObject promiseGlobal(cx, globalObj);
if (promiseGlobal.Failed()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
JS::Rooted<JS::Value> valueToResolve(cx, rval);
if (!JS_WrapValue(cx, &valueToResolve)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
binding_detail::FastErrorResult promiseRv;
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(promiseGlobal.GetAsSupports());
if (!global) {
promiseRv.Throw(NS_ERROR_UNEXPECTED);
MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
rvalDecl = Promise::Resolve(global, cx, valueToResolve,
promiseRv);
if (promiseRv.MaybeSetPendingException(cx)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
}
return rvalDecl.forget();
}
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise>
UnderlyingSourcePullCallback::Call(BindingCallContext& cx, JS::Handle<JS::Value> aThisVal, const ReadableStreamDefaultControllerOrReadableByteStreamController& controller, ErrorResult& aRv)
{
JS::Rooted<JS::Value> rval(cx);
JS::RootedVector<JS::Value> argv(cx);
if (!argv.resize(1)) {
// That threw an exception on the JSContext, and our CallSetup will do
// the right thing with that.
return nullptr;
}
unsigned argc = 1;
do {
JS::Rooted<JSObject*> callbackObj(cx, CallbackKnownNotGray());
if (!controller.ToJSVal(cx, callbackObj, argv[0])) {
// Convert exception to a rejected promise.
// step 10 and step 15.5.
return CreateRejectedPromiseFromThrownException(cx, aRv);
}
break;
} while (false);
JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
if (!JS::Call(cx, aThisVal, callable,
JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
// Convert exception to a rejected promise.
// step 12 and step 15.5.
return CreateRejectedPromiseFromThrownException(cx, aRv);
}
RefPtr<Promise> rvalDecl;
{ // Scope for our GlobalObject, FastErrorResult, JSAutoRealm,
// etc.
JS::Rooted<JSObject*> globalObj(cx);
// We basically want our entry global here. Play it safe
// and use GetEntryGlobal() to get it, with whatever
// principal-clamping it ends up doing.
globalObj = GetEntryGlobal()->GetGlobalJSObject();
JSAutoRealm ar(cx, globalObj);
GlobalObject promiseGlobal(cx, globalObj);
if (promiseGlobal.Failed()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
JS::Rooted<JS::Value> valueToResolve(cx, rval);
if (!JS_WrapValue(cx, &valueToResolve)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
binding_detail::FastErrorResult promiseRv;
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(promiseGlobal.GetAsSupports());
if (!global) {
promiseRv.Throw(NS_ERROR_UNEXPECTED);
MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
rvalDecl = Promise::Resolve(global, cx, valueToResolve,
promiseRv);
if (promiseRv.MaybeSetPendingException(cx)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
}
return rvalDecl.forget();
}
MOZ_CAN_RUN_SCRIPT void
UnderlyingSourceStartCallback::Call(BindingCallContext& cx, JS::Handle<JS::Value> aThisVal, const ReadableStreamDefaultControllerOrReadableByteStreamController& controller, JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv)
{
JS::Rooted<JS::Value> rval(cx);
JS::RootedVector<JS::Value> argv(cx);
if (!argv.resize(1)) {
// That threw an exception on the JSContext, and our CallSetup will do
// the right thing with that.
return;
}
unsigned argc = 1;
do {
JS::Rooted<JSObject*> callbackObj(cx, CallbackKnownNotGray());
if (!controller.ToJSVal(cx, callbackObj, argv[0])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
break;
} while (false);
JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
if (!JS::Call(cx, aThisVal, callable,
JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
aRv.NoteJSContextException(cx);
return;
}
JS::Rooted<JS::Value> rvalDecl(cx);
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((false) && !CallerSubsumes(rval)) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("return value of UnderlyingSourceStartCallback");
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
rvalDecl = rval;
aRetVal.set(rvalDecl);
}
} // namespace mozilla::dom