mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
646 lines
15 KiB
C
646 lines
15 KiB
C
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: set ts=4 sw=4 et tw=79:
|
|
*
|
|
* 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 "jsfriendapi.h"
|
|
|
|
/***************************************************************************/
|
|
|
|
inline void
|
|
XPCJSRuntime::AddVariantRoot(XPCTraceableVariant* variant)
|
|
{
|
|
variant->AddToRootSet(GetMapLock(), &mVariantRoots);
|
|
}
|
|
|
|
inline void
|
|
XPCJSRuntime::AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS)
|
|
{
|
|
wrappedJS->AddToRootSet(GetMapLock(), &mWrappedJSRoots);
|
|
}
|
|
|
|
inline void
|
|
XPCJSRuntime::AddObjectHolderRoot(XPCJSObjectHolder* holder)
|
|
{
|
|
holder->AddToRootSet(GetMapLock(), &mObjectHolderRoots);
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
inline JSBool
|
|
XPCCallContext::IsValid() const
|
|
{
|
|
return mState != INIT_FAILED;
|
|
}
|
|
|
|
inline nsXPConnect*
|
|
XPCCallContext::GetXPConnect() const
|
|
{
|
|
CHECK_STATE(HAVE_CONTEXT);
|
|
return mXPC;
|
|
}
|
|
|
|
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 JSBool
|
|
XPCCallContext::GetContextPopRequired() const
|
|
{
|
|
CHECK_STATE(HAVE_CONTEXT);
|
|
return mContextPopRequired;
|
|
}
|
|
|
|
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 JSObject*
|
|
XPCCallContext::GetScopeForNewJSObjects() const
|
|
{
|
|
CHECK_STATE(HAVE_SCOPE);
|
|
return mScopeForNewJSObjects;
|
|
}
|
|
|
|
inline void
|
|
XPCCallContext::SetScopeForNewJSObjects(JSObject *scope)
|
|
{
|
|
NS_ABORT_IF_FALSE(mState == HAVE_CONTEXT, "wrong call context state");
|
|
NS_ABORT_IF_FALSE(js::IsObjectInContextCompartment(scope, mJSContext), "wrong compartment");
|
|
mScopeForNewJSObjects = scope;
|
|
mState = HAVE_SCOPE;
|
|
}
|
|
|
|
inline JSObject*
|
|
XPCCallContext::GetFlattenedJSObject() const
|
|
{
|
|
CHECK_STATE(HAVE_OBJECT);
|
|
return mFlattenedJSObject;
|
|
}
|
|
|
|
inline nsISupports*
|
|
XPCCallContext::GetIdentityObject() const
|
|
{
|
|
CHECK_STATE(HAVE_OBJECT);
|
|
if (mWrapper)
|
|
return mWrapper->GetIdentityObject();
|
|
return mFlattenedJSObject ?
|
|
static_cast<nsISupports*>(xpc_GetJSPrivate(mFlattenedJSObject)) :
|
|
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);
|
|
if (mWrapper)
|
|
return mWrapper->GetProto();
|
|
return mFlattenedJSObject ? GetSlimWrapperProto(mFlattenedJSObject) : nullptr;
|
|
}
|
|
|
|
inline JSBool
|
|
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 JSBool
|
|
XPCCallContext::CanGetSet() const
|
|
{
|
|
return mState >= HAVE_NAME;
|
|
}
|
|
|
|
inline XPCNativeSet*
|
|
XPCCallContext::GetSet() const
|
|
{
|
|
CHECK_STATE(HAVE_NAME);
|
|
return mSet;
|
|
}
|
|
|
|
inline JSBool
|
|
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 JSBool
|
|
XPCCallContext::HasInterfaceAndMember() const
|
|
{
|
|
return mState >= HAVE_NAME && mInterface && mMember;
|
|
}
|
|
|
|
inline jsid
|
|
XPCCallContext::GetName() const
|
|
{
|
|
CHECK_STATE(HAVE_NAME);
|
|
return mName;
|
|
}
|
|
|
|
inline JSBool
|
|
XPCCallContext::GetStaticMemberIsLocal() const
|
|
{
|
|
CHECK_STATE(HAVE_NAME);
|
|
return mStaticMemberIsLocal;
|
|
}
|
|
|
|
inline unsigned
|
|
XPCCallContext::GetArgc() const
|
|
{
|
|
CHECK_STATE(READY_TO_CALL);
|
|
return mArgc;
|
|
}
|
|
|
|
inline jsval*
|
|
XPCCallContext::GetArgv() const
|
|
{
|
|
CHECK_STATE(READY_TO_CALL);
|
|
return mArgv;
|
|
}
|
|
|
|
inline jsval*
|
|
XPCCallContext::GetRetVal() const
|
|
{
|
|
CHECK_STATE(READY_TO_CALL);
|
|
return mRetVal;
|
|
}
|
|
|
|
inline void
|
|
XPCCallContext::SetRetVal(jsval 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 JSBool
|
|
XPCCallContext::GetDestroyJSContextInDestructor() const
|
|
{
|
|
CHECK_STATE(HAVE_CONTEXT);
|
|
return mDestroyJSContextInDestructor;
|
|
}
|
|
|
|
inline void
|
|
XPCCallContext::SetDestroyJSContextInDestructor(JSBool b)
|
|
{
|
|
CHECK_STATE(HAVE_CONTEXT);
|
|
mDestroyJSContextInDestructor = b;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
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 JSBool
|
|
XPCNativeInterface::HasAncestor(const nsIID* iid) const
|
|
{
|
|
bool found = false;
|
|
mInfo->HasAncestor(iid, &found);
|
|
return found;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
inline JSBool
|
|
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 JSBool
|
|
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 JSBool
|
|
XPCNativeSet::FindMember(jsid name,
|
|
XPCNativeMember** pMember,
|
|
XPCNativeInterface** pInterface,
|
|
XPCNativeSet* protoSet,
|
|
JSBool* 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 JSBool
|
|
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 JSBool
|
|
XPCNativeSet::HasInterfaceWithAncestor(XPCNativeInterface* aInterface) const
|
|
{
|
|
return HasInterfaceWithAncestor(aInterface->GetIID());
|
|
}
|
|
|
|
inline JSBool
|
|
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 JSBool
|
|
XPCNativeSet::MatchesSetUpToInterface(const XPCNativeSet* other,
|
|
XPCNativeInterface* iface) const
|
|
{
|
|
int count = js::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()
|
|
{
|
|
NS_ASSERTION(!IsMarked(), "bad");
|
|
|
|
XPCNativeInterface* const * pp = mInterfaces;
|
|
|
|
for (int i = (int) mInterfaceCount; i > 0; i--, pp++)
|
|
NS_ASSERTION(!(*pp)->IsMarked(), "bad");
|
|
}
|
|
#endif
|
|
|
|
/***************************************************************************/
|
|
|
|
inline
|
|
JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const
|
|
{
|
|
return reinterpret_cast<JSObject *>(reinterpret_cast<uintptr_t>(mJSObject) & ~1);
|
|
}
|
|
|
|
inline
|
|
JSObject* XPCWrappedNativeTearOff::GetJSObject()
|
|
{
|
|
JSObject *obj = GetJSObjectPreserveColor();
|
|
xpc_UnmarkGrayObject(obj);
|
|
return obj;
|
|
}
|
|
|
|
inline
|
|
void XPCWrappedNativeTearOff::SetJSObject(JSObject* JSObj)
|
|
{
|
|
MOZ_ASSERT(!IsMarked());
|
|
mJSObject = JSObj;
|
|
}
|
|
|
|
inline
|
|
XPCWrappedNativeTearOff::~XPCWrappedNativeTearOff()
|
|
{
|
|
NS_ASSERTION(!(GetInterface()||GetNative()||GetJSObjectPreserveColor()),
|
|
"tearoff not empty in dtor");
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
inline JSBool
|
|
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->mTearOffs;
|
|
for (int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK; i > 0; i--, to++) {
|
|
JSBool 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()) {
|
|
nsISupports* obj = to->GetNative();
|
|
if (obj) {
|
|
obj->Release();
|
|
to->SetNative(nullptr);
|
|
}
|
|
to->SetInterface(nullptr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
inline JSBool
|
|
xpc_ForcePropertyResolve(JSContext* cx, JSObject* obj, jsid id)
|
|
{
|
|
jsval prop;
|
|
|
|
if (!JS_LookupPropertyById(cx, obj, id, &prop))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
inline jsid
|
|
GetRTIdByIndex(JSContext *cx, unsigned index)
|
|
{
|
|
XPCJSRuntime *rt = nsXPConnect::FastGetXPConnect()->GetRuntime();
|
|
return rt->GetStringID(index);
|
|
}
|
|
|
|
inline
|
|
JSBool 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);
|
|
}
|
|
|
|
inline void
|
|
XPCLazyCallContext::SetWrapper(XPCWrappedNative* wrapper,
|
|
XPCWrappedNativeTearOff* tearoff)
|
|
{
|
|
mWrapper = wrapper;
|
|
mTearOff = tearoff;
|
|
if (mTearOff)
|
|
mFlattenedJSObject = mTearOff->GetJSObject();
|
|
else
|
|
mFlattenedJSObject = mWrapper->GetFlatJSObject();
|
|
}
|
|
inline void
|
|
XPCLazyCallContext::SetWrapper(JSObject* flattenedJSObject)
|
|
{
|
|
NS_ASSERTION(IS_SLIM_WRAPPER_OBJECT(flattenedJSObject),
|
|
"What kind of object is this?");
|
|
mWrapper = nullptr;
|
|
mTearOff = nullptr;
|
|
mFlattenedJSObject = flattenedJSObject;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
#endif /* xpcinlines_h___ */
|