mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-06-27 02:29:35 +00:00
591 lines
13 KiB
C++
591 lines
13 KiB
C++
/* -*- 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
|
|
XPCJSRuntime::AddVariantRoot(XPCTraceableVariant* variant)
|
|
{
|
|
variant->AddToRootSet(&mVariantRoots);
|
|
}
|
|
|
|
inline void
|
|
XPCJSRuntime::AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS)
|
|
{
|
|
wrappedJS->AddToRootSet(&mWrappedJSRoots);
|
|
}
|
|
|
|
inline void
|
|
XPCJSRuntime::AddObjectHolderRoot(XPCJSObjectHolder* holder)
|
|
{
|
|
holder->AddToRootSet(&mObjectHolderRoots);
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
inline bool
|
|
XPCCallContext::IsValid() const
|
|
{
|
|
return mState != INIT_FAILED;
|
|
}
|
|
|
|
inline XPCJSRuntime*
|
|
XPCCallContext::GetRuntime() const
|
|
{
|
|
CHECK_STATE(HAVE_CONTEXT);
|
|
return mXPCContext->GetRuntime();
|
|
}
|
|
|
|
inline XPCContext*
|
|
XPCCallContext::GetXPCContext() const
|
|
{
|
|
CHECK_STATE(HAVE_CONTEXT);
|
|
return mXPCContext;
|
|
}
|
|
|
|
inline JSContext*
|
|
XPCCallContext::GetJSContext() const
|
|
{
|
|
CHECK_STATE(HAVE_CONTEXT);
|
|
return mJSContext;
|
|
}
|
|
|
|
inline XPCContext::LangType
|
|
XPCCallContext::GetCallerLanguage() const
|
|
{
|
|
CHECK_STATE(HAVE_CONTEXT);
|
|
return mCallerLanguage;
|
|
}
|
|
|
|
inline XPCContext::LangType
|
|
XPCCallContext::GetPrevCallerLanguage() const
|
|
{
|
|
CHECK_STATE(HAVE_CONTEXT);
|
|
return mPrevCallerLanguage;
|
|
}
|
|
|
|
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 bool
|
|
XPCCallContext::CanGetInterface() const
|
|
{
|
|
return mState >= HAVE_NAME;
|
|
}
|
|
|
|
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(JS::Value val)
|
|
{
|
|
CHECK_STATE(HAVE_ARGS);
|
|
if (mRetVal)
|
|
*mRetVal = val;
|
|
}
|
|
|
|
inline jsid
|
|
XPCCallContext::GetResolveName() const
|
|
{
|
|
CHECK_STATE(HAVE_CONTEXT);
|
|
return XPCJSRuntime::Get()->GetResolveName();
|
|
}
|
|
|
|
inline jsid
|
|
XPCCallContext::SetResolveName(JS::HandleId name)
|
|
{
|
|
CHECK_STATE(HAVE_CONTEXT);
|
|
return XPCJSRuntime::Get()->SetResolveName(name);
|
|
}
|
|
|
|
inline XPCWrappedNative*
|
|
XPCCallContext::GetResolvingWrapper() const
|
|
{
|
|
CHECK_STATE(HAVE_OBJECT);
|
|
return XPCJSRuntime::Get()->GetResolvingWrapper();
|
|
}
|
|
|
|
inline XPCWrappedNative*
|
|
XPCCallContext::SetResolvingWrapper(XPCWrappedNative* w)
|
|
{
|
|
CHECK_STATE(HAVE_OBJECT);
|
|
return XPCJSRuntime::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 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,
|
|
XPCNativeInterface** pInterface) const
|
|
{
|
|
uint16_t index;
|
|
if (!FindMember(name, pMember, &index))
|
|
return false;
|
|
*pInterface = mInterfaces[index];
|
|
return true;
|
|
}
|
|
|
|
inline bool
|
|
XPCNativeSet::FindMember(jsid name,
|
|
XPCNativeMember** pMember,
|
|
XPCNativeInterface** pInterface,
|
|
XPCNativeSet* protoSet,
|
|
bool* pIsLocal) const
|
|
{
|
|
XPCNativeMember* Member;
|
|
XPCNativeInterface* Interface;
|
|
XPCNativeMember* protoMember;
|
|
|
|
if (!FindMember(name, &Member, &Interface))
|
|
return false;
|
|
|
|
*pMember = Member;
|
|
*pInterface = Interface;
|
|
|
|
*pIsLocal =
|
|
!Member ||
|
|
!protoSet ||
|
|
(protoSet != this &&
|
|
!protoSet->MatchesSetUpToInterface(this, Interface) &&
|
|
(!protoSet->FindMember(name, &protoMember, (uint16_t*)nullptr) ||
|
|
protoMember != Member));
|
|
|
|
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 void XPCNativeSet::Mark()
|
|
{
|
|
if (IsMarked())
|
|
return;
|
|
|
|
XPCNativeInterface* const * pp = mInterfaces;
|
|
|
|
for (int i = (int) mInterfaceCount; i > 0; i--, pp++)
|
|
(*pp)->Mark();
|
|
|
|
MarkSelfOnly();
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
inline void XPCNativeSet::ASSERT_NotMarked()
|
|
{
|
|
MOZ_ASSERT(!IsMarked(), "bad");
|
|
|
|
XPCNativeInterface* const * pp = mInterfaces;
|
|
|
|
for (int i = (int) mInterfaceCount; i > 0; i--, pp++)
|
|
MOZ_ASSERT(!(*pp)->IsMarked(), "bad");
|
|
}
|
|
#endif
|
|
|
|
/***************************************************************************/
|
|
|
|
inline
|
|
JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const
|
|
{
|
|
return mJSObject.getPtr();
|
|
}
|
|
|
|
inline
|
|
JSObject* XPCWrappedNativeTearOff::GetJSObject()
|
|
{
|
|
JSObject* obj = GetJSObjectPreserveColor();
|
|
if (obj) {
|
|
JS::ExposeObjectToActiveJS(obj);
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
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 == 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()
|
|
{
|
|
XPCWrappedNativeTearOffChunk* chunk;
|
|
for (chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk) {
|
|
XPCWrappedNativeTearOff* to = &chunk->mTearOff;
|
|
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
|
|
GetRTIdByIndex(JSContext* cx, unsigned index)
|
|
{
|
|
XPCJSRuntime* rt = nsXPConnect::XPConnect()->GetRuntime();
|
|
return rt->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___ */
|