Copy as Markdown

Other Tools

/* THIS FILE IS AUTOGENERATED FROM TestFunctions.webidl BY Codegen.py - DO NOT EDIT */
#include <type_traits>
#include "AtomList.h"
#include "MainThreadUtils.h"
#include "TestFunctionsBinding.h"
#include "WrapperFactory.h"
#include "XrayWrapper.h"
#include "js/Array.h"
#include "js/CallAndConstruct.h"
#include "js/Exception.h"
#include "js/ForOfIterator.h"
#include "js/MapAndSet.h"
#include "js/Object.h"
#include "js/PropertyAndElement.h"
#include "js/PropertyDescriptor.h"
#include "js/experimental/JitInfo.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "mozilla/Atomics.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/ProfilerLabels.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMJSClass.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/RootedDictionary.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/TestFunctions.h"
#include "mozilla/dom/TestInterfaceLength.h"
#include "mozilla/dom/TestTrialInterface.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/dom/WebIDLPrefs.h"
#include "mozilla/dom/WrapperCachedNonISupportsTestInterface.h"
#include "mozilla/dom/XrayExpandoClass.h"
#include "nsContentUtils.h"
namespace mozilla {
namespace dom {
namespace binding_detail {}; // Just to make sure it's known as a namespace
using namespace mozilla::dom::binding_detail;
namespace binding_detail {
const nsLiteralCString EnumStrings<StringType>::Values[4] = {
"literal"_ns,
"stringbuffer"_ns,
"inline"_ns,
"other"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, StringType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(binding_detail::EnumStrings<StringType>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<StringType>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<StringType>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
bool
ArrayBufferOrArrayBufferViewOrString::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 (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
}
return true;
}
bool
ArrayBufferOrArrayBufferViewOrString::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
bool
ArrayBufferOrArrayBufferViewOrString::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 (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
if (JS::IsLargeArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
}
return true;
}
bool
ArrayBufferOrArrayBufferViewOrString::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
bool
ArrayBufferOrArrayBufferViewOrString::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
ArrayBufferOrArrayBufferViewOrString::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 ||
(failed = !TrySetToArrayBufferView(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, ArrayBufferView");
return false;
}
return true;
}
bool
ArrayBufferOrArrayBufferViewOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ArrayBufferOrArrayBufferViewOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
case eArrayBufferView: {
rval.setObject(*mValue.mArrayBufferView.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningArrayBufferOrArrayBufferViewOrString::OwningArrayBufferOrArrayBufferViewOrString(OwningArrayBufferOrArrayBufferViewOrString&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eArrayBuffer: {
mType = eArrayBuffer;
mValue.mArrayBuffer.SetValue(std::move(aOther.mValue.mArrayBuffer.Value()));
break;
}
case eArrayBufferView: {
mType = eArrayBufferView;
mValue.mArrayBufferView.SetValue(std::move(aOther.mValue.mArrayBufferView.Value()));
break;
}
case eString: {
mType = eString;
mValue.mString.SetValue(std::move(aOther.mValue.mString.Value()));
break;
}
}
}
bool
OwningArrayBufferOrArrayBufferViewOrString::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 (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
}
return true;
}
bool
OwningArrayBufferOrArrayBufferViewOrString::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBuffer&
OwningArrayBufferOrArrayBufferViewOrString::RawSetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
[[nodiscard]] ArrayBuffer&
OwningArrayBufferOrArrayBufferViewOrString::SetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
Uninit();
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
void
OwningArrayBufferOrArrayBufferViewOrString::DestroyArrayBuffer()
{
MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!");
mValue.mArrayBuffer.Destroy();
mType = eUninitialized;
}
bool
OwningArrayBufferOrArrayBufferViewOrString::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 (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
if (JS::IsLargeArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (ArrayBuffer or ArrayBufferView or DOMString)");
return false;
}
}
return true;
}
bool
OwningArrayBufferOrArrayBufferViewOrString::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBufferView&
OwningArrayBufferOrArrayBufferViewOrString::RawSetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
[[nodiscard]] ArrayBufferView&
OwningArrayBufferOrArrayBufferViewOrString::SetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
Uninit();
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
void
OwningArrayBufferOrArrayBufferViewOrString::DestroyArrayBufferView()
{
MOZ_RELEASE_ASSERT(IsArrayBufferView(), "Wrong type!");
mValue.mArrayBufferView.Destroy();
mType = eUninitialized;
}
bool
OwningArrayBufferOrArrayBufferViewOrString::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&
OwningArrayBufferOrArrayBufferViewOrString::RawSetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eString;
return mValue.mString.SetValue();
}
[[nodiscard]] nsString&
OwningArrayBufferOrArrayBufferViewOrString::SetAsString()
{
if (mType == eString) {
return mValue.mString.Value();
}
Uninit();
mType = eString;
return mValue.mString.SetValue();
}
void
OwningArrayBufferOrArrayBufferViewOrString::DestroyString()
{
MOZ_RELEASE_ASSERT(IsString(), "Wrong type!");
mValue.mString.Destroy();
mType = eUninitialized;
}
bool
OwningArrayBufferOrArrayBufferViewOrString::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 ||
(failed = !TrySetToArrayBufferView(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, ArrayBufferView");
return false;
}
return true;
}
bool
OwningArrayBufferOrArrayBufferViewOrString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningArrayBufferOrArrayBufferViewOrString::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eArrayBuffer: {
DestroyArrayBuffer();
break;
}
case eArrayBufferView: {
DestroyArrayBufferView();
break;
}
case eString: {
DestroyString();
break;
}
}
}
bool
OwningArrayBufferOrArrayBufferViewOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
case eArrayBufferView: {
rval.setObject(*mValue.mArrayBufferView.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
case eString: {
if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
void
OwningArrayBufferOrArrayBufferViewOrString::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eArrayBuffer: {
mValue.mArrayBuffer.Value().TraceSelf(trc);
break;
}
case eArrayBufferView: {
mValue.mArrayBufferView.Value().TraceSelf(trc);
break;
}
default: {
}
}
}
OwningArrayBufferOrArrayBufferViewOrString&
OwningArrayBufferOrArrayBufferViewOrString::operator=(OwningArrayBufferOrArrayBufferViewOrString&& aOther)
{
this->~OwningArrayBufferOrArrayBufferViewOrString();
new (this) OwningArrayBufferOrArrayBufferViewOrString (std::move(aOther));
return *this;
}
DictWithAllowSharedBufferSource::DictWithAllowSharedBufferSource()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
DictWithAllowSharedBufferSource::InitIds(JSContext* cx, DictWithAllowSharedBufferSourceAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->arrayBufferView_id.init(cx, "arrayBufferView") ||
!atomsCache->arrayBuffer_id.init(cx, "arrayBuffer") ||
!atomsCache->allowSharedArrayBufferView_id.init(cx, "allowSharedArrayBufferView") ||
!atomsCache->allowSharedArrayBuffer_id.init(cx, "allowSharedArrayBuffer")) {
return false;
}
return true;
}
bool
DictWithAllowSharedBufferSource::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
DictWithAllowSharedBufferSourceAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<DictWithAllowSharedBufferSourceAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->allowSharedArrayBuffer_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mAllowSharedArrayBuffer.Construct();
if (temp.ref().isObject()) {
if (!(mAllowSharedArrayBuffer.Value()).Init(&temp.ref().toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'allowSharedArrayBuffer' member of DictWithAllowSharedBufferSource", "ArrayBuffer");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared((mAllowSharedArrayBuffer.Value()).Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("'allowSharedArrayBuffer' member of DictWithAllowSharedBufferSource");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared((mAllowSharedArrayBuffer.Value()).Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("'allowSharedArrayBuffer' member of DictWithAllowSharedBufferSource");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'allowSharedArrayBuffer' member of DictWithAllowSharedBufferSource");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->allowSharedArrayBufferView_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mAllowSharedArrayBufferView.Construct();
if (temp.ref().isObject()) {
if (!(mAllowSharedArrayBufferView.Value()).Init(&temp.ref().toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'allowSharedArrayBufferView' member of DictWithAllowSharedBufferSource", "ArrayBufferView");
return false;
}
if (JS::IsLargeArrayBufferView((mAllowSharedArrayBufferView.Value()).Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("'allowSharedArrayBufferView' member of DictWithAllowSharedBufferSource");
return false;
}
if (JS::IsResizableArrayBufferView((mAllowSharedArrayBufferView.Value()).Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("'allowSharedArrayBufferView' member of DictWithAllowSharedBufferSource");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'allowSharedArrayBufferView' member of DictWithAllowSharedBufferSource");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->arrayBuffer_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mArrayBuffer.Construct();
if (temp.ref().isObject()) {
if (!(mArrayBuffer.Value()).Init(&temp.ref().toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'arrayBuffer' member of DictWithAllowSharedBufferSource", "ArrayBuffer");
return false;
}
if (JS::IsSharedArrayBufferObject((mArrayBuffer.Value()).Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("'arrayBuffer' member of DictWithAllowSharedBufferSource");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared((mArrayBuffer.Value()).Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("'arrayBuffer' member of DictWithAllowSharedBufferSource");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared((mArrayBuffer.Value()).Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("'arrayBuffer' member of DictWithAllowSharedBufferSource");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'arrayBuffer' member of DictWithAllowSharedBufferSource");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->arrayBufferView_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mArrayBufferView.Construct();
if (temp.ref().isObject()) {
if (!(mArrayBufferView.Value()).Init(&temp.ref().toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'arrayBufferView' member of DictWithAllowSharedBufferSource", "ArrayBufferView");
return false;
}
if (JS::IsArrayBufferViewShared((mArrayBufferView.Value()).Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("'arrayBufferView' member of DictWithAllowSharedBufferSource");
return false;
}
if (JS::IsLargeArrayBufferView((mArrayBufferView.Value()).Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("'arrayBufferView' member of DictWithAllowSharedBufferSource");
return false;
}
if (JS::IsResizableArrayBufferView((mArrayBufferView.Value()).Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("'arrayBufferView' member of DictWithAllowSharedBufferSource");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'arrayBufferView' member of DictWithAllowSharedBufferSource");
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
DictWithAllowSharedBufferSource::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
DictWithAllowSharedBufferSource::TraceDictionary(JSTracer* trc)
{
if (mAllowSharedArrayBuffer.WasPassed()) {
mAllowSharedArrayBuffer.Value().TraceSelf(trc);
}
if (mAllowSharedArrayBufferView.WasPassed()) {
mAllowSharedArrayBufferView.Value().TraceSelf(trc);
}
if (mArrayBuffer.WasPassed()) {
mArrayBuffer.Value().TraceSelf(trc);
}
if (mArrayBufferView.WasPassed()) {
mArrayBufferView.Value().TraceSelf(trc);
}
}
bool
MaybeSharedArrayBufferOrMaybeSharedArrayBufferView::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 (ArrayBuffer or ArrayBufferView)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (ArrayBuffer or ArrayBufferView)");
return false;
}
}
return true;
}
bool
MaybeSharedArrayBufferOrMaybeSharedArrayBufferView::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
bool
MaybeSharedArrayBufferOrMaybeSharedArrayBufferView::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 (ArrayBuffer or ArrayBufferView)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (ArrayBuffer or ArrayBufferView)");
return false;
}
}
return true;
}
bool
MaybeSharedArrayBufferOrMaybeSharedArrayBufferView::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
bool
MaybeSharedArrayBufferOrMaybeSharedArrayBufferView::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 ||
(failed = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBuffer, ArrayBufferView");
return false;
}
return true;
}
bool
MaybeSharedArrayBufferOrMaybeSharedArrayBufferView::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
MaybeSharedArrayBufferOrMaybeSharedArrayBufferView::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
case eArrayBufferView: {
rval.setObject(*mValue.mArrayBufferView.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView(OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eArrayBuffer: {
mType = eArrayBuffer;
mValue.mArrayBuffer.SetValue(std::move(aOther.mValue.mArrayBuffer.Value()));
break;
}
case eArrayBufferView: {
mType = eArrayBufferView;
mValue.mArrayBufferView.SetValue(std::move(aOther.mValue.mArrayBufferView.Value()));
break;
}
}
}
bool
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::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 (ArrayBuffer or ArrayBufferView)");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (ArrayBuffer or ArrayBufferView)");
return false;
}
}
return true;
}
bool
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBuffer&
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::RawSetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
[[nodiscard]] ArrayBuffer&
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::SetAsArrayBuffer()
{
if (mType == eArrayBuffer) {
return mValue.mArrayBuffer.Value();
}
Uninit();
mType = eArrayBuffer;
return mValue.mArrayBuffer.SetValue();
}
void
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::DestroyArrayBuffer()
{
MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!");
mValue.mArrayBuffer.Destroy();
mType = eUninitialized;
}
bool
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::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 (ArrayBuffer or ArrayBufferView)");
return false;
}
if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (ArrayBuffer or ArrayBufferView)");
return false;
}
}
return true;
}
bool
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] ArrayBufferView&
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::RawSetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
[[nodiscard]] ArrayBufferView&
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::SetAsArrayBufferView()
{
if (mType == eArrayBufferView) {
return mValue.mArrayBufferView.Value();
}
Uninit();
mType = eArrayBufferView;
return mValue.mArrayBufferView.SetValue();
}
void
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::DestroyArrayBufferView()
{
MOZ_RELEASE_ASSERT(IsArrayBufferView(), "Wrong type!");
mValue.mArrayBufferView.Destroy();
mType = eUninitialized;
}
bool
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::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 ||
(failed = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ArrayBuffer, ArrayBufferView");
return false;
}
return true;
}
bool
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eArrayBuffer: {
DestroyArrayBuffer();
break;
}
case eArrayBufferView: {
DestroyArrayBufferView();
break;
}
}
}
bool
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eArrayBuffer: {
rval.setObject(*mValue.mArrayBuffer.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
case eArrayBufferView: {
rval.setObject(*mValue.mArrayBufferView.Value().Obj());
if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
void
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::TraceUnion(JSTracer* trc)
{
switch (mType) {
case eArrayBuffer: {
mValue.mArrayBuffer.Value().TraceSelf(trc);
break;
}
case eArrayBufferView: {
mValue.mArrayBufferView.Value().TraceSelf(trc);
break;
}
default: {
}
}
}
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView&
OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView::operator=(OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView&& aOther)
{
this->~OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView();
new (this) OwningMaybeSharedArrayBufferOrMaybeSharedArrayBufferView (std::move(aOther));
return *this;
}
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise>
PromiseReturner::Call(BindingCallContext& cx, JS::Handle<JS::Value> aThisVal, ErrorResult& aRv)
{
JS::Rooted<JS::Value> rval(cx);
JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
if (!JS::Call(cx, aThisVal, callable,
JS::HandleValueArray::empty(), &rval)) {
// Convert exception to a rejected promise.
// step 12 and step 15.5.
return CreateRejectedPromiseFromThrownException(cx, aRv);
}
RefPtr<Promise> rvalDecl;
{ // Scope for our GlobalObject, FastErrorResult, JSAutoRealm,
// etc.
JS::Rooted<JSObject*> globalObj(cx);
// We basically want our entry global here. Play it safe
// and use GetEntryGlobal() to get it, with whatever
// principal-clamping it ends up doing.
globalObj = GetEntryGlobal()->GetGlobalJSObject();
JSAutoRealm ar(cx, globalObj);
GlobalObject promiseGlobal(cx, globalObj);
if (promiseGlobal.Failed()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
JS::Rooted<JS::Value> valueToResolve(cx, rval);
if (!JS_WrapValue(cx, &valueToResolve)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
binding_detail::FastErrorResult promiseRv;
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(promiseGlobal.GetAsSupports());
if (!global) {
promiseRv.Throw(NS_ERROR_UNEXPECTED);
MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
rvalDecl = Promise::Resolve(global, cx, valueToResolve,
promiseRv);
if (promiseRv.MaybeSetPendingException(cx)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
}
return rvalDecl.forget();
}
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise>
PromiseReturner2::Call(BindingCallContext& cx, JS::Handle<JS::Value> aThisVal, JS::Handle<JS::Value> arg, const nsAString& arg2, ErrorResult& aRv)
{
JS::Rooted<JS::Value> rval(cx);
JS::RootedVector<JS::Value> argv(cx);
if (!argv.resize(2)) {
// That threw an exception on the JSContext, and our CallSetup will do
// the right thing with that.
return nullptr;
}
unsigned argc = 2;
do {
if (!xpc::NonVoidStringToJsval(cx, arg2, argv[1])) {
// Convert exception to a rejected promise.
// step 10 and step 15.5.
return CreateRejectedPromiseFromThrownException(cx, aRv);
}
break;
} while (false);
do {
JS::ExposeValueToActiveJS(arg);
argv[0].set(arg);
if (!MaybeWrapValue(cx, argv[0])) {
// Convert exception to a rejected promise.
// step 10 and step 15.5.
return CreateRejectedPromiseFromThrownException(cx, aRv);
}
break;
} while (false);
JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
if (!JS::Call(cx, aThisVal, callable,
JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
// Convert exception to a rejected promise.
// step 12 and step 15.5.
return CreateRejectedPromiseFromThrownException(cx, aRv);
}
RefPtr<Promise> rvalDecl;
{ // Scope for our GlobalObject, FastErrorResult, JSAutoRealm,
// etc.
JS::Rooted<JSObject*> globalObj(cx);
// We basically want our entry global here. Play it safe
// and use GetEntryGlobal() to get it, with whatever
// principal-clamping it ends up doing.
globalObj = GetEntryGlobal()->GetGlobalJSObject();
JSAutoRealm ar(cx, globalObj);
GlobalObject promiseGlobal(cx, globalObj);
if (promiseGlobal.Failed()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
JS::Rooted<JS::Value> valueToResolve(cx, rval);
if (!JS_WrapValue(cx, &valueToResolve)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
binding_detail::FastErrorResult promiseRv;
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(promiseGlobal.GetAsSupports());
if (!global) {
promiseRv.Throw(NS_ERROR_UNEXPECTED);
MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
rvalDecl = Promise::Resolve(global, cx, valueToResolve,
promiseRv);
if (promiseRv.MaybeSetPendingException(cx)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
}
return rvalDecl.forget();
}
namespace TestFunctions_Binding {
MOZ_CAN_RUN_SCRIPT static bool
throwUncatchableException(JSContext* cx, unsigned argc, JS::Value* vp)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "throwUncatchableException", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
if (global.Failed()) {
return false;
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(mozilla::dom::TestFunctions::ThrowUncatchableException(global, rv))>, "Should be returning void here");
mozilla::dom::TestFunctions::ThrowUncatchableException(global, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.throwUncatchableException"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
passThroughPromise(JSContext* cx, unsigned argc, JS::Value* vp)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "passThroughPromise", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
if (!args.requireAtLeast(cx, "TestFunctions.passThroughPromise", 1)) {
return false;
}
GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
if (global.Failed()) {
return false;
}
OwningNonNull<Promise> arg0;
{ // Scope for our GlobalObject, FastErrorResult, JSAutoRealm,
// etc.
JS::Rooted<JSObject*> globalObj(cx);
globalObj = JS::CurrentGlobalOrNull(cx);
JSAutoRealm ar(cx, globalObj);
GlobalObject promiseGlobal(cx, globalObj);
if (promiseGlobal.Failed()) {
return false;
}
JS::Rooted<JS::Value> valueToResolve(cx, args[0]);
if (!JS_WrapValue(cx, &valueToResolve)) {
return false;
}
binding_detail::FastErrorResult promiseRv;
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(promiseGlobal.GetAsSupports());
if (!global) {
promiseRv.Throw(NS_ERROR_UNEXPECTED);
MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
return false;
}
arg0 = Promise::Resolve(global, cx, valueToResolve,
promiseRv);
if (promiseRv.MaybeSetPendingException(cx)) {
return false;
}
}
auto result(StrongOrRawPtr<Promise>(mozilla::dom::TestFunctions::PassThroughPromise(global, NonNullHelper(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo passThroughPromise_methodinfo = {
{ (JSJitGetterOp)passThroughPromise },
{ prototypes::id::_ID_Count }, { 0 }, JSJitInfo::StaticMethod,
JSJitInfo::AliasEverything, JSVAL_TYPE_OBJECT, false, false,
false, false, 0
};
MOZ_CAN_RUN_SCRIPT static bool
passThroughCallbackPromise(JSContext* cx_, unsigned argc, JS::Value* vp)
{
BindingCallContext cx(cx_, "TestFunctions.passThroughCallbackPromise");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "passThroughCallbackPromise", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
if (!args.requireAtLeast(cx, "TestFunctions.passThroughCallbackPromise", 1)) {
return false;
}
GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
if (global.Failed()) {
return false;
}
RootedCallback<OwningNonNull<binding_detail::FastPromiseReturner>> arg0(cx);
if (args[0].isObject()) {
if (JS::IsCallable(&args[0].toObject())) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastPromiseReturner(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
cx.ThrowErrorMessage<MSG_NOT_CALLABLE>("Argument 1");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(mozilla::dom::TestFunctions::PassThroughCallbackPromise(global, MOZ_KnownLive(NonNullHelper(arg0)), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.passThroughCallbackPromise"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo passThroughCallbackPromise_methodinfo = {
{ (JSJitGetterOp)passThroughCallbackPromise },
{ prototypes::id::_ID_Count }, { 0 }, JSJitInfo::StaticMethod,
JSJitInfo::AliasEverything, JSVAL_TYPE_OBJECT, false, false,
false, false, 0
};
MOZ_CAN_RUN_SCRIPT static bool
setStringData(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "setStringData", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
if (!args.requireAtLeast(cx, "TestFunctions.setStringData", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetStringData(NonNullHelper(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetStringData(NonNullHelper(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setStringData_methodinfo = {
{ (JSJitGetterOp)setStringData },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getStringDataAsAString(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "TestFunctions.getStringDataAsAString");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "getStringDataAsAString", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
unsigned argcount = std::min(args.length(), 1u);
switch (argcount) {
case 0: {
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetStringDataAsAString(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetStringDataAsAString(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
break;
}
case 1: {
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetStringDataAsAString(arg0, result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetStringDataAsAString(arg0, result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
break;
}
default: {
// Using nsPrintfCString here would require including that
// header. Let's not worry about it.
nsAutoCString argCountStr;
argCountStr.AppendPrintf("%u", args.length());
return cx.ThrowErrorMessage<MSG_INVALID_OVERLOAD_ARGCOUNT>(argCountStr.get());
}
}
MOZ_CRASH("We have an always-returning default case");
return false;
}
static const JSJitInfo getStringDataAsAString_methodinfo = {
{ (JSJitGetterOp)getStringDataAsAString },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getStringDataAsDOMString(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "getStringDataAsDOMString", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
Optional<uint32_t> arg0;
if (args.hasDefined(0)) {
arg0.Construct();
if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], "Argument 1", &arg0.Value())) {
return false;
}
}
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetStringDataAsDOMString(Constify(arg0), result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetStringDataAsDOMString(Constify(arg0), result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo getStringDataAsDOMString_methodinfo = {
{ (JSJitGetterOp)getStringDataAsDOMString },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getShortLiteralString(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "getShortLiteralString", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetShortLiteralString(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetShortLiteralString(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo getShortLiteralString_methodinfo = {
{ (JSJitGetterOp)getShortLiteralString },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getMediumLiteralString(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "getMediumLiteralString", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetMediumLiteralString(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetMediumLiteralString(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo getMediumLiteralString_methodinfo = {
{ (JSJitGetterOp)getMediumLiteralString },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getLongLiteralString(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "getLongLiteralString", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLongLiteralString(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLongLiteralString(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo getLongLiteralString_methodinfo = {
{ (JSJitGetterOp)getLongLiteralString },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getStringbufferString(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "getStringbufferString", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
if (!args.requireAtLeast(cx, "TestFunctions.getStringbufferString", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetStringbufferString(NonNullHelper(Constify(arg0)), result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetStringbufferString(NonNullHelper(Constify(arg0)), result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo getStringbufferString_methodinfo = {
{ (JSJitGetterOp)getStringbufferString },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getStringType(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "getStringType", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
if (!args.requireAtLeast(cx, "TestFunctions.getStringType", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
StringType result(MOZ_KnownLive(self)->GetStringType(NonNullHelper(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo getStringType_methodinfo = {
{ (JSJitGetterOp)getStringType },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
stringbufferMatchesStored(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "stringbufferMatchesStored", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
if (!args.requireAtLeast(cx, "TestFunctions.stringbufferMatchesStored", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
bool result(MOZ_KnownLive(self)->StringbufferMatchesStored(NonNullHelper(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setBoolean(result);
return true;
}
static const JSJitInfo stringbufferMatchesStored_methodinfo = {
{ (JSJitGetterOp)stringbufferMatchesStored },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
testThrowNsresult(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "testThrowNsresult", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->TestThrowNsresult(rv))>, "Should be returning void here");
MOZ_KnownLive(self)->TestThrowNsresult(rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.testThrowNsresult"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo testThrowNsresult_methodinfo = {
{ (JSJitGetterOp)testThrowNsresult },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
testThrowNsresultFromNative(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "testThrowNsresultFromNative", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->TestThrowNsresultFromNative(rv))>, "Should be returning void here");
MOZ_KnownLive(self)->TestThrowNsresultFromNative(rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.testThrowNsresultFromNative"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo testThrowNsresultFromNative_methodinfo = {
{ (JSJitGetterOp)testThrowNsresultFromNative },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
throwToRejectPromise(JSContext* cx, unsigned argc, JS::Value* vp)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "throwToRejectPromise", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
if (global.Failed()) {
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(mozilla::dom::TestFunctions::ThrowToRejectPromise(global, rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.throwToRejectPromise"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo throwToRejectPromise_methodinfo = {
{ (JSJitGetterOp)throwToRejectPromise },
{ prototypes::id::_ID_Count }, { 0 }, JSJitInfo::StaticMethod,
JSJitInfo::AliasEverything, JSVAL_TYPE_OBJECT, false, false,
false, false, 0
};
MOZ_CAN_RUN_SCRIPT static bool
get_one(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "one", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
int32_t result(MOZ_KnownLive(self)->One());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setInt32(int32_t(result));
return true;
}
static const JSJitInfo one_getterinfo = {
{ get_one },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_INT32, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_two(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "two", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
int32_t result(MOZ_KnownLive(self)->Two());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setInt32(int32_t(result));
return true;
}
static const JSJitInfo two_getterinfo = {
{ get_two },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_INT32, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_wrapperCachedNonISupportsObject(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "wrapperCachedNonISupportsObject", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::WrapperCachedNonISupportsTestInterface>(MOZ_KnownLive(self)->WrapperCachedNonISupportsObject()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo wrapperCachedNonISupportsObject_getterinfo = {
{ get_wrapperCachedNonISupportsObject },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_clampedNullableOctet(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "clampedNullableOctet", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
Nullable<uint8_t> result(MOZ_KnownLive(self)->GetClampedNullableOctet());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result.IsNull()) {
args.rval().setNull();
return true;
}
args.rval().setInt32(int32_t(result.Value()));
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_clampedNullableOctet(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "clampedNullableOctet", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
Nullable<uint8_t> arg0;
if (args[0].isNullOrUndefined()) {
arg0.SetNull();
} else if (!ValueToPrimitive<uint8_t, eClamp>(cx, args[0], "Value being assigned", &arg0.SetValue())) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetClampedNullableOctet(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetClampedNullableOctet(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo clampedNullableOctet_getterinfo = {
{ get_clampedNullableOctet },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo clampedNullableOctet_setterinfo = {
{ (JSJitGetterOp)set_clampedNullableOctet },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_enforcedNullableOctet(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "enforcedNullableOctet", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
Nullable<uint8_t> result(MOZ_KnownLive(self)->GetEnforcedNullableOctet());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result.IsNull()) {
args.rval().setNull();
return true;
}
args.rval().setInt32(int32_t(result.Value()));
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_enforcedNullableOctet(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
BindingCallContext cx(cx_, "TestFunctions.enforcedNullableOctet setter");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "enforcedNullableOctet", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
Nullable<uint8_t> arg0;
if (args[0].isNullOrUndefined()) {
arg0.SetNull();
} else if (!ValueToPrimitive<uint8_t, eEnforceRange>(cx, args[0], "Value being assigned", &arg0.SetValue())) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetEnforcedNullableOctet(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetEnforcedNullableOctet(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo enforcedNullableOctet_getterinfo = {
{ get_enforcedNullableOctet },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo enforcedNullableOctet_setterinfo = {
{ (JSJitGetterOp)set_enforcedNullableOctet },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_arrayBufferView(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "arrayBufferView", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
JS::Rooted<JSObject*> unwrappedObj(cx, js::CheckedUnwrapStatic(obj));
// Caller should have ensured that "obj" can be unwrapped already.
MOZ_DIAGNOSTIC_ASSERT(unwrappedObj);
FastErrorResult rv;
JS::Rooted<JSObject*> result(cx);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetArrayBufferView(cx, unwrappedObj, &result, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->GetArrayBufferView(cx, unwrappedObj, &result, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.arrayBufferView getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_arrayBufferView(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
BindingCallContext cx(cx_, "TestFunctions.arrayBufferView setter");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "arrayBufferView", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
RootedSpiderMonkeyInterface<ArrayBufferView> arg0(cx);
if (args[0].isObject()) {
if (!arg0.Init(&args[0].toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Value being assigned", "ArrayBufferView");
return false;
}
if (JS::IsArrayBufferViewShared(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("Value being assigned");
return false;
}
if (JS::IsLargeArrayBufferView(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Value being assigned");
return false;
}
if (JS::IsResizableArrayBufferView(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Value being assigned");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Value being assigned");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetArrayBufferView(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetArrayBufferView(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo arrayBufferView_getterinfo = {
{ get_arrayBufferView },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo arrayBufferView_setterinfo = {
{ (JSJitGetterOp)set_arrayBufferView },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_allowSharedArrayBufferView(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "allowSharedArrayBufferView", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
JS::Rooted<JSObject*> unwrappedObj(cx, js::CheckedUnwrapStatic(obj));
// Caller should have ensured that "obj" can be unwrapped already.
MOZ_DIAGNOSTIC_ASSERT(unwrappedObj);
FastErrorResult rv;
JS::Rooted<JSObject*> result(cx);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetAllowSharedArrayBufferView(cx, unwrappedObj, &result, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->GetAllowSharedArrayBufferView(cx, unwrappedObj, &result, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.allowSharedArrayBufferView getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_allowSharedArrayBufferView(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
BindingCallContext cx(cx_, "TestFunctions.allowSharedArrayBufferView setter");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "allowSharedArrayBufferView", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
RootedSpiderMonkeyInterface<ArrayBufferView> arg0(cx);
if (args[0].isObject()) {
if (!arg0.Init(&args[0].toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Value being assigned", "ArrayBufferView");
return false;
}
if (JS::IsLargeArrayBufferView(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Value being assigned");
return false;
}
if (JS::IsResizableArrayBufferView(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Value being assigned");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Value being assigned");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetAllowSharedArrayBufferView(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetAllowSharedArrayBufferView(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo allowSharedArrayBufferView_getterinfo = {
{ get_allowSharedArrayBufferView },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo allowSharedArrayBufferView_setterinfo = {
{ (JSJitGetterOp)set_allowSharedArrayBufferView },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_sequenceOfArrayBufferView(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "sequenceOfArrayBufferView", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
// Have to either root across the getter call or reget after.
bool isXray;
JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
if (!slotStorage) {
return false;
}
const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(JS::GetClass(slotStorage)) > slotIndex);
{
// Scope for cachedVal
JS::Value cachedVal = JS::GetReservedSlot(slotStorage, slotIndex);
if (!cachedVal.isUndefined()) {
args.rval().set(cachedVal);
// The cached value is in the compartment of slotStorage,
// so wrap into the caller compartment as needed.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
}
JS::Rooted<JSObject*> unwrappedObj(cx, js::CheckedUnwrapStatic(obj));
// Caller should have ensured that "obj" can be unwrapped already.
MOZ_DIAGNOSTIC_ASSERT(unwrappedObj);
FastErrorResult rv;
nsTArray<JSObject*> result;
SequenceRooter<JSObject* > resultRooter(cx, &result);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetSequenceOfArrayBufferView(cx, unwrappedObj, result, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->GetSequenceOfArrayBufferView(cx, unwrappedObj, result, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.sequenceOfArrayBufferView getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
{
JS::Rooted<JSObject*> conversionScope(cx, isXray ? JS::CurrentGlobalOrNull(cx) : slotStorage);
JSAutoRealm ar(cx, conversionScope);
do { // block we break out of when done wrapping
uint32_t length = result.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(result[sequenceIdx0]);
tmp.setObject(*result[sequenceIdx0]);
if (!MaybeWrapNonDOMObjectValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
args.rval().setObject(*returnArray);
break;
} while (false);
}
{ // And now store things in the realm of our slotStorage.
JSAutoRealm ar(cx, slotStorage);
// Make a copy so that we don't do unnecessary wrapping on args.rval().
JS::Rooted<JS::Value> storedVal(cx, args.rval());
if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
return false;
}
JS::SetReservedSlot(slotStorage, slotIndex, storedVal);
}
// And now make sure args.rval() is in the caller realm.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
MOZ_CAN_RUN_SCRIPT static bool
set_sequenceOfArrayBufferView(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
BindingCallContext cx(cx_, "TestFunctions.sequenceOfArrayBufferView setter");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "sequenceOfArrayBufferView", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
binding_detail::AutoSequence<ArrayBufferView> arg0;
SequenceRooter<ArrayBufferView> arg0_holder(cx, &arg0);
if (args[0].isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Value being assigned", "sequence");
return false;
}
binding_detail::AutoSequence<ArrayBufferView> &arr = arg0;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
ArrayBufferView* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
ArrayBufferView& slot = *slotPtr;
if (temp.isObject()) {
if (!slot.Init(&temp.toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of value being assigned", "ArrayBufferView");
return false;
}
if (JS::IsArrayBufferViewShared(slot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("Element of value being assigned");
return false;
}
if (JS::IsLargeArrayBufferView(slot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Element of value being assigned");
return false;
}
if (JS::IsResizableArrayBufferView(slot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Element of value being assigned");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of value being assigned");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Value being assigned", "sequence");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetSequenceOfArrayBufferView(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetSequenceOfArrayBufferView(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo sequenceOfArrayBufferView_getterinfo = {
{ get_sequenceOfArrayBufferView },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
true, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
(DOM_INSTANCE_RESERVED_SLOTS + 0) /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 5, "There is no slot for us");
static const JSJitInfo sequenceOfArrayBufferView_setterinfo = {
{ (JSJitGetterOp)set_sequenceOfArrayBufferView },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_sequenceOfAllowSharedArrayBufferView(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "sequenceOfAllowSharedArrayBufferView", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
// Have to either root across the getter call or reget after.
bool isXray;
JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
if (!slotStorage) {
return false;
}
const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 1) : (DOM_INSTANCE_RESERVED_SLOTS + 1);
MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(JS::GetClass(slotStorage)) > slotIndex);
{
// Scope for cachedVal
JS::Value cachedVal = JS::GetReservedSlot(slotStorage, slotIndex);
if (!cachedVal.isUndefined()) {
args.rval().set(cachedVal);
// The cached value is in the compartment of slotStorage,
// so wrap into the caller compartment as needed.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
}
JS::Rooted<JSObject*> unwrappedObj(cx, js::CheckedUnwrapStatic(obj));
// Caller should have ensured that "obj" can be unwrapped already.
MOZ_DIAGNOSTIC_ASSERT(unwrappedObj);
FastErrorResult rv;
nsTArray<JSObject*> result;
SequenceRooter<JSObject* > resultRooter(cx, &result);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetSequenceOfAllowSharedArrayBufferView(cx, unwrappedObj, result, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->GetSequenceOfAllowSharedArrayBufferView(cx, unwrappedObj, result, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.sequenceOfAllowSharedArrayBufferView getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
{
JS::Rooted<JSObject*> conversionScope(cx, isXray ? JS::CurrentGlobalOrNull(cx) : slotStorage);
JSAutoRealm ar(cx, conversionScope);
do { // block we break out of when done wrapping
uint32_t length = result.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(result[sequenceIdx0]);
tmp.setObject(*result[sequenceIdx0]);
if (!MaybeWrapNonDOMObjectValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
args.rval().setObject(*returnArray);
break;
} while (false);
}
{ // And now store things in the realm of our slotStorage.
JSAutoRealm ar(cx, slotStorage);
// Make a copy so that we don't do unnecessary wrapping on args.rval().
JS::Rooted<JS::Value> storedVal(cx, args.rval());
if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
return false;
}
JS::SetReservedSlot(slotStorage, slotIndex, storedVal);
}
// And now make sure args.rval() is in the caller realm.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
MOZ_CAN_RUN_SCRIPT static bool
set_sequenceOfAllowSharedArrayBufferView(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
BindingCallContext cx(cx_, "TestFunctions.sequenceOfAllowSharedArrayBufferView setter");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "sequenceOfAllowSharedArrayBufferView", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
binding_detail::AutoSequence<ArrayBufferView> arg0;
SequenceRooter<ArrayBufferView> arg0_holder(cx, &arg0);
if (args[0].isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Value being assigned", "sequence");
return false;
}
binding_detail::AutoSequence<ArrayBufferView> &arr = arg0;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
ArrayBufferView* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
ArrayBufferView& slot = *slotPtr;
if (temp.isObject()) {
if (!slot.Init(&temp.toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of value being assigned", "ArrayBufferView");
return false;
}
if (JS::IsLargeArrayBufferView(slot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Element of value being assigned");
return false;
}
if (JS::IsResizableArrayBufferView(slot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Element of value being assigned");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of value being assigned");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Value being assigned", "sequence");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetSequenceOfAllowSharedArrayBufferView(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetSequenceOfAllowSharedArrayBufferView(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo sequenceOfAllowSharedArrayBufferView_getterinfo = {
{ get_sequenceOfAllowSharedArrayBufferView },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
true, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
(DOM_INSTANCE_RESERVED_SLOTS + 1) /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) < 5, "There is no slot for us");
static const JSJitInfo sequenceOfAllowSharedArrayBufferView_setterinfo = {
{ (JSJitGetterOp)set_sequenceOfAllowSharedArrayBufferView },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_arrayBuffer(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "arrayBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
JS::Rooted<JSObject*> unwrappedObj(cx, js::CheckedUnwrapStatic(obj));
// Caller should have ensured that "obj" can be unwrapped already.
MOZ_DIAGNOSTIC_ASSERT(unwrappedObj);
FastErrorResult rv;
JS::Rooted<JSObject*> result(cx);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetArrayBuffer(cx, unwrappedObj, &result, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->GetArrayBuffer(cx, unwrappedObj, &result, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.arrayBuffer getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_arrayBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
BindingCallContext cx(cx_, "TestFunctions.arrayBuffer setter");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "arrayBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
RootedSpiderMonkeyInterface<ArrayBuffer> arg0(cx);
if (args[0].isObject()) {
if (!arg0.Init(&args[0].toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Value being assigned", "ArrayBuffer");
return false;
}
if (JS::IsSharedArrayBufferObject(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("Value being assigned");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Value being assigned");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Value being assigned");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Value being assigned");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetArrayBuffer(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetArrayBuffer(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo arrayBuffer_getterinfo = {
{ get_arrayBuffer },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo arrayBuffer_setterinfo = {
{ (JSJitGetterOp)set_arrayBuffer },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_allowSharedArrayBuffer(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "allowSharedArrayBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
JS::Rooted<JSObject*> unwrappedObj(cx, js::CheckedUnwrapStatic(obj));
// Caller should have ensured that "obj" can be unwrapped already.
MOZ_DIAGNOSTIC_ASSERT(unwrappedObj);
FastErrorResult rv;
JS::Rooted<JSObject*> result(cx);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetAllowSharedArrayBuffer(cx, unwrappedObj, &result, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->GetAllowSharedArrayBuffer(cx, unwrappedObj, &result, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.allowSharedArrayBuffer getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_allowSharedArrayBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
BindingCallContext cx(cx_, "TestFunctions.allowSharedArrayBuffer setter");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "allowSharedArrayBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
RootedSpiderMonkeyInterface<ArrayBuffer> arg0(cx);
if (args[0].isObject()) {
if (!arg0.Init(&args[0].toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Value being assigned", "ArrayBuffer");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Value being assigned");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Value being assigned");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Value being assigned");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetAllowSharedArrayBuffer(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetAllowSharedArrayBuffer(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo allowSharedArrayBuffer_getterinfo = {
{ get_allowSharedArrayBuffer },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo allowSharedArrayBuffer_setterinfo = {
{ (JSJitGetterOp)set_allowSharedArrayBuffer },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_sequenceOfArrayBuffer(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "sequenceOfArrayBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
// Have to either root across the getter call or reget after.
bool isXray;
JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
if (!slotStorage) {
return false;
}
const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 2) : (DOM_INSTANCE_RESERVED_SLOTS + 2);
MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(JS::GetClass(slotStorage)) > slotIndex);
{
// Scope for cachedVal
JS::Value cachedVal = JS::GetReservedSlot(slotStorage, slotIndex);
if (!cachedVal.isUndefined()) {
args.rval().set(cachedVal);
// The cached value is in the compartment of slotStorage,
// so wrap into the caller compartment as needed.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
}
JS::Rooted<JSObject*> unwrappedObj(cx, js::CheckedUnwrapStatic(obj));
// Caller should have ensured that "obj" can be unwrapped already.
MOZ_DIAGNOSTIC_ASSERT(unwrappedObj);
FastErrorResult rv;
nsTArray<JSObject*> result;
SequenceRooter<JSObject* > resultRooter(cx, &result);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetSequenceOfArrayBuffer(cx, unwrappedObj, result, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->GetSequenceOfArrayBuffer(cx, unwrappedObj, result, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.sequenceOfArrayBuffer getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
{
JS::Rooted<JSObject*> conversionScope(cx, isXray ? JS::CurrentGlobalOrNull(cx) : slotStorage);
JSAutoRealm ar(cx, conversionScope);
do { // block we break out of when done wrapping
uint32_t length = result.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(result[sequenceIdx0]);
tmp.setObject(*result[sequenceIdx0]);
if (!MaybeWrapNonDOMObjectValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
args.rval().setObject(*returnArray);
break;
} while (false);
}
{ // And now store things in the realm of our slotStorage.
JSAutoRealm ar(cx, slotStorage);
// Make a copy so that we don't do unnecessary wrapping on args.rval().
JS::Rooted<JS::Value> storedVal(cx, args.rval());
if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
return false;
}
JS::SetReservedSlot(slotStorage, slotIndex, storedVal);
}
// And now make sure args.rval() is in the caller realm.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
MOZ_CAN_RUN_SCRIPT static bool
set_sequenceOfArrayBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
BindingCallContext cx(cx_, "TestFunctions.sequenceOfArrayBuffer setter");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "sequenceOfArrayBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
binding_detail::AutoSequence<ArrayBuffer> arg0;
SequenceRooter<ArrayBuffer> arg0_holder(cx, &arg0);
if (args[0].isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Value being assigned", "sequence");
return false;
}
binding_detail::AutoSequence<ArrayBuffer> &arr = arg0;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
ArrayBuffer* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
ArrayBuffer& slot = *slotPtr;
if (temp.isObject()) {
if (!slot.Init(&temp.toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of value being assigned", "ArrayBuffer");
return false;
}
if (JS::IsSharedArrayBufferObject(slot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("Element of value being assigned");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(slot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Element of value being assigned");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(slot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Element of value being assigned");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of value being assigned");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Value being assigned", "sequence");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetSequenceOfArrayBuffer(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetSequenceOfArrayBuffer(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo sequenceOfArrayBuffer_getterinfo = {
{ get_sequenceOfArrayBuffer },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
true, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
(DOM_INSTANCE_RESERVED_SLOTS + 2) /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) < 5, "There is no slot for us");
static const JSJitInfo sequenceOfArrayBuffer_setterinfo = {
{ (JSJitGetterOp)set_sequenceOfArrayBuffer },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_sequenceOfAllowSharedArrayBuffer(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "sequenceOfAllowSharedArrayBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
// Have to either root across the getter call or reget after.
bool isXray;
JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
if (!slotStorage) {
return false;
}
const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 3) : (DOM_INSTANCE_RESERVED_SLOTS + 3);
MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(JS::GetClass(slotStorage)) > slotIndex);
{
// Scope for cachedVal
JS::Value cachedVal = JS::GetReservedSlot(slotStorage, slotIndex);
if (!cachedVal.isUndefined()) {
args.rval().set(cachedVal);
// The cached value is in the compartment of slotStorage,
// so wrap into the caller compartment as needed.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
}
JS::Rooted<JSObject*> unwrappedObj(cx, js::CheckedUnwrapStatic(obj));
// Caller should have ensured that "obj" can be unwrapped already.
MOZ_DIAGNOSTIC_ASSERT(unwrappedObj);
FastErrorResult rv;
nsTArray<JSObject*> result;
SequenceRooter<JSObject* > resultRooter(cx, &result);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetSequenceOfAllowSharedArrayBuffer(cx, unwrappedObj, result, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->GetSequenceOfAllowSharedArrayBuffer(cx, unwrappedObj, result, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "TestFunctions.sequenceOfAllowSharedArrayBuffer getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
{
JS::Rooted<JSObject*> conversionScope(cx, isXray ? JS::CurrentGlobalOrNull(cx) : slotStorage);
JSAutoRealm ar(cx, conversionScope);
do { // block we break out of when done wrapping
uint32_t length = result.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(result[sequenceIdx0]);
tmp.setObject(*result[sequenceIdx0]);
if (!MaybeWrapNonDOMObjectValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
args.rval().setObject(*returnArray);
break;
} while (false);
}
{ // And now store things in the realm of our slotStorage.
JSAutoRealm ar(cx, slotStorage);
// Make a copy so that we don't do unnecessary wrapping on args.rval().
JS::Rooted<JS::Value> storedVal(cx, args.rval());
if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
return false;
}
JS::SetReservedSlot(slotStorage, slotIndex, storedVal);
}
// And now make sure args.rval() is in the caller realm.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
MOZ_CAN_RUN_SCRIPT static bool
set_sequenceOfAllowSharedArrayBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
BindingCallContext cx(cx_, "TestFunctions.sequenceOfAllowSharedArrayBuffer setter");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "sequenceOfAllowSharedArrayBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
binding_detail::AutoSequence<ArrayBuffer> arg0;
SequenceRooter<ArrayBuffer> arg0_holder(cx, &arg0);
if (args[0].isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Value being assigned", "sequence");
return false;
}
binding_detail::AutoSequence<ArrayBuffer> &arr = arg0;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
ArrayBuffer* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
ArrayBuffer& slot = *slotPtr;
if (temp.isObject()) {
if (!slot.Init(&temp.toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of value being assigned", "ArrayBuffer");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(slot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Element of value being assigned");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(slot.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Element of value being assigned");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of value being assigned");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Value being assigned", "sequence");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetSequenceOfAllowSharedArrayBuffer(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetSequenceOfAllowSharedArrayBuffer(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo sequenceOfAllowSharedArrayBuffer_getterinfo = {
{ get_sequenceOfAllowSharedArrayBuffer },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
true, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
(DOM_INSTANCE_RESERVED_SLOTS + 3) /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 3) <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 3) < 5, "There is no slot for us");
static const JSJitInfo sequenceOfAllowSharedArrayBuffer_setterinfo = {
{ (JSJitGetterOp)set_sequenceOfAllowSharedArrayBuffer },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
testNotAllowShared(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "TestFunctions.testNotAllowShared");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "testNotAllowShared", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
unsigned argcount = std::min(args.length(), 1u);
switch (argcount) {
case 1: {
if (args[0].isObject()) {
do {
RootedSpiderMonkeyInterface<ArrayBufferView> arg0(cx);
if (!arg0.Init(&args[0].toObject())) {
break;
}
if (JS::IsArrayBufferViewShared(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("Argument 1");
return false;
}
if (JS::IsLargeArrayBufferView(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Argument 1");
return false;
}
if (JS::IsResizableArrayBufferView(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Argument 1");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->TestNotAllowShared(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->TestNotAllowShared(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
} while (false);
do {
RootedSpiderMonkeyInterface<ArrayBuffer> arg0(cx);
if (!arg0.Init(&args[0].toObject())) {
break;
}
if (JS::IsSharedArrayBufferObject(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("Argument 1");
return false;
}
if (JS::IsLargeArrayBufferMaybeShared(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Argument 1");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Argument 1");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->TestNotAllowShared(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->TestNotAllowShared(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
} while (false);
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->TestNotAllowShared(NonNullHelper(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->TestNotAllowShared(NonNullHelper(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
break;
}
default: {
// Using nsPrintfCString here would require including that
// header. Let's not worry about it.
nsAutoCString argCountStr;
argCountStr.AppendPrintf("%u", args.length());
return cx.ThrowErrorMessage<MSG_INVALID_OVERLOAD_ARGCOUNT>(argCountStr.get());
}
}
MOZ_CRASH("We have an always-returning default case");
return false;
}
static const JSJitInfo testNotAllowShared_methodinfo = {
{ (JSJitGetterOp)testNotAllowShared },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
testAllowShared(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "TestFunctions.testAllowShared");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "testAllowShared", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
unsigned argcount = std::min(args.length(), 1u);
switch (argcount) {
case 1: {
if (args[0].isObject()) {
do {
RootedSpiderMonkeyInterface<ArrayBufferView> arg0(cx);
if (!arg0.Init(&args[0].toObject())) {
break;
}
if (JS::IsLargeArrayBufferView(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Argument 1");
return false;
}
if (JS::IsResizableArrayBufferView(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Argument 1");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->TestAllowShared(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->TestAllowShared(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
} while (false);
do {
RootedSpiderMonkeyInterface<ArrayBuffer> arg0(cx);
if (!arg0.Init(&args[0].toObject())) {
break;
}
if (JS::IsLargeArrayBufferMaybeShared(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Argument 1");
return false;
}
if (JS::IsResizableArrayBufferMaybeShared(arg0.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Argument 1");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->TestAllowShared(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->TestAllowShared(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
} while (false);
}
return cx.ThrowErrorMessage<MSG_OVERLOAD_RESOLUTION_FAILED>("1", "1");
break;
}
default: {
// Using nsPrintfCString here would require including that
// header. Let's not worry about it.
nsAutoCString argCountStr;
argCountStr.AppendPrintf("%u", args.length());
return cx.ThrowErrorMessage<MSG_INVALID_OVERLOAD_ARGCOUNT>(argCountStr.get());
}
}
MOZ_CRASH("We have an always-returning default case");
return false;
}
static const JSJitInfo testAllowShared_methodinfo = {
{ (JSJitGetterOp)testAllowShared },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
testDictWithAllowShared(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "TestFunctions.testDictWithAllowShared");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "testDictWithAllowShared", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
RootedDictionary<binding_detail::FastDictWithAllowSharedBufferSource> arg0(cx);
if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->TestDictWithAllowShared(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->TestDictWithAllowShared(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo testDictWithAllowShared_methodinfo = {
{ (JSJitGetterOp)testDictWithAllowShared },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
testUnionOfBuffferSource(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "TestFunctions.testUnionOfBuffferSource");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "testUnionOfBuffferSource", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
if (!args.requireAtLeast(cx, "TestFunctions.testUnionOfBuffferSource", 1)) {
return false;
}
ArrayBufferOrArrayBufferViewOrString arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->TestUnionOfBuffferSource(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->TestUnionOfBuffferSource(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo testUnionOfBuffferSource_methodinfo = {
{ (JSJitGetterOp)testUnionOfBuffferSource },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
testUnionOfAllowSharedBuffferSource(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "TestFunctions.testUnionOfAllowSharedBuffferSource");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "testUnionOfAllowSharedBuffferSource", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
if (!args.requireAtLeast(cx, "TestFunctions.testUnionOfAllowSharedBuffferSource", 1)) {
return false;
}
MaybeSharedArrayBufferOrMaybeSharedArrayBufferView arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->TestUnionOfAllowSharedBuffferSource(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->TestUnionOfAllowSharedBuffferSource(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo testUnionOfAllowSharedBuffferSource_methodinfo = {
{ (JSJitGetterOp)testUnionOfAllowSharedBuffferSource },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
staticAndNonStaticOverload(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "staticAndNonStaticOverload", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
bool result(MOZ_KnownLive(self)->StaticAndNonStaticOverload());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setBoolean(result);
return true;
}
static const JSJitInfo staticAndNonStaticOverload_methodinfo = {
{ (JSJitGetterOp)staticAndNonStaticOverload },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
staticAndNonStaticOverload(JSContext* cx, unsigned argc, JS::Value* vp)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "staticAndNonStaticOverload", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
if (global.Failed()) {
return false;
}
Optional<uint32_t> arg0;
if (args.hasDefined(0)) {
arg0.Construct();
if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], "Argument 1", &arg0.Value())) {
return false;
}
}
bool result(mozilla::dom::TestFunctions::StaticAndNonStaticOverload(global, Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setBoolean(result);
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
toJSON(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "toJSON", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::TestFunctions*>(void_self);
JS::Rooted<JSObject*> result(cx, JS_NewPlainObject(cx));
if (!result) {
return false;
}
if (!TestFunctions_Binding::CollectJSONAttributes(cx, obj, MOZ_KnownLive(self), result)) {
return false;
}
args.rval().setObject(*result);
return true;
}
static const JSJitInfo toJSON_methodinfo = {
{ (JSJitGetterOp)toJSON },
{ prototypes::id::TestFunctions },
{ PrototypeTraits<prototypes::id::TestFunctions>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::dom::TestFunctions* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestFunctions>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::dom::TestFunctions>(self);
}
}
static const JSFunctionSpec sStaticMethods_specs[] = {
JS_FNSPEC("throwUncatchableException", throwUncatchableException, nullptr, 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("passThroughPromise", StaticMethodPromiseWrapper, &passThroughPromise_methodinfo, 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("passThroughCallbackPromise", StaticMethodPromiseWrapper, &passThroughCallbackPromise_methodinfo, 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("throwToRejectPromise", StaticMethodPromiseWrapper, &throwToRejectPromise_methodinfo, 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("staticAndNonStaticOverload", staticAndNonStaticOverload, nullptr, 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const Prefable<const JSFunctionSpec> sStaticMethods[] = {
{ nullptr, &sStaticMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("setStringData", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setStringData_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getStringDataAsAString", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getStringDataAsAString_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getStringDataAsDOMString", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getStringDataAsDOMString_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getShortLiteralString", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getShortLiteralString_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getMediumLiteralString", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getMediumLiteralString_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getLongLiteralString", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getLongLiteralString_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getStringbufferString", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getStringbufferString_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getStringType", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getStringType_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("stringbufferMatchesStored", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&stringbufferMatchesStored_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("testThrowNsresult", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&testThrowNsresult_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("testThrowNsresultFromNative", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&testThrowNsresultFromNative_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("toJSON", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&toJSON_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("testNotAllowShared", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&testNotAllowShared_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("testAllowShared", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&testAllowShared_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("testDictWithAllowShared", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&testDictWithAllowShared_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("testUnionOfBuffferSource", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&testUnionOfBuffferSource_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("testUnionOfAllowSharedBuffferSource", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&testUnionOfAllowSharedBuffferSource_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("staticAndNonStaticOverload", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&staticAndNonStaticOverload_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ nullptr, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(18 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("one", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &one_getterinfo, nullptr, nullptr),
JS_PS_END,
JSPropertySpec::nativeAccessors("two", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &two_getterinfo, nullptr, nullptr),
JS_PS_END,
JSPropertySpec::nativeAccessors("wrapperCachedNonISupportsObject", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wrapperCachedNonISupportsObject_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("clampedNullableOctet", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &clampedNullableOctet_getterinfo, GenericSetter<NormalThisPolicy>, &clampedNullableOctet_setterinfo),
JSPropertySpec::nativeAccessors("enforcedNullableOctet", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &enforcedNullableOctet_getterinfo, GenericSetter<NormalThisPolicy>, &enforcedNullableOctet_setterinfo),
JSPropertySpec::nativeAccessors("arrayBufferView", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &arrayBufferView_getterinfo, GenericSetter<NormalThisPolicy>, &arrayBufferView_setterinfo),
JSPropertySpec::nativeAccessors("allowSharedArrayBufferView", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &allowSharedArrayBufferView_getterinfo, GenericSetter<NormalThisPolicy>, &allowSharedArrayBufferView_setterinfo),
JSPropertySpec::nativeAccessors("sequenceOfArrayBufferView", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &sequenceOfArrayBufferView_getterinfo, GenericSetter<NormalThisPolicy>, &sequenceOfArrayBufferView_setterinfo),
JSPropertySpec::nativeAccessors("sequenceOfAllowSharedArrayBufferView", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &sequenceOfAllowSharedArrayBufferView_getterinfo, GenericSetter<NormalThisPolicy>, &sequenceOfAllowSharedArrayBufferView_setterinfo),
JSPropertySpec::nativeAccessors("arrayBuffer", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &arrayBuffer_getterinfo, GenericSetter<NormalThisPolicy>, &arrayBuffer_setterinfo),
JSPropertySpec::nativeAccessors("allowSharedArrayBuffer", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &allowSharedArrayBuffer_getterinfo, GenericSetter<NormalThisPolicy>, &allowSharedArrayBuffer_setterinfo),
JSPropertySpec::nativeAccessors("sequenceOfArrayBuffer", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &sequenceOfArrayBuffer_getterinfo, GenericSetter<NormalThisPolicy>, &sequenceOfArrayBuffer_setterinfo),
JSPropertySpec::nativeAccessors("sequenceOfAllowSharedArrayBuffer", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &sequenceOfAllowSharedArrayBuffer_getterinfo, GenericSetter<NormalThisPolicy>, &sequenceOfAllowSharedArrayBuffer_setterinfo),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers2 = {
WebIDLPrefIndex::NoPref, 0, false, OriginTrial(0), &mozilla::dom::TestFunctions::ObjectFromAboutBlank
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ &sAttributes_disablers2, &sAttributes_specs[2] },
{ nullptr, &sAttributes_specs[4] },
{ nullptr, nullptr }
};
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(11 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[36];
static PropertyInfo sNativeProperties_propertyInfos[36];
static const NativePropertiesN<3> sNativeProperties = {
true, 0 /* sStaticMethods */,
false, 0,
true, 1 /* sMethods */,
true, 2 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
36,
sNativeProperties_sortedPropertyIndices,
{
{ sStaticMethods, &sNativeProperties_propertyInfos[0] },
{ sMethods, &sNativeProperties_propertyInfos[5] },
{ sAttributes, &sNativeProperties_propertyInfos[23] }
}
};
static_assert(36 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
MOZ_CAN_RUN_SCRIPT bool
CollectJSONAttributes(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestFunctions* self, JS::Rooted<JSObject*>& result)
{
JS::Rooted<JSObject*> unwrappedObj(cx, js::CheckedUnwrapStatic(obj));
if (!unwrappedObj) {
// How did that happen? We managed to get called with that
// object as "this"! Just give up on sanity.
return false;
}
{ // scope for "temp"
JS::Rooted<JS::Value> temp(cx);
if (!get_one(cx, obj, self, JSJitGetterCallArgs(&temp))) {
return false;
}
if (!JS_DefineProperty(cx, result, "one", temp, JSPROP_ENUMERATE)) {
return false;
}
}
// This is unfortunately a linear scan through sAttributes, but we
// only do it for things which _might_ be disabled, which should
// help keep the performance problems down.
if (IsGetterEnabled(cx, unwrappedObj, (JSJitGetterOp)get_two, sAttributes)) {
JS::Rooted<JS::Value> temp(cx);
if (!get_two(cx, obj, self, JSJitGetterCallArgs(&temp))) {
return false;
}
if (!JS_DefineProperty(cx, result, "two", temp, JSPROP_ENUMERATE)) {
return false;
}
}
{ // scope for "temp"
JS::Rooted<JS::Value> temp(cx);
if (!get_clampedNullableOctet(cx, obj, self, JSJitGetterCallArgs(&temp))) {
return false;
}
if (!JS_DefineProperty(cx, result, "clampedNullableOctet", temp, JSPROP_ENUMERATE)) {
return false;
}
}
{ // scope for "temp"
JS::Rooted<JS::Value> temp(cx);
if (!get_enforcedNullableOctet(cx, obj, self, JSJitGetterCallArgs(&temp))) {
return false;
}
if (!JS_DefineProperty(cx, result, "enforcedNullableOctet", temp, JSPROP_ENUMERATE)) {
return false;
}
}
return true;
}
// This may allocate too many slots, because we only really need
// slots for our non-interface-typed members that we cache. But
// allocating slots only for those would make the slot index
// computations much more complicated, so let's do this the simple
// way for now.
DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 4);
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::TestFunctions,
constructors::id::TestFunctions,
&sXrayExpandoObjectClass
};
static bool
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestFunctions", "constructor", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
if (!args.isConstructing()) {
return ThrowConstructorWithoutNew(cx, "TestFunctions");
}
JS::Rooted<JSObject*> desiredProto(cx);
if (!GetDesiredProto(cx, args,
prototypes::id::TestFunctions,
CreateInterfaceObjects,
&desiredProto)) {
return false;
}
GlobalObject global(cx, obj);
if (global.Failed()) {
return false;
}
bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
Maybe<JSAutoRealm> ar;
if (objIsXray) {
// Since our object is an Xray, we can just CheckedUnwrapStatic:
// we know Xrays have no dynamic unwrap behavior.
obj = js::CheckedUnwrapStatic(obj);
if (!obj) {
return false;
}
ar.emplace(cx, obj);
if (!JS_WrapObject(cx, &desiredProto)) {
return false;
}
}
auto result(StrongOrRawPtr<mozilla::dom::TestFunctions>(mozilla::dom::TestFunctions::Constructor(global)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
static_assert(!std::is_pointer_v<decltype(result)>,
"NewObject implies that we need to keep the object alive with a strong reference.");
if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval(), desiredProto)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ _constructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::TestFunctions,
PrototypeTraits<prototypes::id::TestFunctions>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"TestFunctionsPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::TestFunctions,
PrototypeTraits<prototypes::id::TestFunctions>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_expose_test_interfaces();
}
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
nullptr /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "TestFunctions",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(5),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::TestFunctions, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::dom::TestFunctions>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::TestFunctions>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::TestFunctions>::Get(),
nullptr,
nullptr
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(5 >= 5,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::dom::TestFunctions* aObject, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::TestFunctions*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::dom::TestFunctions> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
creator.InitializationSucceeded();
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestFunctions);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestFunctions);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"TestFunctions", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace TestFunctions_Binding
namespace TestInterfaceLength_Binding {
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::TestInterfaceLength* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceLength>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::dom::TestInterfaceLength* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceLength>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::dom::TestInterfaceLength>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::TestInterfaceLength* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceLength>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::TestInterfaceLength* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceLength>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ nullptr, nullptr, &sNativePropertiesInited },
prototypes::id::TestInterfaceLength,
constructors::id::TestInterfaceLength,
&DefaultXrayExpandoObjectClass
};
static bool
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestInterfaceLength", "constructor", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
if (!nsContentUtils::ThreadsafeIsSystemCaller(cx)) {
return ThrowingConstructor(cx, argc, vp);
}
if (!args.isConstructing()) {
return ThrowConstructorWithoutNew(cx, "TestInterfaceLength");
}
JS::Rooted<JSObject*> desiredProto(cx);
if (!GetDesiredProto(cx, args,
prototypes::id::TestInterfaceLength,
CreateInterfaceObjects,
&desiredProto)) {
return false;
}
if (!args.requireAtLeast(cx, "TestInterfaceLength constructor", 1)) {
return false;
}
GlobalObject global(cx, obj);
if (global.Failed()) {
return false;
}
bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
bool arg0;
if (!ValueToPrimitive<bool, eDefault>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
Maybe<JSAutoRealm> ar;
if (objIsXray) {
// Since our object is an Xray, we can just CheckedUnwrapStatic:
// we know Xrays have no dynamic unwrap behavior.
obj = js::CheckedUnwrapStatic(obj);
if (!obj) {
return false;
}
ar.emplace(cx, obj);
if (!JS_WrapObject(cx, &desiredProto)) {
return false;
}
}
auto result(StrongOrRawPtr<mozilla::dom::TestInterfaceLength>(mozilla::dom::TestInterfaceLength::Constructor(global, arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
static_assert(!std::is_pointer_v<decltype(result)>,
"NewObject implies that we need to keep the object alive with a strong reference.");
if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ _constructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::TestInterfaceLength,
PrototypeTraits<prototypes::id::TestInterfaceLength>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"TestInterfaceLengthPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::TestInterfaceLength,
PrototypeTraits<prototypes::id::TestInterfaceLength>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_expose_test_interfaces();
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "TestInterfaceLength",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::TestInterfaceLength, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::dom::TestInterfaceLength>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::TestInterfaceLength>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::TestInterfaceLength>::Get(),
nullptr,
_getWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::dom::TestInterfaceLength* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::TestInterfaceLength>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::TestInterfaceLength*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::dom::TestInterfaceLength> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceLength);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestInterfaceLength);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 1, true, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
nullptr,
nullptr,
"TestInterfaceLength", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace TestInterfaceLength_Binding
namespace TestTrialInterface_Binding {
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::TestTrialInterface* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestTrialInterface>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::dom::TestTrialInterface* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestTrialInterface>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::dom::TestTrialInterface>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::TestTrialInterface* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestTrialInterface>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::TestTrialInterface* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestTrialInterface>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ nullptr, nullptr, &sNativePropertiesInited },
prototypes::id::TestTrialInterface,
constructors::id::TestTrialInterface,
&DefaultXrayExpandoObjectClass
};
static bool
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"TestTrialInterface", "constructor", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
if (!args.isConstructing()) {
return ThrowConstructorWithoutNew(cx, "TestTrialInterface");
}
JS::Rooted<JSObject*> desiredProto(cx);
if (!GetDesiredProto(cx, args,
prototypes::id::TestTrialInterface,
CreateInterfaceObjects,
&desiredProto)) {
return false;
}
GlobalObject global(cx, obj);
if (global.Failed()) {
return false;
}
bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
Maybe<JSAutoRealm> ar;
if (objIsXray) {
// Since our object is an Xray, we can just CheckedUnwrapStatic:
// we know Xrays have no dynamic unwrap behavior.
obj = js::CheckedUnwrapStatic(obj);
if (!obj) {
return false;
}
ar.emplace(cx, obj);
if (!JS_WrapObject(cx, &desiredProto)) {
return false;
}
}
auto result(StrongOrRawPtr<mozilla::dom::TestTrialInterface>(mozilla::dom::TestTrialInterface::Constructor(global)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
static_assert(!std::is_pointer_v<decltype(result)>,
"NewObject implies that we need to keep the object alive with a strong reference.");
if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ _constructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::TestTrialInterface,
PrototypeTraits<prototypes::id::TestTrialInterface>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"TestTrialInterfacePrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::TestTrialInterface,
PrototypeTraits<prototypes::id::TestTrialInterface>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return OriginTrials::IsEnabled(aCx, aObj, OriginTrial::TestTrial);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "TestTrialInterface",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::TestTrialInterface, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::dom::TestTrialInterface>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::TestTrialInterface>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::TestTrialInterface>::Get(),
nullptr,
_getWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::dom::TestTrialInterface* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::TestTrialInterface>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::TestTrialInterface*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::dom::TestTrialInterface> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestTrialInterface);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestTrialInterface);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
nullptr,
nullptr,
"TestTrialInterface", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace TestTrialInterface_Binding
namespace WrapperCachedNonISupportsTestInterface_Binding {
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::WrapperCachedNonISupportsTestInterface* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::WrapperCachedNonISupportsTestInterface>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::dom::WrapperCachedNonISupportsTestInterface* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::WrapperCachedNonISupportsTestInterface>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::dom::WrapperCachedNonISupportsTestInterface>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::WrapperCachedNonISupportsTestInterface* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::WrapperCachedNonISupportsTestInterface>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::WrapperCachedNonISupportsTestInterface* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::WrapperCachedNonISupportsTestInterface>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ nullptr, nullptr, &sNativePropertiesInited },
prototypes::id::WrapperCachedNonISupportsTestInterface,
constructors::id::WrapperCachedNonISupportsTestInterface,
&DefaultXrayExpandoObjectClass
};
static bool
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"WrapperCachedNonISupportsTestInterface", "constructor", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
if (!StaticPrefs::dom_webidl_test1()) {
return ThrowingConstructor(cx, argc, vp);
}
if (!args.isConstructing()) {
return ThrowConstructorWithoutNew(cx, "WrapperCachedNonISupportsTestInterface");
}
JS::Rooted<JSObject*> desiredProto(cx);
if (!GetDesiredProto(cx, args,
prototypes::id::WrapperCachedNonISupportsTestInterface,
CreateInterfaceObjects,
&desiredProto)) {
return false;
}
GlobalObject global(cx, obj);
if (global.Failed()) {
return false;
}
bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
Maybe<JSAutoRealm> ar;
if (objIsXray) {
// Since our object is an Xray, we can just CheckedUnwrapStatic:
// we know Xrays have no dynamic unwrap behavior.
obj = js::CheckedUnwrapStatic(obj);
if (!obj) {
return false;
}
ar.emplace(cx, obj);
if (!JS_WrapObject(cx, &desiredProto)) {
return false;
}
}
auto result(StrongOrRawPtr<mozilla::dom::WrapperCachedNonISupportsTestInterface>(mozilla::dom::WrapperCachedNonISupportsTestInterface::Constructor(global)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
static_assert(!std::is_pointer_v<decltype(result)>,
"NewObject implies that we need to keep the object alive with a strong reference.");
if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ _constructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::WrapperCachedNonISupportsTestInterface,
PrototypeTraits<prototypes::id::WrapperCachedNonISupportsTestInterface>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"WrapperCachedNonISupportsTestInterfacePrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::WrapperCachedNonISupportsTestInterface,
PrototypeTraits<prototypes::id::WrapperCachedNonISupportsTestInterface>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_expose_test_interfaces();
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "WrapperCachedNonISupportsTestInterface",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::WrapperCachedNonISupportsTestInterface, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::dom::WrapperCachedNonISupportsTestInterface>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::WrapperCachedNonISupportsTestInterface>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::WrapperCachedNonISupportsTestInterface>::Get(),
nullptr,
_getWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::dom::WrapperCachedNonISupportsTestInterface* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::WrapperCachedNonISupportsTestInterface>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::WrapperCachedNonISupportsTestInterface*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::dom::WrapperCachedNonISupportsTestInterface> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::WrapperCachedNonISupportsTestInterface);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::WrapperCachedNonISupportsTestInterface);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
nullptr,
nullptr,
"WrapperCachedNonISupportsTestInterface", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace WrapperCachedNonISupportsTestInterface_Binding
} // namespace dom
} // namespace mozilla