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___ */