js/xpconnect/src/XPCInlines.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/xpconnect/src/XPCInlines.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,580 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     1.5 +/* vim: set ts=8 sts=4 et sw=4 tw=99: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +/* private inline methods (#include'd by xpcprivate.h). */
    1.11 +
    1.12 +#ifndef xpcinlines_h___
    1.13 +#define xpcinlines_h___
    1.14 +
    1.15 +#include <algorithm>
    1.16 +
    1.17 +/***************************************************************************/
    1.18 +
    1.19 +inline void
    1.20 +XPCJSRuntime::AddVariantRoot(XPCTraceableVariant* variant)
    1.21 +{
    1.22 +    variant->AddToRootSet(&mVariantRoots);
    1.23 +}
    1.24 +
    1.25 +inline void
    1.26 +XPCJSRuntime::AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS)
    1.27 +{
    1.28 +    wrappedJS->AddToRootSet(&mWrappedJSRoots);
    1.29 +}
    1.30 +
    1.31 +inline void
    1.32 +XPCJSRuntime::AddObjectHolderRoot(XPCJSObjectHolder* holder)
    1.33 +{
    1.34 +    holder->AddToRootSet(&mObjectHolderRoots);
    1.35 +}
    1.36 +
    1.37 +/***************************************************************************/
    1.38 +
    1.39 +inline bool
    1.40 +XPCCallContext::IsValid() const
    1.41 +{
    1.42 +    return mState != INIT_FAILED;
    1.43 +}
    1.44 +
    1.45 +inline XPCJSRuntime*
    1.46 +XPCCallContext::GetRuntime() const
    1.47 +{
    1.48 +    CHECK_STATE(HAVE_CONTEXT);
    1.49 +    return mXPCContext->GetRuntime();
    1.50 +}
    1.51 +
    1.52 +inline XPCContext*
    1.53 +XPCCallContext::GetXPCContext() const
    1.54 +{
    1.55 +    CHECK_STATE(HAVE_CONTEXT);
    1.56 +    return mXPCContext;
    1.57 +}
    1.58 +
    1.59 +inline JSContext*
    1.60 +XPCCallContext::GetJSContext() const
    1.61 +{
    1.62 +    CHECK_STATE(HAVE_CONTEXT);
    1.63 +    return mJSContext;
    1.64 +}
    1.65 +
    1.66 +inline XPCContext::LangType
    1.67 +XPCCallContext::GetCallerLanguage() const
    1.68 +{
    1.69 +    CHECK_STATE(HAVE_CONTEXT);
    1.70 +    return mCallerLanguage;
    1.71 +}
    1.72 +
    1.73 +inline XPCContext::LangType
    1.74 +XPCCallContext::GetPrevCallerLanguage() const
    1.75 +{
    1.76 +    CHECK_STATE(HAVE_CONTEXT);
    1.77 +    return mPrevCallerLanguage;
    1.78 +}
    1.79 +
    1.80 +inline XPCCallContext*
    1.81 +XPCCallContext::GetPrevCallContext() const
    1.82 +{
    1.83 +    CHECK_STATE(HAVE_CONTEXT);
    1.84 +    return mPrevCallContext;
    1.85 +}
    1.86 +
    1.87 +inline JSObject*
    1.88 +XPCCallContext::GetFlattenedJSObject() const
    1.89 +{
    1.90 +    CHECK_STATE(HAVE_OBJECT);
    1.91 +    return mFlattenedJSObject;
    1.92 +}
    1.93 +
    1.94 +inline nsISupports*
    1.95 +XPCCallContext::GetIdentityObject() const
    1.96 +{
    1.97 +    CHECK_STATE(HAVE_OBJECT);
    1.98 +    if (mWrapper)
    1.99 +        return mWrapper->GetIdentityObject();
   1.100 +    return mFlattenedJSObject ?
   1.101 +           static_cast<nsISupports*>(xpc_GetJSPrivate(mFlattenedJSObject)) :
   1.102 +           nullptr;
   1.103 +}
   1.104 +
   1.105 +inline XPCWrappedNative*
   1.106 +XPCCallContext::GetWrapper() const
   1.107 +{
   1.108 +    if (mState == INIT_FAILED)
   1.109 +        return nullptr;
   1.110 +
   1.111 +    CHECK_STATE(HAVE_OBJECT);
   1.112 +    return mWrapper;
   1.113 +}
   1.114 +
   1.115 +inline XPCWrappedNativeProto*
   1.116 +XPCCallContext::GetProto() const
   1.117 +{
   1.118 +    CHECK_STATE(HAVE_OBJECT);
   1.119 +    return mWrapper ? mWrapper->GetProto() : nullptr;
   1.120 +}
   1.121 +
   1.122 +inline bool
   1.123 +XPCCallContext::CanGetTearOff() const
   1.124 +{
   1.125 +    return mState >= HAVE_OBJECT;
   1.126 +}
   1.127 +
   1.128 +inline XPCWrappedNativeTearOff*
   1.129 +XPCCallContext::GetTearOff() const
   1.130 +{
   1.131 +    CHECK_STATE(HAVE_OBJECT);
   1.132 +    return mTearOff;
   1.133 +}
   1.134 +
   1.135 +inline XPCNativeScriptableInfo*
   1.136 +XPCCallContext::GetScriptableInfo() const
   1.137 +{
   1.138 +    CHECK_STATE(HAVE_OBJECT);
   1.139 +    return mScriptableInfo;
   1.140 +}
   1.141 +
   1.142 +inline bool
   1.143 +XPCCallContext::CanGetSet() const
   1.144 +{
   1.145 +    return mState >= HAVE_NAME;
   1.146 +}
   1.147 +
   1.148 +inline XPCNativeSet*
   1.149 +XPCCallContext::GetSet() const
   1.150 +{
   1.151 +    CHECK_STATE(HAVE_NAME);
   1.152 +    return mSet;
   1.153 +}
   1.154 +
   1.155 +inline bool
   1.156 +XPCCallContext::CanGetInterface() const
   1.157 +{
   1.158 +    return mState >= HAVE_NAME;
   1.159 +}
   1.160 +
   1.161 +inline XPCNativeInterface*
   1.162 +XPCCallContext::GetInterface() const
   1.163 +{
   1.164 +    CHECK_STATE(HAVE_NAME);
   1.165 +    return mInterface;
   1.166 +}
   1.167 +
   1.168 +inline XPCNativeMember*
   1.169 +XPCCallContext::GetMember() const
   1.170 +{
   1.171 +    CHECK_STATE(HAVE_NAME);
   1.172 +    return mMember;
   1.173 +}
   1.174 +
   1.175 +inline bool
   1.176 +XPCCallContext::HasInterfaceAndMember() const
   1.177 +{
   1.178 +    return mState >= HAVE_NAME && mInterface && mMember;
   1.179 +}
   1.180 +
   1.181 +inline jsid
   1.182 +XPCCallContext::GetName() const
   1.183 +{
   1.184 +    CHECK_STATE(HAVE_NAME);
   1.185 +    return mName;
   1.186 +}
   1.187 +
   1.188 +inline bool
   1.189 +XPCCallContext::GetStaticMemberIsLocal() const
   1.190 +{
   1.191 +    CHECK_STATE(HAVE_NAME);
   1.192 +    return mStaticMemberIsLocal;
   1.193 +}
   1.194 +
   1.195 +inline unsigned
   1.196 +XPCCallContext::GetArgc() const
   1.197 +{
   1.198 +    CHECK_STATE(READY_TO_CALL);
   1.199 +    return mArgc;
   1.200 +}
   1.201 +
   1.202 +inline jsval*
   1.203 +XPCCallContext::GetArgv() const
   1.204 +{
   1.205 +    CHECK_STATE(READY_TO_CALL);
   1.206 +    return mArgv;
   1.207 +}
   1.208 +
   1.209 +inline jsval*
   1.210 +XPCCallContext::GetRetVal() const
   1.211 +{
   1.212 +    CHECK_STATE(READY_TO_CALL);
   1.213 +    return mRetVal;
   1.214 +}
   1.215 +
   1.216 +inline void
   1.217 +XPCCallContext::SetRetVal(jsval val)
   1.218 +{
   1.219 +    CHECK_STATE(HAVE_ARGS);
   1.220 +    if (mRetVal)
   1.221 +        *mRetVal = val;
   1.222 +}
   1.223 +
   1.224 +inline jsid
   1.225 +XPCCallContext::GetResolveName() const
   1.226 +{
   1.227 +    CHECK_STATE(HAVE_CONTEXT);
   1.228 +    return XPCJSRuntime::Get()->GetResolveName();
   1.229 +}
   1.230 +
   1.231 +inline jsid
   1.232 +XPCCallContext::SetResolveName(JS::HandleId name)
   1.233 +{
   1.234 +    CHECK_STATE(HAVE_CONTEXT);
   1.235 +    return XPCJSRuntime::Get()->SetResolveName(name);
   1.236 +}
   1.237 +
   1.238 +inline XPCWrappedNative*
   1.239 +XPCCallContext::GetResolvingWrapper() const
   1.240 +{
   1.241 +    CHECK_STATE(HAVE_OBJECT);
   1.242 +    return XPCJSRuntime::Get()->GetResolvingWrapper();
   1.243 +}
   1.244 +
   1.245 +inline XPCWrappedNative*
   1.246 +XPCCallContext::SetResolvingWrapper(XPCWrappedNative* w)
   1.247 +{
   1.248 +    CHECK_STATE(HAVE_OBJECT);
   1.249 +    return XPCJSRuntime::Get()->SetResolvingWrapper(w);
   1.250 +}
   1.251 +
   1.252 +inline uint16_t
   1.253 +XPCCallContext::GetMethodIndex() const
   1.254 +{
   1.255 +    CHECK_STATE(HAVE_OBJECT);
   1.256 +    return mMethodIndex;
   1.257 +}
   1.258 +
   1.259 +inline void
   1.260 +XPCCallContext::SetMethodIndex(uint16_t index)
   1.261 +{
   1.262 +    CHECK_STATE(HAVE_OBJECT);
   1.263 +    mMethodIndex = index;
   1.264 +}
   1.265 +
   1.266 +/***************************************************************************/
   1.267 +
   1.268 +inline const nsIID*
   1.269 +XPCNativeInterface::GetIID() const
   1.270 +{
   1.271 +    const nsIID* iid;
   1.272 +    return NS_SUCCEEDED(mInfo->GetIIDShared(&iid)) ? iid : nullptr;
   1.273 +}
   1.274 +
   1.275 +inline const char*
   1.276 +XPCNativeInterface::GetNameString() const
   1.277 +{
   1.278 +    const char* name;
   1.279 +    return NS_SUCCEEDED(mInfo->GetNameShared(&name)) ? name : nullptr;
   1.280 +}
   1.281 +
   1.282 +inline XPCNativeMember*
   1.283 +XPCNativeInterface::FindMember(jsid name) const
   1.284 +{
   1.285 +    const XPCNativeMember* member = mMembers;
   1.286 +    for (int i = (int) mMemberCount; i > 0; i--, member++)
   1.287 +        if (member->GetName() == name)
   1.288 +            return const_cast<XPCNativeMember*>(member);
   1.289 +    return nullptr;
   1.290 +}
   1.291 +
   1.292 +inline bool
   1.293 +XPCNativeInterface::HasAncestor(const nsIID* iid) const
   1.294 +{
   1.295 +    bool found = false;
   1.296 +    mInfo->HasAncestor(iid, &found);
   1.297 +    return found;
   1.298 +}
   1.299 +
   1.300 +/***************************************************************************/
   1.301 +
   1.302 +inline bool
   1.303 +XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember,
   1.304 +                         uint16_t* pInterfaceIndex) const
   1.305 +{
   1.306 +    XPCNativeInterface* const * iface;
   1.307 +    int count = (int) mInterfaceCount;
   1.308 +    int i;
   1.309 +
   1.310 +    // look for interface names first
   1.311 +
   1.312 +    for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
   1.313 +        if (name == (*iface)->GetName()) {
   1.314 +            if (pMember)
   1.315 +                *pMember = nullptr;
   1.316 +            if (pInterfaceIndex)
   1.317 +                *pInterfaceIndex = (uint16_t) i;
   1.318 +            return true;
   1.319 +        }
   1.320 +    }
   1.321 +
   1.322 +    // look for method names
   1.323 +    for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
   1.324 +        XPCNativeMember* member = (*iface)->FindMember(name);
   1.325 +        if (member) {
   1.326 +            if (pMember)
   1.327 +                *pMember = member;
   1.328 +            if (pInterfaceIndex)
   1.329 +                *pInterfaceIndex = (uint16_t) i;
   1.330 +            return true;
   1.331 +        }
   1.332 +    }
   1.333 +    return false;
   1.334 +}
   1.335 +
   1.336 +inline bool
   1.337 +XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember,
   1.338 +                         XPCNativeInterface** pInterface) const
   1.339 +{
   1.340 +    uint16_t index;
   1.341 +    if (!FindMember(name, pMember, &index))
   1.342 +        return false;
   1.343 +    *pInterface = mInterfaces[index];
   1.344 +    return true;
   1.345 +}
   1.346 +
   1.347 +inline bool
   1.348 +XPCNativeSet::FindMember(jsid name,
   1.349 +                         XPCNativeMember** pMember,
   1.350 +                         XPCNativeInterface** pInterface,
   1.351 +                         XPCNativeSet* protoSet,
   1.352 +                         bool* pIsLocal) const
   1.353 +{
   1.354 +    XPCNativeMember* Member;
   1.355 +    XPCNativeInterface* Interface;
   1.356 +    XPCNativeMember* protoMember;
   1.357 +
   1.358 +    if (!FindMember(name, &Member, &Interface))
   1.359 +        return false;
   1.360 +
   1.361 +    *pMember = Member;
   1.362 +    *pInterface = Interface;
   1.363 +
   1.364 +    *pIsLocal =
   1.365 +        !Member ||
   1.366 +        !protoSet ||
   1.367 +        (protoSet != this &&
   1.368 +         !protoSet->MatchesSetUpToInterface(this, Interface) &&
   1.369 +         (!protoSet->FindMember(name, &protoMember, (uint16_t*)nullptr) ||
   1.370 +          protoMember != Member));
   1.371 +
   1.372 +    return true;
   1.373 +}
   1.374 +
   1.375 +inline XPCNativeInterface*
   1.376 +XPCNativeSet::FindNamedInterface(jsid name) const
   1.377 +{
   1.378 +    XPCNativeInterface* const * pp = mInterfaces;
   1.379 +
   1.380 +    for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
   1.381 +        XPCNativeInterface* iface = *pp;
   1.382 +
   1.383 +        if (name == iface->GetName())
   1.384 +            return iface;
   1.385 +    }
   1.386 +    return nullptr;
   1.387 +}
   1.388 +
   1.389 +inline XPCNativeInterface*
   1.390 +XPCNativeSet::FindInterfaceWithIID(const nsIID& iid) const
   1.391 +{
   1.392 +    XPCNativeInterface* const * pp = mInterfaces;
   1.393 +
   1.394 +    for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
   1.395 +        XPCNativeInterface* iface = *pp;
   1.396 +
   1.397 +        if (iface->GetIID()->Equals(iid))
   1.398 +            return iface;
   1.399 +    }
   1.400 +    return nullptr;
   1.401 +}
   1.402 +
   1.403 +inline bool
   1.404 +XPCNativeSet::HasInterface(XPCNativeInterface* aInterface) const
   1.405 +{
   1.406 +    XPCNativeInterface* const * pp = mInterfaces;
   1.407 +
   1.408 +    for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
   1.409 +        if (aInterface == *pp)
   1.410 +            return true;
   1.411 +    }
   1.412 +    return false;
   1.413 +}
   1.414 +
   1.415 +inline bool
   1.416 +XPCNativeSet::HasInterfaceWithAncestor(XPCNativeInterface* aInterface) const
   1.417 +{
   1.418 +    return HasInterfaceWithAncestor(aInterface->GetIID());
   1.419 +}
   1.420 +
   1.421 +inline bool
   1.422 +XPCNativeSet::HasInterfaceWithAncestor(const nsIID* iid) const
   1.423 +{
   1.424 +    // We can safely skip the first interface which is *always* nsISupports.
   1.425 +    XPCNativeInterface* const * pp = mInterfaces+1;
   1.426 +    for (int i = (int) mInterfaceCount; i > 1; i--, pp++)
   1.427 +        if ((*pp)->HasAncestor(iid))
   1.428 +            return true;
   1.429 +
   1.430 +    // This is rare, so check last.
   1.431 +    if (iid == &NS_GET_IID(nsISupports))
   1.432 +        return true;
   1.433 +
   1.434 +    return false;
   1.435 +}
   1.436 +
   1.437 +inline bool
   1.438 +XPCNativeSet::MatchesSetUpToInterface(const XPCNativeSet* other,
   1.439 +                                      XPCNativeInterface* iface) const
   1.440 +{
   1.441 +    int count = std::min(int(mInterfaceCount), int(other->mInterfaceCount));
   1.442 +
   1.443 +    XPCNativeInterface* const * pp1 = mInterfaces;
   1.444 +    XPCNativeInterface* const * pp2 = other->mInterfaces;
   1.445 +
   1.446 +    for (int i = (int) count; i > 0; i--, pp1++, pp2++) {
   1.447 +        XPCNativeInterface* cur = (*pp1);
   1.448 +        if (cur != (*pp2))
   1.449 +            return false;
   1.450 +        if (cur == iface)
   1.451 +            return true;
   1.452 +    }
   1.453 +    return false;
   1.454 +}
   1.455 +
   1.456 +inline void XPCNativeSet::Mark()
   1.457 +{
   1.458 +    if (IsMarked())
   1.459 +        return;
   1.460 +
   1.461 +    XPCNativeInterface* const * pp = mInterfaces;
   1.462 +
   1.463 +    for (int i = (int) mInterfaceCount; i > 0; i--, pp++)
   1.464 +        (*pp)->Mark();
   1.465 +
   1.466 +    MarkSelfOnly();
   1.467 +}
   1.468 +
   1.469 +#ifdef DEBUG
   1.470 +inline void XPCNativeSet::ASSERT_NotMarked()
   1.471 +{
   1.472 +    MOZ_ASSERT(!IsMarked(), "bad");
   1.473 +
   1.474 +    XPCNativeInterface* const * pp = mInterfaces;
   1.475 +
   1.476 +    for (int i = (int) mInterfaceCount; i > 0; i--, pp++)
   1.477 +        MOZ_ASSERT(!(*pp)->IsMarked(), "bad");
   1.478 +}
   1.479 +#endif
   1.480 +
   1.481 +/***************************************************************************/
   1.482 +
   1.483 +inline
   1.484 +JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const
   1.485 +{
   1.486 +    return reinterpret_cast<JSObject *>(reinterpret_cast<uintptr_t>(mJSObject) & ~1);
   1.487 +}
   1.488 +
   1.489 +inline
   1.490 +JSObject* XPCWrappedNativeTearOff::GetJSObject()
   1.491 +{
   1.492 +    JSObject *obj = GetJSObjectPreserveColor();
   1.493 +    if (obj) {
   1.494 +      JS::ExposeObjectToActiveJS(obj);
   1.495 +    }
   1.496 +    return obj;
   1.497 +}
   1.498 +
   1.499 +inline
   1.500 +void XPCWrappedNativeTearOff::SetJSObject(JSObject*  JSObj)
   1.501 +{
   1.502 +    MOZ_ASSERT(!IsMarked());
   1.503 +    mJSObject = JSObj;
   1.504 +}
   1.505 +
   1.506 +inline
   1.507 +XPCWrappedNativeTearOff::~XPCWrappedNativeTearOff()
   1.508 +{
   1.509 +    MOZ_ASSERT(!(GetInterface() || GetNative() || GetJSObjectPreserveColor()),
   1.510 +               "tearoff not empty in dtor");
   1.511 +}
   1.512 +
   1.513 +/***************************************************************************/
   1.514 +
   1.515 +inline bool
   1.516 +XPCWrappedNative::HasInterfaceNoQI(const nsIID& iid)
   1.517 +{
   1.518 +    return nullptr != GetSet()->FindInterfaceWithIID(iid);
   1.519 +}
   1.520 +
   1.521 +inline void
   1.522 +XPCWrappedNative::SweepTearOffs()
   1.523 +{
   1.524 +    XPCWrappedNativeTearOffChunk* chunk;
   1.525 +    for (chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk) {
   1.526 +        XPCWrappedNativeTearOff* to = chunk->mTearOffs;
   1.527 +        for (int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK; i > 0; i--, to++) {
   1.528 +            bool marked = to->IsMarked();
   1.529 +            to->Unmark();
   1.530 +            if (marked)
   1.531 +                continue;
   1.532 +
   1.533 +            // If this tearoff does not have a live dedicated JSObject,
   1.534 +            // then let's recycle it.
   1.535 +            if (!to->GetJSObjectPreserveColor()) {
   1.536 +                nsISupports* obj = to->GetNative();
   1.537 +                if (obj) {
   1.538 +                    obj->Release();
   1.539 +                    to->SetNative(nullptr);
   1.540 +                }
   1.541 +                to->SetInterface(nullptr);
   1.542 +            }
   1.543 +        }
   1.544 +    }
   1.545 +}
   1.546 +
   1.547 +/***************************************************************************/
   1.548 +
   1.549 +inline bool
   1.550 +xpc_ForcePropertyResolve(JSContext* cx, JS::HandleObject obj, jsid idArg)
   1.551 +{
   1.552 +    JS::RootedValue prop(cx);
   1.553 +    JS::RootedId id(cx, idArg);
   1.554 +
   1.555 +    if (!JS_LookupPropertyById(cx, obj, id, &prop))
   1.556 +        return false;
   1.557 +    return true;
   1.558 +}
   1.559 +
   1.560 +inline jsid
   1.561 +GetRTIdByIndex(JSContext *cx, unsigned index)
   1.562 +{
   1.563 +  XPCJSRuntime *rt = nsXPConnect::XPConnect()->GetRuntime();
   1.564 +  return rt->GetStringID(index);
   1.565 +}
   1.566 +
   1.567 +inline
   1.568 +bool ThrowBadParam(nsresult rv, unsigned paramNum, XPCCallContext& ccx)
   1.569 +{
   1.570 +    XPCThrower::ThrowBadParam(rv, paramNum, ccx);
   1.571 +    return false;
   1.572 +}
   1.573 +
   1.574 +inline
   1.575 +void ThrowBadResult(nsresult result, XPCCallContext& ccx)
   1.576 +{
   1.577 +    XPCThrower::ThrowBadResult(NS_ERROR_XPC_NATIVE_RETURNED_FAILURE,
   1.578 +                               result, ccx);
   1.579 +}
   1.580 +
   1.581 +/***************************************************************************/
   1.582 +
   1.583 +#endif /* xpcinlines_h___ */

mercurial