Copy as Markdown

Other Tools

#include "js/ForOfIterator.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/Blob.h"
#include "mozilla/dom/CanvasGradient.h"
#include "mozilla/dom/CanvasPattern.h"
#include "mozilla/dom/Directory.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FormData.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/dom/HTMLOptGroupElement.h"
#include "mozilla/dom/HTMLOptionElement.h"
#include "mozilla/dom/OffscreenCanvas.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/UnionTypes.h"
#include "nsGenericHTMLElement.h"
#include "nsIContent.h"
namespace mozilla::dom {
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsBlob()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsBlob(), "mBlob", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningCanvasPatternOrCanvasGradient& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsCanvasPattern()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsCanvasPattern(), "mCanvasPattern", aFlags);
} else if (aUnion.IsCanvasGradient()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsCanvasGradient(), "mCanvasGradient", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningCanvasPatternOrNullOrCanvasGradient& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsCanvasPattern()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsCanvasPattern(), "mCanvasPattern", aFlags);
} else if (aUnion.IsCanvasGradient()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsCanvasGradient(), "mCanvasGradient", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningEventHandlerNonNullOrNullOrLong& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsEventHandlerNonNull()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsEventHandlerNonNull(), "mEventHandlerNonNull", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningFileOrDirectory& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsFile()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsFile(), "mFile", aFlags);
} else if (aUnion.IsDirectory()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsDirectory(), "mDirectory", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningFileOrUSVStringOrFormData& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsFile()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsFile(), "mFile", aFlags);
} else if (aUnion.IsFormData()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsFormData(), "mFormData", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningHTMLCanvasElementOrOffscreenCanvas& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsHTMLCanvasElement()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLCanvasElement(), "mHTMLCanvasElement", aFlags);
} else if (aUnion.IsOffscreenCanvas()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsOffscreenCanvas(), "mOffscreenCanvas", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningHTMLElementOrLong& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsHTMLElement()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLElement(), "mHTMLElement", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningHTMLOptionElementOrHTMLOptGroupElement& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsHTMLOptionElement()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLOptionElement(), "mHTMLOptionElement", aFlags);
} else if (aUnion.IsHTMLOptGroupElement()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLOptGroupElement(), "mHTMLOptGroupElement", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningImageDataOrNullSequenceOrLong& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsImageDataOrNullSequence()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsImageDataOrNullSequence(), "mImageDataOrNullSequence", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningImageDataOrNullSequenceSequenceOrLong& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsImageDataOrNullSequenceSequence()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsImageDataOrNullSequenceSequence(), "mImageDataOrNullSequenceSequence", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningImageDataSequenceOrLong& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsImageDataSequence()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsImageDataSequence(), "mImageDataSequence", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningImageDataSequenceSequenceOrLong& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsImageDataSequenceSequence()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsImageDataSequenceSequence(), "mImageDataSequenceSequence", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningNodeOrLongOrBoolean& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsNode()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsNode(), "mNode", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningNodeOrString& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsNode()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsNode(), "mNode", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningUndefinedOrCanvasPattern& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsCanvasPattern()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsCanvasPattern(), "mCanvasPattern", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningUndefinedOrCanvasPatternOrNull& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsCanvasPattern()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsCanvasPattern(), "mCanvasPattern", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningUndefinedOrNullOrCanvasPattern& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsCanvasPattern()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsCanvasPattern(), "mCanvasPattern", aFlags);
}
}
void
ImplCycleCollectionUnlink(OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningCanvasPatternOrCanvasGradient& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningCanvasPatternOrNullOrCanvasGradient& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningEventHandlerNonNullOrNullOrLong& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningFileOrDirectory& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningFileOrUSVStringOrFormData& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningHTMLCanvasElementOrOffscreenCanvas& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningHTMLElementOrLong& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningHTMLOptionElementOrHTMLOptGroupElement& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningImageDataOrNullSequenceOrLong& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningImageDataOrNullSequenceSequenceOrLong& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningImageDataSequenceOrLong& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningImageDataSequenceSequenceOrLong& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningNodeOrLongOrBoolean& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningNodeOrString& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningUndefinedOrCanvasPattern& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningUndefinedOrCanvasPatternOrNull& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningUndefinedOrNullOrCanvasPattern& aUnion)
{
aUnion.Uninit();
}
bool
ArrayBufferViewOrArrayBuffer::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBufferView>& memberSlot = RawSetAsArrayBufferView(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBufferView();
tryNext = true;
return true;
}
if (JS::IsArrayBufferViewShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsLargeArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
}
return true;
}
bool
ArrayBufferViewOrArrayBuffer::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
bool
ArrayBufferViewOrArrayBuffer::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBuffer>& memberSlot = RawSetAsArrayBuffer(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBuffer();
tryNext = true;
return true;
}
if (JS::IsSharedArrayBufferObject(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
}
return true;
}
bool
ArrayBufferViewOrArrayBuffer::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
bool
ArrayBufferViewOrArrayBuffer::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 = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBufferView, ArrayBuffer");
return false;
}
return true;
}
bool
ArrayBufferViewOrArrayBuffer::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ArrayBufferViewOrArrayBuffer::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
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;
}
default: {
return false;
}
}
}
bool
ArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBufferView>& memberSlot = RawSetAsArrayBufferView(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBufferView();
tryNext = true;
return true;
}
if (JS::IsArrayBufferViewShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBufferView branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
if (JS::IsLargeArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
}
return true;
}
bool
ArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
bool
ArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBuffer>& memberSlot = RawSetAsArrayBuffer(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBuffer();
tryNext = true;
return true;
}
if (JS::IsSharedArrayBufferObject(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
}
return true;
}
bool
ArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
bool
ArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToBlob(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::Blob>& memberSlot = RawSetAsBlob();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::Blob, mozilla::dom::Blob>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyBlob();
tryNext = true;
return true;
}
}
}
return true;
}
bool
ArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToBlob(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToBlob(cx, value, tryNext, passedToJSImpl);
}
bool
ArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char>& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
ArrayBufferViewOrArrayBufferOrBlobOrUTF8String::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 = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToBlob(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBufferView, ArrayBuffer, Blob");
return false;
}
return true;
}
bool
ArrayBufferViewOrArrayBufferOrBlobOrUTF8String::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ArrayBufferViewOrArrayBufferOrBlobOrUTF8String::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
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 eBlob: {
if (!GetOrCreateDOMReflector(cx, mValue.mBlob.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
ArrayBufferViewOrArrayBufferOrNull::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBufferView>& memberSlot = RawSetAsArrayBufferView(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBufferView();
tryNext = true;
return true;
}
if (JS::IsArrayBufferViewShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
if (JS::IsLargeArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
}
return true;
}
bool
ArrayBufferViewOrArrayBufferOrNull::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
bool
ArrayBufferViewOrArrayBufferOrNull::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBuffer>& memberSlot = RawSetAsArrayBuffer(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBuffer();
tryNext = true;
return true;
}
if (JS::IsSharedArrayBufferObject(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
}
return true;
}
bool
ArrayBufferViewOrArrayBufferOrNull::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
bool
ArrayBufferViewOrArrayBufferOrNull::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBufferView, ArrayBuffer");
return false;
}
}
return true;
}
bool
ArrayBufferViewOrArrayBufferOrNull::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ArrayBufferViewOrArrayBufferOrNull::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
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;
}
default: {
return false;
}
}
}
bool
ByteStringOrLong::TrySetToByteString(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsCString& memberSlot = RawSetAsByteString();
if (!ConvertJSValueToByteString(cx, value, false, "ByteString branch of (ByteString or long)", memberSlot)) {
return false;
}
}
return true;
}
bool
ByteStringOrLong::TrySetToByteString(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToByteString(cx, value, tryNext, passedToJSImpl);
}
bool
ByteStringOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (ByteString or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ByteStringOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToByteString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
ByteStringOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ByteStringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eByteString: {
if (!NonVoidByteStringToJsval(cx, mValue.mByteString.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
CanvasPatternOrCanvasGradient::TrySetToCanvasPattern(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::CanvasPattern>& memberSlot = RawSetAsCanvasPattern();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasPattern, mozilla::dom::CanvasPattern>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasPattern();
tryNext = true;
return true;
}
}
}
return true;
}
bool
CanvasPatternOrCanvasGradient::TrySetToCanvasPattern(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl);
}
bool
CanvasPatternOrCanvasGradient::TrySetToCanvasGradient(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::CanvasGradient>& memberSlot = RawSetAsCanvasGradient();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasGradient, mozilla::dom::CanvasGradient>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasGradient();
tryNext = true;
return true;
}
}
}
return true;
}
bool
CanvasPatternOrCanvasGradient::TrySetToCanvasGradient(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasGradient(cx, value, tryNext, passedToJSImpl);
}
bool
CanvasPatternOrCanvasGradient::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 = !TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToCanvasGradient(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CanvasPattern, CanvasGradient");
return false;
}
return true;
}
bool
CanvasPatternOrCanvasGradient::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
CanvasPatternOrCanvasGradient::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eCanvasPattern: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasPattern.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eCanvasGradient: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasGradient.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
CanvasPatternOrNullOrCanvasGradient::TrySetToCanvasPattern(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::CanvasPattern>& memberSlot = RawSetAsCanvasPattern();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasPattern, mozilla::dom::CanvasPattern>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasPattern();
tryNext = true;
return true;
}
}
}
return true;
}
bool
CanvasPatternOrNullOrCanvasGradient::TrySetToCanvasPattern(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl);
}
bool
CanvasPatternOrNullOrCanvasGradient::TrySetToCanvasGradient(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::CanvasGradient>& memberSlot = RawSetAsCanvasGradient();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasGradient, mozilla::dom::CanvasGradient>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasGradient();
tryNext = true;
return true;
}
}
}
return true;
}
bool
CanvasPatternOrNullOrCanvasGradient::TrySetToCanvasGradient(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasGradient(cx, value, tryNext, passedToJSImpl);
}
bool
CanvasPatternOrNullOrCanvasGradient::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToCanvasGradient(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CanvasPattern, CanvasGradient");
return false;
}
}
return true;
}
bool
CanvasPatternOrNullOrCanvasGradient::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
CanvasPatternOrNullOrCanvasGradient::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eCanvasPattern: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasPattern.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eCanvasGradient: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasGradient.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
CustomEventInitOrLong::TrySetToCustomEventInit(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedDictionary<binding_detail::FastCustomEventInit>& memberSlot = RawSetAsCustomEventInit(cx);
if (!IsConvertibleToDictionary(value)) {
DestroyCustomEventInit();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "CustomEventInit branch of (CustomEventInit or long)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
CustomEventInitOrLong::TrySetToCustomEventInit(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCustomEventInit(cx, value, tryNext, passedToJSImpl);
}
bool
CustomEventInitOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (CustomEventInit or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
CustomEventInitOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (!done) {
done = (failed = !TrySetToCustomEventInit(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CustomEventInit");
return false;
}
return true;
}
bool
CustomEventInitOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
CustomEventInitOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eCustomEventInit: {
if (!mValue.mCustomEventInit.Value().ToObjectInternal(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
DoubleOrByteString::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double or ByteString)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double or ByteString)");
return false;
}
}
return true;
}
bool
DoubleOrByteString::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}
bool
DoubleOrByteString::TrySetToByteString(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsCString& memberSlot = RawSetAsByteString();
if (!ConvertJSValueToByteString(cx, value, false, "ByteString branch of (double or ByteString)", memberSlot)) {
return false;
}
}
return true;
}
bool
DoubleOrByteString::TrySetToByteString(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToByteString(cx, value, tryNext, passedToJSImpl);
}
bool
DoubleOrByteString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToByteString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
DoubleOrByteString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
DoubleOrByteString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eDouble: {
rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
return true;
}
case eByteString: {
if (!NonVoidByteStringToJsval(cx, mValue.mByteString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
DoubleOrString::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double or DOMString)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double or DOMString)");
return false;
}
}
return true;
}
bool
DoubleOrString::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}
bool
DoubleOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
DoubleOrString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
DoubleOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
DoubleOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eDouble: {
rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
DoubleOrSupportedType::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double or SupportedType)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double or SupportedType)");
return false;
}
}
return true;
}
bool
DoubleOrSupportedType::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}
bool
DoubleOrSupportedType::TrySetToSupportedType(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
SupportedType& memberSlot = RawSetAsSupportedType();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, value,
binding_detail::EnumStrings<SupportedType>::Values,
"SupportedType", "SupportedType branch of (double or SupportedType)",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
memberSlot = static_cast<SupportedType>(index);
}
}
return true;
}
bool
DoubleOrSupportedType::TrySetToSupportedType(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToSupportedType(cx, value, tryNext, passedToJSImpl);
}
bool
DoubleOrSupportedType::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToSupportedType(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
DoubleOrSupportedType::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
DoubleOrSupportedType::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eDouble: {
rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
return true;
}
case eSupportedType: {
if (!ToJSValue(cx, mValue.mSupportedType.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
DoubleOrUSVString::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double or USVString)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double or USVString)");
return false;
}
}
return true;
}
bool
DoubleOrUSVString::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}
bool
DoubleOrUSVString::TrySetToUSVString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsUSVString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
if (!NormalizeUSVString(memberSlot)) {
JS_ReportOutOfMemory(cx);
return false;
}
}
return true;
}
bool
DoubleOrUSVString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToUSVString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
DoubleOrUSVString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
DoubleOrUSVString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eDouble: {
rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
return true;
}
case eUSVString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
DoubleOrUTF8String::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double or USVString)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double or USVString)");
return false;
}
}
return true;
}
bool
DoubleOrUTF8String::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}
bool
DoubleOrUTF8String::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char>& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
DoubleOrUTF8String::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
DoubleOrUTF8String::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
DoubleOrUTF8String::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eDouble: {
rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
return true;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
EventHandlerNonNullOrNullOrLong::TrySetToEventHandlerNonNull(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedCallback<OwningNonNull<binding_detail::FastEventHandlerNonNull>>& memberSlot = RawSetAsEventHandlerNonNull(cx);
if (JS::IsCallable(&value.toObject())) {
{ // scope for tempRoot and tempGlobalRoot if needed
memberSlot = new binding_detail::FastEventHandlerNonNull(&value.toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
DestroyEventHandlerNonNull();
tryNext = true;
return true;
}
}
return true;
}
bool
EventHandlerNonNullOrNullOrLong::TrySetToEventHandlerNonNull(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToEventHandlerNonNull(cx, value, tryNext, passedToJSImpl);
}
bool
EventHandlerNonNullOrNullOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (EventHandlerNonNull? or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
EventHandlerNonNullOrNullOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToEventHandlerNonNull(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "EventHandlerNonNull");
return false;
}
}
return true;
}
bool
EventHandlerNonNullOrNullOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
EventHandlerNonNullOrNullOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eEventHandlerNonNull: {
rval.setObjectOrNull(GetCallbackFromCallbackObject(cx, mValue.mEventHandlerNonNull.Value()));
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
EventInitOrLong::TrySetToEventInit(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FastEventInit& memberSlot = RawSetAsEventInit();
if (!IsConvertibleToDictionary(value)) {
DestroyEventInit();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "EventInit branch of (EventInit or long)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
EventInitOrLong::TrySetToEventInit(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToEventInit(cx, value, tryNext, passedToJSImpl);
}
bool
EventInitOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (EventInit or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
EventInitOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (!done) {
done = (failed = !TrySetToEventInit(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "EventInit");
return false;
}
return true;
}
bool
EventInitOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
EventInitOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eEventInit: {
if (!mValue.mEventInit.Value().ToObjectInternal(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
EventInitOrStringSequence::TrySetToEventInit(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FastEventInit& memberSlot = RawSetAsEventInit();
if (!IsConvertibleToDictionary(value)) {
DestroyEventInit();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "EventInit branch of (EventInit or sequence<DOMString>)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
EventInitOrStringSequence::TrySetToEventInit(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToEventInit(cx, value, tryNext, passedToJSImpl);
}
bool
EventInitOrStringSequence::TrySetToStringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<nsString>& memberSlot = RawSetAsStringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyStringSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<nsString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
EventInitOrStringSequence::TrySetToStringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringSequence(cx, value, tryNext, passedToJSImpl);
}
bool
EventInitOrStringSequence::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 = !TrySetToStringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToEventInit(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<DOMString>, EventInit");
return false;
}
return true;
}
bool
EventInitOrStringSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
EventInitOrStringSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eEventInit: {
if (!mValue.mEventInit.Value().ToObjectInternal(cx, rval)) {
return false;
}
return true;
}
case eStringSequence: {
uint32_t length = mValue.mStringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
default: {
return false;
}
}
}
bool
FileOrDirectory::TrySetToFile(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::File>& memberSlot = RawSetAsFile();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::File, mozilla::dom::File>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyFile();
tryNext = true;
return true;
}
}
}
return true;
}
bool
FileOrDirectory::TrySetToFile(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToFile(cx, value, tryNext, passedToJSImpl);
}
bool
FileOrDirectory::TrySetToDirectory(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::Directory>& memberSlot = RawSetAsDirectory();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::Directory, mozilla::dom::Directory>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyDirectory();
tryNext = true;
return true;
}
}
}
return true;
}
bool
FileOrDirectory::TrySetToDirectory(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDirectory(cx, value, tryNext, passedToJSImpl);
}
bool
FileOrDirectory::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 = !TrySetToFile(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToDirectory(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "File, Directory");
return false;
}
return true;
}
bool
FileOrDirectory::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
FileOrDirectory::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eFile: {
if (!GetOrCreateDOMReflector(cx, mValue.mFile.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eDirectory: {
if (!GetOrCreateDOMReflector(cx, mValue.mDirectory.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
FileOrUSVStringOrFormData::TrySetToFile(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::File>& memberSlot = RawSetAsFile();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::File, mozilla::dom::File>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyFile();
tryNext = true;
return true;
}
}
}
return true;
}
bool
FileOrUSVStringOrFormData::TrySetToFile(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToFile(cx, value, tryNext, passedToJSImpl);
}
bool
FileOrUSVStringOrFormData::TrySetToUSVString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsUSVString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
if (!NormalizeUSVString(memberSlot)) {
JS_ReportOutOfMemory(cx);
return false;
}
}
return true;
}
bool
FileOrUSVStringOrFormData::TrySetToFormData(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::FormData>& memberSlot = RawSetAsFormData();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::FormData, mozilla::dom::FormData>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyFormData();
tryNext = true;
return true;
}
}
}
return true;
}
bool
FileOrUSVStringOrFormData::TrySetToFormData(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToFormData(cx, value, tryNext, passedToJSImpl);
}
bool
FileOrUSVStringOrFormData::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 = !TrySetToFile(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToFormData(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<MSG_NOT_IN_UNION>(sourceDescription, "File, FormData");
return false;
}
return true;
}
bool
FileOrUSVStringOrFormData::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
FileOrUSVStringOrFormData::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eFile: {
if (!GetOrCreateDOMReflector(cx, mValue.mFile.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;
}
case eFormData: {
if (!GetOrCreateDOMReflector(cx, mValue.mFormData.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
FloatOrString::TrySetToFloat(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
float& memberSlot = RawSetAsFloat();
if (!ValueToPrimitive<float, eDefault>(cx, value, "Float branch of (float or DOMString)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Float branch of (float or DOMString)");
return false;
}
}
return true;
}
bool
FloatOrString::TrySetToFloat(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToFloat(cx, value, tryNext, passedToJSImpl);
}
bool
FloatOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
FloatOrString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToFloat(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
FloatOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
FloatOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eFloat: {
rval.set(JS_NumberValue(double(mValue.mFloat.Value())));
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
HTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::HTMLCanvasElement>& memberSlot = RawSetAsHTMLCanvasElement();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLCanvasElement, mozilla::dom::HTMLCanvasElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLCanvasElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
HTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl);
}
bool
HTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::OffscreenCanvas>& memberSlot = RawSetAsOffscreenCanvas();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::OffscreenCanvas, mozilla::dom::OffscreenCanvas>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyOffscreenCanvas();
tryNext = true;
return true;
}
}
}
return true;
}
bool
HTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl);
}
bool
HTMLCanvasElementOrOffscreenCanvas::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 = !TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "HTMLCanvasElement, OffscreenCanvas");
return false;
}
return true;
}
bool
HTMLCanvasElementOrOffscreenCanvas::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
HTMLCanvasElementOrOffscreenCanvas::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eHTMLCanvasElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLCanvasElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eOffscreenCanvas: {
if (!GetOrCreateDOMReflector(cx, mValue.mOffscreenCanvas.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
HTMLElementOrLong::TrySetToHTMLElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<nsGenericHTMLElement>& memberSlot = RawSetAsHTMLElement();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLElement, nsGenericHTMLElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
HTMLElementOrLong::TrySetToHTMLElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLElement(cx, value, tryNext, passedToJSImpl);
}
bool
HTMLElementOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (HTMLElement or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
HTMLElementOrLong::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 = !TrySetToHTMLElement(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "HTMLElement");
return false;
}
return true;
}
bool
HTMLElementOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
HTMLElementOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eHTMLElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
HTMLOptionElementOrHTMLOptGroupElement::TrySetToHTMLOptionElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::HTMLOptionElement>& memberSlot = RawSetAsHTMLOptionElement();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLOptionElement, mozilla::dom::HTMLOptionElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLOptionElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
HTMLOptionElementOrHTMLOptGroupElement::TrySetToHTMLOptionElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLOptionElement(cx, value, tryNext, passedToJSImpl);
}
bool
HTMLOptionElementOrHTMLOptGroupElement::TrySetToHTMLOptGroupElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::HTMLOptGroupElement>& memberSlot = RawSetAsHTMLOptGroupElement();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLOptGroupElement, mozilla::dom::HTMLOptGroupElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLOptGroupElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
HTMLOptionElementOrHTMLOptGroupElement::TrySetToHTMLOptGroupElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLOptGroupElement(cx, value, tryNext, passedToJSImpl);
}
bool
HTMLOptionElementOrHTMLOptGroupElement::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 = !TrySetToHTMLOptionElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToHTMLOptGroupElement(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "HTMLOptionElement, HTMLOptGroupElement");
return false;
}
return true;
}
bool
HTMLOptionElementOrHTMLOptGroupElement::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
HTMLOptionElementOrHTMLOptGroupElement::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eHTMLOptionElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLOptionElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eHTMLOptGroupElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLOptGroupElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
ImageDataOrNullSequenceOrLong::TrySetToImageDataOrNullSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<RefPtr<mozilla::dom::ImageData>>& memberSlot = RawSetAsImageDataOrNullSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyImageDataOrNullSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<RefPtr<mozilla::dom::ImageData>> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
RefPtr<mozilla::dom::ImageData>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
RefPtr<mozilla::dom::ImageData>& slot = *slotPtr;
if (temp.isObject()) {
static_assert(IsRefcounted<mozilla::dom::ImageData>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ImageData, mozilla::dom::ImageData>(&temp, slot, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of sequence<ImageData?> branch of (sequence<ImageData?> or long)", "ImageData");
return false;
}
}
} else if (temp.isNullOrUndefined()) {
slot = nullptr;
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of sequence<ImageData?> branch of (sequence<ImageData?> or long)");
return false;
}
}
}
return true;
}
bool
ImageDataOrNullSequenceOrLong::TrySetToImageDataOrNullSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToImageDataOrNullSequence(cx, value, tryNext, passedToJSImpl);
}
bool
ImageDataOrNullSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<ImageData?> or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ImageDataOrNullSequenceOrLong::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 = !TrySetToImageDataOrNullSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<ImageData?>");
return false;
}
return true;
}
bool
ImageDataOrNullSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ImageDataOrNullSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eImageDataOrNullSequence: {
uint32_t length = mValue.mImageDataOrNullSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!mValue.mImageDataOrNullSequence.Value()[sequenceIdx0]) {
tmp.setNull();
break;
}
if (!WrapNewBindingNonWrapperCachedObject(cx, returnArray, mValue.mImageDataOrNullSequence.Value()[sequenceIdx0], &tmp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
ImageDataOrNullSequenceSequenceOrLong::TrySetToImageDataOrNullSequenceSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<Sequence<RefPtr<mozilla::dom::ImageData>>>& memberSlot = RawSetAsImageDataOrNullSequenceSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyImageDataOrNullSequenceSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<Sequence<RefPtr<mozilla::dom::ImageData>>> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
Sequence<RefPtr<mozilla::dom::ImageData>>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
Sequence<RefPtr<mozilla::dom::ImageData>>& slot = *slotPtr;
if (temp.isObject()) {
JS::ForOfIterator iter1(cx);
if (!iter1.init(temp, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter1.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Element of sequence<sequence<ImageData?>> branch of (sequence<sequence<ImageData?>> or long)", "sequence");
return false;
}
Sequence<RefPtr<mozilla::dom::ImageData>> &arr1 = slot;
JS::Rooted<JS::Value> temp1(cx);
while (true) {
bool done1;
if (!iter1.next(&temp1, &done1)) {
return false;
}
if (done1) {
break;
}
RefPtr<mozilla::dom::ImageData>* slotPtr1 = arr1.AppendElement(mozilla::fallible);
if (!slotPtr1) {
JS_ReportOutOfMemory(cx);
return false;
}
RefPtr<mozilla::dom::ImageData>& slot1 = *slotPtr1;
if (temp1.isObject()) {
static_assert(IsRefcounted<mozilla::dom::ImageData>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ImageData, mozilla::dom::ImageData>(&temp1, slot1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of element of sequence<sequence<ImageData?>> branch of (sequence<sequence<ImageData?>> or long)", "ImageData");
return false;
}
}
} else if (temp1.isNullOrUndefined()) {
slot1 = nullptr;
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of element of sequence<sequence<ImageData?>> branch of (sequence<sequence<ImageData?>> or long)");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Element of sequence<sequence<ImageData?>> branch of (sequence<sequence<ImageData?>> or long)", "sequence");
return false;
}
}
}
return true;
}
bool
ImageDataOrNullSequenceSequenceOrLong::TrySetToImageDataOrNullSequenceSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToImageDataOrNullSequenceSequence(cx, value, tryNext, passedToJSImpl);
}
bool
ImageDataOrNullSequenceSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<sequence<ImageData?>> or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ImageDataOrNullSequenceSequenceOrLong::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 = !TrySetToImageDataOrNullSequenceSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<sequence<ImageData?>>");
return false;
}
return true;
}
bool
ImageDataOrNullSequenceSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ImageDataOrNullSequenceSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eImageDataOrNullSequenceSequence: {
uint32_t length = mValue.mImageDataOrNullSequenceSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
uint32_t length = mValue.mImageDataOrNullSequenceSequence.Value()[sequenceIdx0].Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx1 = 0; sequenceIdx1 < length; ++sequenceIdx1) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!mValue.mImageDataOrNullSequenceSequence.Value()[sequenceIdx0][sequenceIdx1]) {
tmp.setNull();
break;
}
if (!WrapNewBindingNonWrapperCachedObject(cx, returnArray, mValue.mImageDataOrNullSequenceSequence.Value()[sequenceIdx0][sequenceIdx1], &tmp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx1, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
tmp.setObject(*returnArray);
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
ImageDataSequenceOrLong::TrySetToImageDataSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<OwningNonNull<mozilla::dom::ImageData>>& memberSlot = RawSetAsImageDataSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyImageDataSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<OwningNonNull<mozilla::dom::ImageData>> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
OwningNonNull<mozilla::dom::ImageData>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
OwningNonNull<mozilla::dom::ImageData>& slot = *slotPtr;
if (temp.isObject()) {
static_assert(IsRefcounted<mozilla::dom::ImageData>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ImageData, mozilla::dom::ImageData>(&temp, slot, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of sequence<ImageData> branch of (sequence<ImageData> or long)", "ImageData");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of sequence<ImageData> branch of (sequence<ImageData> or long)");
return false;
}
}
}
return true;
}
bool
ImageDataSequenceOrLong::TrySetToImageDataSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToImageDataSequence(cx, value, tryNext, passedToJSImpl);
}
bool
ImageDataSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<ImageData> or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ImageDataSequenceOrLong::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 = !TrySetToImageDataSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<ImageData>");
return false;
}
return true;
}
bool
ImageDataSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ImageDataSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eImageDataSequence: {
uint32_t length = mValue.mImageDataSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!WrapNewBindingNonWrapperCachedObject(cx, returnArray, mValue.mImageDataSequence.Value()[sequenceIdx0], &tmp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
ImageDataSequenceSequenceOrLong::TrySetToImageDataSequenceSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<Sequence<OwningNonNull<mozilla::dom::ImageData>>>& memberSlot = RawSetAsImageDataSequenceSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyImageDataSequenceSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<Sequence<OwningNonNull<mozilla::dom::ImageData>>> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
Sequence<OwningNonNull<mozilla::dom::ImageData>>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
Sequence<OwningNonNull<mozilla::dom::ImageData>>& slot = *slotPtr;
if (temp.isObject()) {
JS::ForOfIterator iter1(cx);
if (!iter1.init(temp, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter1.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Element of sequence<sequence<ImageData>> branch of (sequence<sequence<ImageData>> or long)", "sequence");
return false;
}
Sequence<OwningNonNull<mozilla::dom::ImageData>> &arr1 = slot;
JS::Rooted<JS::Value> temp1(cx);
while (true) {
bool done1;
if (!iter1.next(&temp1, &done1)) {
return false;
}
if (done1) {
break;
}
OwningNonNull<mozilla::dom::ImageData>* slotPtr1 = arr1.AppendElement(mozilla::fallible);
if (!slotPtr1) {
JS_ReportOutOfMemory(cx);
return false;
}
OwningNonNull<mozilla::dom::ImageData>& slot1 = *slotPtr1;
if (temp1.isObject()) {
static_assert(IsRefcounted<mozilla::dom::ImageData>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ImageData, mozilla::dom::ImageData>(&temp1, slot1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of element of sequence<sequence<ImageData>> branch of (sequence<sequence<ImageData>> or long)", "ImageData");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of element of sequence<sequence<ImageData>> branch of (sequence<sequence<ImageData>> or long)");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Element of sequence<sequence<ImageData>> branch of (sequence<sequence<ImageData>> or long)", "sequence");
return false;
}
}
}
return true;
}
bool
ImageDataSequenceSequenceOrLong::TrySetToImageDataSequenceSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToImageDataSequenceSequence(cx, value, tryNext, passedToJSImpl);
}
bool
ImageDataSequenceSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<sequence<ImageData>> or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ImageDataSequenceSequenceOrLong::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 = !TrySetToImageDataSequenceSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<sequence<ImageData>>");
return false;
}
return true;
}
bool
ImageDataSequenceSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ImageDataSequenceSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eImageDataSequenceSequence: {
uint32_t length = mValue.mImageDataSequenceSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
uint32_t length = mValue.mImageDataSequenceSequence.Value()[sequenceIdx0].Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx1 = 0; sequenceIdx1 < length; ++sequenceIdx1) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!WrapNewBindingNonWrapperCachedObject(cx, returnArray, mValue.mImageDataSequenceSequence.Value()[sequenceIdx0][sequenceIdx1], &tmp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx1, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
tmp.setObject(*returnArray);
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
LongOrBoolean::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
bool
LongOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
bool
LongOrBoolean::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
LongOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
LongOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
bool
LongOrStringAnyRecord::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (long or record<DOMString, any>)", &memberSlot)) {
return false;
}
}
return true;
}
bool
LongOrStringAnyRecord::TrySetToStringAnyRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedRecord<nsString, JS::Value>& memberSlot = RawSetAsStringAnyRecord(cx);
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, any> branch of (long or record<DOMString, any>)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, JS::Value>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
JS::Value& slot = entry->mValue;
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp)) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("value in record<DOMString, any> branch of (long or record<DOMString, any>)");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
slot = temp;
}
}
return true;
}
bool
LongOrStringAnyRecord::TrySetToStringAnyRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringAnyRecord(cx, value, tryNext, passedToJSImpl);
}
bool
LongOrStringAnyRecord::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()) {
if (!done) {
done = (failed = !TrySetToStringAnyRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "record<DOMString, any>");
return false;
}
return true;
}
bool
LongOrStringAnyRecord::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
LongOrStringAnyRecord::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
case eStringAnyRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringAnyRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
JS::ExposeValueToActiveJS(recordValue0);
tmp.set(recordValue0);
if (!MaybeWrapValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
default: {
return false;
}
}
}
bool
LongSequenceOrLong::TrySetToLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<int32_t>& memberSlot = RawSetAsLongSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyLongSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<int32_t> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
int32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
int32_t& slot = *slotPtr;
if (!ValueToPrimitive<int32_t, eDefault>(cx, temp, "Element of sequence<long> branch of (sequence<long> or long)", &slot)) {
return false;
}
}
}
return true;
}
bool
LongSequenceOrLong::TrySetToLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToLongSequence(cx, value, tryNext, passedToJSImpl);
}
bool
LongSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<long> or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
LongSequenceOrLong::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 = !TrySetToLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<long>");
return false;
}
return true;
}
bool
LongSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
LongSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eLongSequence: {
uint32_t length = mValue.mLongSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
tmp.setInt32(int32_t(mValue.mLongSequence.Value()[sequenceIdx0]));
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
LongSequenceOrNullOrLong::TrySetToLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<int32_t>& memberSlot = RawSetAsLongSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyLongSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<int32_t> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
int32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
int32_t& slot = *slotPtr;
if (!ValueToPrimitive<int32_t, eDefault>(cx, temp, "Element of sequence<long> branch of (sequence<long>? or long)", &slot)) {
return false;
}
}
}
return true;
}
bool
LongSequenceOrNullOrLong::TrySetToLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToLongSequence(cx, value, tryNext, passedToJSImpl);
}
bool
LongSequenceOrNullOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<long>? or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
LongSequenceOrNullOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<long>");
return false;
}
}
return true;
}
bool
LongSequenceOrNullOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
LongSequenceOrNullOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eLongSequence: {
uint32_t length = mValue.mLongSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
tmp.setInt32(int32_t(mValue.mLongSequence.Value()[sequenceIdx0]));
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBufferView>& memberSlot = RawSetAsArrayBufferView(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBufferView();
tryNext = true;
return true;
}
if (JS::IsLargeArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
}
return true;
}
bool
MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
bool
MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBuffer>& memberSlot = RawSetAsArrayBuffer(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBuffer();
tryNext = true;
return true;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
}
return true;
}
bool
MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
bool
MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::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 = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBufferView, ArrayBuffer");
return false;
}
return true;
}
bool
MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
MaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
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;
}
default: {
return false;
}
}
}
bool
NodeOrLongOrBoolean::TrySetToNode(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<nsINode>& memberSlot = RawSetAsNode();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::Node, nsINode>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyNode();
tryNext = true;
return true;
}
}
}
return true;
}
bool
NodeOrLongOrBoolean::TrySetToNode(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToNode(cx, value, tryNext, passedToJSImpl);
}
bool
NodeOrLongOrBoolean::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (Node or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
bool
NodeOrLongOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (Node or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
bool
NodeOrLongOrBoolean::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 = !TrySetToNode(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "Node");
return false;
}
return true;
}
bool
NodeOrLongOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
NodeOrLongOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNode: {
if (!GetOrCreateDOMReflector(cx, mValue.mNode.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
bool
NodeOrString::TrySetToNode(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<nsINode>& memberSlot = RawSetAsNode();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::Node, nsINode>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyNode();
tryNext = true;
return true;
}
}
}
return true;
}
bool
NodeOrString::TrySetToNode(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToNode(cx, value, tryNext, passedToJSImpl);
}
bool
NodeOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
NodeOrString::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 = !TrySetToNode(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "Node");
return false;
}
return true;
}
bool
NodeOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
NodeOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNode: {
if (!GetOrCreateDOMReflector(cx, mValue.mNode.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
ObjectOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (object or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrBoolean::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
ObjectOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ObjectOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
bool
ObjectOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrLong::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
ObjectOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ObjectOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
ObjectOrLongOrBoolean::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrLongOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (object or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrLongOrBoolean::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
ObjectOrLongOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ObjectOrLongOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
bool
ObjectOrLongOrNull::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object or long?)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrLongOrNull::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
}
return true;
}
bool
ObjectOrLongOrNull::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ObjectOrLongOrNull::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
ObjectOrNullOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object? or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrNullOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
}
return true;
}
bool
ObjectOrNullOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ObjectOrNullOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
ObjectOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrString::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
ObjectOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ObjectOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
ObjectOrStringOrBoolean::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrStringOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (object or DOMString or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrStringOrBoolean::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
ObjectOrStringOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ObjectOrStringOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
bool
ObjectOrStringOrLong::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrStringOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object or DOMString or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrStringOrLong::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
ObjectOrStringOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ObjectOrStringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
ObjectOrStringOrLongOrBoolean::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrStringOrLongOrBoolean::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object or DOMString or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrStringOrLongOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (object or DOMString or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectOrStringOrLongOrBoolean::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
ObjectOrStringOrLongOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ObjectOrStringOrLongOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
bool
ObjectSequenceOrLong::TrySetToObjectSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::RootedAutoSequence<JSObject*>& memberSlot = RawSetAsObjectSequence(cx);
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyObjectSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<JSObject*> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
JSObject** slotPtr = arr.AppendElement(nullptr, mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
JSObject*& slot = *slotPtr;
if (temp.isObject()) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp)) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("element of sequence<object> branch of (sequence<object> or long)");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
slot = &temp.toObject();
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of sequence<object> branch of (sequence<object> or long)");
return false;
}
}
}
return true;
}
bool
ObjectSequenceOrLong::TrySetToObjectSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToObjectSequence(cx, value, tryNext, passedToJSImpl);
}
bool
ObjectSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<object> or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
ObjectSequenceOrLong::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 = !TrySetToObjectSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<object>");
return false;
}
return true;
}
bool
ObjectSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ObjectSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObjectSequence: {
uint32_t length = mValue.mObjectSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
JS::ExposeObjectToActiveJS(mValue.mObjectSequence.Value()[sequenceIdx0]);
tmp.setObject(*mValue.mObjectSequence.Value()[sequenceIdx0]);
if (!MaybeWrapObjectValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
StringLongRecordOrLong::TrySetToStringLongRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Record<nsString, int32_t>& memberSlot = RawSetAsStringLongRecord();
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, long> branch of (record<DOMString, long> or long)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, int32_t>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
int32_t& slot = entry->mValue;
if (!ValueToPrimitive<int32_t, eDefault>(cx, temp, "Value in record<DOMString, long> branch of (record<DOMString, long> or long)", &slot)) {
return false;
}
}
}
return true;
}
bool
StringLongRecordOrLong::TrySetToStringLongRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringLongRecord(cx, value, tryNext, passedToJSImpl);
}
bool
StringLongRecordOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (record<DOMString, long> or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
StringLongRecordOrLong::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()) {
if (!done) {
done = (failed = !TrySetToStringLongRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "record<DOMString, long>");
return false;
}
return true;
}
bool
StringLongRecordOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringLongRecordOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringLongRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringLongRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
tmp.setInt32(int32_t(recordValue0));
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
StringObjectRecordOrLong::TrySetToStringObjectRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedRecord<nsString, JSObject*>& memberSlot = RawSetAsStringObjectRecord(cx);
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, object> branch of (record<DOMString, object> or long)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, JSObject*>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
JSObject*& slot = entry->mValue;
if (temp.isObject()) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp)) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("value in record<DOMString, object> branch of (record<DOMString, object> or long)");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
slot = &temp.toObject();
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Value in record<DOMString, object> branch of (record<DOMString, object> or long)");
return false;
}
}
}
return true;
}
bool
StringObjectRecordOrLong::TrySetToStringObjectRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringObjectRecord(cx, value, tryNext, passedToJSImpl);
}
bool
StringObjectRecordOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (record<DOMString, object> or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
StringObjectRecordOrLong::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()) {
if (!done) {
done = (failed = !TrySetToStringObjectRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "record<DOMString, object>");
return false;
}
return true;
}
bool
StringObjectRecordOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringObjectRecordOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringObjectRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringObjectRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
JS::ExposeObjectToActiveJS(recordValue0);
tmp.setObject(*recordValue0);
if (!MaybeWrapObjectValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
StringOrArrayBuffer::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
StringOrArrayBuffer::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBuffer>& memberSlot = RawSetAsArrayBuffer(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBuffer();
tryNext = true;
return true;
}
if (JS::IsSharedArrayBufferObject(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (DOMString or ArrayBuffer)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (DOMString or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (DOMString or ArrayBuffer)");
return false;
}
}
return true;
}
bool
StringOrArrayBuffer::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
bool
StringOrArrayBuffer::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 = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBuffer");
return false;
}
return true;
}
bool
StringOrArrayBuffer::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringOrArrayBuffer::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
StringOrBooleanOrObject::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
StringOrBooleanOrObject::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (DOMString or boolean or object)", &memberSlot)) {
return false;
}
}
return true;
}
bool
StringOrBooleanOrObject::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
StringOrBooleanOrObject::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringOrBooleanOrObject::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
StringOrLong::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
StringOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (DOMString or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
StringOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
StringOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
StringOrMaybeSharedArrayBuffer::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
StringOrMaybeSharedArrayBuffer::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBuffer>& memberSlot = RawSetAsArrayBuffer(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBuffer();
tryNext = true;
return true;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (DOMString or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (DOMString or ArrayBuffer)");
return false;
}
}
return true;
}
bool
StringOrMaybeSharedArrayBuffer::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
bool
StringOrMaybeSharedArrayBuffer::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 = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBuffer");
return false;
}
return true;
}
bool
StringOrMaybeSharedArrayBuffer::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringOrMaybeSharedArrayBuffer::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
StringOrObject::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
StringOrObject::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
StringOrObject::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringOrObject::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
StringOrStringSequence::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
StringOrStringSequence::TrySetToStringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<nsString>& memberSlot = RawSetAsStringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyStringSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<nsString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
StringOrStringSequence::TrySetToStringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringSequence(cx, value, tryNext, passedToJSImpl);
}
bool
StringOrStringSequence::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 = !TrySetToStringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<DOMString>");
return false;
}
return true;
}
bool
StringOrStringSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringOrStringSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eStringSequence: {
uint32_t length = mValue.mStringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
default: {
return false;
}
}
}
bool
StringSequenceOrEventInit::TrySetToStringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<nsString>& memberSlot = RawSetAsStringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyStringSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<nsString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
StringSequenceOrEventInit::TrySetToStringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringSequence(cx, value, tryNext, passedToJSImpl);
}
bool
StringSequenceOrEventInit::TrySetToEventInit(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FastEventInit& memberSlot = RawSetAsEventInit();
if (!IsConvertibleToDictionary(value)) {
DestroyEventInit();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "EventInit branch of (sequence<DOMString> or EventInit)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
StringSequenceOrEventInit::TrySetToEventInit(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToEventInit(cx, value, tryNext, passedToJSImpl);
}
bool
StringSequenceOrEventInit::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 = !TrySetToStringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToEventInit(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<DOMString>, EventInit");
return false;
}
return true;
}
bool
StringSequenceOrEventInit::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringSequenceOrEventInit::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringSequence: {
uint32_t length = mValue.mStringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eEventInit: {
if (!mValue.mEventInit.Value().ToObjectInternal(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
StringSequenceOrStringStringRecord::TrySetToStringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<nsString>& memberSlot = RawSetAsStringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyStringSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<nsString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
StringSequenceOrStringStringRecord::TrySetToStringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringSequence(cx, value, tryNext, passedToJSImpl);
}
bool
StringSequenceOrStringStringRecord::TrySetToStringStringRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Record<nsString, nsString>& memberSlot = RawSetAsStringStringRecord();
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, DOMString> branch of (sequence<DOMString> or record<DOMString, DOMString>)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, nsString>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
nsString& slot = entry->mValue;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
StringSequenceOrStringStringRecord::TrySetToStringStringRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl);
}
bool
StringSequenceOrStringStringRecord::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 = !TrySetToStringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
if (!done) {
done = (failed = !TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<DOMString>, record<DOMString, DOMString>");
return false;
}
return true;
}
bool
StringSequenceOrStringStringRecord::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringSequenceOrStringStringRecord::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringSequence: {
uint32_t length = mValue.mStringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eStringStringRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringStringRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
if (!xpc::NonVoidStringToJsval(cx, recordValue0, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
default: {
return false;
}
}
}
bool
StringStringRecordOrString::TrySetToStringStringRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Record<nsString, nsString>& memberSlot = RawSetAsStringStringRecord();
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, DOMString> branch of (record<DOMString, DOMString> or DOMString)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, nsString>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
nsString& slot = entry->mValue;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
StringStringRecordOrString::TrySetToStringStringRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl);
}
bool
StringStringRecordOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
StringStringRecordOrString::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()) {
if (!done) {
done = (failed = !TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (!done) {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "record<DOMString, DOMString>");
return false;
}
return true;
}
bool
StringStringRecordOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringStringRecordOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringStringRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringStringRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
if (!xpc::NonVoidStringToJsval(cx, recordValue0, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
StringStringRecordOrStringSequence::TrySetToStringStringRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Record<nsString, nsString>& memberSlot = RawSetAsStringStringRecord();
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, DOMString> branch of (record<DOMString, DOMString> or sequence<DOMString>)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, nsString>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
nsString& slot = entry->mValue;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
StringStringRecordOrStringSequence::TrySetToStringStringRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl);
}
bool
StringStringRecordOrStringSequence::TrySetToStringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<nsString>& memberSlot = RawSetAsStringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyStringSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<nsString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
StringStringRecordOrStringSequence::TrySetToStringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringSequence(cx, value, tryNext, passedToJSImpl);
}
bool
StringStringRecordOrStringSequence::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 = !TrySetToStringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
if (!done) {
done = (failed = !TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<DOMString>, record<DOMString, DOMString>");
return false;
}
return true;
}
bool
StringStringRecordOrStringSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
StringStringRecordOrStringSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringStringRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringStringRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
if (!xpc::NonVoidStringToJsval(cx, recordValue0, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
case eStringSequence: {
uint32_t length = mValue.mStringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
default: {
return false;
}
}
}
bool
SupportedTypeOrObject::TrySetToSupportedType(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
SupportedType& memberSlot = RawSetAsSupportedType();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, value,
binding_detail::EnumStrings<SupportedType>::Values,
"SupportedType", "SupportedType branch of (SupportedType or object)",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
memberSlot = static_cast<SupportedType>(index);
}
}
return true;
}
bool
SupportedTypeOrObject::TrySetToSupportedType(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToSupportedType(cx, value, tryNext, passedToJSImpl);
}
bool
SupportedTypeOrObject::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToSupportedType(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
SupportedTypeOrObject::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
SupportedTypeOrObject::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eSupportedType: {
if (!ToJSValue(cx, mValue.mSupportedType.Value(), rval)) {
return false;
}
return true;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
USVStringOrLong::TrySetToUSVString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsUSVString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
if (!NormalizeUSVString(memberSlot)) {
JS_ReportOutOfMemory(cx);
return false;
}
}
return true;
}
bool
USVStringOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (USVString or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
USVStringOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToUSVString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
USVStringOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
USVStringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUSVString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
UTF8StringOrArrayBuffer::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char>& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
UTF8StringOrArrayBuffer::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBuffer>& memberSlot = RawSetAsArrayBuffer(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBuffer();
tryNext = true;
return true;
}
if (JS::IsSharedArrayBufferObject(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (USVString or ArrayBuffer)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (USVString or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (USVString or ArrayBuffer)");
return false;
}
}
return true;
}
bool
UTF8StringOrArrayBuffer::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
bool
UTF8StringOrArrayBuffer::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 = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBuffer");
return false;
}
return true;
}
bool
UTF8StringOrArrayBuffer::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
UTF8StringOrArrayBuffer::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
UTF8StringOrArrayBufferOrNull::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char>& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
UTF8StringOrArrayBufferOrNull::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
RootedSpiderMonkeyInterface<ArrayBuffer>& memberSlot = RawSetAsArrayBuffer(cx);
if (!memberSlot.Init(&value.toObject())) {
DestroyArrayBuffer();
tryNext = true;
return true;
}
if (JS::IsSharedArrayBufferObject(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (USVString or ArrayBuffer?)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (USVString or ArrayBuffer?)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (USVString or ArrayBuffer?)");
return false;
}
}
return true;
}
bool
UTF8StringOrArrayBufferOrNull::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
bool
UTF8StringOrArrayBufferOrNull::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBuffer");
return false;
}
}
return true;
}
bool
UTF8StringOrArrayBufferOrNull::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
UTF8StringOrArrayBufferOrNull::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
UTF8StringOrLong::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char>& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
UTF8StringOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (USVString or long)", &memberSlot)) {
return false;
}
}
return true;
}
bool
UTF8StringOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
UTF8StringOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
UTF8StringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
bool
UTF8StringOrUTF8StringSequence::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char>& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
UTF8StringOrUTF8StringSequence::TrySetToUTF8StringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<nsCString>& memberSlot = RawSetAsUTF8StringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyUTF8StringSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<nsCString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsCString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsCString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
UTF8StringOrUTF8StringSequence::TrySetToUTF8StringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToUTF8StringSequence(cx, value, tryNext, passedToJSImpl);
}
bool
UTF8StringOrUTF8StringSequence::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 = !TrySetToUTF8StringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<USVString>");
return false;
}
return true;
}
bool
UTF8StringOrUTF8StringSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
UTF8StringOrUTF8StringSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
case eUTF8StringSequence: {
uint32_t length = mValue.mUTF8StringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8StringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
default: {
return false;
}
}
}
bool
UndefinedOrCanvasPattern::TrySetToCanvasPattern(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::CanvasPattern>& memberSlot = RawSetAsCanvasPattern();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasPattern, mozilla::dom::CanvasPattern>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasPattern();
tryNext = true;
return true;
}
}
}
return true;
}
bool
UndefinedOrCanvasPattern::TrySetToCanvasPattern(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl);
}
bool
UndefinedOrCanvasPattern::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isUndefined()) {
SetUndefined();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CanvasPattern");
return false;
}
}
return true;
}
bool
UndefinedOrCanvasPattern::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
UndefinedOrCanvasPattern::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUndefined: {
rval.setUndefined();
return true;
}
case eCanvasPattern: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasPattern.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
UndefinedOrCanvasPatternOrNull::TrySetToCanvasPattern(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::CanvasPattern>& memberSlot = RawSetAsCanvasPattern();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasPattern, mozilla::dom::CanvasPattern>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasPattern();
tryNext = true;
return true;
}
}
}
return true;
}
bool
UndefinedOrCanvasPatternOrNull::TrySetToCanvasPattern(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl);
}
bool
UndefinedOrCanvasPatternOrNull::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isUndefined()) {
SetUndefined();
} else if (value.isNull()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CanvasPattern");
return false;
}
}
return true;
}
bool
UndefinedOrCanvasPatternOrNull::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
UndefinedOrCanvasPatternOrNull::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eUndefined: {
rval.setUndefined();
return true;
}
case eCanvasPattern: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasPattern.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
UndefinedOrNullOrCanvasPattern::TrySetToCanvasPattern(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::CanvasPattern>& memberSlot = RawSetAsCanvasPattern();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasPattern, mozilla::dom::CanvasPattern>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasPattern();
tryNext = true;
return true;
}
}
}
return true;
}
bool
UndefinedOrNullOrCanvasPattern::TrySetToCanvasPattern(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl);
}
bool
UndefinedOrNullOrCanvasPattern::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isUndefined()) {
SetUndefined();
} else if (value.isNull()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CanvasPattern");
return false;
}
}
return true;
}
bool
UndefinedOrNullOrCanvasPattern::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
UndefinedOrNullOrCanvasPattern::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eUndefined: {
rval.setUndefined();
return true;
}
case eCanvasPattern: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasPattern.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
UnrestrictedDoubleOrString::TrySetToUnrestrictedDouble(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsUnrestrictedDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Unrestricted double branch of (unrestricted double or DOMString)", &memberSlot)) {
return false;
}
}
return true;
}
bool
UnrestrictedDoubleOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
UnrestrictedDoubleOrString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToUnrestrictedDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
UnrestrictedDoubleOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
UnrestrictedDoubleOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUnrestrictedDouble: {
rval.set(JS_NumberValue(double(mValue.mUnrestrictedDouble.Value())));
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
bool
UnrestrictedFloatOrString::TrySetToUnrestrictedFloat(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
float& memberSlot = RawSetAsUnrestrictedFloat();
if (!ValueToPrimitive<float, eDefault>(cx, value, "Unrestricted float branch of (unrestricted float or DOMString)", &memberSlot)) {
return false;
}
}
return true;
}
bool
UnrestrictedFloatOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FakeString<char16_t>& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
bool
UnrestrictedFloatOrString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToUnrestrictedFloat(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
UnrestrictedFloatOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
UnrestrictedFloatOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUnrestrictedFloat: {
rval.set(JS_NumberValue(double(mValue.mUnrestrictedFloat.Value())));
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningArrayBufferViewOrArrayBuffer::OwningArrayBufferViewOrArrayBuffer(OwningArrayBufferViewOrArrayBuffer&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
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;
}
}
}
bool
OwningArrayBufferViewOrArrayBuffer::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle<JS::Value> 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<MSG_TYPEDARRAY_IS_SHARED>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsLargeArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
}
return true;
}
bool
OwningArrayBufferViewOrArrayBuffer::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBufferView&
OwningArrayBufferViewOrArrayBuffer::RawSetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
[[nodiscard]] ArrayBufferView&
OwningArrayBufferViewOrArrayBuffer::SetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
Uninit();
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
void
OwningArrayBufferViewOrArrayBuffer::DestroyArrayBufferView()
{
MOZ_RELEASE_ASSERT(IsArrayBufferView(), "Wrong type!");
mValue.mArrayBufferView.Destroy();
mType = eUninitialized;
}
bool
OwningArrayBufferViewOrArrayBuffer::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> 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<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
}
return true;
}
bool
OwningArrayBufferViewOrArrayBuffer::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBuffer&
OwningArrayBufferViewOrArrayBuffer::RawSetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
[[nodiscard]] ArrayBuffer&
OwningArrayBufferViewOrArrayBuffer::SetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
Uninit();
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
void
OwningArrayBufferViewOrArrayBuffer::DestroyArrayBuffer()
{
MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!");
mValue.mArrayBuffer.Destroy();
mType = eUninitialized;
}
bool
OwningArrayBufferViewOrArrayBuffer::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 = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBufferView, ArrayBuffer");
return false;
}
return true;
}
bool
OwningArrayBufferViewOrArrayBuffer::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningArrayBufferViewOrArrayBuffer::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eArrayBufferView: {
DestroyArrayBufferView();
break;
}
case eArrayBuffer: {
DestroyArrayBuffer();
break;
}
}
}
bool
OwningArrayBufferViewOrArrayBuffer::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
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;
}
default: {
return false;
}
}
}
void
OwningArrayBufferViewOrArrayBuffer::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eArrayBufferView: {
mValue.mArrayBufferView.Value().TraceSelf(trc);
break;
}
case eArrayBuffer: {
mValue.mArrayBuffer.Value().TraceSelf(trc);
break;
}
default: {
}
}
}
OwningArrayBufferViewOrArrayBuffer&
OwningArrayBufferViewOrArrayBuffer::operator=(OwningArrayBufferViewOrArrayBuffer&& aOther)
{
this->~OwningArrayBufferViewOrArrayBuffer();
new (this) OwningArrayBufferViewOrArrayBuffer (std::move(aOther));
return *this;
}
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String(OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
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 eBlob: {
mType = eBlob;
mValue.mBlob.SetValue(std::move(aOther.mValue.mBlob.Value()));
break;
}
case eUTF8String: {
mType = eUTF8String;
mValue.mUTF8String.SetValue(std::move(aOther.mValue.mUTF8String.Value()));
break;
}
}
}
bool
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle<JS::Value> 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<MSG_TYPEDARRAY_IS_SHARED>("ArrayBufferView branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
if (JS::IsLargeArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
}
return true;
}
bool
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBufferView&
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::RawSetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
[[nodiscard]] ArrayBufferView&
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::SetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
Uninit();
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
void
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::DestroyArrayBufferView()
{
MOZ_RELEASE_ASSERT(IsArrayBufferView(), "Wrong type!");
mValue.mArrayBufferView.Destroy();
mType = eUninitialized;
}
bool
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> 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<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of ((ArrayBufferView or ArrayBuffer) or Blob or USVString)");
return false;
}
}
return true;
}
bool
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBuffer&
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::RawSetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
[[nodiscard]] ArrayBuffer&
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::SetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
Uninit();
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
void
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::DestroyArrayBuffer()
{
MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!");
mValue.mArrayBuffer.Destroy();
mType = eUninitialized;
}
bool
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToBlob(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::Blob>& memberSlot = RawSetAsBlob();
static_assert(IsRefcounted<mozilla::dom::Blob>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::Blob, mozilla::dom::Blob>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyBlob();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToBlob(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToBlob(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::Blob>&
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::RawSetAsBlob()
{
if (mType == eBlob) {
return mValue.mBlob.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eBlob;
return mValue.mBlob.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::Blob>&
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::SetAsBlob()
{
if (mType == eBlob) {
return mValue.mBlob.Value();
}
Uninit();
mType = eBlob;
return mValue.mBlob.SetValue();
}
void
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::DestroyBlob()
{
MOZ_RELEASE_ASSERT(IsBlob(), "Wrong type!");
mValue.mBlob.Destroy();
mType = eUninitialized;
}
bool
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsCString& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsCString&
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::RawSetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
[[nodiscard]] nsCString&
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::SetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
Uninit();
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
void
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::DestroyUTF8String()
{
MOZ_RELEASE_ASSERT(IsUTF8String(), "Wrong type!");
mValue.mUTF8String.Destroy();
mType = eUninitialized;
}
bool
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::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 = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToBlob(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBufferView, ArrayBuffer, Blob");
return false;
}
return true;
}
bool
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eArrayBufferView: {
DestroyArrayBufferView();
break;
}
case eArrayBuffer: {
DestroyArrayBuffer();
break;
}
case eBlob: {
DestroyBlob();
break;
}
case eUTF8String: {
DestroyUTF8String();
break;
}
}
}
bool
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
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 eBlob: {
if (!GetOrCreateDOMReflector(cx, mValue.mBlob.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
void
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eArrayBufferView: {
mValue.mArrayBufferView.Value().TraceSelf(trc);
break;
}
case eArrayBuffer: {
mValue.mArrayBuffer.Value().TraceSelf(trc);
break;
}
default: {
}
}
}
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String&
OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String::operator=(OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String&& aOther)
{
this->~OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String();
new (this) OwningArrayBufferViewOrArrayBufferOrBlobOrUTF8String (std::move(aOther));
return *this;
}
OwningArrayBufferViewOrArrayBufferOrNull::OwningArrayBufferViewOrArrayBufferOrNull(OwningArrayBufferViewOrArrayBufferOrNull&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
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;
}
}
}
bool
OwningArrayBufferViewOrArrayBufferOrNull::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle<JS::Value> 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<MSG_TYPEDARRAY_IS_SHARED>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
if (JS::IsLargeArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
}
return true;
}
bool
OwningArrayBufferViewOrArrayBufferOrNull::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBufferView&
OwningArrayBufferViewOrArrayBufferOrNull::RawSetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
[[nodiscard]] ArrayBufferView&
OwningArrayBufferViewOrArrayBufferOrNull::SetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
Uninit();
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
void
OwningArrayBufferViewOrArrayBufferOrNull::DestroyArrayBufferView()
{
MOZ_RELEASE_ASSERT(IsArrayBufferView(), "Wrong type!");
mValue.mArrayBufferView.Destroy();
mType = eUninitialized;
}
bool
OwningArrayBufferViewOrArrayBufferOrNull::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> 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<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer?)");
return false;
}
}
return true;
}
bool
OwningArrayBufferViewOrArrayBufferOrNull::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBuffer&
OwningArrayBufferViewOrArrayBufferOrNull::RawSetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
[[nodiscard]] ArrayBuffer&
OwningArrayBufferViewOrArrayBufferOrNull::SetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
Uninit();
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
void
OwningArrayBufferViewOrArrayBufferOrNull::DestroyArrayBuffer()
{
MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!");
mValue.mArrayBuffer.Destroy();
mType = eUninitialized;
}
bool
OwningArrayBufferViewOrArrayBufferOrNull::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBufferView, ArrayBuffer");
return false;
}
}
return true;
}
bool
OwningArrayBufferViewOrArrayBufferOrNull::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningArrayBufferViewOrArrayBufferOrNull::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eNull: {
break;
}
case eArrayBufferView: {
DestroyArrayBufferView();
break;
}
case eArrayBuffer: {
DestroyArrayBuffer();
break;
}
}
}
bool
OwningArrayBufferViewOrArrayBufferOrNull::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
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;
}
default: {
return false;
}
}
}
void
OwningArrayBufferViewOrArrayBufferOrNull::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eArrayBufferView: {
mValue.mArrayBufferView.Value().TraceSelf(trc);
break;
}
case eArrayBuffer: {
mValue.mArrayBuffer.Value().TraceSelf(trc);
break;
}
default: {
}
}
}
OwningArrayBufferViewOrArrayBufferOrNull&
OwningArrayBufferViewOrArrayBufferOrNull::operator=(OwningArrayBufferViewOrArrayBufferOrNull&& aOther)
{
this->~OwningArrayBufferViewOrArrayBufferOrNull();
new (this) OwningArrayBufferViewOrArrayBufferOrNull (std::move(aOther));
return *this;
}
OwningByteStringOrLong::OwningByteStringOrLong(OwningByteStringOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eByteString: {
mType = eByteString;
mValue.mByteString.SetValue(std::move(aOther.mValue.mByteString.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningByteStringOrLong::TrySetToByteString(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsCString& memberSlot = RawSetAsByteString();
if (!ConvertJSValueToByteString(cx, value, false, "ByteString branch of (ByteString or long)", memberSlot)) {
return false;
}
}
return true;
}
bool
OwningByteStringOrLong::TrySetToByteString(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToByteString(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] nsCString&
OwningByteStringOrLong::RawSetAsByteString()
{
if (mType == eByteString) {
return mValue.mByteString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eByteString;
return mValue.mByteString.SetValue();
}
[[nodiscard]] nsCString&
OwningByteStringOrLong::SetAsByteString()
{
if (mType == eByteString) {
return mValue.mByteString.Value();
}
Uninit();
mType = eByteString;
return mValue.mByteString.SetValue();
}
void
OwningByteStringOrLong::DestroyByteString()
{
MOZ_RELEASE_ASSERT(IsByteString(), "Wrong type!");
mValue.mByteString.Destroy();
mType = eUninitialized;
}
bool
OwningByteStringOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (ByteString or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningByteStringOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningByteStringOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningByteStringOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningByteStringOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToByteString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningByteStringOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningByteStringOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eByteString: {
DestroyByteString();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningByteStringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eByteString: {
if (!NonVoidByteStringToJsval(cx, mValue.mByteString.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningByteStringOrLong&
OwningByteStringOrLong::operator=(OwningByteStringOrLong&& aOther)
{
this->~OwningByteStringOrLong();
new (this) OwningByteStringOrLong (std::move(aOther));
return *this;
}
OwningByteStringOrLong&
OwningByteStringOrLong::operator=(const OwningByteStringOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eByteString: {
SetAsByteString() = aOther.GetAsByteString();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningCanvasPatternOrCanvasGradient::OwningCanvasPatternOrCanvasGradient(OwningCanvasPatternOrCanvasGradient&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eCanvasPattern: {
mType = eCanvasPattern;
mValue.mCanvasPattern.SetValue(std::move(aOther.mValue.mCanvasPattern.Value()));
break;
}
case eCanvasGradient: {
mType = eCanvasGradient;
mValue.mCanvasGradient.SetValue(std::move(aOther.mValue.mCanvasGradient.Value()));
break;
}
}
}
bool
OwningCanvasPatternOrCanvasGradient::TrySetToCanvasPattern(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::CanvasPattern>& memberSlot = RawSetAsCanvasPattern();
static_assert(IsRefcounted<mozilla::dom::CanvasPattern>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasPattern, mozilla::dom::CanvasPattern>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasPattern();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningCanvasPatternOrCanvasGradient::TrySetToCanvasPattern(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasPattern>&
OwningCanvasPatternOrCanvasGradient::RawSetAsCanvasPattern()
{
if (mType == eCanvasPattern) {
return mValue.mCanvasPattern.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eCanvasPattern;
return mValue.mCanvasPattern.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasPattern>&
OwningCanvasPatternOrCanvasGradient::SetAsCanvasPattern()
{
if (mType == eCanvasPattern) {
return mValue.mCanvasPattern.Value();
}
Uninit();
mType = eCanvasPattern;
return mValue.mCanvasPattern.SetValue();
}
void
OwningCanvasPatternOrCanvasGradient::DestroyCanvasPattern()
{
MOZ_RELEASE_ASSERT(IsCanvasPattern(), "Wrong type!");
mValue.mCanvasPattern.Destroy();
mType = eUninitialized;
}
bool
OwningCanvasPatternOrCanvasGradient::TrySetToCanvasGradient(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::CanvasGradient>& memberSlot = RawSetAsCanvasGradient();
static_assert(IsRefcounted<mozilla::dom::CanvasGradient>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasGradient, mozilla::dom::CanvasGradient>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasGradient();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningCanvasPatternOrCanvasGradient::TrySetToCanvasGradient(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasGradient(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasGradient>&
OwningCanvasPatternOrCanvasGradient::RawSetAsCanvasGradient()
{
if (mType == eCanvasGradient) {
return mValue.mCanvasGradient.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eCanvasGradient;
return mValue.mCanvasGradient.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasGradient>&
OwningCanvasPatternOrCanvasGradient::SetAsCanvasGradient()
{
if (mType == eCanvasGradient) {
return mValue.mCanvasGradient.Value();
}
Uninit();
mType = eCanvasGradient;
return mValue.mCanvasGradient.SetValue();
}
void
OwningCanvasPatternOrCanvasGradient::DestroyCanvasGradient()
{
MOZ_RELEASE_ASSERT(IsCanvasGradient(), "Wrong type!");
mValue.mCanvasGradient.Destroy();
mType = eUninitialized;
}
bool
OwningCanvasPatternOrCanvasGradient::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 = !TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToCanvasGradient(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CanvasPattern, CanvasGradient");
return false;
}
return true;
}
bool
OwningCanvasPatternOrCanvasGradient::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningCanvasPatternOrCanvasGradient::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eCanvasPattern: {
DestroyCanvasPattern();
break;
}
case eCanvasGradient: {
DestroyCanvasGradient();
break;
}
}
}
bool
OwningCanvasPatternOrCanvasGradient::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eCanvasPattern: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasPattern.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eCanvasGradient: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasGradient.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningCanvasPatternOrCanvasGradient&
OwningCanvasPatternOrCanvasGradient::operator=(OwningCanvasPatternOrCanvasGradient&& aOther)
{
this->~OwningCanvasPatternOrCanvasGradient();
new (this) OwningCanvasPatternOrCanvasGradient (std::move(aOther));
return *this;
}
OwningCanvasPatternOrCanvasGradient&
OwningCanvasPatternOrCanvasGradient::operator=(const OwningCanvasPatternOrCanvasGradient& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eCanvasPattern: {
SetAsCanvasPattern() = aOther.GetAsCanvasPattern();
break;
}
case eCanvasGradient: {
SetAsCanvasGradient() = aOther.GetAsCanvasGradient();
break;
}
}
return *this;
}
OwningCanvasPatternOrNullOrCanvasGradient::OwningCanvasPatternOrNullOrCanvasGradient(OwningCanvasPatternOrNullOrCanvasGradient&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eCanvasPattern: {
mType = eCanvasPattern;
mValue.mCanvasPattern.SetValue(std::move(aOther.mValue.mCanvasPattern.Value()));
break;
}
case eCanvasGradient: {
mType = eCanvasGradient;
mValue.mCanvasGradient.SetValue(std::move(aOther.mValue.mCanvasGradient.Value()));
break;
}
}
}
bool
OwningCanvasPatternOrNullOrCanvasGradient::TrySetToCanvasPattern(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::CanvasPattern>& memberSlot = RawSetAsCanvasPattern();
static_assert(IsRefcounted<mozilla::dom::CanvasPattern>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasPattern, mozilla::dom::CanvasPattern>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasPattern();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningCanvasPatternOrNullOrCanvasGradient::TrySetToCanvasPattern(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasPattern>&
OwningCanvasPatternOrNullOrCanvasGradient::RawSetAsCanvasPattern()
{
if (mType == eCanvasPattern) {
return mValue.mCanvasPattern.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eCanvasPattern;
return mValue.mCanvasPattern.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasPattern>&
OwningCanvasPatternOrNullOrCanvasGradient::SetAsCanvasPattern()
{
if (mType == eCanvasPattern) {
return mValue.mCanvasPattern.Value();
}
Uninit();
mType = eCanvasPattern;
return mValue.mCanvasPattern.SetValue();
}
void
OwningCanvasPatternOrNullOrCanvasGradient::DestroyCanvasPattern()
{
MOZ_RELEASE_ASSERT(IsCanvasPattern(), "Wrong type!");
mValue.mCanvasPattern.Destroy();
mType = eUninitialized;
}
bool
OwningCanvasPatternOrNullOrCanvasGradient::TrySetToCanvasGradient(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::CanvasGradient>& memberSlot = RawSetAsCanvasGradient();
static_assert(IsRefcounted<mozilla::dom::CanvasGradient>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasGradient, mozilla::dom::CanvasGradient>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasGradient();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningCanvasPatternOrNullOrCanvasGradient::TrySetToCanvasGradient(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasGradient(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasGradient>&
OwningCanvasPatternOrNullOrCanvasGradient::RawSetAsCanvasGradient()
{
if (mType == eCanvasGradient) {
return mValue.mCanvasGradient.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eCanvasGradient;
return mValue.mCanvasGradient.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasGradient>&
OwningCanvasPatternOrNullOrCanvasGradient::SetAsCanvasGradient()
{
if (mType == eCanvasGradient) {
return mValue.mCanvasGradient.Value();
}
Uninit();
mType = eCanvasGradient;
return mValue.mCanvasGradient.SetValue();
}
void
OwningCanvasPatternOrNullOrCanvasGradient::DestroyCanvasGradient()
{
MOZ_RELEASE_ASSERT(IsCanvasGradient(), "Wrong type!");
mValue.mCanvasGradient.Destroy();
mType = eUninitialized;
}
bool
OwningCanvasPatternOrNullOrCanvasGradient::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToCanvasGradient(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CanvasPattern, CanvasGradient");
return false;
}
}
return true;
}
bool
OwningCanvasPatternOrNullOrCanvasGradient::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningCanvasPatternOrNullOrCanvasGradient::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eNull: {
break;
}
case eCanvasPattern: {
DestroyCanvasPattern();
break;
}
case eCanvasGradient: {
DestroyCanvasGradient();
break;
}
}
}
bool
OwningCanvasPatternOrNullOrCanvasGradient::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eCanvasPattern: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasPattern.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eCanvasGradient: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasGradient.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningCanvasPatternOrNullOrCanvasGradient&
OwningCanvasPatternOrNullOrCanvasGradient::operator=(OwningCanvasPatternOrNullOrCanvasGradient&& aOther)
{
this->~OwningCanvasPatternOrNullOrCanvasGradient();
new (this) OwningCanvasPatternOrNullOrCanvasGradient (std::move(aOther));
return *this;
}
OwningCanvasPatternOrNullOrCanvasGradient&
OwningCanvasPatternOrNullOrCanvasGradient::operator=(const OwningCanvasPatternOrNullOrCanvasGradient& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eCanvasPattern: {
SetAsCanvasPattern() = aOther.GetAsCanvasPattern();
break;
}
case eCanvasGradient: {
SetAsCanvasGradient() = aOther.GetAsCanvasGradient();
break;
}
}
return *this;
}
OwningCustomEventInitOrLong::OwningCustomEventInitOrLong(OwningCustomEventInitOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eCustomEventInit: {
mType = eCustomEventInit;
mValue.mCustomEventInit.SetValue(std::move(aOther.mValue.mCustomEventInit.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningCustomEventInitOrLong::TrySetToCustomEventInit(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
CustomEventInit& memberSlot = RawSetAsCustomEventInit();
if (!IsConvertibleToDictionary(value)) {
DestroyCustomEventInit();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "CustomEventInit branch of (CustomEventInit or long)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
OwningCustomEventInitOrLong::TrySetToCustomEventInit(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCustomEventInit(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] CustomEventInit&
OwningCustomEventInitOrLong::RawSetAsCustomEventInit()
{
if (mType == eCustomEventInit) {
return mValue.mCustomEventInit.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eCustomEventInit;
return mValue.mCustomEventInit.SetValue();
}
[[nodiscard]] CustomEventInit&
OwningCustomEventInitOrLong::SetAsCustomEventInit()
{
if (mType == eCustomEventInit) {
return mValue.mCustomEventInit.Value();
}
Uninit();
mType = eCustomEventInit;
return mValue.mCustomEventInit.SetValue();
}
void
OwningCustomEventInitOrLong::DestroyCustomEventInit()
{
MOZ_RELEASE_ASSERT(IsCustomEventInit(), "Wrong type!");
mValue.mCustomEventInit.Destroy();
mType = eUninitialized;
}
bool
OwningCustomEventInitOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (CustomEventInit or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningCustomEventInitOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningCustomEventInitOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningCustomEventInitOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningCustomEventInitOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (!done) {
done = (failed = !TrySetToCustomEventInit(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CustomEventInit");
return false;
}
return true;
}
bool
OwningCustomEventInitOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningCustomEventInitOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eCustomEventInit: {
DestroyCustomEventInit();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningCustomEventInitOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eCustomEventInit: {
if (!mValue.mCustomEventInit.Value().ToObjectInternal(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
void
OwningCustomEventInitOrLong::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eCustomEventInit: {
mValue.mCustomEventInit.Value().TraceDictionary(trc);
break;
}
default: {
}
}
}
OwningCustomEventInitOrLong&
OwningCustomEventInitOrLong::operator=(OwningCustomEventInitOrLong&& aOther)
{
this->~OwningCustomEventInitOrLong();
new (this) OwningCustomEventInitOrLong (std::move(aOther));
return *this;
}
OwningDoubleOrByteString::OwningDoubleOrByteString(OwningDoubleOrByteString&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDouble: {
mType = eDouble;
mValue.mDouble.SetValue(std::move(aOther.mValue.mDouble.Value()));
break;
}
case eByteString: {
mType = eByteString;
mValue.mByteString.SetValue(std::move(aOther.mValue.mByteString.Value()));
break;
}
}
}
bool
OwningDoubleOrByteString::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double or ByteString)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double or ByteString)");
return false;
}
}
return true;
}
bool
OwningDoubleOrByteString::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] double&
OwningDoubleOrByteString::RawSetAsDouble()
{
if (mType == eDouble) {
return mValue.mDouble.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eDouble;
return mValue.mDouble.SetValue();
}
[[nodiscard]] double&
OwningDoubleOrByteString::SetAsDouble()
{
if (mType == eDouble) {
return mValue.mDouble.Value();
}
Uninit();
mType = eDouble;
return mValue.mDouble.SetValue();
}
void
OwningDoubleOrByteString::DestroyDouble()
{
MOZ_RELEASE_ASSERT(IsDouble(), "Wrong type!");
mValue.mDouble.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleOrByteString::TrySetToByteString(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsCString& memberSlot = RawSetAsByteString();
if (!ConvertJSValueToByteString(cx, value, false, "ByteString branch of (double or ByteString)", memberSlot)) {
return false;
}
}
return true;
}
bool
OwningDoubleOrByteString::TrySetToByteString(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToByteString(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] nsCString&
OwningDoubleOrByteString::RawSetAsByteString()
{
if (mType == eByteString) {
return mValue.mByteString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eByteString;
return mValue.mByteString.SetValue();
}
[[nodiscard]] nsCString&
OwningDoubleOrByteString::SetAsByteString()
{
if (mType == eByteString) {
return mValue.mByteString.Value();
}
Uninit();
mType = eByteString;
return mValue.mByteString.SetValue();
}
void
OwningDoubleOrByteString::DestroyByteString()
{
MOZ_RELEASE_ASSERT(IsByteString(), "Wrong type!");
mValue.mByteString.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleOrByteString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToByteString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningDoubleOrByteString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningDoubleOrByteString::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eDouble: {
DestroyDouble();
break;
}
case eByteString: {
DestroyByteString();
break;
}
}
}
bool
OwningDoubleOrByteString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eDouble: {
rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
return true;
}
case eByteString: {
if (!NonVoidByteStringToJsval(cx, mValue.mByteString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningDoubleOrByteString&
OwningDoubleOrByteString::operator=(OwningDoubleOrByteString&& aOther)
{
this->~OwningDoubleOrByteString();
new (this) OwningDoubleOrByteString (std::move(aOther));
return *this;
}
OwningDoubleOrByteString&
OwningDoubleOrByteString::operator=(const OwningDoubleOrByteString& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDouble: {
SetAsDouble() = aOther.GetAsDouble();
break;
}
case eByteString: {
SetAsByteString() = aOther.GetAsByteString();
break;
}
}
return *this;
}
OwningDoubleOrString::OwningDoubleOrString(OwningDoubleOrString&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDouble: {
mType = eDouble;
mValue.mDouble.SetValue(std::move(aOther.mValue.mDouble.Value()));
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
}
}
bool
OwningDoubleOrString::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double or DOMString)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double or DOMString)");
return false;
}
}
return true;
}
bool
OwningDoubleOrString::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] double&
OwningDoubleOrString::RawSetAsDouble()
{
if (mType == eDouble) {
return mValue.mDouble.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eDouble;
return mValue.mDouble.SetValue();
}
[[nodiscard]] double&
OwningDoubleOrString::SetAsDouble()
{
if (mType == eDouble) {
return mValue.mDouble.Value();
}
Uninit();
mType = eDouble;
return mValue.mDouble.SetValue();
}
void
OwningDoubleOrString::DestroyDouble()
{
MOZ_RELEASE_ASSERT(IsDouble(), "Wrong type!");
mValue.mDouble.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningDoubleOrString::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningDoubleOrString::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningDoubleOrString::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleOrString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningDoubleOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningDoubleOrString::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eDouble: {
DestroyDouble();
break;
}
case eString: {
DestroyString();
break;
}
}
}
bool
OwningDoubleOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eDouble: {
rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningDoubleOrString&
OwningDoubleOrString::operator=(OwningDoubleOrString&& aOther)
{
this->~OwningDoubleOrString();
new (this) OwningDoubleOrString (std::move(aOther));
return *this;
}
OwningDoubleOrString&
OwningDoubleOrString::operator=(const OwningDoubleOrString& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDouble: {
SetAsDouble() = aOther.GetAsDouble();
break;
}
case eString: {
SetAsString() = aOther.GetAsString();
break;
}
}
return *this;
}
OwningDoubleOrSupportedType::OwningDoubleOrSupportedType(OwningDoubleOrSupportedType&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDouble: {
mType = eDouble;
mValue.mDouble.SetValue(std::move(aOther.mValue.mDouble.Value()));
break;
}
case eSupportedType: {
mType = eSupportedType;
mValue.mSupportedType.SetValue(std::move(aOther.mValue.mSupportedType.Value()));
break;
}
}
}
bool
OwningDoubleOrSupportedType::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double or SupportedType)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double or SupportedType)");
return false;
}
}
return true;
}
bool
OwningDoubleOrSupportedType::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] double&
OwningDoubleOrSupportedType::RawSetAsDouble()
{
if (mType == eDouble) {
return mValue.mDouble.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eDouble;
return mValue.mDouble.SetValue();
}
[[nodiscard]] double&
OwningDoubleOrSupportedType::SetAsDouble()
{
if (mType == eDouble) {
return mValue.mDouble.Value();
}
Uninit();
mType = eDouble;
return mValue.mDouble.SetValue();
}
void
OwningDoubleOrSupportedType::DestroyDouble()
{
MOZ_RELEASE_ASSERT(IsDouble(), "Wrong type!");
mValue.mDouble.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleOrSupportedType::TrySetToSupportedType(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
SupportedType& memberSlot = RawSetAsSupportedType();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, value,
binding_detail::EnumStrings<SupportedType>::Values,
"SupportedType", "SupportedType branch of (double or SupportedType)",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
memberSlot = static_cast<SupportedType>(index);
}
}
return true;
}
bool
OwningDoubleOrSupportedType::TrySetToSupportedType(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToSupportedType(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] SupportedType&
OwningDoubleOrSupportedType::RawSetAsSupportedType()
{
if (mType == eSupportedType) {
return mValue.mSupportedType.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eSupportedType;
return mValue.mSupportedType.SetValue();
}
[[nodiscard]] SupportedType&
OwningDoubleOrSupportedType::SetAsSupportedType()
{
if (mType == eSupportedType) {
return mValue.mSupportedType.Value();
}
Uninit();
mType = eSupportedType;
return mValue.mSupportedType.SetValue();
}
void
OwningDoubleOrSupportedType::DestroySupportedType()
{
MOZ_RELEASE_ASSERT(IsSupportedType(), "Wrong type!");
mValue.mSupportedType.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleOrSupportedType::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToSupportedType(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningDoubleOrSupportedType::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningDoubleOrSupportedType::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eDouble: {
DestroyDouble();
break;
}
case eSupportedType: {
DestroySupportedType();
break;
}
}
}
bool
OwningDoubleOrSupportedType::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eDouble: {
rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
return true;
}
case eSupportedType: {
if (!ToJSValue(cx, mValue.mSupportedType.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningDoubleOrSupportedType&
OwningDoubleOrSupportedType::operator=(OwningDoubleOrSupportedType&& aOther)
{
this->~OwningDoubleOrSupportedType();
new (this) OwningDoubleOrSupportedType (std::move(aOther));
return *this;
}
OwningDoubleOrSupportedType&
OwningDoubleOrSupportedType::operator=(const OwningDoubleOrSupportedType& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDouble: {
SetAsDouble() = aOther.GetAsDouble();
break;
}
case eSupportedType: {
SetAsSupportedType() = aOther.GetAsSupportedType();
break;
}
}
return *this;
}
OwningDoubleOrUSVString::OwningDoubleOrUSVString(OwningDoubleOrUSVString&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDouble: {
mType = eDouble;
mValue.mDouble.SetValue(std::move(aOther.mValue.mDouble.Value()));
break;
}
case eUSVString: {
mType = eUSVString;
mValue.mUSVString.SetValue(std::move(aOther.mValue.mUSVString.Value()));
break;
}
}
}
bool
OwningDoubleOrUSVString::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double or USVString)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double or USVString)");
return false;
}
}
return true;
}
bool
OwningDoubleOrUSVString::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] double&
OwningDoubleOrUSVString::RawSetAsDouble()
{
if (mType == eDouble) {
return mValue.mDouble.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eDouble;
return mValue.mDouble.SetValue();
}
[[nodiscard]] double&
OwningDoubleOrUSVString::SetAsDouble()
{
if (mType == eDouble) {
return mValue.mDouble.Value();
}
Uninit();
mType = eDouble;
return mValue.mDouble.SetValue();
}
void
OwningDoubleOrUSVString::DestroyDouble()
{
MOZ_RELEASE_ASSERT(IsDouble(), "Wrong type!");
mValue.mDouble.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleOrUSVString::TrySetToUSVString(JSContext* cx, JS::Handle<JS::Value> 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&
OwningDoubleOrUSVString::RawSetAsUSVString()
{
if (mType == eUSVString) {
return mValue.mUSVString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUSVString;
return mValue.mUSVString.SetValue();
}
[[nodiscard]] nsString&
OwningDoubleOrUSVString::SetAsUSVString()
{
if (mType == eUSVString) {
return mValue.mUSVString.Value();
}
Uninit();
mType = eUSVString;
return mValue.mUSVString.SetValue();
}
void
OwningDoubleOrUSVString::DestroyUSVString()
{
MOZ_RELEASE_ASSERT(IsUSVString(), "Wrong type!");
mValue.mUSVString.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleOrUSVString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToUSVString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningDoubleOrUSVString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningDoubleOrUSVString::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eDouble: {
DestroyDouble();
break;
}
case eUSVString: {
DestroyUSVString();
break;
}
}
}
bool
OwningDoubleOrUSVString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eDouble: {
rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
return true;
}
case eUSVString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningDoubleOrUSVString&
OwningDoubleOrUSVString::operator=(OwningDoubleOrUSVString&& aOther)
{
this->~OwningDoubleOrUSVString();
new (this) OwningDoubleOrUSVString (std::move(aOther));
return *this;
}
OwningDoubleOrUSVString&
OwningDoubleOrUSVString::operator=(const OwningDoubleOrUSVString& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDouble: {
SetAsDouble() = aOther.GetAsDouble();
break;
}
case eUSVString: {
SetAsUSVString() = aOther.GetAsUSVString();
break;
}
}
return *this;
}
OwningDoubleOrUTF8String::OwningDoubleOrUTF8String(OwningDoubleOrUTF8String&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDouble: {
mType = eDouble;
mValue.mDouble.SetValue(std::move(aOther.mValue.mDouble.Value()));
break;
}
case eUTF8String: {
mType = eUTF8String;
mValue.mUTF8String.SetValue(std::move(aOther.mValue.mUTF8String.Value()));
break;
}
}
}
bool
OwningDoubleOrUTF8String::TrySetToDouble(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Double branch of (double or USVString)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Double branch of (double or USVString)");
return false;
}
}
return true;
}
bool
OwningDoubleOrUTF8String::TrySetToDouble(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDouble(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] double&
OwningDoubleOrUTF8String::RawSetAsDouble()
{
if (mType == eDouble) {
return mValue.mDouble.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eDouble;
return mValue.mDouble.SetValue();
}
[[nodiscard]] double&
OwningDoubleOrUTF8String::SetAsDouble()
{
if (mType == eDouble) {
return mValue.mDouble.Value();
}
Uninit();
mType = eDouble;
return mValue.mDouble.SetValue();
}
void
OwningDoubleOrUTF8String::DestroyDouble()
{
MOZ_RELEASE_ASSERT(IsDouble(), "Wrong type!");
mValue.mDouble.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleOrUTF8String::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsCString& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsCString&
OwningDoubleOrUTF8String::RawSetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
[[nodiscard]] nsCString&
OwningDoubleOrUTF8String::SetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
Uninit();
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
void
OwningDoubleOrUTF8String::DestroyUTF8String()
{
MOZ_RELEASE_ASSERT(IsUTF8String(), "Wrong type!");
mValue.mUTF8String.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleOrUTF8String::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningDoubleOrUTF8String::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningDoubleOrUTF8String::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eDouble: {
DestroyDouble();
break;
}
case eUTF8String: {
DestroyUTF8String();
break;
}
}
}
bool
OwningDoubleOrUTF8String::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eDouble: {
rval.set(JS_NumberValue(double(mValue.mDouble.Value())));
return true;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningDoubleOrUTF8String&
OwningDoubleOrUTF8String::operator=(OwningDoubleOrUTF8String&& aOther)
{
this->~OwningDoubleOrUTF8String();
new (this) OwningDoubleOrUTF8String (std::move(aOther));
return *this;
}
OwningDoubleOrUTF8String&
OwningDoubleOrUTF8String::operator=(const OwningDoubleOrUTF8String& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDouble: {
SetAsDouble() = aOther.GetAsDouble();
break;
}
case eUTF8String: {
SetAsUTF8String() = aOther.GetAsUTF8String();
break;
}
}
return *this;
}
OwningEventHandlerNonNullOrNullOrLong::OwningEventHandlerNonNullOrNullOrLong(OwningEventHandlerNonNullOrNullOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eEventHandlerNonNull: {
mType = eEventHandlerNonNull;
mValue.mEventHandlerNonNull.SetValue(std::move(aOther.mValue.mEventHandlerNonNull.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningEventHandlerNonNullOrNullOrLong::TrySetToEventHandlerNonNull(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<EventHandlerNonNull>& memberSlot = RawSetAsEventHandlerNonNull();
if (JS::IsCallable(&value.toObject())) {
{ // scope for tempRoot and tempGlobalRoot if needed
JS::Rooted<JSObject*> tempRoot(cx, &value.toObject());
JS::Rooted<JSObject*> tempGlobalRoot(cx, JS::CurrentGlobalOrNull(cx));
memberSlot = new EventHandlerNonNull(cx, tempRoot, tempGlobalRoot, GetIncumbentGlobal());
}
} else {
DestroyEventHandlerNonNull();
tryNext = true;
return true;
}
}
return true;
}
bool
OwningEventHandlerNonNullOrNullOrLong::TrySetToEventHandlerNonNull(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToEventHandlerNonNull(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<EventHandlerNonNull>&
OwningEventHandlerNonNullOrNullOrLong::RawSetAsEventHandlerNonNull()
{
if (mType == eEventHandlerNonNull) {
return mValue.mEventHandlerNonNull.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eEventHandlerNonNull;
return mValue.mEventHandlerNonNull.SetValue();
}
[[nodiscard]] OwningNonNull<EventHandlerNonNull>&
OwningEventHandlerNonNullOrNullOrLong::SetAsEventHandlerNonNull()
{
if (mType == eEventHandlerNonNull) {
return mValue.mEventHandlerNonNull.Value();
}
Uninit();
mType = eEventHandlerNonNull;
return mValue.mEventHandlerNonNull.SetValue();
}
void
OwningEventHandlerNonNullOrNullOrLong::DestroyEventHandlerNonNull()
{
MOZ_RELEASE_ASSERT(IsEventHandlerNonNull(), "Wrong type!");
mValue.mEventHandlerNonNull.Destroy();
mType = eUninitialized;
}
bool
OwningEventHandlerNonNullOrNullOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (EventHandlerNonNull? or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningEventHandlerNonNullOrNullOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningEventHandlerNonNullOrNullOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningEventHandlerNonNullOrNullOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningEventHandlerNonNullOrNullOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToEventHandlerNonNull(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "EventHandlerNonNull");
return false;
}
}
return true;
}
bool
OwningEventHandlerNonNullOrNullOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningEventHandlerNonNullOrNullOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eNull: {
break;
}
case eEventHandlerNonNull: {
DestroyEventHandlerNonNull();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningEventHandlerNonNullOrNullOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eEventHandlerNonNull: {
rval.setObjectOrNull(GetCallbackFromCallbackObject(cx, mValue.mEventHandlerNonNull.Value()));
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningEventHandlerNonNullOrNullOrLong&
OwningEventHandlerNonNullOrNullOrLong::operator=(OwningEventHandlerNonNullOrNullOrLong&& aOther)
{
this->~OwningEventHandlerNonNullOrNullOrLong();
new (this) OwningEventHandlerNonNullOrNullOrLong (std::move(aOther));
return *this;
}
OwningEventInitOrLong::OwningEventInitOrLong(OwningEventInitOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eEventInit: {
mType = eEventInit;
mValue.mEventInit.SetValue(std::move(aOther.mValue.mEventInit.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningEventInitOrLong::TrySetToEventInit(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
EventInit& memberSlot = RawSetAsEventInit();
if (!IsConvertibleToDictionary(value)) {
DestroyEventInit();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "EventInit branch of (EventInit or long)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
OwningEventInitOrLong::TrySetToEventInit(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToEventInit(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] EventInit&
OwningEventInitOrLong::RawSetAsEventInit()
{
if (mType == eEventInit) {
return mValue.mEventInit.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eEventInit;
return mValue.mEventInit.SetValue();
}
[[nodiscard]] EventInit&
OwningEventInitOrLong::SetAsEventInit()
{
if (mType == eEventInit) {
return mValue.mEventInit.Value();
}
Uninit();
mType = eEventInit;
return mValue.mEventInit.SetValue();
}
void
OwningEventInitOrLong::DestroyEventInit()
{
MOZ_RELEASE_ASSERT(IsEventInit(), "Wrong type!");
mValue.mEventInit.Destroy();
mType = eUninitialized;
}
bool
OwningEventInitOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (EventInit or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningEventInitOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningEventInitOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningEventInitOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningEventInitOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (!done) {
done = (failed = !TrySetToEventInit(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "EventInit");
return false;
}
return true;
}
bool
OwningEventInitOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningEventInitOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eEventInit: {
DestroyEventInit();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningEventInitOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eEventInit: {
if (!mValue.mEventInit.Value().ToObjectInternal(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningEventInitOrLong&
OwningEventInitOrLong::operator=(OwningEventInitOrLong&& aOther)
{
this->~OwningEventInitOrLong();
new (this) OwningEventInitOrLong (std::move(aOther));
return *this;
}
OwningEventInitOrLong&
OwningEventInitOrLong::operator=(const OwningEventInitOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eEventInit: {
SetAsEventInit() = aOther.GetAsEventInit();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningEventInitOrStringSequence::OwningEventInitOrStringSequence(OwningEventInitOrStringSequence&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eEventInit: {
mType = eEventInit;
mValue.mEventInit.SetValue(std::move(aOther.mValue.mEventInit.Value()));
break;
}
case eStringSequence: {
mType = eStringSequence;
mValue.mStringSequence.SetValue(std::move(aOther.mValue.mStringSequence.Value()));
break;
}
}
}
bool
OwningEventInitOrStringSequence::TrySetToEventInit(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
EventInit& memberSlot = RawSetAsEventInit();
if (!IsConvertibleToDictionary(value)) {
DestroyEventInit();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "EventInit branch of (EventInit or sequence<DOMString>)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
OwningEventInitOrStringSequence::TrySetToEventInit(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToEventInit(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] EventInit&
OwningEventInitOrStringSequence::RawSetAsEventInit()
{
if (mType == eEventInit) {
return mValue.mEventInit.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eEventInit;
return mValue.mEventInit.SetValue();
}
[[nodiscard]] EventInit&
OwningEventInitOrStringSequence::SetAsEventInit()
{
if (mType == eEventInit) {
return mValue.mEventInit.Value();
}
Uninit();
mType = eEventInit;
return mValue.mEventInit.SetValue();
}
void
OwningEventInitOrStringSequence::DestroyEventInit()
{
MOZ_RELEASE_ASSERT(IsEventInit(), "Wrong type!");
mValue.mEventInit.Destroy();
mType = eUninitialized;
}
bool
OwningEventInitOrStringSequence::TrySetToStringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<nsString>& memberSlot = RawSetAsStringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyStringSequence();
tryNext = true;
return true;
}
Sequence<nsString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
OwningEventInitOrStringSequence::TrySetToStringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<nsString>&
OwningEventInitOrStringSequence::RawSetAsStringSequence()
{
if (mType == eStringSequence) {
return mValue.mStringSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eStringSequence;
return mValue.mStringSequence.SetValue();
}
[[nodiscard]] Sequence<nsString>&
OwningEventInitOrStringSequence::SetAsStringSequence()
{
if (mType == eStringSequence) {
return mValue.mStringSequence.Value();
}
Uninit();
mType = eStringSequence;
return mValue.mStringSequence.SetValue();
}
void
OwningEventInitOrStringSequence::DestroyStringSequence()
{
MOZ_RELEASE_ASSERT(IsStringSequence(), "Wrong type!");
mValue.mStringSequence.Destroy();
mType = eUninitialized;
}
bool
OwningEventInitOrStringSequence::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 = !TrySetToStringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToEventInit(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<DOMString>, EventInit");
return false;
}
return true;
}
bool
OwningEventInitOrStringSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningEventInitOrStringSequence::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eEventInit: {
DestroyEventInit();
break;
}
case eStringSequence: {
DestroyStringSequence();
break;
}
}
}
bool
OwningEventInitOrStringSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eEventInit: {
if (!mValue.mEventInit.Value().ToObjectInternal(cx, rval)) {
return false;
}
return true;
}
case eStringSequence: {
uint32_t length = mValue.mStringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
default: {
return false;
}
}
}
OwningEventInitOrStringSequence&
OwningEventInitOrStringSequence::operator=(OwningEventInitOrStringSequence&& aOther)
{
this->~OwningEventInitOrStringSequence();
new (this) OwningEventInitOrStringSequence (std::move(aOther));
return *this;
}
OwningEventInitOrStringSequence&
OwningEventInitOrStringSequence::operator=(const OwningEventInitOrStringSequence& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eEventInit: {
SetAsEventInit() = aOther.GetAsEventInit();
break;
}
case eStringSequence: {
SetAsStringSequence() = aOther.GetAsStringSequence();
break;
}
}
return *this;
}
OwningFileOrDirectory::OwningFileOrDirectory(OwningFileOrDirectory&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eFile: {
mType = eFile;
mValue.mFile.SetValue(std::move(aOther.mValue.mFile.Value()));
break;
}
case eDirectory: {
mType = eDirectory;
mValue.mDirectory.SetValue(std::move(aOther.mValue.mDirectory.Value()));
break;
}
}
}
bool
OwningFileOrDirectory::TrySetToFile(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::File>& memberSlot = RawSetAsFile();
static_assert(IsRefcounted<mozilla::dom::File>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::File, mozilla::dom::File>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyFile();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningFileOrDirectory::TrySetToFile(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToFile(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::File>&
OwningFileOrDirectory::RawSetAsFile()
{
if (mType == eFile) {
return mValue.mFile.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eFile;
return mValue.mFile.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::File>&
OwningFileOrDirectory::SetAsFile()
{
if (mType == eFile) {
return mValue.mFile.Value();
}
Uninit();
mType = eFile;
return mValue.mFile.SetValue();
}
void
OwningFileOrDirectory::DestroyFile()
{
MOZ_RELEASE_ASSERT(IsFile(), "Wrong type!");
mValue.mFile.Destroy();
mType = eUninitialized;
}
bool
OwningFileOrDirectory::TrySetToDirectory(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::Directory>& memberSlot = RawSetAsDirectory();
static_assert(IsRefcounted<mozilla::dom::Directory>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::Directory, mozilla::dom::Directory>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyDirectory();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningFileOrDirectory::TrySetToDirectory(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDirectory(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::Directory>&
OwningFileOrDirectory::RawSetAsDirectory()
{
if (mType == eDirectory) {
return mValue.mDirectory.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eDirectory;
return mValue.mDirectory.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::Directory>&
OwningFileOrDirectory::SetAsDirectory()
{
if (mType == eDirectory) {
return mValue.mDirectory.Value();
}
Uninit();
mType = eDirectory;
return mValue.mDirectory.SetValue();
}
void
OwningFileOrDirectory::DestroyDirectory()
{
MOZ_RELEASE_ASSERT(IsDirectory(), "Wrong type!");
mValue.mDirectory.Destroy();
mType = eUninitialized;
}
bool
OwningFileOrDirectory::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 = !TrySetToFile(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToDirectory(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "File, Directory");
return false;
}
return true;
}
bool
OwningFileOrDirectory::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningFileOrDirectory::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eFile: {
DestroyFile();
break;
}
case eDirectory: {
DestroyDirectory();
break;
}
}
}
bool
OwningFileOrDirectory::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eFile: {
if (!GetOrCreateDOMReflector(cx, mValue.mFile.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eDirectory: {
if (!GetOrCreateDOMReflector(cx, mValue.mDirectory.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningFileOrDirectory&
OwningFileOrDirectory::operator=(OwningFileOrDirectory&& aOther)
{
this->~OwningFileOrDirectory();
new (this) OwningFileOrDirectory (std::move(aOther));
return *this;
}
OwningFileOrDirectory&
OwningFileOrDirectory::operator=(const OwningFileOrDirectory& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eFile: {
SetAsFile() = aOther.GetAsFile();
break;
}
case eDirectory: {
SetAsDirectory() = aOther.GetAsDirectory();
break;
}
}
return *this;
}
OwningFileOrUSVStringOrFormData::OwningFileOrUSVStringOrFormData(OwningFileOrUSVStringOrFormData&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eFile: {
mType = eFile;
mValue.mFile.SetValue(std::move(aOther.mValue.mFile.Value()));
break;
}
case eUSVString: {
mType = eUSVString;
mValue.mUSVString.SetValue(std::move(aOther.mValue.mUSVString.Value()));
break;
}
case eFormData: {
mType = eFormData;
mValue.mFormData.SetValue(std::move(aOther.mValue.mFormData.Value()));
break;
}
}
}
bool
OwningFileOrUSVStringOrFormData::TrySetToFile(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::File>& memberSlot = RawSetAsFile();
static_assert(IsRefcounted<mozilla::dom::File>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::File, mozilla::dom::File>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyFile();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningFileOrUSVStringOrFormData::TrySetToFile(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToFile(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::File>&
OwningFileOrUSVStringOrFormData::RawSetAsFile()
{
if (mType == eFile) {
return mValue.mFile.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eFile;
return mValue.mFile.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::File>&
OwningFileOrUSVStringOrFormData::SetAsFile()
{
if (mType == eFile) {
return mValue.mFile.Value();
}
Uninit();
mType = eFile;
return mValue.mFile.SetValue();
}
void
OwningFileOrUSVStringOrFormData::DestroyFile()
{
MOZ_RELEASE_ASSERT(IsFile(), "Wrong type!");
mValue.mFile.Destroy();
mType = eUninitialized;
}
bool
OwningFileOrUSVStringOrFormData::TrySetToUSVString(JSContext* cx, JS::Handle<JS::Value> 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&
OwningFileOrUSVStringOrFormData::RawSetAsUSVString()
{
if (mType == eUSVString) {
return mValue.mUSVString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUSVString;
return mValue.mUSVString.SetValue();
}
[[nodiscard]] nsString&
OwningFileOrUSVStringOrFormData::SetAsUSVString()
{
if (mType == eUSVString) {
return mValue.mUSVString.Value();
}
Uninit();
mType = eUSVString;
return mValue.mUSVString.SetValue();
}
void
OwningFileOrUSVStringOrFormData::DestroyUSVString()
{
MOZ_RELEASE_ASSERT(IsUSVString(), "Wrong type!");
mValue.mUSVString.Destroy();
mType = eUninitialized;
}
bool
OwningFileOrUSVStringOrFormData::TrySetToFormData(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::FormData>& memberSlot = RawSetAsFormData();
static_assert(IsRefcounted<mozilla::dom::FormData>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::FormData, mozilla::dom::FormData>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyFormData();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningFileOrUSVStringOrFormData::TrySetToFormData(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToFormData(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::FormData>&
OwningFileOrUSVStringOrFormData::RawSetAsFormData()
{
if (mType == eFormData) {
return mValue.mFormData.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eFormData;
return mValue.mFormData.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::FormData>&
OwningFileOrUSVStringOrFormData::SetAsFormData()
{
if (mType == eFormData) {
return mValue.mFormData.Value();
}
Uninit();
mType = eFormData;
return mValue.mFormData.SetValue();
}
void
OwningFileOrUSVStringOrFormData::DestroyFormData()
{
MOZ_RELEASE_ASSERT(IsFormData(), "Wrong type!");
mValue.mFormData.Destroy();
mType = eUninitialized;
}
bool
OwningFileOrUSVStringOrFormData::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 = !TrySetToFile(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToFormData(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<MSG_NOT_IN_UNION>(sourceDescription, "File, FormData");
return false;
}
return true;
}
bool
OwningFileOrUSVStringOrFormData::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningFileOrUSVStringOrFormData::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eFile: {
DestroyFile();
break;
}
case eUSVString: {
DestroyUSVString();
break;
}
case eFormData: {
DestroyFormData();
break;
}
}
}
bool
OwningFileOrUSVStringOrFormData::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eFile: {
if (!GetOrCreateDOMReflector(cx, mValue.mFile.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;
}
case eFormData: {
if (!GetOrCreateDOMReflector(cx, mValue.mFormData.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningFileOrUSVStringOrFormData&
OwningFileOrUSVStringOrFormData::operator=(OwningFileOrUSVStringOrFormData&& aOther)
{
this->~OwningFileOrUSVStringOrFormData();
new (this) OwningFileOrUSVStringOrFormData (std::move(aOther));
return *this;
}
OwningFileOrUSVStringOrFormData&
OwningFileOrUSVStringOrFormData::operator=(const OwningFileOrUSVStringOrFormData& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eFile: {
SetAsFile() = aOther.GetAsFile();
break;
}
case eUSVString: {
SetAsUSVString() = aOther.GetAsUSVString();
break;
}
case eFormData: {
SetAsFormData() = aOther.GetAsFormData();
break;
}
}
return *this;
}
OwningFloatOrString::OwningFloatOrString(OwningFloatOrString&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eFloat: {
mType = eFloat;
mValue.mFloat.SetValue(std::move(aOther.mValue.mFloat.Value()));
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
}
}
bool
OwningFloatOrString::TrySetToFloat(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
float& memberSlot = RawSetAsFloat();
if (!ValueToPrimitive<float, eDefault>(cx, value, "Float branch of (float or DOMString)", &memberSlot)) {
return false;
} else if (!std::isfinite(memberSlot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Float branch of (float or DOMString)");
return false;
}
}
return true;
}
bool
OwningFloatOrString::TrySetToFloat(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToFloat(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] float&
OwningFloatOrString::RawSetAsFloat()
{
if (mType == eFloat) {
return mValue.mFloat.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eFloat;
return mValue.mFloat.SetValue();
}
[[nodiscard]] float&
OwningFloatOrString::SetAsFloat()
{
if (mType == eFloat) {
return mValue.mFloat.Value();
}
Uninit();
mType = eFloat;
return mValue.mFloat.SetValue();
}
void
OwningFloatOrString::DestroyFloat()
{
MOZ_RELEASE_ASSERT(IsFloat(), "Wrong type!");
mValue.mFloat.Destroy();
mType = eUninitialized;
}
bool
OwningFloatOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningFloatOrString::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningFloatOrString::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningFloatOrString::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningFloatOrString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToFloat(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningFloatOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningFloatOrString::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eFloat: {
DestroyFloat();
break;
}
case eString: {
DestroyString();
break;
}
}
}
bool
OwningFloatOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eFloat: {
rval.set(JS_NumberValue(double(mValue.mFloat.Value())));
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningFloatOrString&
OwningFloatOrString::operator=(OwningFloatOrString&& aOther)
{
this->~OwningFloatOrString();
new (this) OwningFloatOrString (std::move(aOther));
return *this;
}
OwningFloatOrString&
OwningFloatOrString::operator=(const OwningFloatOrString& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eFloat: {
SetAsFloat() = aOther.GetAsFloat();
break;
}
case eString: {
SetAsString() = aOther.GetAsString();
break;
}
}
return *this;
}
OwningHTMLCanvasElementOrOffscreenCanvas::OwningHTMLCanvasElementOrOffscreenCanvas(OwningHTMLCanvasElementOrOffscreenCanvas&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eHTMLCanvasElement: {
mType = eHTMLCanvasElement;
mValue.mHTMLCanvasElement.SetValue(std::move(aOther.mValue.mHTMLCanvasElement.Value()));
break;
}
case eOffscreenCanvas: {
mType = eOffscreenCanvas;
mValue.mOffscreenCanvas.SetValue(std::move(aOther.mValue.mOffscreenCanvas.Value()));
break;
}
}
}
bool
OwningHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::HTMLCanvasElement>& memberSlot = RawSetAsHTMLCanvasElement();
static_assert(IsRefcounted<mozilla::dom::HTMLCanvasElement>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLCanvasElement, mozilla::dom::HTMLCanvasElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLCanvasElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLCanvasElement>&
OwningHTMLCanvasElementOrOffscreenCanvas::RawSetAsHTMLCanvasElement()
{
if (mType == eHTMLCanvasElement) {
return mValue.mHTMLCanvasElement.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eHTMLCanvasElement;
return mValue.mHTMLCanvasElement.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLCanvasElement>&
OwningHTMLCanvasElementOrOffscreenCanvas::SetAsHTMLCanvasElement()
{
if (mType == eHTMLCanvasElement) {
return mValue.mHTMLCanvasElement.Value();
}
Uninit();
mType = eHTMLCanvasElement;
return mValue.mHTMLCanvasElement.SetValue();
}
void
OwningHTMLCanvasElementOrOffscreenCanvas::DestroyHTMLCanvasElement()
{
MOZ_RELEASE_ASSERT(IsHTMLCanvasElement(), "Wrong type!");
mValue.mHTMLCanvasElement.Destroy();
mType = eUninitialized;
}
bool
OwningHTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::OffscreenCanvas>& memberSlot = RawSetAsOffscreenCanvas();
static_assert(IsRefcounted<mozilla::dom::OffscreenCanvas>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::OffscreenCanvas, mozilla::dom::OffscreenCanvas>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyOffscreenCanvas();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningHTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::OffscreenCanvas>&
OwningHTMLCanvasElementOrOffscreenCanvas::RawSetAsOffscreenCanvas()
{
if (mType == eOffscreenCanvas) {
return mValue.mOffscreenCanvas.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eOffscreenCanvas;
return mValue.mOffscreenCanvas.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::OffscreenCanvas>&
OwningHTMLCanvasElementOrOffscreenCanvas::SetAsOffscreenCanvas()
{
if (mType == eOffscreenCanvas) {
return mValue.mOffscreenCanvas.Value();
}
Uninit();
mType = eOffscreenCanvas;
return mValue.mOffscreenCanvas.SetValue();
}
void
OwningHTMLCanvasElementOrOffscreenCanvas::DestroyOffscreenCanvas()
{
MOZ_RELEASE_ASSERT(IsOffscreenCanvas(), "Wrong type!");
mValue.mOffscreenCanvas.Destroy();
mType = eUninitialized;
}
bool
OwningHTMLCanvasElementOrOffscreenCanvas::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 = !TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "HTMLCanvasElement, OffscreenCanvas");
return false;
}
return true;
}
bool
OwningHTMLCanvasElementOrOffscreenCanvas::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningHTMLCanvasElementOrOffscreenCanvas::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eHTMLCanvasElement: {
DestroyHTMLCanvasElement();
break;
}
case eOffscreenCanvas: {
DestroyOffscreenCanvas();
break;
}
}
}
bool
OwningHTMLCanvasElementOrOffscreenCanvas::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eHTMLCanvasElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLCanvasElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eOffscreenCanvas: {
if (!GetOrCreateDOMReflector(cx, mValue.mOffscreenCanvas.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningHTMLCanvasElementOrOffscreenCanvas&
OwningHTMLCanvasElementOrOffscreenCanvas::operator=(OwningHTMLCanvasElementOrOffscreenCanvas&& aOther)
{
this->~OwningHTMLCanvasElementOrOffscreenCanvas();
new (this) OwningHTMLCanvasElementOrOffscreenCanvas (std::move(aOther));
return *this;
}
OwningHTMLCanvasElementOrOffscreenCanvas&
OwningHTMLCanvasElementOrOffscreenCanvas::operator=(const OwningHTMLCanvasElementOrOffscreenCanvas& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eHTMLCanvasElement: {
SetAsHTMLCanvasElement() = aOther.GetAsHTMLCanvasElement();
break;
}
case eOffscreenCanvas: {
SetAsOffscreenCanvas() = aOther.GetAsOffscreenCanvas();
break;
}
}
return *this;
}
OwningHTMLElementOrLong::OwningHTMLElementOrLong(OwningHTMLElementOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eHTMLElement: {
mType = eHTMLElement;
mValue.mHTMLElement.SetValue(std::move(aOther.mValue.mHTMLElement.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningHTMLElementOrLong::TrySetToHTMLElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<nsGenericHTMLElement>& memberSlot = RawSetAsHTMLElement();
static_assert(IsRefcounted<nsGenericHTMLElement>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLElement, nsGenericHTMLElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningHTMLElementOrLong::TrySetToHTMLElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLElement(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<nsGenericHTMLElement>&
OwningHTMLElementOrLong::RawSetAsHTMLElement()
{
if (mType == eHTMLElement) {
return mValue.mHTMLElement.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eHTMLElement;
return mValue.mHTMLElement.SetValue();
}
[[nodiscard]] OwningNonNull<nsGenericHTMLElement>&
OwningHTMLElementOrLong::SetAsHTMLElement()
{
if (mType == eHTMLElement) {
return mValue.mHTMLElement.Value();
}
Uninit();
mType = eHTMLElement;
return mValue.mHTMLElement.SetValue();
}
void
OwningHTMLElementOrLong::DestroyHTMLElement()
{
MOZ_RELEASE_ASSERT(IsHTMLElement(), "Wrong type!");
mValue.mHTMLElement.Destroy();
mType = eUninitialized;
}
bool
OwningHTMLElementOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (HTMLElement or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningHTMLElementOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningHTMLElementOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningHTMLElementOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningHTMLElementOrLong::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 = !TrySetToHTMLElement(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "HTMLElement");
return false;
}
return true;
}
bool
OwningHTMLElementOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningHTMLElementOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eHTMLElement: {
DestroyHTMLElement();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningHTMLElementOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eHTMLElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningHTMLElementOrLong&
OwningHTMLElementOrLong::operator=(OwningHTMLElementOrLong&& aOther)
{
this->~OwningHTMLElementOrLong();
new (this) OwningHTMLElementOrLong (std::move(aOther));
return *this;
}
OwningHTMLElementOrLong&
OwningHTMLElementOrLong::operator=(const OwningHTMLElementOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eHTMLElement: {
SetAsHTMLElement() = aOther.GetAsHTMLElement();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningHTMLOptionElementOrHTMLOptGroupElement::OwningHTMLOptionElementOrHTMLOptGroupElement(OwningHTMLOptionElementOrHTMLOptGroupElement&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eHTMLOptionElement: {
mType = eHTMLOptionElement;
mValue.mHTMLOptionElement.SetValue(std::move(aOther.mValue.mHTMLOptionElement.Value()));
break;
}
case eHTMLOptGroupElement: {
mType = eHTMLOptGroupElement;
mValue.mHTMLOptGroupElement.SetValue(std::move(aOther.mValue.mHTMLOptGroupElement.Value()));
break;
}
}
}
bool
OwningHTMLOptionElementOrHTMLOptGroupElement::TrySetToHTMLOptionElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::HTMLOptionElement>& memberSlot = RawSetAsHTMLOptionElement();
static_assert(IsRefcounted<mozilla::dom::HTMLOptionElement>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLOptionElement, mozilla::dom::HTMLOptionElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLOptionElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningHTMLOptionElementOrHTMLOptGroupElement::TrySetToHTMLOptionElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLOptionElement(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLOptionElement>&
OwningHTMLOptionElementOrHTMLOptGroupElement::RawSetAsHTMLOptionElement()
{
if (mType == eHTMLOptionElement) {
return mValue.mHTMLOptionElement.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eHTMLOptionElement;
return mValue.mHTMLOptionElement.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLOptionElement>&
OwningHTMLOptionElementOrHTMLOptGroupElement::SetAsHTMLOptionElement()
{
if (mType == eHTMLOptionElement) {
return mValue.mHTMLOptionElement.Value();
}
Uninit();
mType = eHTMLOptionElement;
return mValue.mHTMLOptionElement.SetValue();
}
void
OwningHTMLOptionElementOrHTMLOptGroupElement::DestroyHTMLOptionElement()
{
MOZ_RELEASE_ASSERT(IsHTMLOptionElement(), "Wrong type!");
mValue.mHTMLOptionElement.Destroy();
mType = eUninitialized;
}
bool
OwningHTMLOptionElementOrHTMLOptGroupElement::TrySetToHTMLOptGroupElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::HTMLOptGroupElement>& memberSlot = RawSetAsHTMLOptGroupElement();
static_assert(IsRefcounted<mozilla::dom::HTMLOptGroupElement>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLOptGroupElement, mozilla::dom::HTMLOptGroupElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLOptGroupElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningHTMLOptionElementOrHTMLOptGroupElement::TrySetToHTMLOptGroupElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLOptGroupElement(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLOptGroupElement>&
OwningHTMLOptionElementOrHTMLOptGroupElement::RawSetAsHTMLOptGroupElement()
{
if (mType == eHTMLOptGroupElement) {
return mValue.mHTMLOptGroupElement.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eHTMLOptGroupElement;
return mValue.mHTMLOptGroupElement.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLOptGroupElement>&
OwningHTMLOptionElementOrHTMLOptGroupElement::SetAsHTMLOptGroupElement()
{
if (mType == eHTMLOptGroupElement) {
return mValue.mHTMLOptGroupElement.Value();
}
Uninit();
mType = eHTMLOptGroupElement;
return mValue.mHTMLOptGroupElement.SetValue();
}
void
OwningHTMLOptionElementOrHTMLOptGroupElement::DestroyHTMLOptGroupElement()
{
MOZ_RELEASE_ASSERT(IsHTMLOptGroupElement(), "Wrong type!");
mValue.mHTMLOptGroupElement.Destroy();
mType = eUninitialized;
}
bool
OwningHTMLOptionElementOrHTMLOptGroupElement::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 = !TrySetToHTMLOptionElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToHTMLOptGroupElement(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "HTMLOptionElement, HTMLOptGroupElement");
return false;
}
return true;
}
bool
OwningHTMLOptionElementOrHTMLOptGroupElement::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningHTMLOptionElementOrHTMLOptGroupElement::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eHTMLOptionElement: {
DestroyHTMLOptionElement();
break;
}
case eHTMLOptGroupElement: {
DestroyHTMLOptGroupElement();
break;
}
}
}
bool
OwningHTMLOptionElementOrHTMLOptGroupElement::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eHTMLOptionElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLOptionElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eHTMLOptGroupElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLOptGroupElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningHTMLOptionElementOrHTMLOptGroupElement&
OwningHTMLOptionElementOrHTMLOptGroupElement::operator=(OwningHTMLOptionElementOrHTMLOptGroupElement&& aOther)
{
this->~OwningHTMLOptionElementOrHTMLOptGroupElement();
new (this) OwningHTMLOptionElementOrHTMLOptGroupElement (std::move(aOther));
return *this;
}
OwningHTMLOptionElementOrHTMLOptGroupElement&
OwningHTMLOptionElementOrHTMLOptGroupElement::operator=(const OwningHTMLOptionElementOrHTMLOptGroupElement& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eHTMLOptionElement: {
SetAsHTMLOptionElement() = aOther.GetAsHTMLOptionElement();
break;
}
case eHTMLOptGroupElement: {
SetAsHTMLOptGroupElement() = aOther.GetAsHTMLOptGroupElement();
break;
}
}
return *this;
}
OwningImageDataOrNullSequenceOrLong::OwningImageDataOrNullSequenceOrLong(OwningImageDataOrNullSequenceOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eImageDataOrNullSequence: {
mType = eImageDataOrNullSequence;
mValue.mImageDataOrNullSequence.SetValue(std::move(aOther.mValue.mImageDataOrNullSequence.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningImageDataOrNullSequenceOrLong::TrySetToImageDataOrNullSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<RefPtr<mozilla::dom::ImageData>>& memberSlot = RawSetAsImageDataOrNullSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyImageDataOrNullSequence();
tryNext = true;
return true;
}
Sequence<RefPtr<mozilla::dom::ImageData>> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
RefPtr<mozilla::dom::ImageData>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
RefPtr<mozilla::dom::ImageData>& slot = *slotPtr;
if (temp.isObject()) {
static_assert(IsRefcounted<mozilla::dom::ImageData>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ImageData, mozilla::dom::ImageData>(&temp, slot, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of sequence<ImageData?> branch of (sequence<ImageData?> or long)", "ImageData");
return false;
}
}
} else if (temp.isNullOrUndefined()) {
slot = nullptr;
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of sequence<ImageData?> branch of (sequence<ImageData?> or long)");
return false;
}
}
}
return true;
}
bool
OwningImageDataOrNullSequenceOrLong::TrySetToImageDataOrNullSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToImageDataOrNullSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<RefPtr<mozilla::dom::ImageData>>&
OwningImageDataOrNullSequenceOrLong::RawSetAsImageDataOrNullSequence()
{
if (mType == eImageDataOrNullSequence) {
return mValue.mImageDataOrNullSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eImageDataOrNullSequence;
return mValue.mImageDataOrNullSequence.SetValue();
}
[[nodiscard]] Sequence<RefPtr<mozilla::dom::ImageData>>&
OwningImageDataOrNullSequenceOrLong::SetAsImageDataOrNullSequence()
{
if (mType == eImageDataOrNullSequence) {
return mValue.mImageDataOrNullSequence.Value();
}
Uninit();
mType = eImageDataOrNullSequence;
return mValue.mImageDataOrNullSequence.SetValue();
}
void
OwningImageDataOrNullSequenceOrLong::DestroyImageDataOrNullSequence()
{
MOZ_RELEASE_ASSERT(IsImageDataOrNullSequence(), "Wrong type!");
mValue.mImageDataOrNullSequence.Destroy();
mType = eUninitialized;
}
bool
OwningImageDataOrNullSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<ImageData?> or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningImageDataOrNullSequenceOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningImageDataOrNullSequenceOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningImageDataOrNullSequenceOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningImageDataOrNullSequenceOrLong::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 = !TrySetToImageDataOrNullSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<ImageData?>");
return false;
}
return true;
}
bool
OwningImageDataOrNullSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningImageDataOrNullSequenceOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eImageDataOrNullSequence: {
DestroyImageDataOrNullSequence();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningImageDataOrNullSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eImageDataOrNullSequence: {
uint32_t length = mValue.mImageDataOrNullSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!mValue.mImageDataOrNullSequence.Value()[sequenceIdx0]) {
tmp.setNull();
break;
}
if (!WrapNewBindingNonWrapperCachedObject(cx, returnArray, mValue.mImageDataOrNullSequence.Value()[sequenceIdx0], &tmp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningImageDataOrNullSequenceOrLong&
OwningImageDataOrNullSequenceOrLong::operator=(OwningImageDataOrNullSequenceOrLong&& aOther)
{
this->~OwningImageDataOrNullSequenceOrLong();
new (this) OwningImageDataOrNullSequenceOrLong (std::move(aOther));
return *this;
}
OwningImageDataOrNullSequenceOrLong&
OwningImageDataOrNullSequenceOrLong::operator=(const OwningImageDataOrNullSequenceOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eImageDataOrNullSequence: {
SetAsImageDataOrNullSequence() = aOther.GetAsImageDataOrNullSequence();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningImageDataOrNullSequenceSequenceOrLong::OwningImageDataOrNullSequenceSequenceOrLong(OwningImageDataOrNullSequenceSequenceOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eImageDataOrNullSequenceSequence: {
mType = eImageDataOrNullSequenceSequence;
mValue.mImageDataOrNullSequenceSequence.SetValue(std::move(aOther.mValue.mImageDataOrNullSequenceSequence.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningImageDataOrNullSequenceSequenceOrLong::TrySetToImageDataOrNullSequenceSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<Sequence<RefPtr<mozilla::dom::ImageData>>>& memberSlot = RawSetAsImageDataOrNullSequenceSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyImageDataOrNullSequenceSequence();
tryNext = true;
return true;
}
Sequence<Sequence<RefPtr<mozilla::dom::ImageData>>> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
Sequence<RefPtr<mozilla::dom::ImageData>>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
Sequence<RefPtr<mozilla::dom::ImageData>>& slot = *slotPtr;
if (temp.isObject()) {
JS::ForOfIterator iter1(cx);
if (!iter1.init(temp, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter1.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Element of sequence<sequence<ImageData?>> branch of (sequence<sequence<ImageData?>> or long)", "sequence");
return false;
}
Sequence<RefPtr<mozilla::dom::ImageData>> &arr1 = slot;
JS::Rooted<JS::Value> temp1(cx);
while (true) {
bool done1;
if (!iter1.next(&temp1, &done1)) {
return false;
}
if (done1) {
break;
}
RefPtr<mozilla::dom::ImageData>* slotPtr1 = arr1.AppendElement(mozilla::fallible);
if (!slotPtr1) {
JS_ReportOutOfMemory(cx);
return false;
}
RefPtr<mozilla::dom::ImageData>& slot1 = *slotPtr1;
if (temp1.isObject()) {
static_assert(IsRefcounted<mozilla::dom::ImageData>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ImageData, mozilla::dom::ImageData>(&temp1, slot1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of element of sequence<sequence<ImageData?>> branch of (sequence<sequence<ImageData?>> or long)", "ImageData");
return false;
}
}
} else if (temp1.isNullOrUndefined()) {
slot1 = nullptr;
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of element of sequence<sequence<ImageData?>> branch of (sequence<sequence<ImageData?>> or long)");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Element of sequence<sequence<ImageData?>> branch of (sequence<sequence<ImageData?>> or long)", "sequence");
return false;
}
}
}
return true;
}
bool
OwningImageDataOrNullSequenceSequenceOrLong::TrySetToImageDataOrNullSequenceSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToImageDataOrNullSequenceSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<Sequence<RefPtr<mozilla::dom::ImageData>>>&
OwningImageDataOrNullSequenceSequenceOrLong::RawSetAsImageDataOrNullSequenceSequence()
{
if (mType == eImageDataOrNullSequenceSequence) {
return mValue.mImageDataOrNullSequenceSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eImageDataOrNullSequenceSequence;
return mValue.mImageDataOrNullSequenceSequence.SetValue();
}
[[nodiscard]] Sequence<Sequence<RefPtr<mozilla::dom::ImageData>>>&
OwningImageDataOrNullSequenceSequenceOrLong::SetAsImageDataOrNullSequenceSequence()
{
if (mType == eImageDataOrNullSequenceSequence) {
return mValue.mImageDataOrNullSequenceSequence.Value();
}
Uninit();
mType = eImageDataOrNullSequenceSequence;
return mValue.mImageDataOrNullSequenceSequence.SetValue();
}
void
OwningImageDataOrNullSequenceSequenceOrLong::DestroyImageDataOrNullSequenceSequence()
{
MOZ_RELEASE_ASSERT(IsImageDataOrNullSequenceSequence(), "Wrong type!");
mValue.mImageDataOrNullSequenceSequence.Destroy();
mType = eUninitialized;
}
bool
OwningImageDataOrNullSequenceSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<sequence<ImageData?>> or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningImageDataOrNullSequenceSequenceOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningImageDataOrNullSequenceSequenceOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningImageDataOrNullSequenceSequenceOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningImageDataOrNullSequenceSequenceOrLong::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 = !TrySetToImageDataOrNullSequenceSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<sequence<ImageData?>>");
return false;
}
return true;
}
bool
OwningImageDataOrNullSequenceSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningImageDataOrNullSequenceSequenceOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eImageDataOrNullSequenceSequence: {
DestroyImageDataOrNullSequenceSequence();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningImageDataOrNullSequenceSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eImageDataOrNullSequenceSequence: {
uint32_t length = mValue.mImageDataOrNullSequenceSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
uint32_t length = mValue.mImageDataOrNullSequenceSequence.Value()[sequenceIdx0].Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx1 = 0; sequenceIdx1 < length; ++sequenceIdx1) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!mValue.mImageDataOrNullSequenceSequence.Value()[sequenceIdx0][sequenceIdx1]) {
tmp.setNull();
break;
}
if (!WrapNewBindingNonWrapperCachedObject(cx, returnArray, mValue.mImageDataOrNullSequenceSequence.Value()[sequenceIdx0][sequenceIdx1], &tmp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx1, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
tmp.setObject(*returnArray);
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningImageDataOrNullSequenceSequenceOrLong&
OwningImageDataOrNullSequenceSequenceOrLong::operator=(OwningImageDataOrNullSequenceSequenceOrLong&& aOther)
{
this->~OwningImageDataOrNullSequenceSequenceOrLong();
new (this) OwningImageDataOrNullSequenceSequenceOrLong (std::move(aOther));
return *this;
}
OwningImageDataOrNullSequenceSequenceOrLong&
OwningImageDataOrNullSequenceSequenceOrLong::operator=(const OwningImageDataOrNullSequenceSequenceOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eImageDataOrNullSequenceSequence: {
SetAsImageDataOrNullSequenceSequence() = aOther.GetAsImageDataOrNullSequenceSequence();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningImageDataSequenceOrLong::OwningImageDataSequenceOrLong(OwningImageDataSequenceOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eImageDataSequence: {
mType = eImageDataSequence;
mValue.mImageDataSequence.SetValue(std::move(aOther.mValue.mImageDataSequence.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningImageDataSequenceOrLong::TrySetToImageDataSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<OwningNonNull<mozilla::dom::ImageData>>& memberSlot = RawSetAsImageDataSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyImageDataSequence();
tryNext = true;
return true;
}
Sequence<OwningNonNull<mozilla::dom::ImageData>> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
OwningNonNull<mozilla::dom::ImageData>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
OwningNonNull<mozilla::dom::ImageData>& slot = *slotPtr;
if (temp.isObject()) {
static_assert(IsRefcounted<mozilla::dom::ImageData>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ImageData, mozilla::dom::ImageData>(&temp, slot, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of sequence<ImageData> branch of (sequence<ImageData> or long)", "ImageData");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of sequence<ImageData> branch of (sequence<ImageData> or long)");
return false;
}
}
}
return true;
}
bool
OwningImageDataSequenceOrLong::TrySetToImageDataSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToImageDataSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<OwningNonNull<mozilla::dom::ImageData>>&
OwningImageDataSequenceOrLong::RawSetAsImageDataSequence()
{
if (mType == eImageDataSequence) {
return mValue.mImageDataSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eImageDataSequence;
return mValue.mImageDataSequence.SetValue();
}
[[nodiscard]] Sequence<OwningNonNull<mozilla::dom::ImageData>>&
OwningImageDataSequenceOrLong::SetAsImageDataSequence()
{
if (mType == eImageDataSequence) {
return mValue.mImageDataSequence.Value();
}
Uninit();
mType = eImageDataSequence;
return mValue.mImageDataSequence.SetValue();
}
void
OwningImageDataSequenceOrLong::DestroyImageDataSequence()
{
MOZ_RELEASE_ASSERT(IsImageDataSequence(), "Wrong type!");
mValue.mImageDataSequence.Destroy();
mType = eUninitialized;
}
bool
OwningImageDataSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<ImageData> or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningImageDataSequenceOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningImageDataSequenceOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningImageDataSequenceOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningImageDataSequenceOrLong::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 = !TrySetToImageDataSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<ImageData>");
return false;
}
return true;
}
bool
OwningImageDataSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningImageDataSequenceOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eImageDataSequence: {
DestroyImageDataSequence();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningImageDataSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eImageDataSequence: {
uint32_t length = mValue.mImageDataSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!WrapNewBindingNonWrapperCachedObject(cx, returnArray, mValue.mImageDataSequence.Value()[sequenceIdx0], &tmp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningImageDataSequenceOrLong&
OwningImageDataSequenceOrLong::operator=(OwningImageDataSequenceOrLong&& aOther)
{
this->~OwningImageDataSequenceOrLong();
new (this) OwningImageDataSequenceOrLong (std::move(aOther));
return *this;
}
OwningImageDataSequenceOrLong&
OwningImageDataSequenceOrLong::operator=(const OwningImageDataSequenceOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eImageDataSequence: {
SetAsImageDataSequence() = aOther.GetAsImageDataSequence();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningImageDataSequenceSequenceOrLong::OwningImageDataSequenceSequenceOrLong(OwningImageDataSequenceSequenceOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eImageDataSequenceSequence: {
mType = eImageDataSequenceSequence;
mValue.mImageDataSequenceSequence.SetValue(std::move(aOther.mValue.mImageDataSequenceSequence.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningImageDataSequenceSequenceOrLong::TrySetToImageDataSequenceSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<Sequence<OwningNonNull<mozilla::dom::ImageData>>>& memberSlot = RawSetAsImageDataSequenceSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyImageDataSequenceSequence();
tryNext = true;
return true;
}
Sequence<Sequence<OwningNonNull<mozilla::dom::ImageData>>> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
Sequence<OwningNonNull<mozilla::dom::ImageData>>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
Sequence<OwningNonNull<mozilla::dom::ImageData>>& slot = *slotPtr;
if (temp.isObject()) {
JS::ForOfIterator iter1(cx);
if (!iter1.init(temp, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter1.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Element of sequence<sequence<ImageData>> branch of (sequence<sequence<ImageData>> or long)", "sequence");
return false;
}
Sequence<OwningNonNull<mozilla::dom::ImageData>> &arr1 = slot;
JS::Rooted<JS::Value> temp1(cx);
while (true) {
bool done1;
if (!iter1.next(&temp1, &done1)) {
return false;
}
if (done1) {
break;
}
OwningNonNull<mozilla::dom::ImageData>* slotPtr1 = arr1.AppendElement(mozilla::fallible);
if (!slotPtr1) {
JS_ReportOutOfMemory(cx);
return false;
}
OwningNonNull<mozilla::dom::ImageData>& slot1 = *slotPtr1;
if (temp1.isObject()) {
static_assert(IsRefcounted<mozilla::dom::ImageData>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ImageData, mozilla::dom::ImageData>(&temp1, slot1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of element of sequence<sequence<ImageData>> branch of (sequence<sequence<ImageData>> or long)", "ImageData");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of element of sequence<sequence<ImageData>> branch of (sequence<sequence<ImageData>> or long)");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Element of sequence<sequence<ImageData>> branch of (sequence<sequence<ImageData>> or long)", "sequence");
return false;
}
}
}
return true;
}
bool
OwningImageDataSequenceSequenceOrLong::TrySetToImageDataSequenceSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToImageDataSequenceSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<Sequence<OwningNonNull<mozilla::dom::ImageData>>>&
OwningImageDataSequenceSequenceOrLong::RawSetAsImageDataSequenceSequence()
{
if (mType == eImageDataSequenceSequence) {
return mValue.mImageDataSequenceSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eImageDataSequenceSequence;
return mValue.mImageDataSequenceSequence.SetValue();
}
[[nodiscard]] Sequence<Sequence<OwningNonNull<mozilla::dom::ImageData>>>&
OwningImageDataSequenceSequenceOrLong::SetAsImageDataSequenceSequence()
{
if (mType == eImageDataSequenceSequence) {
return mValue.mImageDataSequenceSequence.Value();
}
Uninit();
mType = eImageDataSequenceSequence;
return mValue.mImageDataSequenceSequence.SetValue();
}
void
OwningImageDataSequenceSequenceOrLong::DestroyImageDataSequenceSequence()
{
MOZ_RELEASE_ASSERT(IsImageDataSequenceSequence(), "Wrong type!");
mValue.mImageDataSequenceSequence.Destroy();
mType = eUninitialized;
}
bool
OwningImageDataSequenceSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<sequence<ImageData>> or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningImageDataSequenceSequenceOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningImageDataSequenceSequenceOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningImageDataSequenceSequenceOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningImageDataSequenceSequenceOrLong::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 = !TrySetToImageDataSequenceSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<sequence<ImageData>>");
return false;
}
return true;
}
bool
OwningImageDataSequenceSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningImageDataSequenceSequenceOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eImageDataSequenceSequence: {
DestroyImageDataSequenceSequence();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningImageDataSequenceSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eImageDataSequenceSequence: {
uint32_t length = mValue.mImageDataSequenceSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
uint32_t length = mValue.mImageDataSequenceSequence.Value()[sequenceIdx0].Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx1 = 0; sequenceIdx1 < length; ++sequenceIdx1) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!WrapNewBindingNonWrapperCachedObject(cx, returnArray, mValue.mImageDataSequenceSequence.Value()[sequenceIdx0][sequenceIdx1], &tmp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx1, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
tmp.setObject(*returnArray);
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningImageDataSequenceSequenceOrLong&
OwningImageDataSequenceSequenceOrLong::operator=(OwningImageDataSequenceSequenceOrLong&& aOther)
{
this->~OwningImageDataSequenceSequenceOrLong();
new (this) OwningImageDataSequenceSequenceOrLong (std::move(aOther));
return *this;
}
OwningImageDataSequenceSequenceOrLong&
OwningImageDataSequenceSequenceOrLong::operator=(const OwningImageDataSequenceSequenceOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eImageDataSequenceSequence: {
SetAsImageDataSequenceSequence() = aOther.GetAsImageDataSequenceSequence();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningLongOrBoolean::OwningLongOrBoolean(OwningLongOrBoolean&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
case eBoolean: {
mType = eBoolean;
mValue.mBoolean.SetValue(std::move(aOther.mValue.mBoolean.Value()));
break;
}
}
}
bool
OwningLongOrBoolean::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningLongOrBoolean::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningLongOrBoolean::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningLongOrBoolean::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningLongOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] bool&
OwningLongOrBoolean::RawSetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
[[nodiscard]] bool&
OwningLongOrBoolean::SetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
Uninit();
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
void
OwningLongOrBoolean::DestroyBoolean()
{
MOZ_RELEASE_ASSERT(IsBoolean(), "Wrong type!");
mValue.mBoolean.Destroy();
mType = eUninitialized;
}
bool
OwningLongOrBoolean::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningLongOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningLongOrBoolean::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eLong: {
DestroyLong();
break;
}
case eBoolean: {
DestroyBoolean();
break;
}
}
}
bool
OwningLongOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
OwningLongOrBoolean&
OwningLongOrBoolean::operator=(OwningLongOrBoolean&& aOther)
{
this->~OwningLongOrBoolean();
new (this) OwningLongOrBoolean (std::move(aOther));
return *this;
}
OwningLongOrBoolean&
OwningLongOrBoolean::operator=(const OwningLongOrBoolean& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
case eBoolean: {
SetAsBoolean() = aOther.GetAsBoolean();
break;
}
}
return *this;
}
OwningLongOrStringAnyRecord::OwningLongOrStringAnyRecord(OwningLongOrStringAnyRecord&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
case eStringAnyRecord: {
mType = eStringAnyRecord;
mValue.mStringAnyRecord.SetValue(std::move(aOther.mValue.mStringAnyRecord.Value()));
break;
}
}
}
bool
OwningLongOrStringAnyRecord::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (long or record<DOMString, any>)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningLongOrStringAnyRecord::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningLongOrStringAnyRecord::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningLongOrStringAnyRecord::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningLongOrStringAnyRecord::TrySetToStringAnyRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Record<nsString, JS::Value>& memberSlot = RawSetAsStringAnyRecord();
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, any> branch of (long or record<DOMString, any>)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, JS::Value>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
JS::Value& slot = entry->mValue;
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp)) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("value in record<DOMString, any> branch of (long or record<DOMString, any>)");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
slot = temp;
}
}
return true;
}
bool
OwningLongOrStringAnyRecord::TrySetToStringAnyRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringAnyRecord(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Record<nsString, JS::Value>&
OwningLongOrStringAnyRecord::RawSetAsStringAnyRecord()
{
if (mType == eStringAnyRecord) {
return mValue.mStringAnyRecord.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eStringAnyRecord;
return mValue.mStringAnyRecord.SetValue();
}
[[nodiscard]] Record<nsString, JS::Value>&
OwningLongOrStringAnyRecord::SetAsStringAnyRecord()
{
if (mType == eStringAnyRecord) {
return mValue.mStringAnyRecord.Value();
}
Uninit();
mType = eStringAnyRecord;
return mValue.mStringAnyRecord.SetValue();
}
void
OwningLongOrStringAnyRecord::DestroyStringAnyRecord()
{
MOZ_RELEASE_ASSERT(IsStringAnyRecord(), "Wrong type!");
mValue.mStringAnyRecord.Destroy();
mType = eUninitialized;
}
bool
OwningLongOrStringAnyRecord::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()) {
if (!done) {
done = (failed = !TrySetToStringAnyRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "record<DOMString, any>");
return false;
}
return true;
}
bool
OwningLongOrStringAnyRecord::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningLongOrStringAnyRecord::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eLong: {
DestroyLong();
break;
}
case eStringAnyRecord: {
DestroyStringAnyRecord();
break;
}
}
}
bool
OwningLongOrStringAnyRecord::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
case eStringAnyRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringAnyRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
JS::ExposeValueToActiveJS(recordValue0);
tmp.set(recordValue0);
if (!MaybeWrapValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
default: {
return false;
}
}
}
void
OwningLongOrStringAnyRecord::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eStringAnyRecord: {
TraceRecord(trc, mValue.mStringAnyRecord.Value());
break;
}
default: {
}
}
}
OwningLongOrStringAnyRecord&
OwningLongOrStringAnyRecord::operator=(OwningLongOrStringAnyRecord&& aOther)
{
this->~OwningLongOrStringAnyRecord();
new (this) OwningLongOrStringAnyRecord (std::move(aOther));
return *this;
}
OwningLongSequenceOrLong::OwningLongSequenceOrLong(OwningLongSequenceOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eLongSequence: {
mType = eLongSequence;
mValue.mLongSequence.SetValue(std::move(aOther.mValue.mLongSequence.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningLongSequenceOrLong::TrySetToLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<int32_t>& memberSlot = RawSetAsLongSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyLongSequence();
tryNext = true;
return true;
}
Sequence<int32_t> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
int32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
int32_t& slot = *slotPtr;
if (!ValueToPrimitive<int32_t, eDefault>(cx, temp, "Element of sequence<long> branch of (sequence<long> or long)", &slot)) {
return false;
}
}
}
return true;
}
bool
OwningLongSequenceOrLong::TrySetToLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToLongSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<int32_t>&
OwningLongSequenceOrLong::RawSetAsLongSequence()
{
if (mType == eLongSequence) {
return mValue.mLongSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLongSequence;
return mValue.mLongSequence.SetValue();
}
[[nodiscard]] Sequence<int32_t>&
OwningLongSequenceOrLong::SetAsLongSequence()
{
if (mType == eLongSequence) {
return mValue.mLongSequence.Value();
}
Uninit();
mType = eLongSequence;
return mValue.mLongSequence.SetValue();
}
void
OwningLongSequenceOrLong::DestroyLongSequence()
{
MOZ_RELEASE_ASSERT(IsLongSequence(), "Wrong type!");
mValue.mLongSequence.Destroy();
mType = eUninitialized;
}
bool
OwningLongSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<long> or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningLongSequenceOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningLongSequenceOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningLongSequenceOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningLongSequenceOrLong::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 = !TrySetToLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<long>");
return false;
}
return true;
}
bool
OwningLongSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningLongSequenceOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eLongSequence: {
DestroyLongSequence();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningLongSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eLongSequence: {
uint32_t length = mValue.mLongSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
tmp.setInt32(int32_t(mValue.mLongSequence.Value()[sequenceIdx0]));
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningLongSequenceOrLong&
OwningLongSequenceOrLong::operator=(OwningLongSequenceOrLong&& aOther)
{
this->~OwningLongSequenceOrLong();
new (this) OwningLongSequenceOrLong (std::move(aOther));
return *this;
}
OwningLongSequenceOrLong&
OwningLongSequenceOrLong::operator=(const OwningLongSequenceOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eLongSequence: {
SetAsLongSequence() = aOther.GetAsLongSequence();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningLongSequenceOrNullOrLong::OwningLongSequenceOrNullOrLong(OwningLongSequenceOrNullOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eLongSequence: {
mType = eLongSequence;
mValue.mLongSequence.SetValue(std::move(aOther.mValue.mLongSequence.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningLongSequenceOrNullOrLong::TrySetToLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<int32_t>& memberSlot = RawSetAsLongSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyLongSequence();
tryNext = true;
return true;
}
Sequence<int32_t> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
int32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
int32_t& slot = *slotPtr;
if (!ValueToPrimitive<int32_t, eDefault>(cx, temp, "Element of sequence<long> branch of (sequence<long>? or long)", &slot)) {
return false;
}
}
}
return true;
}
bool
OwningLongSequenceOrNullOrLong::TrySetToLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToLongSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<int32_t>&
OwningLongSequenceOrNullOrLong::RawSetAsLongSequence()
{
if (mType == eLongSequence) {
return mValue.mLongSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLongSequence;
return mValue.mLongSequence.SetValue();
}
[[nodiscard]] Sequence<int32_t>&
OwningLongSequenceOrNullOrLong::SetAsLongSequence()
{
if (mType == eLongSequence) {
return mValue.mLongSequence.Value();
}
Uninit();
mType = eLongSequence;
return mValue.mLongSequence.SetValue();
}
void
OwningLongSequenceOrNullOrLong::DestroyLongSequence()
{
MOZ_RELEASE_ASSERT(IsLongSequence(), "Wrong type!");
mValue.mLongSequence.Destroy();
mType = eUninitialized;
}
bool
OwningLongSequenceOrNullOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<long>? or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningLongSequenceOrNullOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningLongSequenceOrNullOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningLongSequenceOrNullOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningLongSequenceOrNullOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<long>");
return false;
}
}
return true;
}
bool
OwningLongSequenceOrNullOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningLongSequenceOrNullOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eNull: {
break;
}
case eLongSequence: {
DestroyLongSequence();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningLongSequenceOrNullOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eLongSequence: {
uint32_t length = mValue.mLongSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
tmp.setInt32(int32_t(mValue.mLongSequence.Value()[sequenceIdx0]));
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningLongSequenceOrNullOrLong&
OwningLongSequenceOrNullOrLong::operator=(OwningLongSequenceOrNullOrLong&& aOther)
{
this->~OwningLongSequenceOrNullOrLong();
new (this) OwningLongSequenceOrNullOrLong (std::move(aOther));
return *this;
}
OwningLongSequenceOrNullOrLong&
OwningLongSequenceOrNullOrLong::operator=(const OwningLongSequenceOrNullOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eLongSequence: {
SetAsLongSequence() = aOther.GetAsLongSequence();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer(OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
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;
}
}
}
bool
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle<JS::Value> 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::IsLargeArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
}
return true;
}
bool
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBufferView&
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::RawSetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
[[nodiscard]] ArrayBufferView&
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::SetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
Uninit();
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
void
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::DestroyArrayBufferView()
{
MOZ_RELEASE_ASSERT(IsArrayBufferView(), "Wrong type!");
mValue.mArrayBufferView.Destroy();
mType = eUninitialized;
}
bool
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> 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::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (ArrayBufferView or ArrayBuffer)");
return false;
}
}
return true;
}
bool
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBuffer&
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::RawSetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
[[nodiscard]] ArrayBuffer&
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::SetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
Uninit();
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
void
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::DestroyArrayBuffer()
{
MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!");
mValue.mArrayBuffer.Destroy();
mType = eUninitialized;
}
bool
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::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 = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBufferView, ArrayBuffer");
return false;
}
return true;
}
bool
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eArrayBufferView: {
DestroyArrayBufferView();
break;
}
case eArrayBuffer: {
DestroyArrayBuffer();
break;
}
}
}
bool
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
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;
}
default: {
return false;
}
}
}
void
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eArrayBufferView: {
mValue.mArrayBufferView.Value().TraceSelf(trc);
break;
}
case eArrayBuffer: {
mValue.mArrayBuffer.Value().TraceSelf(trc);
break;
}
default: {
}
}
}
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer&
OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer::operator=(OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer&& aOther)
{
this->~OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer();
new (this) OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer (std::move(aOther));
return *this;
}
OwningNodeOrLongOrBoolean::OwningNodeOrLongOrBoolean(OwningNodeOrLongOrBoolean&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNode: {
mType = eNode;
mValue.mNode.SetValue(std::move(aOther.mValue.mNode.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
case eBoolean: {
mType = eBoolean;
mValue.mBoolean.SetValue(std::move(aOther.mValue.mBoolean.Value()));
break;
}
}
}
bool
OwningNodeOrLongOrBoolean::TrySetToNode(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<nsINode>& memberSlot = RawSetAsNode();
static_assert(IsRefcounted<nsINode>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::Node, nsINode>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyNode();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningNodeOrLongOrBoolean::TrySetToNode(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToNode(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<nsINode>&
OwningNodeOrLongOrBoolean::RawSetAsNode()
{
if (mType == eNode) {
return mValue.mNode.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eNode;
return mValue.mNode.SetValue();
}
[[nodiscard]] OwningNonNull<nsINode>&
OwningNodeOrLongOrBoolean::SetAsNode()
{
if (mType == eNode) {
return mValue.mNode.Value();
}
Uninit();
mType = eNode;
return mValue.mNode.SetValue();
}
void
OwningNodeOrLongOrBoolean::DestroyNode()
{
MOZ_RELEASE_ASSERT(IsNode(), "Wrong type!");
mValue.mNode.Destroy();
mType = eUninitialized;
}
bool
OwningNodeOrLongOrBoolean::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (Node or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningNodeOrLongOrBoolean::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningNodeOrLongOrBoolean::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningNodeOrLongOrBoolean::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningNodeOrLongOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (Node or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] bool&
OwningNodeOrLongOrBoolean::RawSetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
[[nodiscard]] bool&
OwningNodeOrLongOrBoolean::SetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
Uninit();
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
void
OwningNodeOrLongOrBoolean::DestroyBoolean()
{
MOZ_RELEASE_ASSERT(IsBoolean(), "Wrong type!");
mValue.mBoolean.Destroy();
mType = eUninitialized;
}
bool
OwningNodeOrLongOrBoolean::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 = !TrySetToNode(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "Node");
return false;
}
return true;
}
bool
OwningNodeOrLongOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningNodeOrLongOrBoolean::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eNode: {
DestroyNode();
break;
}
case eLong: {
DestroyLong();
break;
}
case eBoolean: {
DestroyBoolean();
break;
}
}
}
bool
OwningNodeOrLongOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNode: {
if (!GetOrCreateDOMReflector(cx, mValue.mNode.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
OwningNodeOrLongOrBoolean&
OwningNodeOrLongOrBoolean::operator=(OwningNodeOrLongOrBoolean&& aOther)
{
this->~OwningNodeOrLongOrBoolean();
new (this) OwningNodeOrLongOrBoolean (std::move(aOther));
return *this;
}
OwningNodeOrLongOrBoolean&
OwningNodeOrLongOrBoolean::operator=(const OwningNodeOrLongOrBoolean& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNode: {
SetAsNode() = aOther.GetAsNode();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
case eBoolean: {
SetAsBoolean() = aOther.GetAsBoolean();
break;
}
}
return *this;
}
OwningNodeOrString::OwningNodeOrString(OwningNodeOrString&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNode: {
mType = eNode;
mValue.mNode.SetValue(std::move(aOther.mValue.mNode.Value()));
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
}
}
bool
OwningNodeOrString::TrySetToNode(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<nsINode>& memberSlot = RawSetAsNode();
static_assert(IsRefcounted<nsINode>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::Node, nsINode>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyNode();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningNodeOrString::TrySetToNode(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToNode(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<nsINode>&
OwningNodeOrString::RawSetAsNode()
{
if (mType == eNode) {
return mValue.mNode.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eNode;
return mValue.mNode.SetValue();
}
[[nodiscard]] OwningNonNull<nsINode>&
OwningNodeOrString::SetAsNode()
{
if (mType == eNode) {
return mValue.mNode.Value();
}
Uninit();
mType = eNode;
return mValue.mNode.SetValue();
}
void
OwningNodeOrString::DestroyNode()
{
MOZ_RELEASE_ASSERT(IsNode(), "Wrong type!");
mValue.mNode.Destroy();
mType = eUninitialized;
}
bool
OwningNodeOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningNodeOrString::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningNodeOrString::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningNodeOrString::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningNodeOrString::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 = !TrySetToNode(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "Node");
return false;
}
return true;
}
bool
OwningNodeOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningNodeOrString::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eNode: {
DestroyNode();
break;
}
case eString: {
DestroyString();
break;
}
}
}
bool
OwningNodeOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNode: {
if (!GetOrCreateDOMReflector(cx, mValue.mNode.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningNodeOrString&
OwningNodeOrString::operator=(OwningNodeOrString&& aOther)
{
this->~OwningNodeOrString();
new (this) OwningNodeOrString (std::move(aOther));
return *this;
}
OwningNodeOrString&
OwningNodeOrString::operator=(const OwningNodeOrString& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNode: {
SetAsNode() = aOther.GetAsNode();
break;
}
case eString: {
SetAsString() = aOther.GetAsString();
break;
}
}
return *this;
}
OwningObjectOrBoolean::OwningObjectOrBoolean(OwningObjectOrBoolean&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
case eBoolean: {
mType = eBoolean;
mValue.mBoolean.SetValue(std::move(aOther.mValue.mBoolean.Value()));
break;
}
}
}
[[nodiscard]] JSObject*&
OwningObjectOrBoolean::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningObjectOrBoolean::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningObjectOrBoolean::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (object or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] bool&
OwningObjectOrBoolean::RawSetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
[[nodiscard]] bool&
OwningObjectOrBoolean::SetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
Uninit();
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
void
OwningObjectOrBoolean::DestroyBoolean()
{
MOZ_RELEASE_ASSERT(IsBoolean(), "Wrong type!");
mValue.mBoolean.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrBoolean::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
OwningObjectOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningObjectOrBoolean::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eObject: {
DestroyObject();
break;
}
case eBoolean: {
DestroyBoolean();
break;
}
}
}
bool
OwningObjectOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
void
OwningObjectOrBoolean::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningObjectOrBoolean&
OwningObjectOrBoolean::operator=(OwningObjectOrBoolean&& aOther)
{
this->~OwningObjectOrBoolean();
new (this) OwningObjectOrBoolean (std::move(aOther));
return *this;
}
OwningObjectOrLong::OwningObjectOrLong(OwningObjectOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
[[nodiscard]] JSObject*&
OwningObjectOrLong::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningObjectOrLong::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningObjectOrLong::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningObjectOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningObjectOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningObjectOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrLong::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
OwningObjectOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningObjectOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eObject: {
DestroyObject();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningObjectOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
void
OwningObjectOrLong::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningObjectOrLong&
OwningObjectOrLong::operator=(OwningObjectOrLong&& aOther)
{
this->~OwningObjectOrLong();
new (this) OwningObjectOrLong (std::move(aOther));
return *this;
}
OwningObjectOrLongOrBoolean::OwningObjectOrLongOrBoolean(OwningObjectOrLongOrBoolean&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
case eBoolean: {
mType = eBoolean;
mValue.mBoolean.SetValue(std::move(aOther.mValue.mBoolean.Value()));
break;
}
}
}
[[nodiscard]] JSObject*&
OwningObjectOrLongOrBoolean::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningObjectOrLongOrBoolean::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningObjectOrLongOrBoolean::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrLongOrBoolean::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningObjectOrLongOrBoolean::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningObjectOrLongOrBoolean::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningObjectOrLongOrBoolean::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrLongOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (object or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] bool&
OwningObjectOrLongOrBoolean::RawSetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
[[nodiscard]] bool&
OwningObjectOrLongOrBoolean::SetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
Uninit();
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
void
OwningObjectOrLongOrBoolean::DestroyBoolean()
{
MOZ_RELEASE_ASSERT(IsBoolean(), "Wrong type!");
mValue.mBoolean.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrLongOrBoolean::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
OwningObjectOrLongOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningObjectOrLongOrBoolean::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eObject: {
DestroyObject();
break;
}
case eLong: {
DestroyLong();
break;
}
case eBoolean: {
DestroyBoolean();
break;
}
}
}
bool
OwningObjectOrLongOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
void
OwningObjectOrLongOrBoolean::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningObjectOrLongOrBoolean&
OwningObjectOrLongOrBoolean::operator=(OwningObjectOrLongOrBoolean&& aOther)
{
this->~OwningObjectOrLongOrBoolean();
new (this) OwningObjectOrLongOrBoolean (std::move(aOther));
return *this;
}
OwningObjectOrLongOrNull::OwningObjectOrLongOrNull(OwningObjectOrLongOrNull&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
[[nodiscard]] JSObject*&
OwningObjectOrLongOrNull::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningObjectOrLongOrNull::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningObjectOrLongOrNull::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrLongOrNull::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object or long?)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningObjectOrLongOrNull::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningObjectOrLongOrNull::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningObjectOrLongOrNull::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrLongOrNull::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
}
return true;
}
bool
OwningObjectOrLongOrNull::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningObjectOrLongOrNull::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eNull: {
break;
}
case eObject: {
DestroyObject();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningObjectOrLongOrNull::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
void
OwningObjectOrLongOrNull::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningObjectOrLongOrNull&
OwningObjectOrLongOrNull::operator=(OwningObjectOrLongOrNull&& aOther)
{
this->~OwningObjectOrLongOrNull();
new (this) OwningObjectOrLongOrNull (std::move(aOther));
return *this;
}
OwningObjectOrNullOrLong::OwningObjectOrNullOrLong(OwningObjectOrNullOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
[[nodiscard]] JSObject*&
OwningObjectOrNullOrLong::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningObjectOrNullOrLong::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningObjectOrNullOrLong::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrNullOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object? or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningObjectOrNullOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningObjectOrNullOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningObjectOrNullOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrNullOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
}
return true;
}
bool
OwningObjectOrNullOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningObjectOrNullOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eNull: {
break;
}
case eObject: {
DestroyObject();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningObjectOrNullOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
void
OwningObjectOrNullOrLong::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningObjectOrNullOrLong&
OwningObjectOrNullOrLong::operator=(OwningObjectOrNullOrLong&& aOther)
{
this->~OwningObjectOrNullOrLong();
new (this) OwningObjectOrNullOrLong (std::move(aOther));
return *this;
}
OwningObjectOrString::OwningObjectOrString(OwningObjectOrString&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
}
}
[[nodiscard]] JSObject*&
OwningObjectOrString::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningObjectOrString::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningObjectOrString::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningObjectOrString::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningObjectOrString::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningObjectOrString::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrString::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
OwningObjectOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningObjectOrString::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eObject: {
DestroyObject();
break;
}
case eString: {
DestroyString();
break;
}
}
}
bool
OwningObjectOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
void
OwningObjectOrString::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningObjectOrString&
OwningObjectOrString::operator=(OwningObjectOrString&& aOther)
{
this->~OwningObjectOrString();
new (this) OwningObjectOrString (std::move(aOther));
return *this;
}
OwningObjectOrStringOrBoolean::OwningObjectOrStringOrBoolean(OwningObjectOrStringOrBoolean&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
case eBoolean: {
mType = eBoolean;
mValue.mBoolean.SetValue(std::move(aOther.mValue.mBoolean.Value()));
break;
}
}
}
[[nodiscard]] JSObject*&
OwningObjectOrStringOrBoolean::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningObjectOrStringOrBoolean::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningObjectOrStringOrBoolean::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrStringOrBoolean::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningObjectOrStringOrBoolean::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningObjectOrStringOrBoolean::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningObjectOrStringOrBoolean::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrStringOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (object or DOMString or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] bool&
OwningObjectOrStringOrBoolean::RawSetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
[[nodiscard]] bool&
OwningObjectOrStringOrBoolean::SetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
Uninit();
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
void
OwningObjectOrStringOrBoolean::DestroyBoolean()
{
MOZ_RELEASE_ASSERT(IsBoolean(), "Wrong type!");
mValue.mBoolean.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrStringOrBoolean::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
OwningObjectOrStringOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningObjectOrStringOrBoolean::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eObject: {
DestroyObject();
break;
}
case eString: {
DestroyString();
break;
}
case eBoolean: {
DestroyBoolean();
break;
}
}
}
bool
OwningObjectOrStringOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
void
OwningObjectOrStringOrBoolean::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningObjectOrStringOrBoolean&
OwningObjectOrStringOrBoolean::operator=(OwningObjectOrStringOrBoolean&& aOther)
{
this->~OwningObjectOrStringOrBoolean();
new (this) OwningObjectOrStringOrBoolean (std::move(aOther));
return *this;
}
OwningObjectOrStringOrLong::OwningObjectOrStringOrLong(OwningObjectOrStringOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
[[nodiscard]] JSObject*&
OwningObjectOrStringOrLong::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningObjectOrStringOrLong::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningObjectOrStringOrLong::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrStringOrLong::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningObjectOrStringOrLong::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningObjectOrStringOrLong::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningObjectOrStringOrLong::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrStringOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object or DOMString or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningObjectOrStringOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningObjectOrStringOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningObjectOrStringOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrStringOrLong::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
OwningObjectOrStringOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningObjectOrStringOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eObject: {
DestroyObject();
break;
}
case eString: {
DestroyString();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningObjectOrStringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
void
OwningObjectOrStringOrLong::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningObjectOrStringOrLong&
OwningObjectOrStringOrLong::operator=(OwningObjectOrStringOrLong&& aOther)
{
this->~OwningObjectOrStringOrLong();
new (this) OwningObjectOrStringOrLong (std::move(aOther));
return *this;
}
OwningObjectOrStringOrLongOrBoolean::OwningObjectOrStringOrLongOrBoolean(OwningObjectOrStringOrLongOrBoolean&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
case eBoolean: {
mType = eBoolean;
mValue.mBoolean.SetValue(std::move(aOther.mValue.mBoolean.Value()));
break;
}
}
}
[[nodiscard]] JSObject*&
OwningObjectOrStringOrLongOrBoolean::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningObjectOrStringOrLongOrBoolean::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningObjectOrStringOrLongOrBoolean::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrStringOrLongOrBoolean::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningObjectOrStringOrLongOrBoolean::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningObjectOrStringOrLongOrBoolean::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningObjectOrStringOrLongOrBoolean::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrStringOrLongOrBoolean::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (object or DOMString or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningObjectOrStringOrLongOrBoolean::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningObjectOrStringOrLongOrBoolean::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningObjectOrStringOrLongOrBoolean::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrStringOrLongOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (object or DOMString or long or boolean)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] bool&
OwningObjectOrStringOrLongOrBoolean::RawSetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
[[nodiscard]] bool&
OwningObjectOrStringOrLongOrBoolean::SetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
Uninit();
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
void
OwningObjectOrStringOrLongOrBoolean::DestroyBoolean()
{
MOZ_RELEASE_ASSERT(IsBoolean(), "Wrong type!");
mValue.mBoolean.Destroy();
mType = eUninitialized;
}
bool
OwningObjectOrStringOrLongOrBoolean::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
OwningObjectOrStringOrLongOrBoolean::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningObjectOrStringOrLongOrBoolean::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eObject: {
DestroyObject();
break;
}
case eString: {
DestroyString();
break;
}
case eLong: {
DestroyLong();
break;
}
case eBoolean: {
DestroyBoolean();
break;
}
}
}
bool
OwningObjectOrStringOrLongOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
default: {
return false;
}
}
}
void
OwningObjectOrStringOrLongOrBoolean::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningObjectOrStringOrLongOrBoolean&
OwningObjectOrStringOrLongOrBoolean::operator=(OwningObjectOrStringOrLongOrBoolean&& aOther)
{
this->~OwningObjectOrStringOrLongOrBoolean();
new (this) OwningObjectOrStringOrLongOrBoolean (std::move(aOther));
return *this;
}
OwningObjectSequenceOrLong::OwningObjectSequenceOrLong(OwningObjectSequenceOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eObjectSequence: {
mType = eObjectSequence;
mValue.mObjectSequence.SetValue(std::move(aOther.mValue.mObjectSequence.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningObjectSequenceOrLong::TrySetToObjectSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<JSObject*>& memberSlot = RawSetAsObjectSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyObjectSequence();
tryNext = true;
return true;
}
Sequence<JSObject*> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
JSObject** slotPtr = arr.AppendElement(nullptr, mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
JSObject*& slot = *slotPtr;
if (temp.isObject()) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp)) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("element of sequence<object> branch of (sequence<object> or long)");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
slot = &temp.toObject();
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of sequence<object> branch of (sequence<object> or long)");
return false;
}
}
}
return true;
}
bool
OwningObjectSequenceOrLong::TrySetToObjectSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToObjectSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<JSObject*>&
OwningObjectSequenceOrLong::RawSetAsObjectSequence()
{
if (mType == eObjectSequence) {
return mValue.mObjectSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObjectSequence;
return mValue.mObjectSequence.SetValue();
}
[[nodiscard]] Sequence<JSObject*>&
OwningObjectSequenceOrLong::SetAsObjectSequence()
{
if (mType == eObjectSequence) {
return mValue.mObjectSequence.Value();
}
Uninit();
mType = eObjectSequence;
return mValue.mObjectSequence.SetValue();
}
void
OwningObjectSequenceOrLong::DestroyObjectSequence()
{
MOZ_RELEASE_ASSERT(IsObjectSequence(), "Wrong type!");
mValue.mObjectSequence.Destroy();
mType = eUninitialized;
}
bool
OwningObjectSequenceOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (sequence<object> or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningObjectSequenceOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningObjectSequenceOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningObjectSequenceOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningObjectSequenceOrLong::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 = !TrySetToObjectSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<object>");
return false;
}
return true;
}
bool
OwningObjectSequenceOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningObjectSequenceOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eObjectSequence: {
DestroyObjectSequence();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningObjectSequenceOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eObjectSequence: {
uint32_t length = mValue.mObjectSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
JS::ExposeObjectToActiveJS(mValue.mObjectSequence.Value()[sequenceIdx0]);
tmp.setObject(*mValue.mObjectSequence.Value()[sequenceIdx0]);
if (!MaybeWrapObjectValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
void
OwningObjectSequenceOrLong::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObjectSequence: {
DoTraceSequence(trc, mValue.mObjectSequence.Value());
break;
}
default: {
}
}
}
OwningObjectSequenceOrLong&
OwningObjectSequenceOrLong::operator=(OwningObjectSequenceOrLong&& aOther)
{
this->~OwningObjectSequenceOrLong();
new (this) OwningObjectSequenceOrLong (std::move(aOther));
return *this;
}
OwningStringLongRecordOrLong::OwningStringLongRecordOrLong(OwningStringLongRecordOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eStringLongRecord: {
mType = eStringLongRecord;
mValue.mStringLongRecord.SetValue(std::move(aOther.mValue.mStringLongRecord.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningStringLongRecordOrLong::TrySetToStringLongRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Record<nsString, int32_t>& memberSlot = RawSetAsStringLongRecord();
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, long> branch of (record<DOMString, long> or long)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, int32_t>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
int32_t& slot = entry->mValue;
if (!ValueToPrimitive<int32_t, eDefault>(cx, temp, "Value in record<DOMString, long> branch of (record<DOMString, long> or long)", &slot)) {
return false;
}
}
}
return true;
}
bool
OwningStringLongRecordOrLong::TrySetToStringLongRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringLongRecord(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Record<nsString, int32_t>&
OwningStringLongRecordOrLong::RawSetAsStringLongRecord()
{
if (mType == eStringLongRecord) {
return mValue.mStringLongRecord.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eStringLongRecord;
return mValue.mStringLongRecord.SetValue();
}
[[nodiscard]] Record<nsString, int32_t>&
OwningStringLongRecordOrLong::SetAsStringLongRecord()
{
if (mType == eStringLongRecord) {
return mValue.mStringLongRecord.Value();
}
Uninit();
mType = eStringLongRecord;
return mValue.mStringLongRecord.SetValue();
}
void
OwningStringLongRecordOrLong::DestroyStringLongRecord()
{
MOZ_RELEASE_ASSERT(IsStringLongRecord(), "Wrong type!");
mValue.mStringLongRecord.Destroy();
mType = eUninitialized;
}
bool
OwningStringLongRecordOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (record<DOMString, long> or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningStringLongRecordOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningStringLongRecordOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningStringLongRecordOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningStringLongRecordOrLong::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()) {
if (!done) {
done = (failed = !TrySetToStringLongRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "record<DOMString, long>");
return false;
}
return true;
}
bool
OwningStringLongRecordOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringLongRecordOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eStringLongRecord: {
DestroyStringLongRecord();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningStringLongRecordOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringLongRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringLongRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
tmp.setInt32(int32_t(recordValue0));
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningStringLongRecordOrLong&
OwningStringLongRecordOrLong::operator=(OwningStringLongRecordOrLong&& aOther)
{
this->~OwningStringLongRecordOrLong();
new (this) OwningStringLongRecordOrLong (std::move(aOther));
return *this;
}
OwningStringObjectRecordOrLong::OwningStringObjectRecordOrLong(OwningStringObjectRecordOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eStringObjectRecord: {
mType = eStringObjectRecord;
mValue.mStringObjectRecord.SetValue(std::move(aOther.mValue.mStringObjectRecord.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningStringObjectRecordOrLong::TrySetToStringObjectRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Record<nsString, JSObject*>& memberSlot = RawSetAsStringObjectRecord();
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, object> branch of (record<DOMString, object> or long)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, JSObject*>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
JSObject*& slot = entry->mValue;
if (temp.isObject()) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp)) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("value in record<DOMString, object> branch of (record<DOMString, object> or long)");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
slot = &temp.toObject();
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Value in record<DOMString, object> branch of (record<DOMString, object> or long)");
return false;
}
}
}
return true;
}
bool
OwningStringObjectRecordOrLong::TrySetToStringObjectRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringObjectRecord(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Record<nsString, JSObject*>&
OwningStringObjectRecordOrLong::RawSetAsStringObjectRecord()
{
if (mType == eStringObjectRecord) {
return mValue.mStringObjectRecord.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eStringObjectRecord;
return mValue.mStringObjectRecord.SetValue();
}
[[nodiscard]] Record<nsString, JSObject*>&
OwningStringObjectRecordOrLong::SetAsStringObjectRecord()
{
if (mType == eStringObjectRecord) {
return mValue.mStringObjectRecord.Value();
}
Uninit();
mType = eStringObjectRecord;
return mValue.mStringObjectRecord.SetValue();
}
void
OwningStringObjectRecordOrLong::DestroyStringObjectRecord()
{
MOZ_RELEASE_ASSERT(IsStringObjectRecord(), "Wrong type!");
mValue.mStringObjectRecord.Destroy();
mType = eUninitialized;
}
bool
OwningStringObjectRecordOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (record<DOMString, object> or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningStringObjectRecordOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningStringObjectRecordOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningStringObjectRecordOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningStringObjectRecordOrLong::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()) {
if (!done) {
done = (failed = !TrySetToStringObjectRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (!done) {
do {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "record<DOMString, object>");
return false;
}
return true;
}
bool
OwningStringObjectRecordOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringObjectRecordOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eStringObjectRecord: {
DestroyStringObjectRecord();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningStringObjectRecordOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringObjectRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringObjectRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
JS::ExposeObjectToActiveJS(recordValue0);
tmp.setObject(*recordValue0);
if (!MaybeWrapObjectValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
void
OwningStringObjectRecordOrLong::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eStringObjectRecord: {
TraceRecord(trc, mValue.mStringObjectRecord.Value());
break;
}
default: {
}
}
}
OwningStringObjectRecordOrLong&
OwningStringObjectRecordOrLong::operator=(OwningStringObjectRecordOrLong&& aOther)
{
this->~OwningStringObjectRecordOrLong();
new (this) OwningStringObjectRecordOrLong (std::move(aOther));
return *this;
}
OwningStringOrArrayBuffer::OwningStringOrArrayBuffer(OwningStringOrArrayBuffer&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
case eArrayBuffer: {
mType = eArrayBuffer;
mValue.mArrayBuffer.SetValue(std::move(aOther.mValue.mArrayBuffer.Value()));
break;
}
}
}
bool
OwningStringOrArrayBuffer::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningStringOrArrayBuffer::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningStringOrArrayBuffer::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningStringOrArrayBuffer::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningStringOrArrayBuffer::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> 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<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (DOMString or ArrayBuffer)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (DOMString or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (DOMString or ArrayBuffer)");
return false;
}
}
return true;
}
bool
OwningStringOrArrayBuffer::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBuffer&
OwningStringOrArrayBuffer::RawSetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
[[nodiscard]] ArrayBuffer&
OwningStringOrArrayBuffer::SetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
Uninit();
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
void
OwningStringOrArrayBuffer::DestroyArrayBuffer()
{
MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!");
mValue.mArrayBuffer.Destroy();
mType = eUninitialized;
}
bool
OwningStringOrArrayBuffer::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 = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBuffer");
return false;
}
return true;
}
bool
OwningStringOrArrayBuffer::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringOrArrayBuffer::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eString: {
DestroyString();
break;
}
case eArrayBuffer: {
DestroyArrayBuffer();
break;
}
}
}
bool
OwningStringOrArrayBuffer::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
void
OwningStringOrArrayBuffer::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eArrayBuffer: {
mValue.mArrayBuffer.Value().TraceSelf(trc);
break;
}
default: {
}
}
}
OwningStringOrArrayBuffer&
OwningStringOrArrayBuffer::operator=(OwningStringOrArrayBuffer&& aOther)
{
this->~OwningStringOrArrayBuffer();
new (this) OwningStringOrArrayBuffer (std::move(aOther));
return *this;
}
OwningStringOrBooleanOrObject::OwningStringOrBooleanOrObject(OwningStringOrBooleanOrObject&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
case eBoolean: {
mType = eBoolean;
mValue.mBoolean.SetValue(std::move(aOther.mValue.mBoolean.Value()));
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
}
}
bool
OwningStringOrBooleanOrObject::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningStringOrBooleanOrObject::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningStringOrBooleanOrObject::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningStringOrBooleanOrObject::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningStringOrBooleanOrObject::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
bool& memberSlot = RawSetAsBoolean();
if (!ValueToPrimitive<bool, eDefault>(cx, value, "Boolean branch of (DOMString or boolean or object)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] bool&
OwningStringOrBooleanOrObject::RawSetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
[[nodiscard]] bool&
OwningStringOrBooleanOrObject::SetAsBoolean()
{
if (mType == eBoolean) {
return mValue.mBoolean.Value();
}
Uninit();
mType = eBoolean;
return mValue.mBoolean.SetValue();
}
void
OwningStringOrBooleanOrObject::DestroyBoolean()
{
MOZ_RELEASE_ASSERT(IsBoolean(), "Wrong type!");
mValue.mBoolean.Destroy();
mType = eUninitialized;
}
[[nodiscard]] JSObject*&
OwningStringOrBooleanOrObject::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningStringOrBooleanOrObject::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningStringOrBooleanOrObject::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningStringOrBooleanOrObject::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
if (value.isBoolean()) {
done = (failed = !TrySetToBoolean(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
OwningStringOrBooleanOrObject::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringOrBooleanOrObject::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eString: {
DestroyString();
break;
}
case eBoolean: {
DestroyBoolean();
break;
}
case eObject: {
DestroyObject();
break;
}
}
}
bool
OwningStringOrBooleanOrObject::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eBoolean: {
rval.setBoolean(mValue.mBoolean.Value());
return true;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
void
OwningStringOrBooleanOrObject::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningStringOrBooleanOrObject&
OwningStringOrBooleanOrObject::operator=(OwningStringOrBooleanOrObject&& aOther)
{
this->~OwningStringOrBooleanOrObject();
new (this) OwningStringOrBooleanOrObject (std::move(aOther));
return *this;
}
OwningStringOrLong::OwningStringOrLong(OwningStringOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningStringOrLong::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningStringOrLong::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningStringOrLong::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningStringOrLong::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningStringOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (DOMString or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningStringOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningStringOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningStringOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningStringOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningStringOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eString: {
DestroyString();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningStringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningStringOrLong&
OwningStringOrLong::operator=(OwningStringOrLong&& aOther)
{
this->~OwningStringOrLong();
new (this) OwningStringOrLong (std::move(aOther));
return *this;
}
OwningStringOrLong&
OwningStringOrLong::operator=(const OwningStringOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eString: {
SetAsString() = aOther.GetAsString();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningStringOrMaybeSharedArrayBuffer::OwningStringOrMaybeSharedArrayBuffer(OwningStringOrMaybeSharedArrayBuffer&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
case eArrayBuffer: {
mType = eArrayBuffer;
mValue.mArrayBuffer.SetValue(std::move(aOther.mValue.mArrayBuffer.Value()));
break;
}
}
}
bool
OwningStringOrMaybeSharedArrayBuffer::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningStringOrMaybeSharedArrayBuffer::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningStringOrMaybeSharedArrayBuffer::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningStringOrMaybeSharedArrayBuffer::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningStringOrMaybeSharedArrayBuffer::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> 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::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (DOMString or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (DOMString or ArrayBuffer)");
return false;
}
}
return true;
}
bool
OwningStringOrMaybeSharedArrayBuffer::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBuffer&
OwningStringOrMaybeSharedArrayBuffer::RawSetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
[[nodiscard]] ArrayBuffer&
OwningStringOrMaybeSharedArrayBuffer::SetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
Uninit();
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
void
OwningStringOrMaybeSharedArrayBuffer::DestroyArrayBuffer()
{
MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!");
mValue.mArrayBuffer.Destroy();
mType = eUninitialized;
}
bool
OwningStringOrMaybeSharedArrayBuffer::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 = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBuffer");
return false;
}
return true;
}
bool
OwningStringOrMaybeSharedArrayBuffer::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringOrMaybeSharedArrayBuffer::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eString: {
DestroyString();
break;
}
case eArrayBuffer: {
DestroyArrayBuffer();
break;
}
}
}
bool
OwningStringOrMaybeSharedArrayBuffer::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
void
OwningStringOrMaybeSharedArrayBuffer::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eArrayBuffer: {
mValue.mArrayBuffer.Value().TraceSelf(trc);
break;
}
default: {
}
}
}
OwningStringOrMaybeSharedArrayBuffer&
OwningStringOrMaybeSharedArrayBuffer::operator=(OwningStringOrMaybeSharedArrayBuffer&& aOther)
{
this->~OwningStringOrMaybeSharedArrayBuffer();
new (this) OwningStringOrMaybeSharedArrayBuffer (std::move(aOther));
return *this;
}
OwningStringOrObject::OwningStringOrObject(OwningStringOrObject&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
}
}
bool
OwningStringOrObject::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningStringOrObject::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningStringOrObject::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningStringOrObject::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
[[nodiscard]] JSObject*&
OwningStringOrObject::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningStringOrObject::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningStringOrObject::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningStringOrObject::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
OwningStringOrObject::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringOrObject::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eString: {
DestroyString();
break;
}
case eObject: {
DestroyObject();
break;
}
}
}
bool
OwningStringOrObject::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
void
OwningStringOrObject::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningStringOrObject&
OwningStringOrObject::operator=(OwningStringOrObject&& aOther)
{
this->~OwningStringOrObject();
new (this) OwningStringOrObject (std::move(aOther));
return *this;
}
OwningStringOrStringSequence::OwningStringOrStringSequence(OwningStringOrStringSequence&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
case eStringSequence: {
mType = eStringSequence;
mValue.mStringSequence.SetValue(std::move(aOther.mValue.mStringSequence.Value()));
break;
}
}
}
bool
OwningStringOrStringSequence::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningStringOrStringSequence::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningStringOrStringSequence::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningStringOrStringSequence::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningStringOrStringSequence::TrySetToStringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<nsString>& memberSlot = RawSetAsStringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyStringSequence();
tryNext = true;
return true;
}
Sequence<nsString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
OwningStringOrStringSequence::TrySetToStringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<nsString>&
OwningStringOrStringSequence::RawSetAsStringSequence()
{
if (mType == eStringSequence) {
return mValue.mStringSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eStringSequence;
return mValue.mStringSequence.SetValue();
}
[[nodiscard]] Sequence<nsString>&
OwningStringOrStringSequence::SetAsStringSequence()
{
if (mType == eStringSequence) {
return mValue.mStringSequence.Value();
}
Uninit();
mType = eStringSequence;
return mValue.mStringSequence.SetValue();
}
void
OwningStringOrStringSequence::DestroyStringSequence()
{
MOZ_RELEASE_ASSERT(IsStringSequence(), "Wrong type!");
mValue.mStringSequence.Destroy();
mType = eUninitialized;
}
bool
OwningStringOrStringSequence::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 = !TrySetToStringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<DOMString>");
return false;
}
return true;
}
bool
OwningStringOrStringSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringOrStringSequence::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eString: {
DestroyString();
break;
}
case eStringSequence: {
DestroyStringSequence();
break;
}
}
}
bool
OwningStringOrStringSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
case eStringSequence: {
uint32_t length = mValue.mStringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
default: {
return false;
}
}
}
OwningStringOrStringSequence&
OwningStringOrStringSequence::operator=(OwningStringOrStringSequence&& aOther)
{
this->~OwningStringOrStringSequence();
new (this) OwningStringOrStringSequence (std::move(aOther));
return *this;
}
OwningStringOrStringSequence&
OwningStringOrStringSequence::operator=(const OwningStringOrStringSequence& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eString: {
SetAsString() = aOther.GetAsString();
break;
}
case eStringSequence: {
SetAsStringSequence() = aOther.GetAsStringSequence();
break;
}
}
return *this;
}
OwningStringSequenceOrEventInit::OwningStringSequenceOrEventInit(OwningStringSequenceOrEventInit&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eStringSequence: {
mType = eStringSequence;
mValue.mStringSequence.SetValue(std::move(aOther.mValue.mStringSequence.Value()));
break;
}
case eEventInit: {
mType = eEventInit;
mValue.mEventInit.SetValue(std::move(aOther.mValue.mEventInit.Value()));
break;
}
}
}
bool
OwningStringSequenceOrEventInit::TrySetToStringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<nsString>& memberSlot = RawSetAsStringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyStringSequence();
tryNext = true;
return true;
}
Sequence<nsString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
OwningStringSequenceOrEventInit::TrySetToStringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<nsString>&
OwningStringSequenceOrEventInit::RawSetAsStringSequence()
{
if (mType == eStringSequence) {
return mValue.mStringSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eStringSequence;
return mValue.mStringSequence.SetValue();
}
[[nodiscard]] Sequence<nsString>&
OwningStringSequenceOrEventInit::SetAsStringSequence()
{
if (mType == eStringSequence) {
return mValue.mStringSequence.Value();
}
Uninit();
mType = eStringSequence;
return mValue.mStringSequence.SetValue();
}
void
OwningStringSequenceOrEventInit::DestroyStringSequence()
{
MOZ_RELEASE_ASSERT(IsStringSequence(), "Wrong type!");
mValue.mStringSequence.Destroy();
mType = eUninitialized;
}
bool
OwningStringSequenceOrEventInit::TrySetToEventInit(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
EventInit& memberSlot = RawSetAsEventInit();
if (!IsConvertibleToDictionary(value)) {
DestroyEventInit();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "EventInit branch of (sequence<DOMString> or EventInit)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
OwningStringSequenceOrEventInit::TrySetToEventInit(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToEventInit(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] EventInit&
OwningStringSequenceOrEventInit::RawSetAsEventInit()
{
if (mType == eEventInit) {
return mValue.mEventInit.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eEventInit;
return mValue.mEventInit.SetValue();
}
[[nodiscard]] EventInit&
OwningStringSequenceOrEventInit::SetAsEventInit()
{
if (mType == eEventInit) {
return mValue.mEventInit.Value();
}
Uninit();
mType = eEventInit;
return mValue.mEventInit.SetValue();
}
void
OwningStringSequenceOrEventInit::DestroyEventInit()
{
MOZ_RELEASE_ASSERT(IsEventInit(), "Wrong type!");
mValue.mEventInit.Destroy();
mType = eUninitialized;
}
bool
OwningStringSequenceOrEventInit::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 = !TrySetToStringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToEventInit(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<DOMString>, EventInit");
return false;
}
return true;
}
bool
OwningStringSequenceOrEventInit::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringSequenceOrEventInit::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eStringSequence: {
DestroyStringSequence();
break;
}
case eEventInit: {
DestroyEventInit();
break;
}
}
}
bool
OwningStringSequenceOrEventInit::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringSequence: {
uint32_t length = mValue.mStringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eEventInit: {
if (!mValue.mEventInit.Value().ToObjectInternal(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningStringSequenceOrEventInit&
OwningStringSequenceOrEventInit::operator=(OwningStringSequenceOrEventInit&& aOther)
{
this->~OwningStringSequenceOrEventInit();
new (this) OwningStringSequenceOrEventInit (std::move(aOther));
return *this;
}
OwningStringSequenceOrEventInit&
OwningStringSequenceOrEventInit::operator=(const OwningStringSequenceOrEventInit& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eStringSequence: {
SetAsStringSequence() = aOther.GetAsStringSequence();
break;
}
case eEventInit: {
SetAsEventInit() = aOther.GetAsEventInit();
break;
}
}
return *this;
}
OwningStringSequenceOrStringStringRecord::OwningStringSequenceOrStringStringRecord(OwningStringSequenceOrStringStringRecord&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eStringSequence: {
mType = eStringSequence;
mValue.mStringSequence.SetValue(std::move(aOther.mValue.mStringSequence.Value()));
break;
}
case eStringStringRecord: {
mType = eStringStringRecord;
mValue.mStringStringRecord.SetValue(std::move(aOther.mValue.mStringStringRecord.Value()));
break;
}
}
}
bool
OwningStringSequenceOrStringStringRecord::TrySetToStringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<nsString>& memberSlot = RawSetAsStringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyStringSequence();
tryNext = true;
return true;
}
Sequence<nsString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
OwningStringSequenceOrStringStringRecord::TrySetToStringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<nsString>&
OwningStringSequenceOrStringStringRecord::RawSetAsStringSequence()
{
if (mType == eStringSequence) {
return mValue.mStringSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eStringSequence;
return mValue.mStringSequence.SetValue();
}
[[nodiscard]] Sequence<nsString>&
OwningStringSequenceOrStringStringRecord::SetAsStringSequence()
{
if (mType == eStringSequence) {
return mValue.mStringSequence.Value();
}
Uninit();
mType = eStringSequence;
return mValue.mStringSequence.SetValue();
}
void
OwningStringSequenceOrStringStringRecord::DestroyStringSequence()
{
MOZ_RELEASE_ASSERT(IsStringSequence(), "Wrong type!");
mValue.mStringSequence.Destroy();
mType = eUninitialized;
}
bool
OwningStringSequenceOrStringStringRecord::TrySetToStringStringRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Record<nsString, nsString>& memberSlot = RawSetAsStringStringRecord();
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, DOMString> branch of (sequence<DOMString> or record<DOMString, DOMString>)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, nsString>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
nsString& slot = entry->mValue;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
OwningStringSequenceOrStringStringRecord::TrySetToStringStringRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Record<nsString, nsString>&
OwningStringSequenceOrStringStringRecord::RawSetAsStringStringRecord()
{
if (mType == eStringStringRecord) {
return mValue.mStringStringRecord.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eStringStringRecord;
return mValue.mStringStringRecord.SetValue();
}
[[nodiscard]] Record<nsString, nsString>&
OwningStringSequenceOrStringStringRecord::SetAsStringStringRecord()
{
if (mType == eStringStringRecord) {
return mValue.mStringStringRecord.Value();
}
Uninit();
mType = eStringStringRecord;
return mValue.mStringStringRecord.SetValue();
}
void
OwningStringSequenceOrStringStringRecord::DestroyStringStringRecord()
{
MOZ_RELEASE_ASSERT(IsStringStringRecord(), "Wrong type!");
mValue.mStringStringRecord.Destroy();
mType = eUninitialized;
}
bool
OwningStringSequenceOrStringStringRecord::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 = !TrySetToStringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
if (!done) {
done = (failed = !TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<DOMString>, record<DOMString, DOMString>");
return false;
}
return true;
}
bool
OwningStringSequenceOrStringStringRecord::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringSequenceOrStringStringRecord::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eStringSequence: {
DestroyStringSequence();
break;
}
case eStringStringRecord: {
DestroyStringStringRecord();
break;
}
}
}
bool
OwningStringSequenceOrStringStringRecord::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringSequence: {
uint32_t length = mValue.mStringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
case eStringStringRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringStringRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
if (!xpc::NonVoidStringToJsval(cx, recordValue0, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
default: {
return false;
}
}
}
OwningStringSequenceOrStringStringRecord&
OwningStringSequenceOrStringStringRecord::operator=(OwningStringSequenceOrStringStringRecord&& aOther)
{
this->~OwningStringSequenceOrStringStringRecord();
new (this) OwningStringSequenceOrStringStringRecord (std::move(aOther));
return *this;
}
OwningStringStringRecordOrString::OwningStringStringRecordOrString(OwningStringStringRecordOrString&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eStringStringRecord: {
mType = eStringStringRecord;
mValue.mStringStringRecord.SetValue(std::move(aOther.mValue.mStringStringRecord.Value()));
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
}
}
bool
OwningStringStringRecordOrString::TrySetToStringStringRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Record<nsString, nsString>& memberSlot = RawSetAsStringStringRecord();
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, DOMString> branch of (record<DOMString, DOMString> or DOMString)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, nsString>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
nsString& slot = entry->mValue;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
OwningStringStringRecordOrString::TrySetToStringStringRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Record<nsString, nsString>&
OwningStringStringRecordOrString::RawSetAsStringStringRecord()
{
if (mType == eStringStringRecord) {
return mValue.mStringStringRecord.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eStringStringRecord;
return mValue.mStringStringRecord.SetValue();
}
[[nodiscard]] Record<nsString, nsString>&
OwningStringStringRecordOrString::SetAsStringStringRecord()
{
if (mType == eStringStringRecord) {
return mValue.mStringStringRecord.Value();
}
Uninit();
mType = eStringStringRecord;
return mValue.mStringStringRecord.SetValue();
}
void
OwningStringStringRecordOrString::DestroyStringStringRecord()
{
MOZ_RELEASE_ASSERT(IsStringStringRecord(), "Wrong type!");
mValue.mStringStringRecord.Destroy();
mType = eUninitialized;
}
bool
OwningStringStringRecordOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningStringStringRecordOrString::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningStringStringRecordOrString::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningStringStringRecordOrString::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningStringStringRecordOrString::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()) {
if (!done) {
done = (failed = !TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (!done) {
do {
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "record<DOMString, DOMString>");
return false;
}
return true;
}
bool
OwningStringStringRecordOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringStringRecordOrString::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eStringStringRecord: {
DestroyStringStringRecord();
break;
}
case eString: {
DestroyString();
break;
}
}
}
bool
OwningStringStringRecordOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringStringRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringStringRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
if (!xpc::NonVoidStringToJsval(cx, recordValue0, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningStringStringRecordOrString&
OwningStringStringRecordOrString::operator=(OwningStringStringRecordOrString&& aOther)
{
this->~OwningStringStringRecordOrString();
new (this) OwningStringStringRecordOrString (std::move(aOther));
return *this;
}
OwningStringStringRecordOrStringSequence::OwningStringStringRecordOrStringSequence(OwningStringStringRecordOrStringSequence&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eStringStringRecord: {
mType = eStringStringRecord;
mValue.mStringStringRecord.SetValue(std::move(aOther.mValue.mStringStringRecord.Value()));
break;
}
case eStringSequence: {
mType = eStringSequence;
mValue.mStringSequence.SetValue(std::move(aOther.mValue.mStringSequence.Value()));
break;
}
}
}
bool
OwningStringStringRecordOrStringSequence::TrySetToStringStringRecord(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Record<nsString, nsString>& memberSlot = RawSetAsStringStringRecord();
auto& recordEntries = memberSlot.Entries();
JS::Rooted<JSObject*> recordObj(cx, &value.toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of record<DOMString, DOMString> branch of (record<DOMString, DOMString> or sequence<DOMString>)", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, nsString>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
nsString& slot = entry->mValue;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
OwningStringStringRecordOrStringSequence::TrySetToStringStringRecord(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Record<nsString, nsString>&
OwningStringStringRecordOrStringSequence::RawSetAsStringStringRecord()
{
if (mType == eStringStringRecord) {
return mValue.mStringStringRecord.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eStringStringRecord;
return mValue.mStringStringRecord.SetValue();
}
[[nodiscard]] Record<nsString, nsString>&
OwningStringStringRecordOrStringSequence::SetAsStringStringRecord()
{
if (mType == eStringStringRecord) {
return mValue.mStringStringRecord.Value();
}
Uninit();
mType = eStringStringRecord;
return mValue.mStringStringRecord.SetValue();
}
void
OwningStringStringRecordOrStringSequence::DestroyStringStringRecord()
{
MOZ_RELEASE_ASSERT(IsStringStringRecord(), "Wrong type!");
mValue.mStringStringRecord.Destroy();
mType = eUninitialized;
}
bool
OwningStringStringRecordOrStringSequence::TrySetToStringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<nsString>& memberSlot = RawSetAsStringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyStringSequence();
tryNext = true;
return true;
}
Sequence<nsString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
OwningStringStringRecordOrStringSequence::TrySetToStringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToStringSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<nsString>&
OwningStringStringRecordOrStringSequence::RawSetAsStringSequence()
{
if (mType == eStringSequence) {
return mValue.mStringSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eStringSequence;
return mValue.mStringSequence.SetValue();
}
[[nodiscard]] Sequence<nsString>&
OwningStringStringRecordOrStringSequence::SetAsStringSequence()
{
if (mType == eStringSequence) {
return mValue.mStringSequence.Value();
}
Uninit();
mType = eStringSequence;
return mValue.mStringSequence.SetValue();
}
void
OwningStringStringRecordOrStringSequence::DestroyStringSequence()
{
MOZ_RELEASE_ASSERT(IsStringSequence(), "Wrong type!");
mValue.mStringSequence.Destroy();
mType = eUninitialized;
}
bool
OwningStringStringRecordOrStringSequence::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 = !TrySetToStringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
if (!done) {
done = (failed = !TrySetToStringStringRecord(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<DOMString>, record<DOMString, DOMString>");
return false;
}
return true;
}
bool
OwningStringStringRecordOrStringSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningStringStringRecordOrStringSequence::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eStringStringRecord: {
DestroyStringStringRecord();
break;
}
case eStringSequence: {
DestroyStringSequence();
break;
}
}
}
bool
OwningStringStringRecordOrStringSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eStringStringRecord: {
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : mValue.mStringStringRecord.Value().Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
if (!xpc::NonVoidStringToJsval(cx, recordValue0, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnObj);
return true;
}
case eStringSequence: {
uint32_t length = mValue.mStringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
default: {
return false;
}
}
}
OwningStringStringRecordOrStringSequence&
OwningStringStringRecordOrStringSequence::operator=(OwningStringStringRecordOrStringSequence&& aOther)
{
this->~OwningStringStringRecordOrStringSequence();
new (this) OwningStringStringRecordOrStringSequence (std::move(aOther));
return *this;
}
OwningSupportedTypeOrObject::OwningSupportedTypeOrObject(OwningSupportedTypeOrObject&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eSupportedType: {
mType = eSupportedType;
mValue.mSupportedType.SetValue(std::move(aOther.mValue.mSupportedType.Value()));
break;
}
case eObject: {
mType = eObject;
mValue.mObject.SetValue(std::move(aOther.mValue.mObject.Value()));
break;
}
}
}
bool
OwningSupportedTypeOrObject::TrySetToSupportedType(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
SupportedType& memberSlot = RawSetAsSupportedType();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, value,
binding_detail::EnumStrings<SupportedType>::Values,
"SupportedType", "SupportedType branch of (SupportedType or object)",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
memberSlot = static_cast<SupportedType>(index);
}
}
return true;
}
bool
OwningSupportedTypeOrObject::TrySetToSupportedType(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToSupportedType(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] SupportedType&
OwningSupportedTypeOrObject::RawSetAsSupportedType()
{
if (mType == eSupportedType) {
return mValue.mSupportedType.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eSupportedType;
return mValue.mSupportedType.SetValue();
}
[[nodiscard]] SupportedType&
OwningSupportedTypeOrObject::SetAsSupportedType()
{
if (mType == eSupportedType) {
return mValue.mSupportedType.Value();
}
Uninit();
mType = eSupportedType;
return mValue.mSupportedType.SetValue();
}
void
OwningSupportedTypeOrObject::DestroySupportedType()
{
MOZ_RELEASE_ASSERT(IsSupportedType(), "Wrong type!");
mValue.mSupportedType.Destroy();
mType = eUninitialized;
}
[[nodiscard]] JSObject*&
OwningSupportedTypeOrObject::RawSetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eObject;
return mValue.mObject.SetValue();
}
[[nodiscard]] JSObject*&
OwningSupportedTypeOrObject::SetAsObject()
{
if (mType == eObject) {
return mValue.mObject.Value();
}
Uninit();
mType = eObject;
return mValue.mObject.SetValue();
}
void
OwningSupportedTypeOrObject::DestroyObject()
{
MOZ_RELEASE_ASSERT(IsObject(), "Wrong type!");
mValue.mObject.Destroy();
mType = eUninitialized;
}
bool
OwningSupportedTypeOrObject::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()) {
if (!SetToObject(cx, &value.toObject(), passedToJSImpl)) {
return false;
}
done = true;
} else {
do {
done = (failed = !TrySetToSupportedType(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "object");
return false;
}
return true;
}
bool
OwningSupportedTypeOrObject::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningSupportedTypeOrObject::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eSupportedType: {
DestroySupportedType();
break;
}
case eObject: {
DestroyObject();
break;
}
}
}
bool
OwningSupportedTypeOrObject::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eSupportedType: {
if (!ToJSValue(cx, mValue.mSupportedType.Value(), rval)) {
return false;
}
return true;
}
case eObject: {
JS::ExposeObjectToActiveJS(mValue.mObject.Value());
rval.setObject(*mValue.mObject.Value());
if (!MaybeWrapObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
void
OwningSupportedTypeOrObject::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eObject: {
JS::TraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
break;
}
default: {
}
}
}
OwningSupportedTypeOrObject&
OwningSupportedTypeOrObject::operator=(OwningSupportedTypeOrObject&& aOther)
{
this->~OwningSupportedTypeOrObject();
new (this) OwningSupportedTypeOrObject (std::move(aOther));
return *this;
}
OwningUSVStringOrLong::OwningUSVStringOrLong(OwningUSVStringOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUSVString: {
mType = eUSVString;
mValue.mUSVString.SetValue(std::move(aOther.mValue.mUSVString.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningUSVStringOrLong::TrySetToUSVString(JSContext* cx, JS::Handle<JS::Value> 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&
OwningUSVStringOrLong::RawSetAsUSVString()
{
if (mType == eUSVString) {
return mValue.mUSVString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUSVString;
return mValue.mUSVString.SetValue();
}
[[nodiscard]] nsString&
OwningUSVStringOrLong::SetAsUSVString()
{
if (mType == eUSVString) {
return mValue.mUSVString.Value();
}
Uninit();
mType = eUSVString;
return mValue.mUSVString.SetValue();
}
void
OwningUSVStringOrLong::DestroyUSVString()
{
MOZ_RELEASE_ASSERT(IsUSVString(), "Wrong type!");
mValue.mUSVString.Destroy();
mType = eUninitialized;
}
bool
OwningUSVStringOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (USVString or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningUSVStringOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningUSVStringOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningUSVStringOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningUSVStringOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToUSVString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningUSVStringOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningUSVStringOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eUSVString: {
DestroyUSVString();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningUSVStringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUSVString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningUSVStringOrLong&
OwningUSVStringOrLong::operator=(OwningUSVStringOrLong&& aOther)
{
this->~OwningUSVStringOrLong();
new (this) OwningUSVStringOrLong (std::move(aOther));
return *this;
}
OwningUSVStringOrLong&
OwningUSVStringOrLong::operator=(const OwningUSVStringOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUSVString: {
SetAsUSVString() = aOther.GetAsUSVString();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningUTF8StringOrArrayBuffer::OwningUTF8StringOrArrayBuffer(OwningUTF8StringOrArrayBuffer&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUTF8String: {
mType = eUTF8String;
mValue.mUTF8String.SetValue(std::move(aOther.mValue.mUTF8String.Value()));
break;
}
case eArrayBuffer: {
mType = eArrayBuffer;
mValue.mArrayBuffer.SetValue(std::move(aOther.mValue.mArrayBuffer.Value()));
break;
}
}
}
bool
OwningUTF8StringOrArrayBuffer::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsCString& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsCString&
OwningUTF8StringOrArrayBuffer::RawSetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
[[nodiscard]] nsCString&
OwningUTF8StringOrArrayBuffer::SetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
Uninit();
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
void
OwningUTF8StringOrArrayBuffer::DestroyUTF8String()
{
MOZ_RELEASE_ASSERT(IsUTF8String(), "Wrong type!");
mValue.mUTF8String.Destroy();
mType = eUninitialized;
}
bool
OwningUTF8StringOrArrayBuffer::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> 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<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (USVString or ArrayBuffer)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (USVString or ArrayBuffer)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (USVString or ArrayBuffer)");
return false;
}
}
return true;
}
bool
OwningUTF8StringOrArrayBuffer::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBuffer&
OwningUTF8StringOrArrayBuffer::RawSetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
[[nodiscard]] ArrayBuffer&
OwningUTF8StringOrArrayBuffer::SetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
Uninit();
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
void
OwningUTF8StringOrArrayBuffer::DestroyArrayBuffer()
{
MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!");
mValue.mArrayBuffer.Destroy();
mType = eUninitialized;
}
bool
OwningUTF8StringOrArrayBuffer::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 = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBuffer");
return false;
}
return true;
}
bool
OwningUTF8StringOrArrayBuffer::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningUTF8StringOrArrayBuffer::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eUTF8String: {
DestroyUTF8String();
break;
}
case eArrayBuffer: {
DestroyArrayBuffer();
break;
}
}
}
bool
OwningUTF8StringOrArrayBuffer::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
void
OwningUTF8StringOrArrayBuffer::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eArrayBuffer: {
mValue.mArrayBuffer.Value().TraceSelf(trc);
break;
}
default: {
}
}
}
OwningUTF8StringOrArrayBuffer&
OwningUTF8StringOrArrayBuffer::operator=(OwningUTF8StringOrArrayBuffer&& aOther)
{
this->~OwningUTF8StringOrArrayBuffer();
new (this) OwningUTF8StringOrArrayBuffer (std::move(aOther));
return *this;
}
OwningUTF8StringOrArrayBufferOrNull::OwningUTF8StringOrArrayBufferOrNull(OwningUTF8StringOrArrayBufferOrNull&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eUTF8String: {
mType = eUTF8String;
mValue.mUTF8String.SetValue(std::move(aOther.mValue.mUTF8String.Value()));
break;
}
case eArrayBuffer: {
mType = eArrayBuffer;
mValue.mArrayBuffer.SetValue(std::move(aOther.mValue.mArrayBuffer.Value()));
break;
}
}
}
bool
OwningUTF8StringOrArrayBufferOrNull::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsCString& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsCString&
OwningUTF8StringOrArrayBufferOrNull::RawSetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
[[nodiscard]] nsCString&
OwningUTF8StringOrArrayBufferOrNull::SetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
Uninit();
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
void
OwningUTF8StringOrArrayBufferOrNull::DestroyUTF8String()
{
MOZ_RELEASE_ASSERT(IsUTF8String(), "Wrong type!");
mValue.mUTF8String.Destroy();
mType = eUninitialized;
}
bool
OwningUTF8StringOrArrayBufferOrNull::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> 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<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (USVString or ArrayBuffer?)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (USVString or ArrayBuffer?)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (USVString or ArrayBuffer?)");
return false;
}
}
return true;
}
bool
OwningUTF8StringOrArrayBufferOrNull::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBuffer&
OwningUTF8StringOrArrayBufferOrNull::RawSetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
[[nodiscard]] ArrayBuffer&
OwningUTF8StringOrArrayBufferOrNull::SetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
Uninit();
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
void
OwningUTF8StringOrArrayBufferOrNull::DestroyArrayBuffer()
{
MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!");
mValue.mArrayBuffer.Destroy();
mType = eUninitialized;
}
bool
OwningUTF8StringOrArrayBufferOrNull::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isNullOrUndefined()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBuffer");
return false;
}
}
return true;
}
bool
OwningUTF8StringOrArrayBufferOrNull::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningUTF8StringOrArrayBufferOrNull::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eNull: {
break;
}
case eUTF8String: {
DestroyUTF8String();
break;
}
case eArrayBuffer: {
DestroyArrayBuffer();
break;
}
}
}
bool
OwningUTF8StringOrArrayBufferOrNull::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
void
OwningUTF8StringOrArrayBufferOrNull::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eArrayBuffer: {
mValue.mArrayBuffer.Value().TraceSelf(trc);
break;
}
default: {
}
}
}
OwningUTF8StringOrArrayBufferOrNull&
OwningUTF8StringOrArrayBufferOrNull::operator=(OwningUTF8StringOrArrayBufferOrNull&& aOther)
{
this->~OwningUTF8StringOrArrayBufferOrNull();
new (this) OwningUTF8StringOrArrayBufferOrNull (std::move(aOther));
return *this;
}
OwningUTF8StringOrLong::OwningUTF8StringOrLong(OwningUTF8StringOrLong&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUTF8String: {
mType = eUTF8String;
mValue.mUTF8String.SetValue(std::move(aOther.mValue.mUTF8String.Value()));
break;
}
case eLong: {
mType = eLong;
mValue.mLong.SetValue(std::move(aOther.mValue.mLong.Value()));
break;
}
}
}
bool
OwningUTF8StringOrLong::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsCString& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsCString&
OwningUTF8StringOrLong::RawSetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
[[nodiscard]] nsCString&
OwningUTF8StringOrLong::SetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
Uninit();
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
void
OwningUTF8StringOrLong::DestroyUTF8String()
{
MOZ_RELEASE_ASSERT(IsUTF8String(), "Wrong type!");
mValue.mUTF8String.Destroy();
mType = eUninitialized;
}
bool
OwningUTF8StringOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
int32_t& memberSlot = RawSetAsLong();
if (!ValueToPrimitive<int32_t, eDefault>(cx, value, "Long branch of (USVString or long)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] int32_t&
OwningUTF8StringOrLong::RawSetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eLong;
return mValue.mLong.SetValue();
}
[[nodiscard]] int32_t&
OwningUTF8StringOrLong::SetAsLong()
{
if (mType == eLong) {
return mValue.mLong.Value();
}
Uninit();
mType = eLong;
return mValue.mLong.SetValue();
}
void
OwningUTF8StringOrLong::DestroyLong()
{
MOZ_RELEASE_ASSERT(IsLong(), "Wrong type!");
mValue.mLong.Destroy();
mType = eUninitialized;
}
bool
OwningUTF8StringOrLong::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToLong(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningUTF8StringOrLong::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningUTF8StringOrLong::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eUTF8String: {
DestroyUTF8String();
break;
}
case eLong: {
DestroyLong();
break;
}
}
}
bool
OwningUTF8StringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
case eLong: {
rval.setInt32(int32_t(mValue.mLong.Value()));
return true;
}
default: {
return false;
}
}
}
OwningUTF8StringOrLong&
OwningUTF8StringOrLong::operator=(OwningUTF8StringOrLong&& aOther)
{
this->~OwningUTF8StringOrLong();
new (this) OwningUTF8StringOrLong (std::move(aOther));
return *this;
}
OwningUTF8StringOrLong&
OwningUTF8StringOrLong::operator=(const OwningUTF8StringOrLong& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUTF8String: {
SetAsUTF8String() = aOther.GetAsUTF8String();
break;
}
case eLong: {
SetAsLong() = aOther.GetAsLong();
break;
}
}
return *this;
}
OwningUTF8StringOrUTF8StringSequence::OwningUTF8StringOrUTF8StringSequence(OwningUTF8StringOrUTF8StringSequence&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUTF8String: {
mType = eUTF8String;
mValue.mUTF8String.SetValue(std::move(aOther.mValue.mUTF8String.Value()));
break;
}
case eUTF8StringSequence: {
mType = eUTF8StringSequence;
mValue.mUTF8StringSequence.SetValue(std::move(aOther.mValue.mUTF8StringSequence.Value()));
break;
}
}
}
bool
OwningUTF8StringOrUTF8StringSequence::TrySetToUTF8String(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsCString& memberSlot = RawSetAsUTF8String();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsCString&
OwningUTF8StringOrUTF8StringSequence::RawSetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
[[nodiscard]] nsCString&
OwningUTF8StringOrUTF8StringSequence::SetAsUTF8String()
{
if (mType == eUTF8String) {
return mValue.mUTF8String.Value();
}
Uninit();
mType = eUTF8String;
return mValue.mUTF8String.SetValue();
}
void
OwningUTF8StringOrUTF8StringSequence::DestroyUTF8String()
{
MOZ_RELEASE_ASSERT(IsUTF8String(), "Wrong type!");
mValue.mUTF8String.Destroy();
mType = eUninitialized;
}
bool
OwningUTF8StringOrUTF8StringSequence::TrySetToUTF8StringSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<nsCString>& memberSlot = RawSetAsUTF8StringSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyUTF8StringSequence();
tryNext = true;
return true;
}
Sequence<nsCString> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsCString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsCString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
}
return true;
}
bool
OwningUTF8StringOrUTF8StringSequence::TrySetToUTF8StringSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToUTF8StringSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<nsCString>&
OwningUTF8StringOrUTF8StringSequence::RawSetAsUTF8StringSequence()
{
if (mType == eUTF8StringSequence) {
return mValue.mUTF8StringSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUTF8StringSequence;
return mValue.mUTF8StringSequence.SetValue();
}
[[nodiscard]] Sequence<nsCString>&
OwningUTF8StringOrUTF8StringSequence::SetAsUTF8StringSequence()
{
if (mType == eUTF8StringSequence) {
return mValue.mUTF8StringSequence.Value();
}
Uninit();
mType = eUTF8StringSequence;
return mValue.mUTF8StringSequence.SetValue();
}
void
OwningUTF8StringOrUTF8StringSequence::DestroyUTF8StringSequence()
{
MOZ_RELEASE_ASSERT(IsUTF8StringSequence(), "Wrong type!");
mValue.mUTF8StringSequence.Destroy();
mType = eUninitialized;
}
bool
OwningUTF8StringOrUTF8StringSequence::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 = !TrySetToUTF8StringSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<USVString>");
return false;
}
return true;
}
bool
OwningUTF8StringOrUTF8StringSequence::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningUTF8StringOrUTF8StringSequence::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eUTF8String: {
DestroyUTF8String();
break;
}
case eUTF8StringSequence: {
DestroyUTF8StringSequence();
break;
}
}
}
bool
OwningUTF8StringOrUTF8StringSequence::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUTF8String: {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) {
return false;
}
return true;
}
case eUTF8StringSequence: {
uint32_t length = mValue.mUTF8StringSequence.Value().Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8StringSequence.Value()[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
rval.setObject(*returnArray);
return true;
}
default: {
return false;
}
}
}
OwningUTF8StringOrUTF8StringSequence&
OwningUTF8StringOrUTF8StringSequence::operator=(OwningUTF8StringOrUTF8StringSequence&& aOther)
{
this->~OwningUTF8StringOrUTF8StringSequence();
new (this) OwningUTF8StringOrUTF8StringSequence (std::move(aOther));
return *this;
}
OwningUTF8StringOrUTF8StringSequence&
OwningUTF8StringOrUTF8StringSequence::operator=(const OwningUTF8StringOrUTF8StringSequence& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUTF8String: {
SetAsUTF8String() = aOther.GetAsUTF8String();
break;
}
case eUTF8StringSequence: {
SetAsUTF8StringSequence() = aOther.GetAsUTF8StringSequence();
break;
}
}
return *this;
}
OwningUndefinedOrCanvasPattern::OwningUndefinedOrCanvasPattern(OwningUndefinedOrCanvasPattern&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUndefined: {
MOZ_ASSERT(mType == eUninitialized);
mType = eUndefined;
break;
}
case eCanvasPattern: {
mType = eCanvasPattern;
mValue.mCanvasPattern.SetValue(std::move(aOther.mValue.mCanvasPattern.Value()));
break;
}
}
}
bool
OwningUndefinedOrCanvasPattern::TrySetToCanvasPattern(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::CanvasPattern>& memberSlot = RawSetAsCanvasPattern();
static_assert(IsRefcounted<mozilla::dom::CanvasPattern>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasPattern, mozilla::dom::CanvasPattern>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasPattern();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningUndefinedOrCanvasPattern::TrySetToCanvasPattern(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasPattern>&
OwningUndefinedOrCanvasPattern::RawSetAsCanvasPattern()
{
if (mType == eCanvasPattern) {
return mValue.mCanvasPattern.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eCanvasPattern;
return mValue.mCanvasPattern.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasPattern>&
OwningUndefinedOrCanvasPattern::SetAsCanvasPattern()
{
if (mType == eCanvasPattern) {
return mValue.mCanvasPattern.Value();
}
Uninit();
mType = eCanvasPattern;
return mValue.mCanvasPattern.SetValue();
}
void
OwningUndefinedOrCanvasPattern::DestroyCanvasPattern()
{
MOZ_RELEASE_ASSERT(IsCanvasPattern(), "Wrong type!");
mValue.mCanvasPattern.Destroy();
mType = eUninitialized;
}
bool
OwningUndefinedOrCanvasPattern::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isUndefined()) {
SetUndefined();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CanvasPattern");
return false;
}
}
return true;
}
bool
OwningUndefinedOrCanvasPattern::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningUndefinedOrCanvasPattern::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eUndefined: {
break;
}
case eCanvasPattern: {
DestroyCanvasPattern();
break;
}
}
}
bool
OwningUndefinedOrCanvasPattern::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUndefined: {
rval.setUndefined();
return true;
}
case eCanvasPattern: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasPattern.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningUndefinedOrCanvasPattern&
OwningUndefinedOrCanvasPattern::operator=(OwningUndefinedOrCanvasPattern&& aOther)
{
this->~OwningUndefinedOrCanvasPattern();
new (this) OwningUndefinedOrCanvasPattern (std::move(aOther));
return *this;
}
OwningUndefinedOrCanvasPattern&
OwningUndefinedOrCanvasPattern::operator=(const OwningUndefinedOrCanvasPattern& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUndefined: {
MOZ_ASSERT(mType == eUninitialized);
mType = eUndefined;
break;
}
case eCanvasPattern: {
SetAsCanvasPattern() = aOther.GetAsCanvasPattern();
break;
}
}
return *this;
}
OwningUndefinedOrCanvasPatternOrNull::OwningUndefinedOrCanvasPatternOrNull(OwningUndefinedOrCanvasPatternOrNull&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eUndefined: {
MOZ_ASSERT(mType == eUninitialized);
mType = eUndefined;
break;
}
case eCanvasPattern: {
mType = eCanvasPattern;
mValue.mCanvasPattern.SetValue(std::move(aOther.mValue.mCanvasPattern.Value()));
break;
}
}
}
bool
OwningUndefinedOrCanvasPatternOrNull::TrySetToCanvasPattern(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::CanvasPattern>& memberSlot = RawSetAsCanvasPattern();
static_assert(IsRefcounted<mozilla::dom::CanvasPattern>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasPattern, mozilla::dom::CanvasPattern>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasPattern();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningUndefinedOrCanvasPatternOrNull::TrySetToCanvasPattern(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasPattern>&
OwningUndefinedOrCanvasPatternOrNull::RawSetAsCanvasPattern()
{
if (mType == eCanvasPattern) {
return mValue.mCanvasPattern.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eCanvasPattern;
return mValue.mCanvasPattern.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasPattern>&
OwningUndefinedOrCanvasPatternOrNull::SetAsCanvasPattern()
{
if (mType == eCanvasPattern) {
return mValue.mCanvasPattern.Value();
}
Uninit();
mType = eCanvasPattern;
return mValue.mCanvasPattern.SetValue();
}
void
OwningUndefinedOrCanvasPatternOrNull::DestroyCanvasPattern()
{
MOZ_RELEASE_ASSERT(IsCanvasPattern(), "Wrong type!");
mValue.mCanvasPattern.Destroy();
mType = eUninitialized;
}
bool
OwningUndefinedOrCanvasPatternOrNull::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isUndefined()) {
SetUndefined();
} else if (value.isNull()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CanvasPattern");
return false;
}
}
return true;
}
bool
OwningUndefinedOrCanvasPatternOrNull::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningUndefinedOrCanvasPatternOrNull::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eNull: {
break;
}
case eUndefined: {
break;
}
case eCanvasPattern: {
DestroyCanvasPattern();
break;
}
}
}
bool
OwningUndefinedOrCanvasPatternOrNull::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eUndefined: {
rval.setUndefined();
return true;
}
case eCanvasPattern: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasPattern.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningUndefinedOrCanvasPatternOrNull&
OwningUndefinedOrCanvasPatternOrNull::operator=(OwningUndefinedOrCanvasPatternOrNull&& aOther)
{
this->~OwningUndefinedOrCanvasPatternOrNull();
new (this) OwningUndefinedOrCanvasPatternOrNull (std::move(aOther));
return *this;
}
OwningUndefinedOrCanvasPatternOrNull&
OwningUndefinedOrCanvasPatternOrNull::operator=(const OwningUndefinedOrCanvasPatternOrNull& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eUndefined: {
MOZ_ASSERT(mType == eUninitialized);
mType = eUndefined;
break;
}
case eCanvasPattern: {
SetAsCanvasPattern() = aOther.GetAsCanvasPattern();
break;
}
}
return *this;
}
OwningUndefinedOrNullOrCanvasPattern::OwningUndefinedOrNullOrCanvasPattern(OwningUndefinedOrNullOrCanvasPattern&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eUndefined: {
MOZ_ASSERT(mType == eUninitialized);
mType = eUndefined;
break;
}
case eCanvasPattern: {
mType = eCanvasPattern;
mValue.mCanvasPattern.SetValue(std::move(aOther.mValue.mCanvasPattern.Value()));
break;
}
}
}
bool
OwningUndefinedOrNullOrCanvasPattern::TrySetToCanvasPattern(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::CanvasPattern>& memberSlot = RawSetAsCanvasPattern();
static_assert(IsRefcounted<mozilla::dom::CanvasPattern>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::CanvasPattern, mozilla::dom::CanvasPattern>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyCanvasPattern();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningUndefinedOrNullOrCanvasPattern::TrySetToCanvasPattern(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasPattern>&
OwningUndefinedOrNullOrCanvasPattern::RawSetAsCanvasPattern()
{
if (mType == eCanvasPattern) {
return mValue.mCanvasPattern.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eCanvasPattern;
return mValue.mCanvasPattern.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::CanvasPattern>&
OwningUndefinedOrNullOrCanvasPattern::SetAsCanvasPattern()
{
if (mType == eCanvasPattern) {
return mValue.mCanvasPattern.Value();
}
Uninit();
mType = eCanvasPattern;
return mValue.mCanvasPattern.SetValue();
}
void
OwningUndefinedOrNullOrCanvasPattern::DestroyCanvasPattern()
{
MOZ_RELEASE_ASSERT(IsCanvasPattern(), "Wrong type!");
mValue.mCanvasPattern.Destroy();
mType = eUninitialized;
}
bool
OwningUndefinedOrNullOrCanvasPattern::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
if (value.isUndefined()) {
SetUndefined();
} else if (value.isNull()) {
SetNull();
} else {
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToCanvasPattern(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "CanvasPattern");
return false;
}
}
return true;
}
bool
OwningUndefinedOrNullOrCanvasPattern::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningUndefinedOrNullOrCanvasPattern::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eNull: {
break;
}
case eUndefined: {
break;
}
case eCanvasPattern: {
DestroyCanvasPattern();
break;
}
}
}
bool
OwningUndefinedOrNullOrCanvasPattern::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eNull: {
rval.setNull();
return true;
}
case eUndefined: {
rval.setUndefined();
return true;
}
case eCanvasPattern: {
if (!GetOrCreateDOMReflector(cx, mValue.mCanvasPattern.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningUndefinedOrNullOrCanvasPattern&
OwningUndefinedOrNullOrCanvasPattern::operator=(OwningUndefinedOrNullOrCanvasPattern&& aOther)
{
this->~OwningUndefinedOrNullOrCanvasPattern();
new (this) OwningUndefinedOrNullOrCanvasPattern (std::move(aOther));
return *this;
}
OwningUndefinedOrNullOrCanvasPattern&
OwningUndefinedOrNullOrCanvasPattern::operator=(const OwningUndefinedOrNullOrCanvasPattern& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eNull: {
MOZ_ASSERT(mType == eUninitialized);
mType = eNull;
break;
}
case eUndefined: {
MOZ_ASSERT(mType == eUninitialized);
mType = eUndefined;
break;
}
case eCanvasPattern: {
SetAsCanvasPattern() = aOther.GetAsCanvasPattern();
break;
}
}
return *this;
}
OwningUnrestrictedDoubleOrString::OwningUnrestrictedDoubleOrString(OwningUnrestrictedDoubleOrString&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUnrestrictedDouble: {
mType = eUnrestrictedDouble;
mValue.mUnrestrictedDouble.SetValue(std::move(aOther.mValue.mUnrestrictedDouble.Value()));
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
}
}
bool
OwningUnrestrictedDoubleOrString::TrySetToUnrestrictedDouble(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
double& memberSlot = RawSetAsUnrestrictedDouble();
if (!ValueToPrimitive<double, eDefault>(cx, value, "Unrestricted double branch of (unrestricted double or DOMString)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] double&
OwningUnrestrictedDoubleOrString::RawSetAsUnrestrictedDouble()
{
if (mType == eUnrestrictedDouble) {
return mValue.mUnrestrictedDouble.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUnrestrictedDouble;
return mValue.mUnrestrictedDouble.SetValue();
}
[[nodiscard]] double&
OwningUnrestrictedDoubleOrString::SetAsUnrestrictedDouble()
{
if (mType == eUnrestrictedDouble) {
return mValue.mUnrestrictedDouble.Value();
}
Uninit();
mType = eUnrestrictedDouble;
return mValue.mUnrestrictedDouble.SetValue();
}
void
OwningUnrestrictedDoubleOrString::DestroyUnrestrictedDouble()
{
MOZ_RELEASE_ASSERT(IsUnrestrictedDouble(), "Wrong type!");
mValue.mUnrestrictedDouble.Destroy();
mType = eUninitialized;
}
bool
OwningUnrestrictedDoubleOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningUnrestrictedDoubleOrString::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningUnrestrictedDoubleOrString::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningUnrestrictedDoubleOrString::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningUnrestrictedDoubleOrString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToUnrestrictedDouble(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningUnrestrictedDoubleOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningUnrestrictedDoubleOrString::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eUnrestrictedDouble: {
DestroyUnrestrictedDouble();
break;
}
case eString: {
DestroyString();
break;
}
}
}
bool
OwningUnrestrictedDoubleOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUnrestrictedDouble: {
rval.set(JS_NumberValue(double(mValue.mUnrestrictedDouble.Value())));
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningUnrestrictedDoubleOrString&
OwningUnrestrictedDoubleOrString::operator=(OwningUnrestrictedDoubleOrString&& aOther)
{
this->~OwningUnrestrictedDoubleOrString();
new (this) OwningUnrestrictedDoubleOrString (std::move(aOther));
return *this;
}
OwningUnrestrictedDoubleOrString&
OwningUnrestrictedDoubleOrString::operator=(const OwningUnrestrictedDoubleOrString& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUnrestrictedDouble: {
SetAsUnrestrictedDouble() = aOther.GetAsUnrestrictedDouble();
break;
}
case eString: {
SetAsString() = aOther.GetAsString();
break;
}
}
return *this;
}
OwningUnrestrictedFloatOrString::OwningUnrestrictedFloatOrString(OwningUnrestrictedFloatOrString&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUnrestrictedFloat: {
mType = eUnrestrictedFloat;
mValue.mUnrestrictedFloat.SetValue(std::move(aOther.mValue.mUnrestrictedFloat.Value()));
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
}
}
bool
OwningUnrestrictedFloatOrString::TrySetToUnrestrictedFloat(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
float& memberSlot = RawSetAsUnrestrictedFloat();
if (!ValueToPrimitive<float, eDefault>(cx, value, "Unrestricted float branch of (unrestricted float or DOMString)", &memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] float&
OwningUnrestrictedFloatOrString::RawSetAsUnrestrictedFloat()
{
if (mType == eUnrestrictedFloat) {
return mValue.mUnrestrictedFloat.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eUnrestrictedFloat;
return mValue.mUnrestrictedFloat.SetValue();
}
[[nodiscard]] float&
OwningUnrestrictedFloatOrString::SetAsUnrestrictedFloat()
{
if (mType == eUnrestrictedFloat) {
return mValue.mUnrestrictedFloat.Value();
}
Uninit();
mType = eUnrestrictedFloat;
return mValue.mUnrestrictedFloat.SetValue();
}
void
OwningUnrestrictedFloatOrString::DestroyUnrestrictedFloat()
{
MOZ_RELEASE_ASSERT(IsUnrestrictedFloat(), "Wrong type!");
mValue.mUnrestrictedFloat.Destroy();
mType = eUninitialized;
}
bool
OwningUnrestrictedFloatOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
nsString& memberSlot = RawSetAsString();
if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
return false;
}
}
return true;
}
[[nodiscard]] nsString&
OwningUnrestrictedFloatOrString::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningUnrestrictedFloatOrString::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningUnrestrictedFloatOrString::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningUnrestrictedFloatOrString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
do {
if (value.isNumber()) {
done = (failed = !TrySetToUnrestrictedFloat(cx, value, tryNext)) || !tryNext;
break;
}
done = (failed = !TrySetToString(cx, value, tryNext)) || !tryNext;
break;
} while (false);
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "");
return false;
}
return true;
}
bool
OwningUnrestrictedFloatOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningUnrestrictedFloatOrString::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eUnrestrictedFloat: {
DestroyUnrestrictedFloat();
break;
}
case eString: {
DestroyString();
break;
}
}
}
bool
OwningUnrestrictedFloatOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eUnrestrictedFloat: {
rval.set(JS_NumberValue(double(mValue.mUnrestrictedFloat.Value())));
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningUnrestrictedFloatOrString&
OwningUnrestrictedFloatOrString::operator=(OwningUnrestrictedFloatOrString&& aOther)
{
this->~OwningUnrestrictedFloatOrString();
new (this) OwningUnrestrictedFloatOrString (std::move(aOther));
return *this;
}
OwningUnrestrictedFloatOrString&
OwningUnrestrictedFloatOrString::operator=(const OwningUnrestrictedFloatOrString& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eUnrestrictedFloat: {
SetAsUnrestrictedFloat() = aOther.GetAsUnrestrictedFloat();
break;
}
case eString: {
SetAsString() = aOther.GetAsString();
break;
}
}
return *this;
}
} // namespace mozilla::dom