js/xpconnect/src/XPCInlines.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* vim: set ts=8 sts=4 et sw=4 tw=99: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 /* private inline methods (#include'd by xpcprivate.h). */
michael@0 8
michael@0 9 #ifndef xpcinlines_h___
michael@0 10 #define xpcinlines_h___
michael@0 11
michael@0 12 #include <algorithm>
michael@0 13
michael@0 14 /***************************************************************************/
michael@0 15
michael@0 16 inline void
michael@0 17 XPCJSRuntime::AddVariantRoot(XPCTraceableVariant* variant)
michael@0 18 {
michael@0 19 variant->AddToRootSet(&mVariantRoots);
michael@0 20 }
michael@0 21
michael@0 22 inline void
michael@0 23 XPCJSRuntime::AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS)
michael@0 24 {
michael@0 25 wrappedJS->AddToRootSet(&mWrappedJSRoots);
michael@0 26 }
michael@0 27
michael@0 28 inline void
michael@0 29 XPCJSRuntime::AddObjectHolderRoot(XPCJSObjectHolder* holder)
michael@0 30 {
michael@0 31 holder->AddToRootSet(&mObjectHolderRoots);
michael@0 32 }
michael@0 33
michael@0 34 /***************************************************************************/
michael@0 35
michael@0 36 inline bool
michael@0 37 XPCCallContext::IsValid() const
michael@0 38 {
michael@0 39 return mState != INIT_FAILED;
michael@0 40 }
michael@0 41
michael@0 42 inline XPCJSRuntime*
michael@0 43 XPCCallContext::GetRuntime() const
michael@0 44 {
michael@0 45 CHECK_STATE(HAVE_CONTEXT);
michael@0 46 return mXPCContext->GetRuntime();
michael@0 47 }
michael@0 48
michael@0 49 inline XPCContext*
michael@0 50 XPCCallContext::GetXPCContext() const
michael@0 51 {
michael@0 52 CHECK_STATE(HAVE_CONTEXT);
michael@0 53 return mXPCContext;
michael@0 54 }
michael@0 55
michael@0 56 inline JSContext*
michael@0 57 XPCCallContext::GetJSContext() const
michael@0 58 {
michael@0 59 CHECK_STATE(HAVE_CONTEXT);
michael@0 60 return mJSContext;
michael@0 61 }
michael@0 62
michael@0 63 inline XPCContext::LangType
michael@0 64 XPCCallContext::GetCallerLanguage() const
michael@0 65 {
michael@0 66 CHECK_STATE(HAVE_CONTEXT);
michael@0 67 return mCallerLanguage;
michael@0 68 }
michael@0 69
michael@0 70 inline XPCContext::LangType
michael@0 71 XPCCallContext::GetPrevCallerLanguage() const
michael@0 72 {
michael@0 73 CHECK_STATE(HAVE_CONTEXT);
michael@0 74 return mPrevCallerLanguage;
michael@0 75 }
michael@0 76
michael@0 77 inline XPCCallContext*
michael@0 78 XPCCallContext::GetPrevCallContext() const
michael@0 79 {
michael@0 80 CHECK_STATE(HAVE_CONTEXT);
michael@0 81 return mPrevCallContext;
michael@0 82 }
michael@0 83
michael@0 84 inline JSObject*
michael@0 85 XPCCallContext::GetFlattenedJSObject() const
michael@0 86 {
michael@0 87 CHECK_STATE(HAVE_OBJECT);
michael@0 88 return mFlattenedJSObject;
michael@0 89 }
michael@0 90
michael@0 91 inline nsISupports*
michael@0 92 XPCCallContext::GetIdentityObject() const
michael@0 93 {
michael@0 94 CHECK_STATE(HAVE_OBJECT);
michael@0 95 if (mWrapper)
michael@0 96 return mWrapper->GetIdentityObject();
michael@0 97 return mFlattenedJSObject ?
michael@0 98 static_cast<nsISupports*>(xpc_GetJSPrivate(mFlattenedJSObject)) :
michael@0 99 nullptr;
michael@0 100 }
michael@0 101
michael@0 102 inline XPCWrappedNative*
michael@0 103 XPCCallContext::GetWrapper() const
michael@0 104 {
michael@0 105 if (mState == INIT_FAILED)
michael@0 106 return nullptr;
michael@0 107
michael@0 108 CHECK_STATE(HAVE_OBJECT);
michael@0 109 return mWrapper;
michael@0 110 }
michael@0 111
michael@0 112 inline XPCWrappedNativeProto*
michael@0 113 XPCCallContext::GetProto() const
michael@0 114 {
michael@0 115 CHECK_STATE(HAVE_OBJECT);
michael@0 116 return mWrapper ? mWrapper->GetProto() : nullptr;
michael@0 117 }
michael@0 118
michael@0 119 inline bool
michael@0 120 XPCCallContext::CanGetTearOff() const
michael@0 121 {
michael@0 122 return mState >= HAVE_OBJECT;
michael@0 123 }
michael@0 124
michael@0 125 inline XPCWrappedNativeTearOff*
michael@0 126 XPCCallContext::GetTearOff() const
michael@0 127 {
michael@0 128 CHECK_STATE(HAVE_OBJECT);
michael@0 129 return mTearOff;
michael@0 130 }
michael@0 131
michael@0 132 inline XPCNativeScriptableInfo*
michael@0 133 XPCCallContext::GetScriptableInfo() const
michael@0 134 {
michael@0 135 CHECK_STATE(HAVE_OBJECT);
michael@0 136 return mScriptableInfo;
michael@0 137 }
michael@0 138
michael@0 139 inline bool
michael@0 140 XPCCallContext::CanGetSet() const
michael@0 141 {
michael@0 142 return mState >= HAVE_NAME;
michael@0 143 }
michael@0 144
michael@0 145 inline XPCNativeSet*
michael@0 146 XPCCallContext::GetSet() const
michael@0 147 {
michael@0 148 CHECK_STATE(HAVE_NAME);
michael@0 149 return mSet;
michael@0 150 }
michael@0 151
michael@0 152 inline bool
michael@0 153 XPCCallContext::CanGetInterface() const
michael@0 154 {
michael@0 155 return mState >= HAVE_NAME;
michael@0 156 }
michael@0 157
michael@0 158 inline XPCNativeInterface*
michael@0 159 XPCCallContext::GetInterface() const
michael@0 160 {
michael@0 161 CHECK_STATE(HAVE_NAME);
michael@0 162 return mInterface;
michael@0 163 }
michael@0 164
michael@0 165 inline XPCNativeMember*
michael@0 166 XPCCallContext::GetMember() const
michael@0 167 {
michael@0 168 CHECK_STATE(HAVE_NAME);
michael@0 169 return mMember;
michael@0 170 }
michael@0 171
michael@0 172 inline bool
michael@0 173 XPCCallContext::HasInterfaceAndMember() const
michael@0 174 {
michael@0 175 return mState >= HAVE_NAME && mInterface && mMember;
michael@0 176 }
michael@0 177
michael@0 178 inline jsid
michael@0 179 XPCCallContext::GetName() const
michael@0 180 {
michael@0 181 CHECK_STATE(HAVE_NAME);
michael@0 182 return mName;
michael@0 183 }
michael@0 184
michael@0 185 inline bool
michael@0 186 XPCCallContext::GetStaticMemberIsLocal() const
michael@0 187 {
michael@0 188 CHECK_STATE(HAVE_NAME);
michael@0 189 return mStaticMemberIsLocal;
michael@0 190 }
michael@0 191
michael@0 192 inline unsigned
michael@0 193 XPCCallContext::GetArgc() const
michael@0 194 {
michael@0 195 CHECK_STATE(READY_TO_CALL);
michael@0 196 return mArgc;
michael@0 197 }
michael@0 198
michael@0 199 inline jsval*
michael@0 200 XPCCallContext::GetArgv() const
michael@0 201 {
michael@0 202 CHECK_STATE(READY_TO_CALL);
michael@0 203 return mArgv;
michael@0 204 }
michael@0 205
michael@0 206 inline jsval*
michael@0 207 XPCCallContext::GetRetVal() const
michael@0 208 {
michael@0 209 CHECK_STATE(READY_TO_CALL);
michael@0 210 return mRetVal;
michael@0 211 }
michael@0 212
michael@0 213 inline void
michael@0 214 XPCCallContext::SetRetVal(jsval val)
michael@0 215 {
michael@0 216 CHECK_STATE(HAVE_ARGS);
michael@0 217 if (mRetVal)
michael@0 218 *mRetVal = val;
michael@0 219 }
michael@0 220
michael@0 221 inline jsid
michael@0 222 XPCCallContext::GetResolveName() const
michael@0 223 {
michael@0 224 CHECK_STATE(HAVE_CONTEXT);
michael@0 225 return XPCJSRuntime::Get()->GetResolveName();
michael@0 226 }
michael@0 227
michael@0 228 inline jsid
michael@0 229 XPCCallContext::SetResolveName(JS::HandleId name)
michael@0 230 {
michael@0 231 CHECK_STATE(HAVE_CONTEXT);
michael@0 232 return XPCJSRuntime::Get()->SetResolveName(name);
michael@0 233 }
michael@0 234
michael@0 235 inline XPCWrappedNative*
michael@0 236 XPCCallContext::GetResolvingWrapper() const
michael@0 237 {
michael@0 238 CHECK_STATE(HAVE_OBJECT);
michael@0 239 return XPCJSRuntime::Get()->GetResolvingWrapper();
michael@0 240 }
michael@0 241
michael@0 242 inline XPCWrappedNative*
michael@0 243 XPCCallContext::SetResolvingWrapper(XPCWrappedNative* w)
michael@0 244 {
michael@0 245 CHECK_STATE(HAVE_OBJECT);
michael@0 246 return XPCJSRuntime::Get()->SetResolvingWrapper(w);
michael@0 247 }
michael@0 248
michael@0 249 inline uint16_t
michael@0 250 XPCCallContext::GetMethodIndex() const
michael@0 251 {
michael@0 252 CHECK_STATE(HAVE_OBJECT);
michael@0 253 return mMethodIndex;
michael@0 254 }
michael@0 255
michael@0 256 inline void
michael@0 257 XPCCallContext::SetMethodIndex(uint16_t index)
michael@0 258 {
michael@0 259 CHECK_STATE(HAVE_OBJECT);
michael@0 260 mMethodIndex = index;
michael@0 261 }
michael@0 262
michael@0 263 /***************************************************************************/
michael@0 264
michael@0 265 inline const nsIID*
michael@0 266 XPCNativeInterface::GetIID() const
michael@0 267 {
michael@0 268 const nsIID* iid;
michael@0 269 return NS_SUCCEEDED(mInfo->GetIIDShared(&iid)) ? iid : nullptr;
michael@0 270 }
michael@0 271
michael@0 272 inline const char*
michael@0 273 XPCNativeInterface::GetNameString() const
michael@0 274 {
michael@0 275 const char* name;
michael@0 276 return NS_SUCCEEDED(mInfo->GetNameShared(&name)) ? name : nullptr;
michael@0 277 }
michael@0 278
michael@0 279 inline XPCNativeMember*
michael@0 280 XPCNativeInterface::FindMember(jsid name) const
michael@0 281 {
michael@0 282 const XPCNativeMember* member = mMembers;
michael@0 283 for (int i = (int) mMemberCount; i > 0; i--, member++)
michael@0 284 if (member->GetName() == name)
michael@0 285 return const_cast<XPCNativeMember*>(member);
michael@0 286 return nullptr;
michael@0 287 }
michael@0 288
michael@0 289 inline bool
michael@0 290 XPCNativeInterface::HasAncestor(const nsIID* iid) const
michael@0 291 {
michael@0 292 bool found = false;
michael@0 293 mInfo->HasAncestor(iid, &found);
michael@0 294 return found;
michael@0 295 }
michael@0 296
michael@0 297 /***************************************************************************/
michael@0 298
michael@0 299 inline bool
michael@0 300 XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember,
michael@0 301 uint16_t* pInterfaceIndex) const
michael@0 302 {
michael@0 303 XPCNativeInterface* const * iface;
michael@0 304 int count = (int) mInterfaceCount;
michael@0 305 int i;
michael@0 306
michael@0 307 // look for interface names first
michael@0 308
michael@0 309 for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
michael@0 310 if (name == (*iface)->GetName()) {
michael@0 311 if (pMember)
michael@0 312 *pMember = nullptr;
michael@0 313 if (pInterfaceIndex)
michael@0 314 *pInterfaceIndex = (uint16_t) i;
michael@0 315 return true;
michael@0 316 }
michael@0 317 }
michael@0 318
michael@0 319 // look for method names
michael@0 320 for (i = 0, iface = mInterfaces; i < count; i++, iface++) {
michael@0 321 XPCNativeMember* member = (*iface)->FindMember(name);
michael@0 322 if (member) {
michael@0 323 if (pMember)
michael@0 324 *pMember = member;
michael@0 325 if (pInterfaceIndex)
michael@0 326 *pInterfaceIndex = (uint16_t) i;
michael@0 327 return true;
michael@0 328 }
michael@0 329 }
michael@0 330 return false;
michael@0 331 }
michael@0 332
michael@0 333 inline bool
michael@0 334 XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember,
michael@0 335 XPCNativeInterface** pInterface) const
michael@0 336 {
michael@0 337 uint16_t index;
michael@0 338 if (!FindMember(name, pMember, &index))
michael@0 339 return false;
michael@0 340 *pInterface = mInterfaces[index];
michael@0 341 return true;
michael@0 342 }
michael@0 343
michael@0 344 inline bool
michael@0 345 XPCNativeSet::FindMember(jsid name,
michael@0 346 XPCNativeMember** pMember,
michael@0 347 XPCNativeInterface** pInterface,
michael@0 348 XPCNativeSet* protoSet,
michael@0 349 bool* pIsLocal) const
michael@0 350 {
michael@0 351 XPCNativeMember* Member;
michael@0 352 XPCNativeInterface* Interface;
michael@0 353 XPCNativeMember* protoMember;
michael@0 354
michael@0 355 if (!FindMember(name, &Member, &Interface))
michael@0 356 return false;
michael@0 357
michael@0 358 *pMember = Member;
michael@0 359 *pInterface = Interface;
michael@0 360
michael@0 361 *pIsLocal =
michael@0 362 !Member ||
michael@0 363 !protoSet ||
michael@0 364 (protoSet != this &&
michael@0 365 !protoSet->MatchesSetUpToInterface(this, Interface) &&
michael@0 366 (!protoSet->FindMember(name, &protoMember, (uint16_t*)nullptr) ||
michael@0 367 protoMember != Member));
michael@0 368
michael@0 369 return true;
michael@0 370 }
michael@0 371
michael@0 372 inline XPCNativeInterface*
michael@0 373 XPCNativeSet::FindNamedInterface(jsid name) const
michael@0 374 {
michael@0 375 XPCNativeInterface* const * pp = mInterfaces;
michael@0 376
michael@0 377 for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
michael@0 378 XPCNativeInterface* iface = *pp;
michael@0 379
michael@0 380 if (name == iface->GetName())
michael@0 381 return iface;
michael@0 382 }
michael@0 383 return nullptr;
michael@0 384 }
michael@0 385
michael@0 386 inline XPCNativeInterface*
michael@0 387 XPCNativeSet::FindInterfaceWithIID(const nsIID& iid) const
michael@0 388 {
michael@0 389 XPCNativeInterface* const * pp = mInterfaces;
michael@0 390
michael@0 391 for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
michael@0 392 XPCNativeInterface* iface = *pp;
michael@0 393
michael@0 394 if (iface->GetIID()->Equals(iid))
michael@0 395 return iface;
michael@0 396 }
michael@0 397 return nullptr;
michael@0 398 }
michael@0 399
michael@0 400 inline bool
michael@0 401 XPCNativeSet::HasInterface(XPCNativeInterface* aInterface) const
michael@0 402 {
michael@0 403 XPCNativeInterface* const * pp = mInterfaces;
michael@0 404
michael@0 405 for (int i = (int) mInterfaceCount; i > 0; i--, pp++) {
michael@0 406 if (aInterface == *pp)
michael@0 407 return true;
michael@0 408 }
michael@0 409 return false;
michael@0 410 }
michael@0 411
michael@0 412 inline bool
michael@0 413 XPCNativeSet::HasInterfaceWithAncestor(XPCNativeInterface* aInterface) const
michael@0 414 {
michael@0 415 return HasInterfaceWithAncestor(aInterface->GetIID());
michael@0 416 }
michael@0 417
michael@0 418 inline bool
michael@0 419 XPCNativeSet::HasInterfaceWithAncestor(const nsIID* iid) const
michael@0 420 {
michael@0 421 // We can safely skip the first interface which is *always* nsISupports.
michael@0 422 XPCNativeInterface* const * pp = mInterfaces+1;
michael@0 423 for (int i = (int) mInterfaceCount; i > 1; i--, pp++)
michael@0 424 if ((*pp)->HasAncestor(iid))
michael@0 425 return true;
michael@0 426
michael@0 427 // This is rare, so check last.
michael@0 428 if (iid == &NS_GET_IID(nsISupports))
michael@0 429 return true;
michael@0 430
michael@0 431 return false;
michael@0 432 }
michael@0 433
michael@0 434 inline bool
michael@0 435 XPCNativeSet::MatchesSetUpToInterface(const XPCNativeSet* other,
michael@0 436 XPCNativeInterface* iface) const
michael@0 437 {
michael@0 438 int count = std::min(int(mInterfaceCount), int(other->mInterfaceCount));
michael@0 439
michael@0 440 XPCNativeInterface* const * pp1 = mInterfaces;
michael@0 441 XPCNativeInterface* const * pp2 = other->mInterfaces;
michael@0 442
michael@0 443 for (int i = (int) count; i > 0; i--, pp1++, pp2++) {
michael@0 444 XPCNativeInterface* cur = (*pp1);
michael@0 445 if (cur != (*pp2))
michael@0 446 return false;
michael@0 447 if (cur == iface)
michael@0 448 return true;
michael@0 449 }
michael@0 450 return false;
michael@0 451 }
michael@0 452
michael@0 453 inline void XPCNativeSet::Mark()
michael@0 454 {
michael@0 455 if (IsMarked())
michael@0 456 return;
michael@0 457
michael@0 458 XPCNativeInterface* const * pp = mInterfaces;
michael@0 459
michael@0 460 for (int i = (int) mInterfaceCount; i > 0; i--, pp++)
michael@0 461 (*pp)->Mark();
michael@0 462
michael@0 463 MarkSelfOnly();
michael@0 464 }
michael@0 465
michael@0 466 #ifdef DEBUG
michael@0 467 inline void XPCNativeSet::ASSERT_NotMarked()
michael@0 468 {
michael@0 469 MOZ_ASSERT(!IsMarked(), "bad");
michael@0 470
michael@0 471 XPCNativeInterface* const * pp = mInterfaces;
michael@0 472
michael@0 473 for (int i = (int) mInterfaceCount; i > 0; i--, pp++)
michael@0 474 MOZ_ASSERT(!(*pp)->IsMarked(), "bad");
michael@0 475 }
michael@0 476 #endif
michael@0 477
michael@0 478 /***************************************************************************/
michael@0 479
michael@0 480 inline
michael@0 481 JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const
michael@0 482 {
michael@0 483 return reinterpret_cast<JSObject *>(reinterpret_cast<uintptr_t>(mJSObject) & ~1);
michael@0 484 }
michael@0 485
michael@0 486 inline
michael@0 487 JSObject* XPCWrappedNativeTearOff::GetJSObject()
michael@0 488 {
michael@0 489 JSObject *obj = GetJSObjectPreserveColor();
michael@0 490 if (obj) {
michael@0 491 JS::ExposeObjectToActiveJS(obj);
michael@0 492 }
michael@0 493 return obj;
michael@0 494 }
michael@0 495
michael@0 496 inline
michael@0 497 void XPCWrappedNativeTearOff::SetJSObject(JSObject* JSObj)
michael@0 498 {
michael@0 499 MOZ_ASSERT(!IsMarked());
michael@0 500 mJSObject = JSObj;
michael@0 501 }
michael@0 502
michael@0 503 inline
michael@0 504 XPCWrappedNativeTearOff::~XPCWrappedNativeTearOff()
michael@0 505 {
michael@0 506 MOZ_ASSERT(!(GetInterface() || GetNative() || GetJSObjectPreserveColor()),
michael@0 507 "tearoff not empty in dtor");
michael@0 508 }
michael@0 509
michael@0 510 /***************************************************************************/
michael@0 511
michael@0 512 inline bool
michael@0 513 XPCWrappedNative::HasInterfaceNoQI(const nsIID& iid)
michael@0 514 {
michael@0 515 return nullptr != GetSet()->FindInterfaceWithIID(iid);
michael@0 516 }
michael@0 517
michael@0 518 inline void
michael@0 519 XPCWrappedNative::SweepTearOffs()
michael@0 520 {
michael@0 521 XPCWrappedNativeTearOffChunk* chunk;
michael@0 522 for (chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk) {
michael@0 523 XPCWrappedNativeTearOff* to = chunk->mTearOffs;
michael@0 524 for (int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK; i > 0; i--, to++) {
michael@0 525 bool marked = to->IsMarked();
michael@0 526 to->Unmark();
michael@0 527 if (marked)
michael@0 528 continue;
michael@0 529
michael@0 530 // If this tearoff does not have a live dedicated JSObject,
michael@0 531 // then let's recycle it.
michael@0 532 if (!to->GetJSObjectPreserveColor()) {
michael@0 533 nsISupports* obj = to->GetNative();
michael@0 534 if (obj) {
michael@0 535 obj->Release();
michael@0 536 to->SetNative(nullptr);
michael@0 537 }
michael@0 538 to->SetInterface(nullptr);
michael@0 539 }
michael@0 540 }
michael@0 541 }
michael@0 542 }
michael@0 543
michael@0 544 /***************************************************************************/
michael@0 545
michael@0 546 inline bool
michael@0 547 xpc_ForcePropertyResolve(JSContext* cx, JS::HandleObject obj, jsid idArg)
michael@0 548 {
michael@0 549 JS::RootedValue prop(cx);
michael@0 550 JS::RootedId id(cx, idArg);
michael@0 551
michael@0 552 if (!JS_LookupPropertyById(cx, obj, id, &prop))
michael@0 553 return false;
michael@0 554 return true;
michael@0 555 }
michael@0 556
michael@0 557 inline jsid
michael@0 558 GetRTIdByIndex(JSContext *cx, unsigned index)
michael@0 559 {
michael@0 560 XPCJSRuntime *rt = nsXPConnect::XPConnect()->GetRuntime();
michael@0 561 return rt->GetStringID(index);
michael@0 562 }
michael@0 563
michael@0 564 inline
michael@0 565 bool ThrowBadParam(nsresult rv, unsigned paramNum, XPCCallContext& ccx)
michael@0 566 {
michael@0 567 XPCThrower::ThrowBadParam(rv, paramNum, ccx);
michael@0 568 return false;
michael@0 569 }
michael@0 570
michael@0 571 inline
michael@0 572 void ThrowBadResult(nsresult result, XPCCallContext& ccx)
michael@0 573 {
michael@0 574 XPCThrower::ThrowBadResult(NS_ERROR_XPC_NATIVE_RETURNED_FAILURE,
michael@0 575 result, ccx);
michael@0 576 }
michael@0 577
michael@0 578 /***************************************************************************/
michael@0 579
michael@0 580 #endif /* xpcinlines_h___ */

mercurial