Copy as Markdown

Other Tools

/* THIS FILE IS AUTOGENERATED FROM WebXR.webidl BY Codegen.py - DO NOT EDIT */
#include <type_traits>
#include "AtomList.h"
#include "ClientWebGLContext.h"
#include "DOMPointBinding.h"
#include "EventHandlerBinding.h"
#include "EventTargetBinding.h"
#include "MainThreadUtils.h"
#include "WebXRBinding.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/FloatingPoint.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/DOMJSProxyHandler.h"
#include "mozilla/dom/DOMPoint.h"
#include "mozilla/dom/Gamepad.h"
#include "mozilla/dom/IterableIterator.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ProxyHandlerUtils.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SimpleGlobalObject.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/dom/WebIDLPrefs.h"
#include "mozilla/dom/XRBoundedReferenceSpace.h"
#include "mozilla/dom/XRFrame.h"
#include "mozilla/dom/XRInputSource.h"
#include "mozilla/dom/XRInputSourceArray.h"
#include "mozilla/dom/XRPose.h"
#include "mozilla/dom/XRReferenceSpace.h"
#include "mozilla/dom/XRRenderState.h"
#include "mozilla/dom/XRRigidTransform.h"
#include "mozilla/dom/XRSession.h"
#include "mozilla/dom/XRSpace.h"
#include "mozilla/dom/XRSystem.h"
#include "mozilla/dom/XRView.h"
#include "mozilla/dom/XRViewerPose.h"
#include "mozilla/dom/XRViewport.h"
#include "mozilla/dom/XRWebGLLayer.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<XRSessionMode>::Values[3] = {
"inline"_ns,
"immersive-vr"_ns,
"immersive-ar"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, XRSessionMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(binding_detail::EnumStrings<XRSessionMode>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<XRSessionMode>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<XRSessionMode>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
const nsLiteralCString EnumStrings<XRVisibilityState>::Values[3] = {
"visible"_ns,
"visible-blurred"_ns,
"hidden"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, XRVisibilityState aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(binding_detail::EnumStrings<XRVisibilityState>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<XRVisibilityState>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<XRVisibilityState>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
const nsLiteralCString EnumStrings<XRReferenceSpaceType>::Values[5] = {
"viewer"_ns,
"local"_ns,
"local-floor"_ns,
"bounded-floor"_ns,
"unbounded"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, XRReferenceSpaceType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(binding_detail::EnumStrings<XRReferenceSpaceType>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<XRReferenceSpaceType>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<XRReferenceSpaceType>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
const nsLiteralCString EnumStrings<XREye>::Values[3] = {
"none"_ns,
"left"_ns,
"right"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, XREye aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(binding_detail::EnumStrings<XREye>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<XREye>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<XREye>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
const nsLiteralCString EnumStrings<XRHandedness>::Values[3] = {
"none"_ns,
"left"_ns,
"right"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, XRHandedness aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(binding_detail::EnumStrings<XRHandedness>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<XRHandedness>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<XRHandedness>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
const nsLiteralCString EnumStrings<XRTargetRayMode>::Values[3] = {
"gaze"_ns,
"tracked-pointer"_ns,
"screen"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, XRTargetRayMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(binding_detail::EnumStrings<XRTargetRayMode>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<XRTargetRayMode>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<XRTargetRayMode>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningWebGLRenderingContextOrWebGL2RenderingContext& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsWebGLRenderingContext()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsWebGLRenderingContext(), "mWebGLRenderingContext", aFlags);
} else if (aUnion.IsWebGL2RenderingContext()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsWebGL2RenderingContext(), "mWebGL2RenderingContext", aFlags);
}
}
void
ImplCycleCollectionUnlink(OwningWebGLRenderingContextOrWebGL2RenderingContext& aUnion)
{
aUnion.Uninit();
}
bool
WebGLRenderingContextOrWebGL2RenderingContext::TrySetToWebGLRenderingContext(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::ClientWebGLContext>& memberSlot = RawSetAsWebGLRenderingContext();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::WebGLRenderingContext, mozilla::ClientWebGLContext>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyWebGLRenderingContext();
tryNext = true;
return true;
}
}
}
return true;
}
bool
WebGLRenderingContextOrWebGL2RenderingContext::TrySetToWebGLRenderingContext(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToWebGLRenderingContext(cx, value, tryNext, passedToJSImpl);
}
bool
WebGLRenderingContextOrWebGL2RenderingContext::TrySetToWebGL2RenderingContext(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::ClientWebGLContext>& memberSlot = RawSetAsWebGL2RenderingContext();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::WebGL2RenderingContext, mozilla::ClientWebGLContext>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyWebGL2RenderingContext();
tryNext = true;
return true;
}
}
}
return true;
}
bool
WebGLRenderingContextOrWebGL2RenderingContext::TrySetToWebGL2RenderingContext(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToWebGL2RenderingContext(cx, value, tryNext, passedToJSImpl);
}
bool
WebGLRenderingContextOrWebGL2RenderingContext::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 = !TrySetToWebGLRenderingContext(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToWebGL2RenderingContext(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "WebGLRenderingContext, WebGL2RenderingContext");
return false;
}
return true;
}
bool
WebGLRenderingContextOrWebGL2RenderingContext::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
WebGLRenderingContextOrWebGL2RenderingContext::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eWebGLRenderingContext: {
if (!GetOrCreateDOMReflector(cx, mValue.mWebGLRenderingContext.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eWebGL2RenderingContext: {
if (!GetOrCreateDOMReflector(cx, mValue.mWebGL2RenderingContext.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningWebGLRenderingContextOrWebGL2RenderingContext::OwningWebGLRenderingContextOrWebGL2RenderingContext(OwningWebGLRenderingContextOrWebGL2RenderingContext&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eWebGLRenderingContext: {
mType = eWebGLRenderingContext;
mValue.mWebGLRenderingContext.SetValue(std::move(aOther.mValue.mWebGLRenderingContext.Value()));
break;
}
case eWebGL2RenderingContext: {
mType = eWebGL2RenderingContext;
mValue.mWebGL2RenderingContext.SetValue(std::move(aOther.mValue.mWebGL2RenderingContext.Value()));
break;
}
}
}
bool
OwningWebGLRenderingContextOrWebGL2RenderingContext::TrySetToWebGLRenderingContext(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::ClientWebGLContext>& memberSlot = RawSetAsWebGLRenderingContext();
static_assert(IsRefcounted<mozilla::ClientWebGLContext>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::WebGLRenderingContext, mozilla::ClientWebGLContext>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyWebGLRenderingContext();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningWebGLRenderingContextOrWebGL2RenderingContext::TrySetToWebGLRenderingContext(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToWebGLRenderingContext(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::ClientWebGLContext>&
OwningWebGLRenderingContextOrWebGL2RenderingContext::RawSetAsWebGLRenderingContext()
{
if (mType == eWebGLRenderingContext) {
return mValue.mWebGLRenderingContext.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eWebGLRenderingContext;
return mValue.mWebGLRenderingContext.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::ClientWebGLContext>&
OwningWebGLRenderingContextOrWebGL2RenderingContext::SetAsWebGLRenderingContext()
{
if (mType == eWebGLRenderingContext) {
return mValue.mWebGLRenderingContext.Value();
}
Uninit();
mType = eWebGLRenderingContext;
return mValue.mWebGLRenderingContext.SetValue();
}
void
OwningWebGLRenderingContextOrWebGL2RenderingContext::DestroyWebGLRenderingContext()
{
MOZ_RELEASE_ASSERT(IsWebGLRenderingContext(), "Wrong type!");
mValue.mWebGLRenderingContext.Destroy();
mType = eUninitialized;
}
bool
OwningWebGLRenderingContextOrWebGL2RenderingContext::TrySetToWebGL2RenderingContext(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::ClientWebGLContext>& memberSlot = RawSetAsWebGL2RenderingContext();
static_assert(IsRefcounted<mozilla::ClientWebGLContext>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::WebGL2RenderingContext, mozilla::ClientWebGLContext>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyWebGL2RenderingContext();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningWebGLRenderingContextOrWebGL2RenderingContext::TrySetToWebGL2RenderingContext(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToWebGL2RenderingContext(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::ClientWebGLContext>&
OwningWebGLRenderingContextOrWebGL2RenderingContext::RawSetAsWebGL2RenderingContext()
{
if (mType == eWebGL2RenderingContext) {
return mValue.mWebGL2RenderingContext.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eWebGL2RenderingContext;
return mValue.mWebGL2RenderingContext.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::ClientWebGLContext>&
OwningWebGLRenderingContextOrWebGL2RenderingContext::SetAsWebGL2RenderingContext()
{
if (mType == eWebGL2RenderingContext) {
return mValue.mWebGL2RenderingContext.Value();
}
Uninit();
mType = eWebGL2RenderingContext;
return mValue.mWebGL2RenderingContext.SetValue();
}
void
OwningWebGLRenderingContextOrWebGL2RenderingContext::DestroyWebGL2RenderingContext()
{
MOZ_RELEASE_ASSERT(IsWebGL2RenderingContext(), "Wrong type!");
mValue.mWebGL2RenderingContext.Destroy();
mType = eUninitialized;
}
bool
OwningWebGLRenderingContextOrWebGL2RenderingContext::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 = !TrySetToWebGLRenderingContext(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToWebGL2RenderingContext(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "WebGLRenderingContext, WebGL2RenderingContext");
return false;
}
return true;
}
bool
OwningWebGLRenderingContextOrWebGL2RenderingContext::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningWebGLRenderingContextOrWebGL2RenderingContext::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eWebGLRenderingContext: {
DestroyWebGLRenderingContext();
break;
}
case eWebGL2RenderingContext: {
DestroyWebGL2RenderingContext();
break;
}
}
}
bool
OwningWebGLRenderingContextOrWebGL2RenderingContext::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eWebGLRenderingContext: {
if (!GetOrCreateDOMReflector(cx, mValue.mWebGLRenderingContext.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eWebGL2RenderingContext: {
if (!GetOrCreateDOMReflector(cx, mValue.mWebGL2RenderingContext.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningWebGLRenderingContextOrWebGL2RenderingContext&
OwningWebGLRenderingContextOrWebGL2RenderingContext::operator=(OwningWebGLRenderingContextOrWebGL2RenderingContext&& aOther)
{
this->~OwningWebGLRenderingContextOrWebGL2RenderingContext();
new (this) OwningWebGLRenderingContextOrWebGL2RenderingContext (std::move(aOther));
return *this;
}
OwningWebGLRenderingContextOrWebGL2RenderingContext&
OwningWebGLRenderingContextOrWebGL2RenderingContext::operator=(const OwningWebGLRenderingContextOrWebGL2RenderingContext& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eWebGLRenderingContext: {
SetAsWebGLRenderingContext() = aOther.GetAsWebGLRenderingContext();
break;
}
case eWebGL2RenderingContext: {
SetAsWebGL2RenderingContext() = aOther.GetAsWebGL2RenderingContext();
break;
}
}
return *this;
}
MOZ_CAN_RUN_SCRIPT void
XRFrameRequestCallback::Call(BindingCallContext& cx, JS::Handle<JS::Value> aThisVal, double time, XRFrame& frame, 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;
}
unsigned argc = 2;
do {
if (!GetOrCreateDOMReflector(cx, frame, argv[1])) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
break;
} while (false);
do {
argv[0].set(JS_NumberValue(double(time)));
break;
} while (false);
JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
if (!JS::Call(cx, aThisVal, callable,
JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
aRv.NoteJSContextException(cx);
return;
}
}
XRRenderStateInit::XRRenderStateInit()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
XRRenderStateInit::InitIds(JSContext* cx, XRRenderStateInitAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->inlineVerticalFieldOfView_id.init(cx, "inlineVerticalFieldOfView") ||
!atomsCache->depthNear_id.init(cx, "depthNear") ||
!atomsCache->depthFar_id.init(cx, "depthFar") ||
!atomsCache->baseLayer_id.init(cx, "baseLayer")) {
return false;
}
return true;
}
bool
XRRenderStateInit::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());
XRRenderStateInitAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<XRRenderStateInitAtoms>(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->baseLayer_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mBaseLayer.Construct();
if (temp.ref().isObject()) {
static_assert(IsRefcounted<mozilla::dom::XRWebGLLayer>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::XRWebGLLayer, mozilla::dom::XRWebGLLayer>(temp.ptr(), (mBaseLayer.Value()), cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'baseLayer' member of XRRenderStateInit", "XRWebGLLayer");
return false;
}
}
} else if (temp.ref().isNullOrUndefined()) {
(mBaseLayer.Value()) = nullptr;
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'baseLayer' member of XRRenderStateInit");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthFar_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mDepthFar.Construct();
if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'depthFar' member of XRRenderStateInit", &(mDepthFar.Value()))) {
return false;
} else if (!std::isfinite((mDepthFar.Value()))) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'depthFar' member of XRRenderStateInit");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthNear_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mDepthNear.Construct();
if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'depthNear' member of XRRenderStateInit", &(mDepthNear.Value()))) {
return false;
} else if (!std::isfinite((mDepthNear.Value()))) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'depthNear' member of XRRenderStateInit");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->inlineVerticalFieldOfView_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mInlineVerticalFieldOfView.Construct();
if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'inlineVerticalFieldOfView' member of XRRenderStateInit", &(mInlineVerticalFieldOfView.Value()))) {
return false;
} else if (!std::isfinite((mInlineVerticalFieldOfView.Value()))) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'inlineVerticalFieldOfView' member of XRRenderStateInit");
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
XRRenderStateInit::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
XRRenderStateInit::TraceDictionary(JSTracer* trc)
{
}
XRRenderStateInit&
XRRenderStateInit::operator=(const XRRenderStateInit& aOther)
{
DictionaryBase::operator=(aOther);
mBaseLayer.Reset();
if (aOther.mBaseLayer.WasPassed()) {
mBaseLayer.Construct(aOther.mBaseLayer.Value());
}
mDepthFar.Reset();
if (aOther.mDepthFar.WasPassed()) {
mDepthFar.Construct(aOther.mDepthFar.Value());
}
mDepthNear.Reset();
if (aOther.mDepthNear.WasPassed()) {
mDepthNear.Construct(aOther.mDepthNear.Value());
}
mInlineVerticalFieldOfView.Reset();
if (aOther.mInlineVerticalFieldOfView.WasPassed()) {
mInlineVerticalFieldOfView.Construct(aOther.mInlineVerticalFieldOfView.Value());
}
return *this;
}
XRSessionInit::XRSessionInit()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
XRSessionInit::InitIds(JSContext* cx, XRSessionInitAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->requiredFeatures_id.init(cx, "requiredFeatures") ||
!atomsCache->optionalFeatures_id.init(cx, "optionalFeatures")) {
return false;
}
return true;
}
bool
XRSessionInit::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());
XRSessionInitAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<XRSessionInitAtoms>(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->optionalFeatures_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mOptionalFeatures.Construct();
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'optionalFeatures' member of XRSessionInit", "sequence");
return false;
}
Sequence<nsString> &arr = (mOptionalFeatures.Value());
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'optionalFeatures' member of XRSessionInit", "sequence");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->requiredFeatures_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mRequiredFeatures.Construct();
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'requiredFeatures' member of XRSessionInit", "sequence");
return false;
}
Sequence<nsString> &arr = (mRequiredFeatures.Value());
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'requiredFeatures' member of XRSessionInit", "sequence");
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
XRSessionInit::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
XRSessionInit::TraceDictionary(JSTracer* trc)
{
}
XRSessionInit&
XRSessionInit::operator=(const XRSessionInit& aOther)
{
DictionaryBase::operator=(aOther);
mOptionalFeatures.Reset();
if (aOther.mOptionalFeatures.WasPassed()) {
mOptionalFeatures.Construct(aOther.mOptionalFeatures.Value());
}
mRequiredFeatures.Reset();
if (aOther.mRequiredFeatures.WasPassed()) {
mRequiredFeatures.Construct(aOther.mRequiredFeatures.Value());
}
return *this;
}
XRWebGLLayerInit::XRWebGLLayerInit()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
XRWebGLLayerInit::InitIds(JSContext* cx, XRWebGLLayerInitAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->stencil_id.init(cx, "stencil") ||
!atomsCache->ignoreDepthValues_id.init(cx, "ignoreDepthValues") ||
!atomsCache->framebufferScaleFactor_id.init(cx, "framebufferScaleFactor") ||
!atomsCache->depth_id.init(cx, "depth") ||
!atomsCache->antialias_id.init(cx, "antialias") ||
!atomsCache->alpha_id.init(cx, "alpha")) {
return false;
}
return true;
}
bool
XRWebGLLayerInit::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());
XRWebGLLayerInitAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<XRWebGLLayerInitAtoms>(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->alpha_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'alpha' member of XRWebGLLayerInit", &mAlpha)) {
return false;
}
} else {
mAlpha = true;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->antialias_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'antialias' member of XRWebGLLayerInit", &mAntialias)) {
return false;
}
} else {
mAntialias = true;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depth_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'depth' member of XRWebGLLayerInit", &mDepth)) {
return false;
}
} else {
mDepth = true;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->framebufferScaleFactor_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'framebufferScaleFactor' member of XRWebGLLayerInit", &mFramebufferScaleFactor)) {
return false;
} else if (!std::isfinite(mFramebufferScaleFactor)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'framebufferScaleFactor' member of XRWebGLLayerInit");
return false;
}
} else {
mFramebufferScaleFactor = 1.0;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->ignoreDepthValues_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'ignoreDepthValues' member of XRWebGLLayerInit", &mIgnoreDepthValues)) {
return false;
}
} else {
mIgnoreDepthValues = false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stencil_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'stencil' member of XRWebGLLayerInit", &mStencil)) {
return false;
}
} else {
mStencil = false;
}
mIsAnyMemberPresent = true;
return true;
}
bool
XRWebGLLayerInit::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
XRWebGLLayerInit::TraceDictionary(JSTracer* trc)
{
}
XRWebGLLayerInit&
XRWebGLLayerInit::operator=(const XRWebGLLayerInit& aOther)
{
DictionaryBase::operator=(aOther);
mAlpha = aOther.mAlpha;
mAntialias = aOther.mAntialias;
mDepth = aOther.mDepth;
mFramebufferScaleFactor = aOther.mFramebufferScaleFactor;
mIgnoreDepthValues = aOther.mIgnoreDepthValues;
mStencil = aOther.mStencil;
return *this;
}
bool
XRWebGLLayerInit::operator==(const XRWebGLLayerInit& aOther) const
{
if (mAlpha != aOther.mAlpha) {
return false;
}
if (mAntialias != aOther.mAntialias) {
return false;
}
if (mDepth != aOther.mDepth) {
return false;
}
if (mFramebufferScaleFactor != aOther.mFramebufferScaleFactor) {
return false;
}
if (mIgnoreDepthValues != aOther.mIgnoreDepthValues) {
return false;
}
if (mStencil != aOther.mStencil) {
return false;
}
return true;
}
namespace XRBoundedReferenceSpace_Binding {
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<XRReferenceSpace_Binding::NativeType>::value,
"Can't inherit from an interface with a different ownership model.");
MOZ_CAN_RUN_SCRIPT static bool
get_boundsGeometry(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRBoundedReferenceSpace", "boundsGeometry", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRBoundedReferenceSpace*>(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());
}
}
nsTArray<StrongPtrForMember<mozilla::dom::DOMPointReadOnly>> result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetBoundsGeometry(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetBoundsGeometry(result);
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 {
if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
args.rval().setObject(*returnArray);
break;
} while (false);
JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
if (!JS_FreezeObject(cx, rvalObj)) {
return 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);
if (!isXray) {
// In the Xray case we don't need to do this, because getting the
// expando object already preserved our wrapper.
PreserveWrapper(self);
}
}
// And now make sure args.rval() is in the caller realm.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
static const JSJitInfo boundsGeometry_getterinfo = {
{ get_boundsGeometry },
{ prototypes::id::XRBoundedReferenceSpace },
{ PrototypeTraits<prototypes::id::XRBoundedReferenceSpace>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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) < 2, "There is no slot for us");
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRBoundedReferenceSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRBoundedReferenceSpace>(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::XRBoundedReferenceSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRBoundedReferenceSpace>(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::XRBoundedReferenceSpace>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRBoundedReferenceSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRBoundedReferenceSpace>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRBoundedReferenceSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRBoundedReferenceSpace>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("boundsGeometry", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &boundsGeometry_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
// 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, 1);
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRBoundedReferenceSpace,
constructors::id::XRBoundedReferenceSpace,
&sXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
XRReferenceSpace_Binding::GetConstructorObject,
prototypes::id::XRBoundedReferenceSpace,
PrototypeTraits<prototypes::id::XRBoundedReferenceSpace>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRBoundedReferenceSpacePrototype",
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::XRBoundedReferenceSpace,
PrototypeTraits<prototypes::id::XRBoundedReferenceSpace>::Depth,
&sNativePropertyHooks,
XRReferenceSpace_Binding::GetProtoObject
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRBoundedReferenceSpace",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::EventTarget, prototypes::id::XRSpace, prototypes::id::XRReferenceSpace, prototypes::id::XRBoundedReferenceSpace, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::dom::XRBoundedReferenceSpace>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRBoundedReferenceSpace>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRBoundedReferenceSpace>::Get(),
nullptr,
_getWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(2 >= 2,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::dom::XRBoundedReferenceSpace* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRBoundedReferenceSpace>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRBoundedReferenceSpace*>);
MOZ_ASSERT(static_cast<mozilla::dom::XRReferenceSpace*>(aObject) ==
reinterpret_cast<mozilla::dom::XRReferenceSpace*>(aObject),
"Multiple inheritance for mozilla::dom::XRReferenceSpace is broken.");
MOZ_ASSERT(static_cast<mozilla::dom::XRSpace*>(aObject) ==
reinterpret_cast<mozilla::dom::XRSpace*>(aObject),
"Multiple inheritance for mozilla::dom::XRSpace is broken.");
MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
"Multiple inheritance for mozilla::dom::EventTarget is broken.");
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::XRBoundedReferenceSpace> 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
ClearCachedBoundsGeometryValue(mozilla::dom::XRBoundedReferenceSpace* aObject)
{
JSObject* obj;
obj = aObject->GetWrapper();
if (!obj) {
return;
}
JS::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), JS::UndefinedValue());
xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 0));
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::XRBoundedReferenceSpace);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRBoundedReferenceSpace);
JS::Handle<JSObject*> parentProto(XRReferenceSpace_Binding::GetProtoObjectHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(XRReferenceSpace_Binding::GetConstructorObjectHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"XRBoundedReferenceSpace", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRBoundedReferenceSpace_Binding
namespace XRFrame_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_session(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRFrame", "session", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRFrame*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::XRSession>(MOZ_KnownLive(self)->Session()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo session_getterinfo = {
{ get_session },
{ prototypes::id::XRFrame },
{ PrototypeTraits<prototypes::id::XRFrame>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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
getViewerPose(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "XRFrame.getViewerPose");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRFrame", "getViewerPose", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRFrame*>(void_self);
if (!args.requireAtLeast(cx, "XRFrame.getViewerPose", 1)) {
return false;
}
NonNull<mozilla::dom::XRReferenceSpace> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::XRReferenceSpace, mozilla::dom::XRReferenceSpace>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "XRReferenceSpace");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::dom::XRViewerPose>(MOZ_KnownLive(self)->GetViewerPose(MOZ_KnownLive(NonNullHelper(arg0)), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRFrame.getViewerPose"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!result) {
args.rval().setNull();
return true;
}
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo getViewerPose_methodinfo = {
{ (JSJitGetterOp)getViewerPose },
{ prototypes::id::XRFrame },
{ PrototypeTraits<prototypes::id::XRFrame>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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
getPose(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "XRFrame.getPose");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRFrame", "getPose", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRFrame*>(void_self);
if (!args.requireAtLeast(cx, "XRFrame.getPose", 2)) {
return false;
}
NonNull<mozilla::dom::XRSpace> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::XRSpace, mozilla::dom::XRSpace>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "XRSpace");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
NonNull<mozilla::dom::XRSpace> arg1;
if (args[1].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::XRSpace, mozilla::dom::XRSpace>(args[1], arg1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "XRSpace");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::dom::XRPose>(MOZ_KnownLive(self)->GetPose(MOZ_KnownLive(NonNullHelper(arg0)), MOZ_KnownLive(NonNullHelper(arg1)), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRFrame.getPose"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!result) {
args.rval().setNull();
return true;
}
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo getPose_methodinfo = {
{ (JSJitGetterOp)getPose },
{ prototypes::id::XRFrame },
{ PrototypeTraits<prototypes::id::XRFrame>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRFrame* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRFrame>(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::XRFrame* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRFrame>(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::XRFrame>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRFrame* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRFrame>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRFrame* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRFrame>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("getViewerPose", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getViewerPose_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getPose", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getPose_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &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(2 <= 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("session", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &session_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(1 <= 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[3];
static PropertyInfo sNativeProperties_propertyInfos[3];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
3,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[2] }
}
};
static_assert(3 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRFrame,
constructors::id::XRFrame,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::XRFrame,
PrototypeTraits<prototypes::id::XRFrame>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRFramePrototype",
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::XRFrame,
PrototypeTraits<prototypes::id::XRFrame>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRFrame",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_SKIP_NURSERY_FINALIZE,
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::XRFrame, 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::XRFrame>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRFrame>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRFrame>::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::XRFrame* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRFrame>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRFrame*>);
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::XRFrame> 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::XRFrame);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRFrame);
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,
"XRFrame", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRFrame_Binding
namespace XRInputSource_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_handedness(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRInputSource", "handedness", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRInputSource*>(void_self);
XRHandedness result(MOZ_KnownLive(self)->Handedness());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo handedness_getterinfo = {
{ get_handedness },
{ prototypes::id::XRInputSource },
{ PrototypeTraits<prototypes::id::XRInputSource>::Depth },
JSJitInfo::Getter,
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
get_targetRayMode(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRInputSource", "targetRayMode", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRInputSource*>(void_self);
XRTargetRayMode result(MOZ_KnownLive(self)->TargetRayMode());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo targetRayMode_getterinfo = {
{ get_targetRayMode },
{ prototypes::id::XRInputSource },
{ PrototypeTraits<prototypes::id::XRInputSource>::Depth },
JSJitInfo::Getter,
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
get_targetRaySpace(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRInputSource", "targetRaySpace", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRInputSource*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::XRSpace>(MOZ_KnownLive(self)->TargetRaySpace()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo targetRaySpace_getterinfo = {
{ get_targetRaySpace },
{ prototypes::id::XRInputSource },
{ PrototypeTraits<prototypes::id::XRInputSource>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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_gripSpace(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRInputSource", "gripSpace", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRInputSource*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::XRSpace>(MOZ_KnownLive(self)->GetGripSpace()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!result) {
args.rval().setNull();
return true;
}
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo gripSpace_getterinfo = {
{ get_gripSpace },
{ prototypes::id::XRInputSource },
{ PrototypeTraits<prototypes::id::XRInputSource>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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_profiles(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRInputSource", "profiles", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRInputSource*>(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());
}
}
nsTArray<nsString> result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetProfiles(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetProfiles(result);
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 {
if (!xpc::NonVoidStringToJsval(cx, result[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
args.rval().setObject(*returnArray);
break;
} while (false);
JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
if (!JS_FreezeObject(cx, rvalObj)) {
return 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);
if (!isXray) {
// In the Xray case we don't need to do this, because getting the
// expando object already preserved our wrapper.
PreserveWrapper(self);
}
}
// And now make sure args.rval() is in the caller realm.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
static const JSJitInfo profiles_getterinfo = {
{ get_profiles },
{ prototypes::id::XRInputSource },
{ PrototypeTraits<prototypes::id::XRInputSource>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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) < 2, "There is no slot for us");
MOZ_CAN_RUN_SCRIPT static bool
get_gamepad(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRInputSource", "gamepad", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRInputSource*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::Gamepad>(MOZ_KnownLive(self)->GetGamepad()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!result) {
args.rval().setNull();
return true;
}
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo gamepad_getterinfo = {
{ get_gamepad },
{ prototypes::id::XRInputSource },
{ PrototypeTraits<prototypes::id::XRInputSource>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRInputSource* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRInputSource>(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::XRInputSource* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRInputSource>(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::XRInputSource>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRInputSource* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRInputSource>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRInputSource* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRInputSource>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("handedness", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &handedness_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("targetRayMode", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &targetRayMode_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("targetRaySpace", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &targetRaySpace_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("gripSpace", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &gripSpace_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("profiles", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &profiles_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("gamepad", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &gamepad_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(6 <= 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[6];
static PropertyInfo sNativeProperties_propertyInfos[6];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
6,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(6 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
// 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, 1);
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRInputSource,
constructors::id::XRInputSource,
&sXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::XRInputSource,
PrototypeTraits<prototypes::id::XRInputSource>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRInputSourcePrototype",
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::XRInputSource,
PrototypeTraits<prototypes::id::XRInputSource>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRInputSource",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::XRInputSource, 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::XRInputSource>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRInputSource>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRInputSource>::Get(),
nullptr,
_getWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(2 >= 2,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::dom::XRInputSource* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRInputSource>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRInputSource*>);
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::XRInputSource> 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::XRInputSource);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRInputSource);
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,
"XRInputSource", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRInputSource_Binding
namespace XRInputSourceArray_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_length(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRInputSourceArray", "length", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRInputSourceArray*>(void_self);
uint32_t result(MOZ_KnownLive(self)->Length());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo length_getterinfo = {
{ get_length },
{ prototypes::id::XRInputSourceArray },
{ PrototypeTraits<prototypes::id::XRInputSourceArray>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* 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 JSFunctionSpec sMethods_specs[] = {
JS_SYM_FNSPEC(iterator, nullptr, nullptr, 0, 0, "$ArrayValues"),
JS_FS_END,
JS_FNSPEC("keys", nullptr, nullptr, 0, JSPROP_ENUMERATE, "ArrayKeys"),
JS_FNSPEC("values", nullptr, nullptr, 0, JSPROP_ENUMERATE, "$ArrayValues"),
JS_FNSPEC("entries", nullptr, nullptr, 0, JSPROP_ENUMERATE, "ArrayEntries"),
JS_FNSPEC("forEach", nullptr, nullptr, 1, JSPROP_ENUMERATE, "ArrayForEach"),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers2 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ nullptr, &sMethods_specs[0] },
{ &sMethods_disablers2, &sMethods_specs[2] },
{ nullptr, nullptr }
};
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(4 <= 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("length", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &length_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(1 <= 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[6];
static PropertyInfo sNativeProperties_propertyInfos[6];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
6,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[5] }
}
};
static_assert(6 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
static_assert(std::is_base_of_v<nsISupports, mozilla::dom::XRInputSourceArray>,
"We don't support non-nsISupports native classes for "
"proxy-based bindings yet");
class DOMProxyHandler : public mozilla::dom::DOMProxyHandler
{
public:
explicit constexpr DOMProxyHandler()
{
}
bool
getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<Maybe<JS::PropertyDescriptor>> desc) const override;
bool
defineProperty(JSContext* cx_, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* done) const override;
using mozilla::dom::DOMProxyHandler::defineProperty;
bool
ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::MutableHandleVector<jsid> props) const override;
bool
hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
bool
get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
const char*
className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
bool
finalizeInBackground(const JS::Value& priv) const override;
void
finalize(JS::GCContext* gcx, JSObject* proxy) const override;
static const DOMProxyHandler*
getInstance();
bool
delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
bool
getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const override;
size_t
objectMoved(JSObject* obj, JSObject* old) const override;
};
MOZ_ALWAYS_INLINE bool
IsProxy(JSObject* obj)
{
return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
}
MOZ_ALWAYS_INLINE mozilla::dom::XRInputSourceArray*
UnwrapProxy(JSObject* obj)
{
MOZ_ASSERT(js::IsProxy(obj));
if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
obj = js::UncheckedUnwrap(obj);
}
MOZ_ASSERT(IsProxy(obj));
return static_cast<mozilla::dom::XRInputSourceArray*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
}
const NativeNamedOrIndexedPropertyHooks sNativeNamedOrIndexedPropertyHooks = {
binding_detail::ResolveOwnProperty,
binding_detail::EnumerateOwnProperties,
nullptr
};
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
&sNativeNamedOrIndexedPropertyHooks,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRInputSourceArray,
constructors::id::XRInputSourceArray,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::XRInputSourceArray,
PrototypeTraits<prototypes::id::XRInputSourceArray>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRInputSourceArrayPrototype",
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::XRInputSourceArray,
PrototypeTraits<prototypes::id::XRInputSourceArray>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
bool
DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<Maybe<JS::PropertyDescriptor>> desc) const
{
bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
uint32_t index = GetArrayIndexFromId(id);
if (IsArrayIndex(index)) {
JS::Rooted<JS::Value> value(cx);
mozilla::dom::XRInputSourceArray* self = UnwrapProxy(proxy);
bool found = false;
auto result(StrongOrRawPtr<mozilla::dom::XRInputSource>(MOZ_KnownLive(self)->IndexedGetter(index, found)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (found) {
if (!GetOrCreateDOMReflector(cx, result, &value)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
desc.set(mozilla::Some(JS::PropertyDescriptor::Data(value, { JS::PropertyAttribute::Configurable, JS::PropertyAttribute::Enumerable })));
return true;
}
}
JS::Rooted<JSObject*> expando(cx);
if (!isXray &&(expando = GetExpandoObject(proxy))) {
if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
return false;
}
if (desc.isSome()) {
return true;
}
}
desc.reset();
return true;
}
bool
DOMProxyHandler::defineProperty(JSContext* cx_, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* done) const
{
if (IsArrayIndex(GetArrayIndexFromId(id))) {
*done = true;
return opresult.failNoIndexedSetter();
}
return mozilla::dom::DOMProxyHandler::defineProperty(cx_, proxy, id, desc, opresult, done);
}
bool
DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::MutableHandleVector<jsid> props) const
{
bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
uint32_t length = UnwrapProxy(proxy)->Length();
MOZ_ASSERT(int32_t(length) >= 0);
for (int32_t i = 0; i < int32_t(length); ++i) {
if (!props.append(JS::PropertyKey::Int(i))) {
return false;
}
}
JS::Rooted<JSObject*> expando(cx);
if (!isXray &&(expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
!js::GetPropertyKeys(cx, expando, flags, props)) {
return false;
}
return true;
}
bool
DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
{
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
"Should not have a XrayWrapper here");
uint32_t index = GetArrayIndexFromId(id);
if (IsArrayIndex(index)) {
bool found = false;
mozilla::dom::XRInputSourceArray* self = UnwrapProxy(proxy);
auto result(StrongOrRawPtr<mozilla::dom::XRInputSource>(MOZ_KnownLive(self)->IndexedGetter(index, found)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
(void)result;
*bp = found;
return true;
}
JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
if (expando) {
bool b = true;
bool ok = JS_HasPropertyById(cx, expando, id, &b);
*bp = !!b;
if (!ok || *bp) {
return ok;
}
}
*bp = false;
return true;
}
bool
DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
{
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
"Should not have a XrayWrapper here");
uint32_t index = GetArrayIndexFromId(id);
if (IsArrayIndex(index)) {
mozilla::dom::XRInputSourceArray* self = UnwrapProxy(proxy);
bool found = false;
auto result(StrongOrRawPtr<mozilla::dom::XRInputSource>(MOZ_KnownLive(self)->IndexedGetter(index, found)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (found) {
if (!GetOrCreateDOMReflector(cx, result, vp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
// Even if we don't have this index, we don't forward the
// get on to our expando object.
} else {
bool expandoHasProp = false;
{ // Scope for expando
JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
if (expando) {
if (!JS_HasPropertyById(cx, expando, id, &expandoHasProp)) {
return false;
}
if (expandoHasProp) {
// Forward the get to the expando object, but our receiver is whatever our
// receiver is.
if (!JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp)) {
return false;
}
}
}
}
if (expandoHasProp) {
return true;
}
}
bool foundOnPrototype;
if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
return false;
}
if (foundOnPrototype) {
return true;
}
MOZ_ASSERT(vp.isUndefined());
return true;
}
const char*
DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
{
return "XRInputSourceArray";
}
bool
DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
{
return false;
}
void
DOMProxyHandler::finalize(JS::GCContext* gcx, JSObject* proxy) const
{
mozilla::dom::XRInputSourceArray* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRInputSourceArray>(proxy);
if (self) {
JS::SetReservedSlot(proxy, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, proxy);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(proxy, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::dom::XRInputSourceArray>(self);
}
}
const DOMProxyHandler*
DOMProxyHandler::getInstance()
{
static const DOMProxyHandler instance;
return &instance;
}
bool
DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
{
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
"Should not have a XrayWrapper here");
uint32_t index = GetArrayIndexFromId(id);
if (IsArrayIndex(index)) {
bool deleteSucceeded;
bool found = false;
mozilla::dom::XRInputSourceArray* self = UnwrapProxy(proxy);
auto result(StrongOrRawPtr<mozilla::dom::XRInputSource>(MOZ_KnownLive(self)->IndexedGetter(index, found)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
(void)result;
deleteSucceeded = !found;
return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
}
return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
}
bool
DOMProxyHandler::getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const
{
JS::Rooted<JS::Value> temp(cx);
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
"Should not have a XrayWrapper here");
mozilla::dom::XRInputSourceArray* self = UnwrapProxy(proxy);
uint32_t length = self->Length();
// Compute the end of the indices we'll get ourselves
uint32_t ourEnd = std::max(begin, std::min(end, length));
for (uint32_t index = begin; index < ourEnd; ++index) {
bool found = false;
auto result(StrongOrRawPtr<mozilla::dom::XRInputSource>(MOZ_KnownLive(self)->IndexedGetter(index, found)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
MOZ_ASSERT(found);
if (!GetOrCreateDOMReflector(cx, result, &temp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
if (!adder->append(cx, temp)) return false;
continue;
}
if (end > ourEnd) {
JS::Rooted<JSObject*> proto(cx);
if (!js::GetObjectProto(cx, proxy, &proto)) {
return false;
}
return js::GetElementsWithAdder(cx, proto, proxy, ourEnd, end, adder);
}
return true;
}
size_t
DOMProxyHandler::objectMoved(JSObject* obj, JSObject* old) const
{
mozilla::dom::XRInputSourceArray* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRInputSourceArray>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const DOMJSClass sClass = {
PROXY_CLASS_DEF("XRInputSourceArray",
JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1)),
{ prototypes::id::XRInputSourceArray, 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::XRInputSourceArray>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRInputSourceArray>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRInputSourceArray>::Get(),
nullptr,
nullptr
};
bool
Wrap(JSContext* aCx, mozilla::dom::XRInputSourceArray* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRInputSourceArray>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRInputSourceArray*>);
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()) {
DOMProxyHandler::getInstance()->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::XRInputSourceArray> creator(aCx);
creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
proto, /* aLazyProto = */ false,
aObject, JS::UndefinedHandleValue, 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::XRInputSourceArray);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRInputSourceArray);
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,
"XRInputSourceArray", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRInputSourceArray_Binding
namespace XRPose_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_transform(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRPose", "transform", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRPose*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::XRRigidTransform>(MOZ_KnownLive(self)->Transform()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo transform_getterinfo = {
{ get_transform },
{ prototypes::id::XRPose },
{ PrototypeTraits<prototypes::id::XRPose>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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_emulatedPosition(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRPose", "emulatedPosition", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRPose*>(void_self);
bool result(MOZ_KnownLive(self)->EmulatedPosition());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setBoolean(result);
return true;
}
static const JSJitInfo emulatedPosition_getterinfo = {
{ get_emulatedPosition },
{ prototypes::id::XRPose },
{ PrototypeTraits<prototypes::id::XRPose>::Depth },
JSJitInfo::Getter,
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. */
};
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRPose* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRPose>(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::XRPose* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRPose>(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::XRPose>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRPose* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRPose>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRPose* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRPose>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("transform", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &transform_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("emulatedPosition", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &emulatedPosition_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(2 <= 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[2];
static PropertyInfo sNativeProperties_propertyInfos[2];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
2,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRPose,
constructors::id::XRPose,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::XRPose,
PrototypeTraits<prototypes::id::XRPose>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRPosePrototype",
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::XRPose,
PrototypeTraits<prototypes::id::XRPose>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRPose",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_SKIP_NURSERY_FINALIZE,
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::XRPose, 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::XRPose>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRPose>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRPose>::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::XRPose* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRPose>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRPose*>);
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::XRPose> 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::XRPose);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRPose);
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,
"XRPose", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetProtoObject(JSContext* aCx)
{
return GetProtoObjectHandle(aCx);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRPose_Binding
namespace XRReferenceSpace_Binding {
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<XRSpace_Binding::NativeType>::value,
"Can't inherit from an interface with a different ownership model.");
MOZ_CAN_RUN_SCRIPT static bool
getOffsetReferenceSpace(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "XRReferenceSpace.getOffsetReferenceSpace");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRReferenceSpace", "getOffsetReferenceSpace", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRReferenceSpace*>(void_self);
if (!args.requireAtLeast(cx, "XRReferenceSpace.getOffsetReferenceSpace", 1)) {
return false;
}
NonNull<mozilla::dom::XRRigidTransform> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::XRRigidTransform, mozilla::dom::XRRigidTransform>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "XRRigidTransform");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
auto result(StrongOrRawPtr<mozilla::dom::XRReferenceSpace>(MOZ_KnownLive(self)->GetOffsetReferenceSpace(MOZ_KnownLive(NonNullHelper(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())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo getOffsetReferenceSpace_methodinfo = {
{ (JSJitGetterOp)getOffsetReferenceSpace },
{ prototypes::id::XRReferenceSpace },
{ PrototypeTraits<prototypes::id::XRReferenceSpace>::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. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_onreset(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRReferenceSpace", "onreset", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRReferenceSpace*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOnreset());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_onreset(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRReferenceSpace", "onreset", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRReferenceSpace*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOnreset(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOnreset(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo onreset_getterinfo = {
{ get_onreset },
{ prototypes::id::XRReferenceSpace },
{ PrototypeTraits<prototypes::id::XRReferenceSpace>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 onreset_setterinfo = {
{ (JSJitGetterOp)set_onreset },
{ prototypes::id::XRReferenceSpace },
{ PrototypeTraits<prototypes::id::XRReferenceSpace>::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. */
};
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRReferenceSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRReferenceSpace>(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::XRReferenceSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRReferenceSpace>(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::XRReferenceSpace>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRReferenceSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRReferenceSpace>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRReferenceSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRReferenceSpace>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("getOffsetReferenceSpace", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getOffsetReferenceSpace_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &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(1 <= 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("onreset", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onreset_getterinfo, GenericSetter<NormalThisPolicy>, &onreset_setterinfo),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(1 <= 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[2];
static PropertyInfo sNativeProperties_propertyInfos[2];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
2,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[1] }
}
};
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRReferenceSpace,
constructors::id::XRReferenceSpace,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
XRSpace_Binding::GetConstructorObject,
prototypes::id::XRReferenceSpace,
PrototypeTraits<prototypes::id::XRReferenceSpace>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRReferenceSpacePrototype",
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::XRReferenceSpace,
PrototypeTraits<prototypes::id::XRReferenceSpace>::Depth,
&sNativePropertyHooks,
XRSpace_Binding::GetProtoObject
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRReferenceSpace",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::EventTarget, prototypes::id::XRSpace, prototypes::id::XRReferenceSpace, 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::XRReferenceSpace>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRReferenceSpace>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRReferenceSpace>::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::XRReferenceSpace* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRReferenceSpace>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRReferenceSpace*>);
MOZ_ASSERT(static_cast<mozilla::dom::XRSpace*>(aObject) ==
reinterpret_cast<mozilla::dom::XRSpace*>(aObject),
"Multiple inheritance for mozilla::dom::XRSpace is broken.");
MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
"Multiple inheritance for mozilla::dom::EventTarget is broken.");
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::XRReferenceSpace> 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::XRReferenceSpace);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRReferenceSpace);
JS::Handle<JSObject*> parentProto(XRSpace_Binding::GetProtoObjectHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(XRSpace_Binding::GetConstructorObjectHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"XRReferenceSpace", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetProtoObject(JSContext* aCx)
{
return GetProtoObjectHandle(aCx);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRReferenceSpace_Binding
namespace XRRenderState_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_depthNear(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRRenderState", "depthNear", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRRenderState*>(void_self);
double result(MOZ_KnownLive(self)->DepthNear());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static const JSJitInfo depthNear_getterinfo = {
{ get_depthNear },
{ prototypes::id::XRRenderState },
{ PrototypeTraits<prototypes::id::XRRenderState>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* 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_depthFar(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRRenderState", "depthFar", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRRenderState*>(void_self);
double result(MOZ_KnownLive(self)->DepthFar());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static const JSJitInfo depthFar_getterinfo = {
{ get_depthFar },
{ prototypes::id::XRRenderState },
{ PrototypeTraits<prototypes::id::XRRenderState>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* 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_inlineVerticalFieldOfView(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRRenderState", "inlineVerticalFieldOfView", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRRenderState*>(void_self);
Nullable<double> result(MOZ_KnownLive(self)->GetInlineVerticalFieldOfView());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result.IsNull()) {
args.rval().setNull();
return true;
}
args.rval().set(JS_NumberValue(double(result.Value())));
return true;
}
static const JSJitInfo inlineVerticalFieldOfView_getterinfo = {
{ get_inlineVerticalFieldOfView },
{ prototypes::id::XRRenderState },
{ PrototypeTraits<prototypes::id::XRRenderState>::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. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_baseLayer(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRRenderState", "baseLayer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRRenderState*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::XRWebGLLayer>(MOZ_KnownLive(self)->GetBaseLayer()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!result) {
args.rval().setNull();
return true;
}
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo baseLayer_getterinfo = {
{ get_baseLayer },
{ prototypes::id::XRRenderState },
{ PrototypeTraits<prototypes::id::XRRenderState>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRRenderState* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRRenderState>(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::XRRenderState* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRRenderState>(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::XRRenderState>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRRenderState* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRRenderState>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRRenderState* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRRenderState>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("depthNear", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &depthNear_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("depthFar", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &depthFar_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("inlineVerticalFieldOfView", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &inlineVerticalFieldOfView_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("baseLayer", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &baseLayer_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(4 <= 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[4];
static PropertyInfo sNativeProperties_propertyInfos[4];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
4,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(4 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRRenderState,
constructors::id::XRRenderState,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::XRRenderState,
PrototypeTraits<prototypes::id::XRRenderState>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRRenderStatePrototype",
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::XRRenderState,
PrototypeTraits<prototypes::id::XRRenderState>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRRenderState",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::XRRenderState, 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::XRRenderState>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRRenderState>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRRenderState>::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::XRRenderState* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRRenderState>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRRenderState*>);
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::XRRenderState> 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::XRRenderState);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRRenderState);
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,
"XRRenderState", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRRenderState_Binding
namespace XRRigidTransform_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_position(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRRigidTransform", "position", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRRigidTransform*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::DOMPointReadOnly>(MOZ_KnownLive(self)->Position()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo position_getterinfo = {
{ get_position },
{ prototypes::id::XRRigidTransform },
{ PrototypeTraits<prototypes::id::XRRigidTransform>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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_orientation(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRRigidTransform", "orientation", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRRigidTransform*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::DOMPointReadOnly>(MOZ_KnownLive(self)->Orientation()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo orientation_getterinfo = {
{ get_orientation },
{ prototypes::id::XRRigidTransform },
{ PrototypeTraits<prototypes::id::XRRigidTransform>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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_matrix(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRRigidTransform", "matrix", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRRigidTransform*>(void_self);
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)->GetMatrix(cx, &result, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->GetMatrix(cx, &result, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRRigidTransform.matrix getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo matrix_getterinfo = {
{ get_matrix },
{ prototypes::id::XRRigidTransform },
{ PrototypeTraits<prototypes::id::XRRigidTransform>::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_inverse(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRRigidTransform", "inverse", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRRigidTransform*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::XRRigidTransform>(MOZ_KnownLive(self)->Inverse()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo inverse_getterinfo = {
{ get_inverse },
{ prototypes::id::XRRigidTransform },
{ PrototypeTraits<prototypes::id::XRRigidTransform>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRRigidTransform* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRRigidTransform>(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::XRRigidTransform* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRRigidTransform>(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::XRRigidTransform>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRRigidTransform* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRRigidTransform>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRRigidTransform* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRRigidTransform>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("position", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &position_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("orientation", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &orientation_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("matrix", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &matrix_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("inverse", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &inverse_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(4 <= 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[4];
static PropertyInfo sNativeProperties_propertyInfos[4];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
4,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(4 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRRigidTransform,
constructors::id::XRRigidTransform,
&DefaultXrayExpandoObjectClass
};
static bool
_constructor(JSContext* cx_, unsigned argc, JS::Value* vp)
{
BindingCallContext cx(cx_, "XRRigidTransform constructor");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRRigidTransform", "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, "XRRigidTransform");
}
JS::Rooted<JSObject*> desiredProto(cx);
if (!GetDesiredProto(cx, args,
prototypes::id::XRRigidTransform,
CreateInterfaceObjects,
&desiredProto)) {
return false;
}
GlobalObject global(cx, obj);
if (global.Failed()) {
return false;
}
bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
binding_detail::FastDOMPointInit arg0;
if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
return false;
}
binding_detail::FastDOMPointInit arg1;
if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue, "Argument 2", false)) {
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;
}
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::dom::XRRigidTransform>(mozilla::dom::XRRigidTransform::Constructor(global, Constify(arg0), Constify(arg1), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRRigidTransform constructor"))) {
return false;
}
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::XRRigidTransform,
PrototypeTraits<prototypes::id::XRRigidTransform>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRRigidTransformPrototype",
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::XRRigidTransform,
PrototypeTraits<prototypes::id::XRRigidTransform>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRRigidTransform",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_SKIP_NURSERY_FINALIZE,
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::XRRigidTransform, 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::XRRigidTransform>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRRigidTransform>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRRigidTransform>::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::XRRigidTransform* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRRigidTransform>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRRigidTransform*>);
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::XRRigidTransform> 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::XRRigidTransform);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRRigidTransform);
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,
"XRRigidTransform", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRRigidTransform_Binding
namespace XRSession_Binding {
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTarget_Binding::NativeType>::value,
"Can't inherit from an interface with a different ownership model.");
MOZ_CAN_RUN_SCRIPT static bool
get_visibilityState(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "visibilityState", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
XRVisibilityState result(MOZ_KnownLive(self)->VisibilityState());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo visibilityState_getterinfo = {
{ get_visibilityState },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
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
get_renderState(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "renderState", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::XRRenderState>(MOZ_KnownLive(self)->RenderState()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo renderState_getterinfo = {
{ get_renderState },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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_inputSources(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "inputSources", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
auto result(StrongOrRawPtr<mozilla::dom::XRInputSourceArray>(MOZ_KnownLive(self)->InputSources()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo inputSources_getterinfo = {
{ get_inputSources },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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_frameRate(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "frameRate", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
Nullable<float> result(MOZ_KnownLive(self)->GetFrameRate());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result.IsNull()) {
args.rval().setNull();
return true;
}
args.rval().set(JS_NumberValue(double(result.Value())));
return true;
}
static const JSJitInfo frameRate_getterinfo = {
{ get_frameRate },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_supportedFrameRates(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "supportedFrameRates", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
JS::Rooted<JSObject*> result(cx);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetSupportedFrameRates(cx, &result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetSupportedFrameRates(cx, &result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
JS::ExposeObjectToActiveJS(result);
}
args.rval().setObjectOrNull(result);
if (!MaybeWrapNonDOMObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo supportedFrameRates_getterinfo = {
{ get_supportedFrameRates },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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
updateRenderState(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "XRSession.updateRenderState");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "updateRenderState", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
binding_detail::FastXRRenderStateInit arg0;
if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
return false;
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->UpdateRenderState(Constify(arg0), rv))>, "Should be returning void here");
MOZ_KnownLive(self)->UpdateRenderState(Constify(arg0), rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRSession.updateRenderState"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo updateRenderState_methodinfo = {
{ (JSJitGetterOp)updateRenderState },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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
requestReferenceSpace(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "XRSession.requestReferenceSpace");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "requestReferenceSpace", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
if (!args.requireAtLeast(cx, "XRSession.requestReferenceSpace", 1)) {
return false;
}
XRReferenceSpaceType arg0;
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, args[0],
binding_detail::EnumStrings<XRReferenceSpaceType>::Values,
"XRReferenceSpaceType", "argument 1",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
arg0 = static_cast<XRReferenceSpaceType>(index);
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->RequestReferenceSpace(arg0, rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRSession.requestReferenceSpace"))) {
return false;
}
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 (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
requestReferenceSpace_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = requestReferenceSpace(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo requestReferenceSpace_methodinfo = {
{ (JSJitGetterOp)requestReferenceSpace_promiseWrapper },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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. */
};
MOZ_CAN_RUN_SCRIPT static bool
updateTargetFrameRate(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "XRSession.updateTargetFrameRate");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "updateTargetFrameRate", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
if (!args.requireAtLeast(cx, "XRSession.updateTargetFrameRate", 1)) {
return false;
}
float arg0;
if (!ValueToPrimitive<float, eDefault>(cx, args[0], "Argument 1", &arg0)) {
return false;
} else if (!std::isfinite(arg0)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 1");
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->UpdateTargetFrameRate(arg0, rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRSession.updateTargetFrameRate"))) {
return false;
}
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 (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
updateTargetFrameRate_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = updateTargetFrameRate(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo updateTargetFrameRate_methodinfo = {
{ (JSJitGetterOp)updateTargetFrameRate_promiseWrapper },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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. */
};
MOZ_CAN_RUN_SCRIPT static bool
requestAnimationFrame(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "XRSession.requestAnimationFrame");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "requestAnimationFrame", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
if (!args.requireAtLeast(cx, "XRSession.requestAnimationFrame", 1)) {
return false;
}
RootedCallback<OwningNonNull<binding_detail::FastXRFrameRequestCallback>> arg0(cx);
if (args[0].isObject()) {
if (JS::IsCallable(&args[0].toObject())) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastXRFrameRequestCallback(&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;
int32_t result(MOZ_KnownLive(self)->RequestAnimationFrame(MOZ_KnownLive(NonNullHelper(arg0)), rv));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRSession.requestAnimationFrame"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setInt32(int32_t(result));
return true;
}
static const JSJitInfo requestAnimationFrame_methodinfo = {
{ (JSJitGetterOp)requestAnimationFrame },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_INT32, /* 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
cancelAnimationFrame(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "cancelAnimationFrame", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
if (!args.requireAtLeast(cx, "XRSession.cancelAnimationFrame", 1)) {
return false;
}
int32_t arg0;
if (!ValueToPrimitive<int32_t, eDefault>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CancelAnimationFrame(arg0, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->CancelAnimationFrame(arg0, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRSession.cancelAnimationFrame"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo cancelAnimationFrame_methodinfo = {
{ (JSJitGetterOp)cancelAnimationFrame },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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
end(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "end", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->End(rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRSession.end"))) {
return false;
}
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 (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
end_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = end(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo end_methodinfo = {
{ (JSJitGetterOp)end_promiseWrapper },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_onend(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onend", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOnend());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_onend(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onend", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOnend(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOnend(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo onend_getterinfo = {
{ get_onend },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 onend_setterinfo = {
{ (JSJitGetterOp)set_onend },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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_oninputsourceschange(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "oninputsourceschange", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOninputsourceschange());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_oninputsourceschange(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "oninputsourceschange", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOninputsourceschange(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOninputsourceschange(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo oninputsourceschange_getterinfo = {
{ get_oninputsourceschange },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 oninputsourceschange_setterinfo = {
{ (JSJitGetterOp)set_oninputsourceschange },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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_onselect(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onselect", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOnselect());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_onselect(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onselect", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOnselect(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOnselect(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo onselect_getterinfo = {
{ get_onselect },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 onselect_setterinfo = {
{ (JSJitGetterOp)set_onselect },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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_onselectstart(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onselectstart", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOnselectstart());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_onselectstart(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onselectstart", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOnselectstart(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOnselectstart(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo onselectstart_getterinfo = {
{ get_onselectstart },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 onselectstart_setterinfo = {
{ (JSJitGetterOp)set_onselectstart },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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_onselectend(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onselectend", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOnselectend());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_onselectend(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onselectend", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOnselectend(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOnselectend(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo onselectend_getterinfo = {
{ get_onselectend },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 onselectend_setterinfo = {
{ (JSJitGetterOp)set_onselectend },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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_onsqueeze(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onsqueeze", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOnsqueeze());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_onsqueeze(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onsqueeze", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOnsqueeze(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOnsqueeze(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo onsqueeze_getterinfo = {
{ get_onsqueeze },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 onsqueeze_setterinfo = {
{ (JSJitGetterOp)set_onsqueeze },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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_onsqueezestart(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onsqueezestart", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOnsqueezestart());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_onsqueezestart(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onsqueezestart", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOnsqueezestart(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOnsqueezestart(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo onsqueezestart_getterinfo = {
{ get_onsqueezestart },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 onsqueezestart_setterinfo = {
{ (JSJitGetterOp)set_onsqueezestart },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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_onsqueezeend(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onsqueezeend", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOnsqueezeend());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_onsqueezeend(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onsqueezeend", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOnsqueezeend(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOnsqueezeend(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo onsqueezeend_getterinfo = {
{ get_onsqueezeend },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 onsqueezeend_setterinfo = {
{ (JSJitGetterOp)set_onsqueezeend },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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_onvisibilitychange(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onvisibilitychange", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOnvisibilitychange());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_onvisibilitychange(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSession", "onvisibilitychange", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSession*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOnvisibilitychange(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOnvisibilitychange(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo onvisibilitychange_getterinfo = {
{ get_onvisibilitychange },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 onvisibilitychange_setterinfo = {
{ (JSJitGetterOp)set_onvisibilitychange },
{ prototypes::id::XRSession },
{ PrototypeTraits<prototypes::id::XRSession>::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. */
};
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRSession* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSession>(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::XRSession* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSession>(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::XRSession>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRSession* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSession>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRSession* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSession>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("updateRenderState", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&updateRenderState_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("requestReferenceSpace", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&requestReferenceSpace_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("updateTargetFrameRate", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&updateTargetFrameRate_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("requestAnimationFrame", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&requestAnimationFrame_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("cancelAnimationFrame", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&cancelAnimationFrame_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("end", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&end_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &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(6 <= 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("visibilityState", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &visibilityState_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("renderState", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &renderState_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("inputSources", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &inputSources_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("frameRate", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &frameRate_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("supportedFrameRates", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &supportedFrameRates_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("onend", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onend_getterinfo, GenericSetter<NormalThisPolicy>, &onend_setterinfo),
JSPropertySpec::nativeAccessors("oninputsourceschange", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &oninputsourceschange_getterinfo, GenericSetter<NormalThisPolicy>, &oninputsourceschange_setterinfo),
JSPropertySpec::nativeAccessors("onselect", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onselect_getterinfo, GenericSetter<NormalThisPolicy>, &onselect_setterinfo),
JSPropertySpec::nativeAccessors("onselectstart", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onselectstart_getterinfo, GenericSetter<NormalThisPolicy>, &onselectstart_setterinfo),
JSPropertySpec::nativeAccessors("onselectend", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onselectend_getterinfo, GenericSetter<NormalThisPolicy>, &onselectend_setterinfo),
JSPropertySpec::nativeAccessors("onsqueeze", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onsqueeze_getterinfo, GenericSetter<NormalThisPolicy>, &onsqueeze_setterinfo),
JSPropertySpec::nativeAccessors("onsqueezestart", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onsqueezestart_getterinfo, GenericSetter<NormalThisPolicy>, &onsqueezestart_setterinfo),
JSPropertySpec::nativeAccessors("onsqueezeend", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onsqueezeend_getterinfo, GenericSetter<NormalThisPolicy>, &onsqueezeend_setterinfo),
JSPropertySpec::nativeAccessors("onvisibilitychange", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onvisibilitychange_getterinfo, GenericSetter<NormalThisPolicy>, &onvisibilitychange_setterinfo),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(14 <= 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[20];
static PropertyInfo sNativeProperties_propertyInfos[20];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
20,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[6] }
}
};
static_assert(20 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRSession,
constructors::id::XRSession,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
EventTarget_Binding::GetConstructorObject,
prototypes::id::XRSession,
PrototypeTraits<prototypes::id::XRSession>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRSessionPrototype",
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::XRSession,
PrototypeTraits<prototypes::id::XRSession>::Depth,
&sNativePropertyHooks,
EventTarget_Binding::GetProtoObject
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRSession",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::EventTarget, prototypes::id::XRSession, 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::XRSession>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRSession>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRSession>::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::XRSession* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRSession>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRSession*>);
MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
"Multiple inheritance for mozilla::dom::EventTarget is broken.");
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::XRSession> 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::XRSession);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRSession);
JS::Handle<JSObject*> parentProto(EventTarget_Binding::GetProtoObjectHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(EventTarget_Binding::GetConstructorObjectHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"XRSession", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRSession_Binding
namespace XRSpace_Binding {
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTarget_Binding::NativeType>::value,
"Can't inherit from an interface with a different ownership model.");
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSpace>(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::XRSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSpace>(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::XRSpace>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSpace>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRSpace* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSpace>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ nullptr, nullptr, &sNativePropertiesInited },
prototypes::id::XRSpace,
constructors::id::XRSpace,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
EventTarget_Binding::GetConstructorObject,
prototypes::id::XRSpace,
PrototypeTraits<prototypes::id::XRSpace>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRSpacePrototype",
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::XRSpace,
PrototypeTraits<prototypes::id::XRSpace>::Depth,
&sNativePropertyHooks,
EventTarget_Binding::GetProtoObject
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRSpace",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::EventTarget, prototypes::id::XRSpace, 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::XRSpace>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRSpace>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRSpace>::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::XRSpace* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRSpace>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRSpace*>);
MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
"Multiple inheritance for mozilla::dom::EventTarget is broken.");
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::XRSpace> 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::XRSpace);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRSpace);
JS::Handle<JSObject*> parentProto(EventTarget_Binding::GetProtoObjectHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(EventTarget_Binding::GetConstructorObjectHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
nullptr,
nullptr,
"XRSpace", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetProtoObject(JSContext* aCx)
{
return GetProtoObjectHandle(aCx);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRSpace_Binding
namespace XRSystem_Binding {
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTarget_Binding::NativeType>::value,
"Can't inherit from an interface with a different ownership model.");
MOZ_CAN_RUN_SCRIPT static bool
isSessionSupported(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "XRSystem.isSessionSupported");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSystem", "isSessionSupported", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSystem*>(void_self);
if (!args.requireAtLeast(cx, "XRSystem.isSessionSupported", 1)) {
return false;
}
XRSessionMode arg0;
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, args[0],
binding_detail::EnumStrings<XRSessionMode>::Values,
"XRSessionMode", "argument 1",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
arg0 = static_cast<XRSessionMode>(index);
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->IsSessionSupported(arg0, rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRSystem.isSessionSupported"))) {
return false;
}
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 (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
isSessionSupported_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = isSessionSupported(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo isSessionSupported_methodinfo = {
{ (JSJitGetterOp)isSessionSupported_promiseWrapper },
{ prototypes::id::XRSystem },
{ PrototypeTraits<prototypes::id::XRSystem>::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. */
};
MOZ_CAN_RUN_SCRIPT static bool
requestSession(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "XRSystem.requestSession");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSystem", "requestSession", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSystem*>(void_self);
if (!args.requireAtLeast(cx, "XRSystem.requestSession", 1)) {
return false;
}
XRSessionMode arg0;
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, args[0],
binding_detail::EnumStrings<XRSessionMode>::Values,
"XRSessionMode", "argument 1",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
arg0 = static_cast<XRSessionMode>(index);
}
binding_detail::FastXRSessionInit arg1;
if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue, "Argument 2", false)) {
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->RequestSession(arg0, Constify(arg1), nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRSystem.requestSession"))) {
return false;
}
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 (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
requestSession_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = requestSession(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo requestSession_methodinfo = {
{ (JSJitGetterOp)requestSession_promiseWrapper },
{ prototypes::id::XRSystem },
{ PrototypeTraits<prototypes::id::XRSystem>::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. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_ondevicechange(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSystem", "ondevicechange", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSystem*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOndevicechange());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_ondevicechange(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRSystem", "ondevicechange", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRSystem*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOndevicechange(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOndevicechange(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo ondevicechange_getterinfo = {
{ get_ondevicechange },
{ prototypes::id::XRSystem },
{ PrototypeTraits<prototypes::id::XRSystem>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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 ondevicechange_setterinfo = {
{ (JSJitGetterOp)set_ondevicechange },
{ prototypes::id::XRSystem },
{ PrototypeTraits<prototypes::id::XRSystem>::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. */
};
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRSystem* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSystem>(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::XRSystem* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSystem>(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::XRSystem>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRSystem* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSystem>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRSystem* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRSystem>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("isSessionSupported", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&isSessionSupported_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("requestSession", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&requestSession_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &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(2 <= 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("ondevicechange", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &ondevicechange_getterinfo, GenericSetter<NormalThisPolicy>, &ondevicechange_setterinfo),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(1 <= 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[3];
static PropertyInfo sNativeProperties_propertyInfos[3];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
3,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[2] }
}
};
static_assert(3 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRSystem,
constructors::id::XRSystem,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
EventTarget_Binding::GetConstructorObject,
prototypes::id::XRSystem,
PrototypeTraits<prototypes::id::XRSystem>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRSystemPrototype",
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::XRSystem,
PrototypeTraits<prototypes::id::XRSystem>::Depth,
&sNativePropertyHooks,
EventTarget_Binding::GetProtoObject
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRSystem",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::EventTarget, prototypes::id::XRSystem, 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::XRSystem>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRSystem>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRSystem>::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::XRSystem* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRSystem>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRSystem*>);
MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
"Multiple inheritance for mozilla::dom::EventTarget is broken.");
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::XRSystem> 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::XRSystem);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRSystem);
JS::Handle<JSObject*> parentProto(EventTarget_Binding::GetProtoObjectHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(EventTarget_Binding::GetConstructorObjectHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"XRSystem", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRSystem_Binding
namespace XRView_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_eye(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRView", "eye", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRView*>(void_self);
XREye result(MOZ_KnownLive(self)->Eye());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo eye_getterinfo = {
{ get_eye },
{ prototypes::id::XRView },
{ PrototypeTraits<prototypes::id::XRView>::Depth },
JSJitInfo::Getter,
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
get_projectionMatrix(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRView", "projectionMatrix", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRView*>(void_self);
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)->GetProjectionMatrix(cx, &result, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->GetProjectionMatrix(cx, &result, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRView.projectionMatrix getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo projectionMatrix_getterinfo = {
{ get_projectionMatrix },
{ prototypes::id::XRView },
{ PrototypeTraits<prototypes::id::XRView>::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_transform(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRView", "transform", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRView*>(void_self);
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::dom::XRRigidTransform>(MOZ_KnownLive(self)->GetTransform(rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRView.transform getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo transform_getterinfo = {
{ get_transform },
{ prototypes::id::XRView },
{ PrototypeTraits<prototypes::id::XRView>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRView* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRView>(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::XRView* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRView>(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::XRView>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRView* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRView>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRView* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRView>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("eye", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &eye_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("projectionMatrix", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &projectionMatrix_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("transform", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &transform_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(3 <= 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[3];
static PropertyInfo sNativeProperties_propertyInfos[3];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
3,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(3 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRView,
constructors::id::XRView,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::XRView,
PrototypeTraits<prototypes::id::XRView>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRViewPrototype",
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::XRView,
PrototypeTraits<prototypes::id::XRView>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRView",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_SKIP_NURSERY_FINALIZE,
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::XRView, 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::XRView>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRView>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRView>::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::XRView* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRView>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRView*>);
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::XRView> 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::XRView);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRView);
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,
"XRView", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRView_Binding
namespace XRViewerPose_Binding {
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<XRPose_Binding::NativeType>::value,
"Can't inherit from an interface with a different ownership model.");
MOZ_CAN_RUN_SCRIPT static bool
get_views(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRViewerPose", "views", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRViewerPose*>(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());
}
}
nsTArray<StrongPtrForMember<mozilla::dom::XRView>> result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetViews(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetViews(result);
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 {
if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
args.rval().setObject(*returnArray);
break;
} while (false);
JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
if (!JS_FreezeObject(cx, rvalObj)) {
return 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);
if (!isXray) {
// In the Xray case we don't need to do this, because getting the
// expando object already preserved our wrapper.
PreserveWrapper(self);
}
}
// And now make sure args.rval() is in the caller realm.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
static const JSJitInfo views_getterinfo = {
{ get_views },
{ prototypes::id::XRViewerPose },
{ PrototypeTraits<prototypes::id::XRViewerPose>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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) < 2, "There is no slot for us");
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRViewerPose* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRViewerPose>(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::XRViewerPose* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRViewerPose>(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::XRViewerPose>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRViewerPose* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRViewerPose>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRViewerPose* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRViewerPose>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("views", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &views_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
// 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, 1);
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRViewerPose,
constructors::id::XRViewerPose,
&sXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
XRPose_Binding::GetConstructorObject,
prototypes::id::XRViewerPose,
PrototypeTraits<prototypes::id::XRViewerPose>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRViewerPosePrototype",
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::XRViewerPose,
PrototypeTraits<prototypes::id::XRViewerPose>::Depth,
&sNativePropertyHooks,
XRPose_Binding::GetProtoObject
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRViewerPose",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_SKIP_NURSERY_FINALIZE,
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::XRPose, prototypes::id::XRViewerPose, 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::XRViewerPose>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRViewerPose>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRViewerPose>::Get(),
nullptr,
_getWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(2 >= 2,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::dom::XRViewerPose* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRViewerPose>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRViewerPose*>);
MOZ_ASSERT(static_cast<mozilla::dom::XRPose*>(aObject) ==
reinterpret_cast<mozilla::dom::XRPose*>(aObject),
"Multiple inheritance for mozilla::dom::XRPose is broken.");
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::XRViewerPose> 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::XRViewerPose);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRViewerPose);
JS::Handle<JSObject*> parentProto(XRPose_Binding::GetProtoObjectHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(XRPose_Binding::GetConstructorObjectHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"XRViewerPose", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRViewerPose_Binding
namespace XRViewport_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_x(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRViewport", "x", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRViewport*>(void_self);
int32_t result(MOZ_KnownLive(self)->X());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setInt32(int32_t(result));
return true;
}
static const JSJitInfo x_getterinfo = {
{ get_x },
{ prototypes::id::XRViewport },
{ PrototypeTraits<prototypes::id::XRViewport>::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_y(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRViewport", "y", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRViewport*>(void_self);
int32_t result(MOZ_KnownLive(self)->Y());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setInt32(int32_t(result));
return true;
}
static const JSJitInfo y_getterinfo = {
{ get_y },
{ prototypes::id::XRViewport },
{ PrototypeTraits<prototypes::id::XRViewport>::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_width(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRViewport", "width", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRViewport*>(void_self);
int32_t result(MOZ_KnownLive(self)->Width());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setInt32(int32_t(result));
return true;
}
static const JSJitInfo width_getterinfo = {
{ get_width },
{ prototypes::id::XRViewport },
{ PrototypeTraits<prototypes::id::XRViewport>::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_height(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRViewport", "height", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRViewport*>(void_self);
int32_t result(MOZ_KnownLive(self)->Height());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setInt32(int32_t(result));
return true;
}
static const JSJitInfo height_getterinfo = {
{ get_height },
{ prototypes::id::XRViewport },
{ PrototypeTraits<prototypes::id::XRViewport>::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. */
};
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRViewport* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRViewport>(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::XRViewport* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRViewport>(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::XRViewport>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRViewport* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRViewport>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRViewport* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRViewport>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("x", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &x_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("y", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &y_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("width", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &width_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("height", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &height_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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(4 <= 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[4];
static PropertyInfo sNativeProperties_propertyInfos[4];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
4,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(4 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRViewport,
constructors::id::XRViewport,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::XRViewport,
PrototypeTraits<prototypes::id::XRViewport>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRViewportPrototype",
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::XRViewport,
PrototypeTraits<prototypes::id::XRViewport>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRViewport",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_SKIP_NURSERY_FINALIZE,
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::XRViewport, 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::XRViewport>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRViewport>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRViewport>::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::XRViewport* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRViewport>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRViewport*>);
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::XRViewport> 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::XRViewport);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRViewport);
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,
"XRViewport", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRViewport_Binding
namespace XRWebGLLayer_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_antialias(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRWebGLLayer", "antialias", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRWebGLLayer*>(void_self);
bool result(MOZ_KnownLive(self)->Antialias());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setBoolean(result);
return true;
}
static const JSJitInfo antialias_getterinfo = {
{ get_antialias },
{ prototypes::id::XRWebGLLayer },
{ PrototypeTraits<prototypes::id::XRWebGLLayer>::Depth },
JSJitInfo::Getter,
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
get_ignoreDepthValues(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRWebGLLayer", "ignoreDepthValues", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRWebGLLayer*>(void_self);
bool result(MOZ_KnownLive(self)->IgnoreDepthValues());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setBoolean(result);
return true;
}
static const JSJitInfo ignoreDepthValues_getterinfo = {
{ get_ignoreDepthValues },
{ prototypes::id::XRWebGLLayer },
{ PrototypeTraits<prototypes::id::XRWebGLLayer>::Depth },
JSJitInfo::Getter,
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
get_framebuffer(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRWebGLLayer", "framebuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRWebGLLayer*>(void_self);
auto result(StrongOrRawPtr<mozilla::WebGLFramebufferJS>(MOZ_KnownLive(self)->GetFramebuffer()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!result) {
args.rval().setNull();
return true;
}
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo framebuffer_getterinfo = {
{ get_framebuffer },
{ prototypes::id::XRWebGLLayer },
{ PrototypeTraits<prototypes::id::XRWebGLLayer>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* 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_framebufferWidth(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRWebGLLayer", "framebufferWidth", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRWebGLLayer*>(void_self);
uint32_t result(MOZ_KnownLive(self)->FramebufferWidth());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo framebufferWidth_getterinfo = {
{ get_framebufferWidth },
{ prototypes::id::XRWebGLLayer },
{ PrototypeTraits<prototypes::id::XRWebGLLayer>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* 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_framebufferHeight(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRWebGLLayer", "framebufferHeight", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRWebGLLayer*>(void_self);
uint32_t result(MOZ_KnownLive(self)->FramebufferHeight());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo framebufferHeight_getterinfo = {
{ get_framebufferHeight },
{ prototypes::id::XRWebGLLayer },
{ PrototypeTraits<prototypes::id::XRWebGLLayer>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* 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
getViewport(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "XRWebGLLayer.getViewport");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRWebGLLayer", "getViewport", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::dom::XRWebGLLayer*>(void_self);
if (!args.requireAtLeast(cx, "XRWebGLLayer.getViewport", 1)) {
return false;
}
NonNull<mozilla::dom::XRView> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::XRView, mozilla::dom::XRView>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "XRView");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
auto result(StrongOrRawPtr<mozilla::dom::XRViewport>(MOZ_KnownLive(self)->GetViewport(MOZ_KnownLive(NonNullHelper(arg0)))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!result) {
args.rval().setNull();
return true;
}
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo getViewport_methodinfo = {
{ (JSJitGetterOp)getViewport },
{ prototypes::id::XRWebGLLayer },
{ PrototypeTraits<prototypes::id::XRWebGLLayer>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* 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
getNativeFramebufferScaleFactor(JSContext* cx_, unsigned argc, JS::Value* vp)
{
BindingCallContext cx(cx_, "XRWebGLLayer.getNativeFramebufferScaleFactor");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRWebGLLayer", "getNativeFramebufferScaleFactor", 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, "XRWebGLLayer.getNativeFramebufferScaleFactor", 1)) {
return false;
}
GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
if (global.Failed()) {
return false;
}
NonNull<mozilla::dom::XRSession> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::XRSession, mozilla::dom::XRSession>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "XRSession");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
double result(mozilla::dom::XRWebGLLayer::GetNativeFramebufferScaleFactor(global, MOZ_KnownLive(NonNullHelper(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::dom::XRWebGLLayer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRWebGLLayer>(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::XRWebGLLayer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRWebGLLayer>(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::XRWebGLLayer>(self);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::dom::XRWebGLLayer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRWebGLLayer>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::dom::XRWebGLLayer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XRWebGLLayer>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSFunctionSpec sStaticMethods_specs[] = {
JS_FNSPEC("getNativeFramebufferScaleFactor", getNativeFramebufferScaleFactor, nullptr, 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sStaticMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sStaticMethods[] = {
{ &sStaticMethods_disablers0, &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(1 <= 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("getViewport", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getViewport_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &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(1 <= 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("antialias", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &antialias_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("ignoreDepthValues", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &ignoreDepthValues_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("framebuffer", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &framebuffer_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("framebufferWidth", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &framebufferWidth_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("framebufferHeight", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &framebufferHeight_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_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 uint16_t sNativeProperties_sortedPropertyIndices[7];
static PropertyInfo sNativeProperties_propertyInfos[7];
static const NativePropertiesN<3> sNativeProperties = {
true, 0 /* sStaticMethods */,
false, 0,
true, 1 /* sMethods */,
true, 2 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
7,
sNativeProperties_sortedPropertyIndices,
{
{ sStaticMethods, &sNativeProperties_propertyInfos[0] },
{ sMethods, &sNativeProperties_propertyInfos[1] },
{ sAttributes, &sNativeProperties_propertyInfos[2] }
}
};
static_assert(7 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::XRWebGLLayer,
constructors::id::XRWebGLLayer,
&DefaultXrayExpandoObjectClass
};
static bool
_constructor(JSContext* cx_, unsigned argc, JS::Value* vp)
{
BindingCallContext cx(cx_, "XRWebGLLayer constructor");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"XRWebGLLayer", "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, "XRWebGLLayer");
}
JS::Rooted<JSObject*> desiredProto(cx);
if (!GetDesiredProto(cx, args,
prototypes::id::XRWebGLLayer,
CreateInterfaceObjects,
&desiredProto)) {
return false;
}
if (!args.requireAtLeast(cx, "XRWebGLLayer constructor", 2)) {
return false;
}
GlobalObject global(cx, obj);
if (global.Failed()) {
return false;
}
bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
NonNull<mozilla::dom::XRSession> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::XRSession, mozilla::dom::XRSession>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "XRSession");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
WebGLRenderingContextOrWebGL2RenderingContext arg1;
if (!arg1.Init(cx, args[1], "Argument 2", false)) {
return false;
}
binding_detail::FastXRWebGLLayerInit arg2;
if (!arg2.Init(cx, (args.hasDefined(2)) ? args[2] : JS::NullHandleValue, "Argument 3", false)) {
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;
}
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::dom::XRWebGLLayer>(mozilla::dom::XRWebGLLayer::Constructor(global, MOZ_KnownLive(NonNullHelper(arg0)), Constify(arg1), Constify(arg2), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "XRWebGLLayer constructor"))) {
return false;
}
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::XRWebGLLayer,
PrototypeTraits<prototypes::id::XRWebGLLayer>::Depth,
true,
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"XRWebGLLayerPrototype",
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::XRWebGLLayer,
PrototypeTraits<prototypes::id::XRWebGLLayer>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return StaticPrefs::dom_vr_webxr_enabled() &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 = {
{ "XRWebGLLayer",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::XRWebGLLayer, 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::XRWebGLLayer>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::dom::XRWebGLLayer>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::dom::XRWebGLLayer>::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::XRWebGLLayer* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::XRWebGLLayer>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::dom::XRWebGLLayer*>);
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::XRWebGLLayer> 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::XRWebGLLayer);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XRWebGLLayer);
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, 2, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"XRWebGLLayer", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace XRWebGLLayer_Binding
} // namespace dom
} // namespace mozilla