summaryrefslogtreecommitdiffstats
path: root/js/xpconnect/src/XPCInlines.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/xpconnect/src/XPCInlines.h')
-rw-r--r--js/xpconnect/src/XPCInlines.h545
1 files changed, 545 insertions, 0 deletions
diff --git a/js/xpconnect/src/XPCInlines.h b/js/xpconnect/src/XPCInlines.h
new file mode 100644
index 000000000..20c63c972
--- /dev/null
+++ b/js/xpconnect/src/XPCInlines.h
@@ -0,0 +1,545 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=99: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* private inline methods (#include'd by xpcprivate.h). */
+
+#ifndef xpcinlines_h___
+#define xpcinlines_h___
+
+#include <algorithm>
+
+/***************************************************************************/
+
+inline void
+XPCJSContext::AddVariantRoot(XPCTraceableVariant* variant)
+{
+ variant->AddToRootSet(&mVariantRoots);
+}
+
+inline void
+XPCJSContext::AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS)
+{
+ wrappedJS->AddToRootSet(&mWrappedJSRoots);
+}
+
+inline void
+XPCJSContext::AddObjectHolderRoot(XPCJSObjectHolder* holder)
+{
+ holder->AddToRootSet(&mObjectHolderRoots);
+}
+
+/***************************************************************************/
+
+inline bool
+XPCCallContext::IsValid() const
+{
+ return mState != INIT_FAILED;
+}
+
+inline XPCJSContext*
+XPCCallContext::GetContext() const
+{
+ CHECK_STATE(HAVE_CONTEXT);
+ return mXPCJSContext;
+}
+
+inline JSContext*
+XPCCallContext::GetJSContext() const
+{
+ CHECK_STATE(HAVE_CONTEXT);
+ return mJSContext;
+}
+
+inline XPCCallContext*
+XPCCallContext::GetPrevCallContext() const
+{
+ CHECK_STATE(HAVE_CONTEXT);
+ return mPrevCallContext;
+}
+
+inline nsISupports*
+XPCCallContext::GetIdentityObject() const
+{
+ CHECK_STATE(HAVE_OBJECT);
+ if (mWrapper)
+ return mWrapper->GetIdentityObject();
+ return nullptr;
+}
+
+inline XPCWrappedNative*
+XPCCallContext::GetWrapper() const
+{
+ if (mState == INIT_FAILED)
+ return nullptr;
+
+ CHECK_STATE(HAVE_OBJECT);
+ return mWrapper;
+}
+
+inline XPCWrappedNativeProto*
+XPCCallContext::GetProto() const
+{
+ CHECK_STATE(HAVE_OBJECT);
+ return mWrapper ? mWrapper->GetProto() : nullptr;
+}
+
+inline bool
+XPCCallContext::CanGetTearOff() const
+{
+ return mState >= HAVE_OBJECT;
+}
+
+inline XPCWrappedNativeTearOff*
+XPCCallContext::GetTearOff() const
+{
+ CHECK_STATE(HAVE_OBJECT);
+ return mTearOff;
+}
+
+inline XPCNativeScriptableInfo*
+XPCCallContext::GetScriptableInfo() const
+{
+ CHECK_STATE(HAVE_OBJECT);
+ return mScriptableInfo;
+}
+
+inline bool
+XPCCallContext::CanGetSet() const
+{
+ return mState >= HAVE_NAME;
+}
+
+inline XPCNativeSet*
+XPCCallContext::GetSet() const
+{
+ CHECK_STATE(HAVE_NAME);
+ return mSet;
+}
+
+inline XPCNativeInterface*
+XPCCallContext::GetInterface() const
+{
+ CHECK_STATE(HAVE_NAME);
+ return mInterface;
+}
+
+inline XPCNativeMember*
+XPCCallContext::GetMember() const
+{
+ CHECK_STATE(HAVE_NAME);
+ return mMember;
+}
+
+inline bool
+XPCCallContext::HasInterfaceAndMember() const
+{
+ return mState >= HAVE_NAME && mInterface && mMember;
+}
+
+inline jsid
+XPCCallContext::GetName() const
+{
+ CHECK_STATE(HAVE_NAME);
+ return mName;
+}
+
+inline bool
+XPCCallContext::GetStaticMemberIsLocal() const
+{
+ CHECK_STATE(HAVE_NAME);
+ return mStaticMemberIsLocal;
+}
+
+inline unsigned
+XPCCallContext::GetArgc() const
+{
+ CHECK_STATE(READY_TO_CALL);
+ return mArgc;
+}
+
+inline JS::Value*
+XPCCallContext::GetArgv() const
+{
+ CHECK_STATE(READY_TO_CALL);
+ return mArgv;
+}
+
+inline JS::Value*
+XPCCallContext::GetRetVal() const
+{
+ CHECK_STATE(READY_TO_CALL);
+ return mRetVal;
+}
+
+inline void
+XPCCallContext::SetRetVal(const JS::Value& val)
+{
+ CHECK_STATE(HAVE_ARGS);
+ if (mRetVal)
+ *mRetVal = val;
+}
+
+inline jsid
+XPCCallContext::GetResolveName() const
+{
+ CHECK_STATE(HAVE_CONTEXT);
+ return XPCJSContext::Get()->GetResolveName();
+}
+
+inline jsid
+XPCCallContext::SetResolveName(JS::HandleId name)
+{
+ CHECK_STATE(HAVE_CONTEXT);
+ return XPCJSContext::Get()->SetResolveName(name);
+}
+
+inline XPCWrappedNative*
+XPCCallContext::GetResolvingWrapper() const
+{
+ CHECK_STATE(HAVE_OBJECT);
+ return XPCJSContext::Get()->GetResolvingWrapper();
+}
+
+inline XPCWrappedNative*
+XPCCallContext::SetResolvingWrapper(XPCWrappedNative* w)
+{
+ CHECK_STATE(HAVE_OBJECT);
+ return XPCJSContext::Get()->SetResolvingWrapper(w);
+}
+
+inline uint16_t
+XPCCallContext::GetMethodIndex() const
+{
+ CHECK_STATE(HAVE_OBJECT);
+ return mMethodIndex;
+}
+
+inline void
+XPCCallContext::SetMethodIndex(uint16_t index)
+{
+ CHECK_STATE(HAVE_OBJECT);
+ mMethodIndex = index;
+}
+
+/***************************************************************************/
+inline XPCNativeInterface*
+XPCNativeMember::GetInterface() const
+{
+ XPCNativeMember* arrayStart =
+ const_cast<XPCNativeMember*>(this - mIndexInInterface);
+ size_t arrayStartOffset = XPCNativeInterface::OffsetOfMembers();
+ char* xpcNativeInterfaceStart =
+ reinterpret_cast<char*>(arrayStart) - arrayStartOffset;
+ return reinterpret_cast<XPCNativeInterface*>(xpcNativeInterfaceStart);
+}
+
+/***************************************************************************/
+
+inline const nsIID*
+XPCNativeInterface::GetIID() const
+{
+ const nsIID* iid;
+ return NS_SUCCEEDED(mInfo->GetIIDShared(&iid)) ? iid : nullptr;
+}
+
+inline const char*
+XPCNativeInterface::GetNameString() const
+{
+ const char* name;
+ return NS_SUCCEEDED(mInfo->GetNameShared(&name)) ? name : nullptr;
+}
+
+inline XPCNativeMember*
+XPCNativeInterface::FindMember(jsid name) const
+{
+ const XPCNativeMember* member = mMembers;
+ for (int i = (int) mMemberCount; i > 0; i--, member++)
+ if (member->GetName() == name)
+ return const_cast<XPCNativeMember*>(member);
+ return nullptr;
+}
+
+inline bool
+XPCNativeInterface::HasAncestor(const nsIID* iid) const
+{
+ bool found = false;
+ mInfo->HasAncestor(iid, &found);
+ return found;
+}
+
+/* static */
+inline size_t
+XPCNativeInterface::OffsetOfMembers()
+{
+ return offsetof(XPCNativeInterface, mMembers);
+}
+
+/***************************************************************************/
+
+inline XPCNativeSetKey::XPCNativeSetKey(XPCNativeSet* baseSet,
+ XPCNativeInterface* addition)
+ : mBaseSet(baseSet)
+ , mAddition(addition)
+{
+ MOZ_ASSERT(mBaseSet);
+ MOZ_ASSERT(mAddition);
+ MOZ_ASSERT(!mBaseSet->HasInterface(mAddition));
+}
+
+/***************************************************************************/
+
+inline bool
+XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember,
+ uint16_t* pInterfaceIndex) const
+{
+ XPCNativeInterface* const * iface;
+ int count = (int) mInterfaceCount;
+ int i;
+
+ // look for interface names first
+
+ for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
+ if (name == (*iface)->GetName()) {
+ if (pMember)
+ *pMember = nullptr;
+ if (pInterfaceIndex)
+ *pInterfaceIndex = (uint16_t) i;
+ return true;
+ }
+ }
+
+ // look for method names
+ for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
+ XPCNativeMember* member = (*iface)->FindMember(name);
+ if (member) {
+ if (pMember)
+ *pMember = member;
+ if (pInterfaceIndex)
+ *pInterfaceIndex = (uint16_t) i;
+ return true;
+ }
+ }
+ return false;
+}
+
+inline bool
+XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember,
+ RefPtr<XPCNativeInterface>* pInterface) const
+{
+ uint16_t index;
+ if (!FindMember(name, pMember, &index))
+ return false;
+ *pInterface = mInterfaces[index];
+ return true;
+}
+
+inline bool
+XPCNativeSet::FindMember(JS::HandleId name,
+ XPCNativeMember** pMember,
+ RefPtr<XPCNativeInterface>* pInterface,
+ XPCNativeSet* protoSet,
+ bool* pIsLocal) const
+{
+ XPCNativeMember* Member;
+ RefPtr<XPCNativeInterface> Interface;
+ XPCNativeMember* protoMember;
+
+ if (!FindMember(name, &Member, &Interface))
+ return false;
+
+ *pMember = Member;
+
+ *pIsLocal =
+ !Member ||
+ !protoSet ||
+ (protoSet != this &&
+ !protoSet->MatchesSetUpToInterface(this, Interface) &&
+ (!protoSet->FindMember(name, &protoMember, (uint16_t*)nullptr) ||
+ protoMember != Member));
+
+ *pInterface = Interface.forget();
+
+ return true;
+}
+
+inline XPCNativeInterface*
+XPCNativeSet::FindNamedInterface(jsid name) const
+{
+ XPCNativeInterface* const * pp = mInterfaces;
+
+ for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
+ XPCNativeInterface* iface = *pp;
+
+ if (name == iface->GetName())
+ return iface;
+ }
+ return nullptr;
+}
+
+inline XPCNativeInterface*
+XPCNativeSet::FindInterfaceWithIID(const nsIID& iid) const
+{
+ XPCNativeInterface* const * pp = mInterfaces;
+
+ for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
+ XPCNativeInterface* iface = *pp;
+
+ if (iface->GetIID()->Equals(iid))
+ return iface;
+ }
+ return nullptr;
+}
+
+inline bool
+XPCNativeSet::HasInterface(XPCNativeInterface* aInterface) const
+{
+ XPCNativeInterface* const * pp = mInterfaces;
+
+ for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
+ if (aInterface == *pp)
+ return true;
+ }
+ return false;
+}
+
+inline bool
+XPCNativeSet::HasInterfaceWithAncestor(XPCNativeInterface* aInterface) const
+{
+ return HasInterfaceWithAncestor(aInterface->GetIID());
+}
+
+inline bool
+XPCNativeSet::HasInterfaceWithAncestor(const nsIID* iid) const
+{
+ // We can safely skip the first interface which is *always* nsISupports.
+ XPCNativeInterface* const * pp = mInterfaces+1;
+ for (int i = (int) mInterfaceCount; i > 1; i--, pp++)
+ if ((*pp)->HasAncestor(iid))
+ return true;
+
+ // This is rare, so check last.
+ if (iid == &NS_GET_IID(nsISupports))
+ return true;
+
+ return false;
+}
+
+inline bool
+XPCNativeSet::MatchesSetUpToInterface(const XPCNativeSet* other,
+ XPCNativeInterface* iface) const
+{
+ int count = std::min(int(mInterfaceCount), int(other->mInterfaceCount));
+
+ XPCNativeInterface* const * pp1 = mInterfaces;
+ XPCNativeInterface* const * pp2 = other->mInterfaces;
+
+ for (int i = (int) count; i > 0; i--, pp1++, pp2++) {
+ XPCNativeInterface* cur = (*pp1);
+ if (cur != (*pp2))
+ return false;
+ if (cur == iface)
+ return true;
+ }
+ return false;
+}
+
+/***************************************************************************/
+
+inline
+JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const
+{
+ return mJSObject.unbarrieredGetPtr();
+}
+
+inline
+JSObject* XPCWrappedNativeTearOff::GetJSObject()
+{
+ return mJSObject;
+}
+
+inline
+void XPCWrappedNativeTearOff::SetJSObject(JSObject* JSObj)
+{
+ MOZ_ASSERT(!IsMarked());
+ mJSObject = JSObj;
+}
+
+inline
+void XPCWrappedNativeTearOff::JSObjectMoved(JSObject* obj, const JSObject* old)
+{
+ MOZ_ASSERT(!IsMarked());
+ MOZ_ASSERT(mJSObject.unbarrieredGetPtr() == old);
+ mJSObject = obj;
+}
+
+inline
+XPCWrappedNativeTearOff::~XPCWrappedNativeTearOff()
+{
+ MOZ_COUNT_DTOR(XPCWrappedNativeTearOff);
+ MOZ_ASSERT(!(GetInterface() || GetNative() || GetJSObjectPreserveColor()),
+ "tearoff not empty in dtor");
+}
+
+/***************************************************************************/
+
+inline bool
+XPCWrappedNative::HasInterfaceNoQI(const nsIID& iid)
+{
+ return nullptr != GetSet()->FindInterfaceWithIID(iid);
+}
+
+inline void
+XPCWrappedNative::SweepTearOffs()
+{
+ for (XPCWrappedNativeTearOff* to = &mFirstTearOff; to; to = to->GetNextTearOff()) {
+ bool marked = to->IsMarked();
+ to->Unmark();
+ if (marked)
+ continue;
+
+ // If this tearoff does not have a live dedicated JSObject,
+ // then let's recycle it.
+ if (!to->GetJSObjectPreserveColor()) {
+ to->SetNative(nullptr);
+ to->SetInterface(nullptr);
+ }
+ }
+}
+
+/***************************************************************************/
+
+inline bool
+xpc_ForcePropertyResolve(JSContext* cx, JS::HandleObject obj, jsid idArg)
+{
+ JS::RootedId id(cx, idArg);
+ bool dummy;
+ return JS_HasPropertyById(cx, obj, id, &dummy);
+}
+
+inline jsid
+GetJSIDByIndex(JSContext* cx, unsigned index)
+{
+ XPCJSContext* xpcx = nsXPConnect::XPConnect()->GetContext();
+ return xpcx->GetStringID(index);
+}
+
+inline
+bool ThrowBadParam(nsresult rv, unsigned paramNum, XPCCallContext& ccx)
+{
+ XPCThrower::ThrowBadParam(rv, paramNum, ccx);
+ return false;
+}
+
+inline
+void ThrowBadResult(nsresult result, XPCCallContext& ccx)
+{
+ XPCThrower::ThrowBadResult(NS_ERROR_XPC_NATIVE_RETURNED_FAILURE,
+ result, ccx);
+}
+
+/***************************************************************************/
+
+#endif /* xpcinlines_h___ */