tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

XPCInlines.h (10553B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /* private inline methods (#include'd by xpcprivate.h). */
      8 
      9 #ifndef xpcinlines_h___
     10 #define xpcinlines_h___
     11 
     12 #include <algorithm>
     13 
     14 #include "js/PropertyAndElement.h"  // JS_HasProperty, JS_HasPropertyById
     15 
     16 /***************************************************************************/
     17 
     18 inline void XPCJSRuntime::AddSubjectToFinalizationWJS(
     19    nsXPCWrappedJS* wrappedJS) {
     20  mSubjectToFinalizationWJS.insertBack(wrappedJS);
     21 }
     22 
     23 /***************************************************************************/
     24 
     25 inline bool XPCCallContext::IsValid() const { return mState != INIT_FAILED; }
     26 
     27 inline XPCJSContext* XPCCallContext::GetContext() const {
     28  CHECK_STATE(HAVE_CONTEXT);
     29  return mXPCJSContext;
     30 }
     31 
     32 inline JSContext* XPCCallContext::GetJSContext() const {
     33  CHECK_STATE(HAVE_CONTEXT);
     34  return mJSContext;
     35 }
     36 
     37 inline XPCCallContext* XPCCallContext::GetPrevCallContext() const {
     38  CHECK_STATE(HAVE_CONTEXT);
     39  return mPrevCallContext;
     40 }
     41 
     42 inline XPCWrappedNative* XPCCallContext::GetWrapper() const {
     43  if (mState == INIT_FAILED) {
     44    return nullptr;
     45  }
     46 
     47  CHECK_STATE(HAVE_OBJECT);
     48  return mWrapper;
     49 }
     50 
     51 inline bool XPCCallContext::CanGetTearOff() const {
     52  return mState >= HAVE_OBJECT;
     53 }
     54 
     55 inline XPCWrappedNativeTearOff* XPCCallContext::GetTearOff() const {
     56  CHECK_STATE(HAVE_OBJECT);
     57  return mTearOff;
     58 }
     59 
     60 inline nsIXPCScriptable* XPCCallContext::GetScriptable() const {
     61  CHECK_STATE(HAVE_OBJECT);
     62  return mScriptable;
     63 }
     64 
     65 inline XPCNativeSet* XPCCallContext::GetSet() const {
     66  CHECK_STATE(HAVE_NAME);
     67  return mSet;
     68 }
     69 
     70 inline XPCNativeInterface* XPCCallContext::GetInterface() const {
     71  CHECK_STATE(HAVE_NAME);
     72  return mInterface;
     73 }
     74 
     75 inline XPCNativeMember* XPCCallContext::GetMember() const {
     76  CHECK_STATE(HAVE_NAME);
     77  return mMember;
     78 }
     79 
     80 inline bool XPCCallContext::HasInterfaceAndMember() const {
     81  return mState >= HAVE_NAME && mInterface && mMember;
     82 }
     83 
     84 inline bool XPCCallContext::GetStaticMemberIsLocal() const {
     85  CHECK_STATE(HAVE_NAME);
     86  return mStaticMemberIsLocal;
     87 }
     88 
     89 inline unsigned XPCCallContext::GetArgc() const {
     90  CHECK_STATE(READY_TO_CALL);
     91  return mArgc;
     92 }
     93 
     94 inline JS::Value* XPCCallContext::GetArgv() const {
     95  CHECK_STATE(READY_TO_CALL);
     96  return mArgv;
     97 }
     98 
     99 inline void XPCCallContext::SetRetVal(const JS::Value& val) {
    100  CHECK_STATE(HAVE_ARGS);
    101  if (mRetVal) {
    102    *mRetVal = val;
    103  }
    104 }
    105 
    106 inline jsid XPCCallContext::GetResolveName() const {
    107  CHECK_STATE(HAVE_CONTEXT);
    108  return GetContext()->GetResolveName();
    109 }
    110 
    111 inline jsid XPCCallContext::SetResolveName(JS::HandleId name) {
    112  CHECK_STATE(HAVE_CONTEXT);
    113  return GetContext()->SetResolveName(name);
    114 }
    115 
    116 inline XPCWrappedNative* XPCCallContext::GetResolvingWrapper() const {
    117  CHECK_STATE(HAVE_OBJECT);
    118  return GetContext()->GetResolvingWrapper();
    119 }
    120 
    121 inline XPCWrappedNative* XPCCallContext::SetResolvingWrapper(
    122    XPCWrappedNative* w) {
    123  CHECK_STATE(HAVE_OBJECT);
    124  return GetContext()->SetResolvingWrapper(w);
    125 }
    126 
    127 inline uint16_t XPCCallContext::GetMethodIndex() const {
    128  CHECK_STATE(HAVE_OBJECT);
    129  return mMethodIndex;
    130 }
    131 
    132 /***************************************************************************/
    133 inline XPCNativeInterface* XPCNativeMember::GetInterface() const {
    134  XPCNativeMember* arrayStart =
    135      const_cast<XPCNativeMember*>(this - mIndexInInterface);
    136  size_t arrayStartOffset = XPCNativeInterface::OffsetOfMembers();
    137  char* xpcNativeInterfaceStart =
    138      reinterpret_cast<char*>(arrayStart) - arrayStartOffset;
    139  return reinterpret_cast<XPCNativeInterface*>(xpcNativeInterfaceStart);
    140 }
    141 
    142 /***************************************************************************/
    143 
    144 inline const nsIID* XPCNativeInterface::GetIID() const { return &mInfo->IID(); }
    145 
    146 inline const char* XPCNativeInterface::GetNameString() const {
    147  return mInfo->Name();
    148 }
    149 
    150 inline XPCNativeMember* XPCNativeInterface::FindMember(jsid name) const {
    151  const XPCNativeMember* member = mMembers;
    152  for (int i = (int)mMemberCount; i > 0; i--, member++) {
    153    if (member->GetName() == name) {
    154      return const_cast<XPCNativeMember*>(member);
    155    }
    156  }
    157  return nullptr;
    158 }
    159 
    160 /* static */
    161 inline size_t XPCNativeInterface::OffsetOfMembers() {
    162  return offsetof(XPCNativeInterface, mMembers);
    163 }
    164 
    165 /***************************************************************************/
    166 
    167 inline XPCNativeSetKey::XPCNativeSetKey(XPCNativeSet* baseSet,
    168                                        XPCNativeInterface* addition)
    169    : mCx(nullptr), mBaseSet(baseSet), mAddition(addition) {
    170  MOZ_ASSERT(mBaseSet);
    171  MOZ_ASSERT(mAddition);
    172  MOZ_ASSERT(!mBaseSet->HasInterface(mAddition));
    173 }
    174 
    175 /***************************************************************************/
    176 
    177 inline bool XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember,
    178                                     uint16_t* pInterfaceIndex) const {
    179  XPCNativeInterface* const* iface;
    180  int count = (int)mInterfaceCount;
    181  int i;
    182 
    183  // look for interface names first
    184 
    185  for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
    186    if (name == (*iface)->GetName()) {
    187      if (pMember) {
    188        *pMember = nullptr;
    189      }
    190      if (pInterfaceIndex) {
    191        *pInterfaceIndex = (uint16_t)i;
    192      }
    193      return true;
    194    }
    195  }
    196 
    197  // look for method names
    198  for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
    199    XPCNativeMember* member = (*iface)->FindMember(name);
    200    if (member) {
    201      if (pMember) {
    202        *pMember = member;
    203      }
    204      if (pInterfaceIndex) {
    205        *pInterfaceIndex = (uint16_t)i;
    206      }
    207      return true;
    208    }
    209  }
    210  return false;
    211 }
    212 
    213 inline bool XPCNativeSet::FindMember(
    214    jsid name, XPCNativeMember** pMember,
    215    RefPtr<XPCNativeInterface>* pInterface) const {
    216  uint16_t index;
    217  if (!FindMember(name, pMember, &index)) {
    218    return false;
    219  }
    220  *pInterface = mInterfaces[index];
    221  return true;
    222 }
    223 
    224 inline bool XPCNativeSet::FindMember(JS::HandleId name,
    225                                     XPCNativeMember** pMember,
    226                                     RefPtr<XPCNativeInterface>* pInterface,
    227                                     XPCNativeSet* protoSet,
    228                                     bool* pIsLocal) const {
    229  XPCNativeMember* Member;
    230  RefPtr<XPCNativeInterface> Interface;
    231  XPCNativeMember* protoMember;
    232 
    233  if (!FindMember(name, &Member, &Interface)) {
    234    return false;
    235  }
    236 
    237  *pMember = Member;
    238 
    239  *pIsLocal = !Member || !protoSet ||
    240              (protoSet != this &&
    241               !protoSet->MatchesSetUpToInterface(this, Interface) &&
    242               (!protoSet->FindMember(name, &protoMember, (uint16_t*)nullptr) ||
    243                protoMember != Member));
    244 
    245  *pInterface = std::move(Interface);
    246 
    247  return true;
    248 }
    249 
    250 inline bool XPCNativeSet::HasInterface(XPCNativeInterface* aInterface) const {
    251  XPCNativeInterface* const* pp = mInterfaces;
    252 
    253  for (int i = (int)mInterfaceCount; i > 0; i--, pp++) {
    254    if (aInterface == *pp) {
    255      return true;
    256    }
    257  }
    258  return false;
    259 }
    260 
    261 inline bool XPCNativeSet::MatchesSetUpToInterface(
    262    const XPCNativeSet* other, XPCNativeInterface* iface) const {
    263  int count = std::min(int(mInterfaceCount), int(other->mInterfaceCount));
    264 
    265  XPCNativeInterface* const* pp1 = mInterfaces;
    266  XPCNativeInterface* const* pp2 = other->mInterfaces;
    267 
    268  for (int i = (int)count; i > 0; i--, pp1++, pp2++) {
    269    XPCNativeInterface* cur = (*pp1);
    270    if (cur != (*pp2)) {
    271      return false;
    272    }
    273    if (cur == iface) {
    274      return true;
    275    }
    276  }
    277  return false;
    278 }
    279 
    280 /***************************************************************************/
    281 
    282 inline JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const {
    283  return mJSObject.unbarrieredGetPtr();
    284 }
    285 
    286 inline JSObject* XPCWrappedNativeTearOff::GetJSObject() { return mJSObject; }
    287 
    288 inline void XPCWrappedNativeTearOff::SetJSObject(JSObject* JSObj) {
    289  MOZ_ASSERT(!IsMarked());
    290  mJSObject = JSObj;
    291 }
    292 
    293 inline void XPCWrappedNativeTearOff::JSObjectMoved(JSObject* obj,
    294                                                   const JSObject* old) {
    295  MOZ_ASSERT(!IsMarked());
    296  MOZ_ASSERT(mJSObject == old);
    297  mJSObject = obj;
    298 }
    299 
    300 inline XPCWrappedNativeTearOff::~XPCWrappedNativeTearOff() {
    301  MOZ_COUNT_DTOR(XPCWrappedNativeTearOff);
    302  MOZ_ASSERT(!(GetInterface() || GetNative() || GetJSObjectPreserveColor()),
    303             "tearoff not empty in dtor");
    304 }
    305 
    306 /***************************************************************************/
    307 
    308 inline void XPCWrappedNative::SweepTearOffs() {
    309  for (XPCWrappedNativeTearOff* to = &mFirstTearOff; to;
    310       to = to->GetNextTearOff()) {
    311    bool marked = to->IsMarked();
    312    to->Unmark();
    313    if (marked) {
    314      continue;
    315    }
    316 
    317    // If this tearoff does not have a live dedicated JSObject,
    318    // then let's recycle it.
    319    if (!to->GetJSObjectPreserveColor()) {
    320      to->SetNative(nullptr);
    321      to->SetInterface(nullptr);
    322    }
    323  }
    324 }
    325 
    326 /***************************************************************************/
    327 
    328 inline bool xpc_ForcePropertyResolve(JSContext* cx, JS::HandleObject obj,
    329                                     jsid idArg) {
    330  JS::RootedId id(cx, idArg);
    331  bool dummy;
    332  return JS_HasPropertyById(cx, obj, id, &dummy);
    333 }
    334 
    335 inline jsid GetJSIDByIndex(JSContext* cx, unsigned index) {
    336  XPCJSRuntime* xpcrt = nsXPConnect::GetRuntimeInstance();
    337  return xpcrt->GetStringID(index);
    338 }
    339 
    340 inline bool ThrowBadParam(nsresult rv, unsigned paramNum, XPCCallContext& ccx) {
    341  XPCThrower::ThrowBadParam(rv, paramNum, ccx);
    342  return false;
    343 }
    344 
    345 inline void ThrowBadResult(nsresult result, XPCCallContext& ccx) {
    346  XPCThrower::ThrowBadResult(NS_ERROR_XPC_NATIVE_RETURNED_FAILURE, result, ccx);
    347 }
    348 
    349 /***************************************************************************/
    350 
    351 inline void xpc::CleanupValue(const nsXPTType& aType, void* aValue,
    352                              uint32_t aArrayLen) {
    353  // Check if we can do a cheap early return, and only perform the inner call
    354  // if we can't. We never have to clean up null pointer types or arithmetic
    355  // types.
    356  //
    357  // NOTE: We can skip zeroing arithmetic types in CleanupValue, as they are
    358  // already in a valid state.
    359  if (aType.IsArithmetic() || (aType.IsPointer() && !*(void**)aValue)) {
    360    return;
    361  }
    362  xpc::InnerCleanupValue(aType, aValue, aArrayLen);
    363 }
    364 
    365 /***************************************************************************/
    366 
    367 #endif /* xpcinlines_h___ */