/* THIS FILE IS AUTOGENERATED FROM Fetch.webidl BY Codegen.py - DO NOT EDIT */ #include #include "AtomList.h" #include "FetchBinding.h" #include "MainThreadUtils.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 "jsfriendapi.h" #include "mozilla/OwningNonNull.h" #include "mozilla/dom/BindingCallContext.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/Blob.h" #include "mozilla/dom/FormData.h" #include "mozilla/dom/NonRefcountedDOMObject.h" #include "mozilla/dom/PrimitiveConversions.h" #include "mozilla/dom/ReadableStream.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/SimpleGlobalObject.h" #include "mozilla/dom/URLSearchParams.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, OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString& aUnion, const char* aName, uint32_t aFlags) { if (aUnion.IsReadableStream()) { ImplCycleCollectionTraverse(aCallback, aUnion.GetAsReadableStream(), "mReadableStream", aFlags); } else if (aUnion.IsBlob()) { ImplCycleCollectionTraverse(aCallback, aUnion.GetAsBlob(), "mBlob", aFlags); } else if (aUnion.IsFormData()) { ImplCycleCollectionTraverse(aCallback, aUnion.GetAsFormData(), "mFormData", aFlags); } else if (aUnion.IsURLSearchParams()) { ImplCycleCollectionTraverse(aCallback, aUnion.GetAsURLSearchParams(), "mURLSearchParams", aFlags); } } void ImplCycleCollectionUnlink(OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString& aUnion) { aUnion.Uninit(); } FetchReadableStreamReadDataArray::FetchReadableStreamReadDataArray() { // Safe to pass a null context if we pass a null value Init(nullptr, JS::NullHandleValue); } bool FetchReadableStreamReadDataArray::InitIds(JSContext* cx, FetchReadableStreamReadDataArrayAtoms* atomsCache) { MOZ_ASSERT(reinterpret_cast(atomsCache)->isVoid()); // Initialize these in reverse order so that any failure leaves the first one // uninitialized. if (!atomsCache->value_id.init(cx, "value")) { return false; } return true; } bool FetchReadableStreamReadDataArray::Init(BindingCallContext& cx, JS::Handle 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()); FetchReadableStreamReadDataArrayAtoms* atomsCache = nullptr; if (cx) { atomsCache = GetAtomCache(cx); if (reinterpret_cast(atomsCache)->isVoid() && !InitIds(cx, atomsCache)) { return false; } } if (!IsConvertibleToDictionary(val)) { return cx.ThrowErrorMessage(sourceDescription, "dictionary"); } bool isNull = val.isNullOrUndefined(); // We only need these if !isNull, in which case we have |cx|. Maybe > object; Maybe > temp; if (!isNull) { MOZ_ASSERT(cx); object.emplace(cx, &val.toObject()); temp.emplace(cx); } if (!isNull) { if (!JS_GetPropertyById(cx, *object, atomsCache->value_id, temp.ptr())) { return false; } } if (!isNull && !temp->isUndefined()) { mValue.Construct(); if (temp.ref().isObject()) { if (!(mValue.Value()).Init(&temp.ref().toObject())) { cx.ThrowErrorMessage("'value' member of FetchReadableStreamReadDataArray", "Uint8Array"); return false; } if (JS::IsArrayBufferViewShared((mValue.Value()).Obj())) { cx.ThrowErrorMessage("'value' member of FetchReadableStreamReadDataArray"); return false; } if (JS::IsLargeArrayBufferView((mValue.Value()).Obj())) { cx.ThrowErrorMessage("'value' member of FetchReadableStreamReadDataArray"); return false; } if (JS::IsResizableArrayBufferView((mValue.Value()).Obj())) { cx.ThrowErrorMessage("'value' member of FetchReadableStreamReadDataArray"); return false; } if (JS::IsImmutableArrayBufferView((mValue.Value()).Obj())) { cx.ThrowErrorMessage("'value' member of FetchReadableStreamReadDataArray"); return false; } } else { cx.ThrowErrorMessage("'value' member of FetchReadableStreamReadDataArray"); return false; } mIsAnyMemberPresent = true; } return true; } bool FetchReadableStreamReadDataArray::Init(JSContext* cx_, JS::Handle 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 FetchReadableStreamReadDataArray::TraceDictionary(JSTracer* trc) { if (mValue.WasPassed()) { mValue.Value().TraceSelf(trc); } } FetchReadableStreamReadDataDone::FetchReadableStreamReadDataDone() { // Safe to pass a null context if we pass a null value Init(nullptr, JS::NullHandleValue); } bool FetchReadableStreamReadDataDone::InitIds(JSContext* cx, FetchReadableStreamReadDataDoneAtoms* atomsCache) { MOZ_ASSERT(reinterpret_cast(atomsCache)->isVoid()); // Initialize these in reverse order so that any failure leaves the first one // uninitialized. if (!atomsCache->done_id.init(cx, "done")) { return false; } return true; } bool FetchReadableStreamReadDataDone::Init(BindingCallContext& cx, JS::Handle 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()); FetchReadableStreamReadDataDoneAtoms* atomsCache = nullptr; if (cx) { atomsCache = GetAtomCache(cx); if (reinterpret_cast(atomsCache)->isVoid() && !InitIds(cx, atomsCache)) { return false; } } if (!IsConvertibleToDictionary(val)) { return cx.ThrowErrorMessage(sourceDescription, "dictionary"); } bool isNull = val.isNullOrUndefined(); // We only need these if !isNull, in which case we have |cx|. Maybe > object; Maybe > temp; if (!isNull) { MOZ_ASSERT(cx); object.emplace(cx, &val.toObject()); temp.emplace(cx); } if (!isNull) { if (!JS_GetPropertyById(cx, *object, atomsCache->done_id, temp.ptr())) { return false; } } if (!isNull && !temp->isUndefined()) { if (!ValueToPrimitive(cx, temp.ref(), "'done' member of FetchReadableStreamReadDataDone", &mDone)) { return false; } } else { mDone = false; } mIsAnyMemberPresent = true; return true; } bool FetchReadableStreamReadDataDone::Init(JSContext* cx_, JS::Handle 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 FetchReadableStreamReadDataDone::TraceDictionary(JSTracer* trc) { } FetchReadableStreamReadDataDone& FetchReadableStreamReadDataDone::operator=(const FetchReadableStreamReadDataDone& aOther) { MaybeEmptyDictionaryBase::operator=(aOther); mDone = aOther.mDone; return *this; } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToReadableStream(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot NonNull& memberSlot = RawSetAsReadableStream(); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyReadableStream(); tryNext = true; return true; } } } return true; } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToReadableStream(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToReadableStream(cx, value, tryNext, passedToJSImpl); } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToBlob(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot NonNull& memberSlot = RawSetAsBlob(); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyBlob(); tryNext = true; return true; } } } return true; } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToBlob(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToBlob(cx, value, tryNext, passedToJSImpl); } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot RootedSpiderMonkeyInterface& memberSlot = RawSetAsArrayBufferView(cx); if (!memberSlot.Init(&value.toObject())) { DestroyArrayBufferView(); tryNext = true; return true; } if (JS::IsArrayBufferViewShared(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBufferView branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsLargeArrayBufferView(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBufferView branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsResizableArrayBufferView(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBufferView branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsImmutableArrayBufferView(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBufferView branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } } return true; } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBufferView(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl); } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot RootedSpiderMonkeyInterface& memberSlot = RawSetAsArrayBuffer(cx); if (!memberSlot.Init(&value.toObject())) { DestroyArrayBuffer(); tryNext = true; return true; } if (JS::IsSharedArrayBufferObject(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBuffer branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBuffer branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBuffer branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsImmutableArrayBufferMaybeShared(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBuffer branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } } return true; } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBuffer(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl); } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToFormData(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot NonNull& memberSlot = RawSetAsFormData(); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyFormData(); tryNext = true; return true; } } } return true; } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToFormData(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToFormData(cx, value, tryNext, passedToJSImpl); } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToURLSearchParams(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot NonNull& memberSlot = RawSetAsURLSearchParams(); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyURLSearchParams(); tryNext = true; return true; } } } return true; } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToURLSearchParams(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToURLSearchParams(cx, value, tryNext, passedToJSImpl); } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToUSVString(JSContext* cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot nsAutoString& memberSlot = RawSetAsUSVString(); if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) { return false; } if (!NormalizeUSVString(memberSlot)) { JS_ReportOutOfMemory(cx); return false; } } return true; } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::Init(BindingCallContext& cx, JS::Handle value, const char* sourceDescription, bool passedToJSImpl) { MOZ_ASSERT(mType == eUninitialized); bool done = false, failed = false, tryNext; if (value.isObject()) { done = (failed = !TrySetToReadableStream(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToBlob(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToFormData(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToURLSearchParams(cx, value, tryNext, passedToJSImpl)) || !tryNext; } if (!done) { do { done = (failed = !TrySetToUSVString(cx, value, tryNext)) || !tryNext; break; } while (false); } if (failed) { return false; } if (!done) { cx.ThrowErrorMessage(sourceDescription, "ReadableStream, Blob, ArrayBufferView, ArrayBuffer, FormData, URLSearchParams"); return false; } return true; } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::Init(JSContext* cx_, JS::Handle value, const char* sourceDescription, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return Init(cx, value, sourceDescription, passedToJSImpl); } bool ReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::ToJSVal(JSContext* cx, JS::Handle scopeObj, JS::MutableHandle rval) const { switch (mType) { case eUninitialized: { return false; } case eReadableStream: { if (!GetOrCreateDOMReflector(cx, mValue.mReadableStream.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eBlob: { if (!GetOrCreateDOMReflector(cx, mValue.mBlob.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eArrayBufferView: { rval.setObject(*mValue.mArrayBufferView.Value().Obj()); if (!MaybeWrapNonDOMObjectValue(cx, rval)) { return false; } return true; } case eArrayBuffer: { rval.setObject(*mValue.mArrayBuffer.Value().Obj()); if (!MaybeWrapNonDOMObjectValue(cx, rval)) { return false; } return true; } case eFormData: { if (!GetOrCreateDOMReflector(cx, mValue.mFormData.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eURLSearchParams: { if (!GetOrCreateDOMReflector(cx, mValue.mURLSearchParams.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eUSVString: { if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) { return false; } return true; } default: { return false; } } } OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString(OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString&& aOther) : mType(eUninitialized) { switch (aOther.mType) { case eUninitialized: { MOZ_ASSERT(mType == eUninitialized, "We need to destroy ourselves?"); break; } case eReadableStream: { mType = eReadableStream; mValue.mReadableStream.SetValue(std::move(aOther.mValue.mReadableStream.Value())); break; } case eBlob: { mType = eBlob; mValue.mBlob.SetValue(std::move(aOther.mValue.mBlob.Value())); break; } case eArrayBufferView: { mType = eArrayBufferView; mValue.mArrayBufferView.SetValue(std::move(aOther.mValue.mArrayBufferView.Value())); break; } case eArrayBuffer: { mType = eArrayBuffer; mValue.mArrayBuffer.SetValue(std::move(aOther.mValue.mArrayBuffer.Value())); break; } case eFormData: { mType = eFormData; mValue.mFormData.SetValue(std::move(aOther.mValue.mFormData.Value())); break; } case eURLSearchParams: { mType = eURLSearchParams; mValue.mURLSearchParams.SetValue(std::move(aOther.mValue.mURLSearchParams.Value())); break; } case eUSVString: { mType = eUSVString; mValue.mUSVString.SetValue(std::move(aOther.mValue.mUSVString.Value())); break; } } } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToReadableStream(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot OwningNonNull& memberSlot = RawSetAsReadableStream(); static_assert(IsRefcounted::value, "We can only store refcounted classes."); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyReadableStream(); tryNext = true; return true; } } } return true; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToReadableStream(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToReadableStream(cx, value, tryNext, passedToJSImpl); } [[nodiscard]] OwningNonNull& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsReadableStream() { if (mType == eReadableStream) { return mValue.mReadableStream.Value(); } MOZ_ASSERT(mType == eUninitialized); mType = eReadableStream; return mValue.mReadableStream.SetValue(); } [[nodiscard]] OwningNonNull& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsReadableStream() { if (mType == eReadableStream) { return mValue.mReadableStream.Value(); } Uninit(); mType = eReadableStream; return mValue.mReadableStream.SetValue(); } void OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyReadableStream() { MOZ_RELEASE_ASSERT(IsReadableStream(), "Wrong type!"); mValue.mReadableStream.Destroy(); mType = eUninitialized; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToBlob(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot OwningNonNull& memberSlot = RawSetAsBlob(); static_assert(IsRefcounted::value, "We can only store refcounted classes."); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyBlob(); tryNext = true; return true; } } } return true; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToBlob(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToBlob(cx, value, tryNext, passedToJSImpl); } [[nodiscard]] OwningNonNull& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsBlob() { if (mType == eBlob) { return mValue.mBlob.Value(); } MOZ_ASSERT(mType == eUninitialized); mType = eBlob; return mValue.mBlob.SetValue(); } [[nodiscard]] OwningNonNull& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsBlob() { if (mType == eBlob) { return mValue.mBlob.Value(); } Uninit(); mType = eBlob; return mValue.mBlob.SetValue(); } void OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyBlob() { MOZ_RELEASE_ASSERT(IsBlob(), "Wrong type!"); mValue.mBlob.Destroy(); mType = eUninitialized; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot ArrayBufferView& memberSlot = RawSetAsArrayBufferView(); if (!memberSlot.Init(&value.toObject())) { DestroyArrayBufferView(); tryNext = true; return true; } if (JS::IsArrayBufferViewShared(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBufferView branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsLargeArrayBufferView(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBufferView branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsResizableArrayBufferView(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBufferView branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsImmutableArrayBufferView(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBufferView branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } } return true; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBufferView(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl); } [[nodiscard]] ArrayBufferView& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsArrayBufferView() { if (mType == eArrayBufferView) { return mValue.mArrayBufferView.Value(); } MOZ_ASSERT(mType == eUninitialized); mType = eArrayBufferView; return mValue.mArrayBufferView.SetValue(); } [[nodiscard]] ArrayBufferView& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsArrayBufferView() { if (mType == eArrayBufferView) { return mValue.mArrayBufferView.Value(); } Uninit(); mType = eArrayBufferView; return mValue.mArrayBufferView.SetValue(); } void OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyArrayBufferView() { MOZ_RELEASE_ASSERT(IsArrayBufferView(), "Wrong type!"); mValue.mArrayBufferView.Destroy(); mType = eUninitialized; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot ArrayBuffer& memberSlot = RawSetAsArrayBuffer(); if (!memberSlot.Init(&value.toObject())) { DestroyArrayBuffer(); tryNext = true; return true; } if (JS::IsSharedArrayBufferObject(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBuffer branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBuffer branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBuffer branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } if (JS::IsImmutableArrayBufferMaybeShared(memberSlot.Obj())) { cx.ThrowErrorMessage("ArrayBuffer branch of (ReadableStream or (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString))"); return false; } } return true; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBuffer(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl); } [[nodiscard]] ArrayBuffer& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsArrayBuffer() { if (mType == eArrayBuffer) { return mValue.mArrayBuffer.Value(); } MOZ_ASSERT(mType == eUninitialized); mType = eArrayBuffer; return mValue.mArrayBuffer.SetValue(); } [[nodiscard]] ArrayBuffer& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsArrayBuffer() { if (mType == eArrayBuffer) { return mValue.mArrayBuffer.Value(); } Uninit(); mType = eArrayBuffer; return mValue.mArrayBuffer.SetValue(); } void OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyArrayBuffer() { MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!"); mValue.mArrayBuffer.Destroy(); mType = eUninitialized; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToFormData(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot OwningNonNull& memberSlot = RawSetAsFormData(); static_assert(IsRefcounted::value, "We can only store refcounted classes."); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyFormData(); tryNext = true; return true; } } } return true; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToFormData(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToFormData(cx, value, tryNext, passedToJSImpl); } [[nodiscard]] OwningNonNull& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsFormData() { if (mType == eFormData) { return mValue.mFormData.Value(); } MOZ_ASSERT(mType == eUninitialized); mType = eFormData; return mValue.mFormData.SetValue(); } [[nodiscard]] OwningNonNull& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsFormData() { if (mType == eFormData) { return mValue.mFormData.Value(); } Uninit(); mType = eFormData; return mValue.mFormData.SetValue(); } void OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyFormData() { MOZ_RELEASE_ASSERT(IsFormData(), "Wrong type!"); mValue.mFormData.Destroy(); mType = eUninitialized; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToURLSearchParams(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot OwningNonNull& memberSlot = RawSetAsURLSearchParams(); static_assert(IsRefcounted::value, "We can only store refcounted classes."); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyURLSearchParams(); tryNext = true; return true; } } } return true; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToURLSearchParams(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToURLSearchParams(cx, value, tryNext, passedToJSImpl); } [[nodiscard]] OwningNonNull& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsURLSearchParams() { if (mType == eURLSearchParams) { return mValue.mURLSearchParams.Value(); } MOZ_ASSERT(mType == eUninitialized); mType = eURLSearchParams; return mValue.mURLSearchParams.SetValue(); } [[nodiscard]] OwningNonNull& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsURLSearchParams() { if (mType == eURLSearchParams) { return mValue.mURLSearchParams.Value(); } Uninit(); mType = eURLSearchParams; return mValue.mURLSearchParams.SetValue(); } void OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyURLSearchParams() { MOZ_RELEASE_ASSERT(IsURLSearchParams(), "Wrong type!"); mValue.mURLSearchParams.Destroy(); mType = eUninitialized; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToUSVString(JSContext* cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot nsString& memberSlot = RawSetAsUSVString(); if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) { return false; } if (!NormalizeUSVString(memberSlot)) { JS_ReportOutOfMemory(cx); return false; } } return true; } [[nodiscard]] nsString& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsUSVString() { if (mType == eUSVString) { return mValue.mUSVString.Value(); } MOZ_ASSERT(mType == eUninitialized); mType = eUSVString; return mValue.mUSVString.SetValue(); } [[nodiscard]] nsString& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsUSVString() { if (mType == eUSVString) { return mValue.mUSVString.Value(); } Uninit(); mType = eUSVString; return mValue.mUSVString.SetValue(); } void OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyUSVString() { MOZ_RELEASE_ASSERT(IsUSVString(), "Wrong type!"); mValue.mUSVString.Destroy(); mType = eUninitialized; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::Init(BindingCallContext& cx, JS::Handle value, const char* sourceDescription, bool passedToJSImpl) { MOZ_ASSERT(mType == eUninitialized); bool done = false, failed = false, tryNext; if (value.isObject()) { done = (failed = !TrySetToReadableStream(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToBlob(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToFormData(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToURLSearchParams(cx, value, tryNext, passedToJSImpl)) || !tryNext; } if (!done) { do { done = (failed = !TrySetToUSVString(cx, value, tryNext)) || !tryNext; break; } while (false); } if (failed) { return false; } if (!done) { cx.ThrowErrorMessage(sourceDescription, "ReadableStream, Blob, ArrayBufferView, ArrayBuffer, FormData, URLSearchParams"); return false; } return true; } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::Init(JSContext* cx_, JS::Handle value, const char* sourceDescription, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return Init(cx, value, sourceDescription, passedToJSImpl); } void OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::Uninit() { switch (mType) { case eUninitialized: { break; } case eReadableStream: { DestroyReadableStream(); break; } case eBlob: { DestroyBlob(); break; } case eArrayBufferView: { DestroyArrayBufferView(); break; } case eArrayBuffer: { DestroyArrayBuffer(); break; } case eFormData: { DestroyFormData(); break; } case eURLSearchParams: { DestroyURLSearchParams(); break; } case eUSVString: { DestroyUSVString(); break; } } } bool OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::ToJSVal(JSContext* cx, JS::Handle scopeObj, JS::MutableHandle rval) const { switch (mType) { case eUninitialized: { return false; } case eReadableStream: { if (!GetOrCreateDOMReflector(cx, mValue.mReadableStream.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eBlob: { if (!GetOrCreateDOMReflector(cx, mValue.mBlob.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eArrayBufferView: { rval.setObject(*mValue.mArrayBufferView.Value().Obj()); if (!MaybeWrapNonDOMObjectValue(cx, rval)) { return false; } return true; } case eArrayBuffer: { rval.setObject(*mValue.mArrayBuffer.Value().Obj()); if (!MaybeWrapNonDOMObjectValue(cx, rval)) { return false; } return true; } case eFormData: { if (!GetOrCreateDOMReflector(cx, mValue.mFormData.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eURLSearchParams: { if (!GetOrCreateDOMReflector(cx, mValue.mURLSearchParams.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eUSVString: { if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) { return false; } return true; } default: { return false; } } } void OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TraceUnion(JSTracer* trc) { switch (mType) { case eArrayBufferView: { mValue.mArrayBufferView.Value().TraceSelf(trc); break; } case eArrayBuffer: { mValue.mArrayBuffer.Value().TraceSelf(trc); break; } default: { } } } OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString& OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::operator=(OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString&& aOther) { this->~OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString(); new (this) OwningReadableStreamOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString (std::move(aOther)); return *this; } } // namespace mozilla::dom