PageRenderTime 101ms CodeModel.GetById 14ms app.highlight 39ms RepoModel.GetById 16ms app.codeStats 1ms

/gecko_api/include/nsISupportsImpl.h

http://firefox-mac-pdf.googlecode.com/
C++ Header | 1346 lines | 960 code | 194 blank | 192 comment | 45 complexity | b99377a3e463a67cf34e0f8031c3901b MD5 | raw file
   1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
   2/* ***** BEGIN LICENSE BLOCK *****
   3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
   4 *
   5 * The contents of this file are subject to the Mozilla Public License Version
   6 * 1.1 (the "License"); you may not use this file except in compliance with
   7 * the License. You may obtain a copy of the License at
   8 * http://www.mozilla.org/MPL/
   9 *
  10 * Software distributed under the License is distributed on an "AS IS" basis,
  11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12 * for the specific language governing rights and limitations under the
  13 * License.
  14 *
  15 * The Original Code is XPCOM.
  16 *
  17 * The Initial Developer of the Original Code is Netscape Communications Corp.
  18 * Portions created by the Initial Developer are Copyright (C) 2001
  19 * the Initial Developer. All Rights Reserved.
  20 *
  21 * Contributor(s):
  22 *
  23 * Alternatively, the contents of this file may be used under the terms of
  24 * either the GNU General Public License Version 2 or later (the "GPL"), or
  25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  26 * in which case the provisions of the GPL or the LGPL are applicable instead
  27 * of those above. If you wish to allow use of your version of this file only
  28 * under the terms of either the GPL or the LGPL, and not to allow others to
  29 * use your version of this file under the terms of the MPL, indicate your
  30 * decision by deleting the provisions above and replace them with the notice
  31 * and other provisions required by the GPL or the LGPL. If you do not delete
  32 * the provisions above, a recipient may use your version of this file under
  33 * the terms of any one of the MPL, the GPL or the LGPL.
  34 *
  35 * ***** END LICENSE BLOCK ***** */
  36
  37
  38#ifndef nsISupportsImpl_h__
  39#define nsISupportsImpl_h__
  40
  41#ifndef nscore_h___
  42#include "nscore.h"
  43#endif
  44
  45#ifndef nsISupportsBase_h__
  46#include "nsISupportsBase.h"
  47#endif
  48
  49#ifndef nsISupportsUtils_h__
  50#include "nsISupportsUtils.h"
  51#endif
  52
  53
  54#if !defined(XPCOM_GLUE_AVOID_NSPR)
  55#include "prthread.h" /* needed for thread-safety checks */
  56#include "pratom.h"   /* needed for PR_AtomicIncrement and PR_AtomicDecrement */
  57#endif
  58
  59#include "nsDebug.h"
  60#include "nsTraceRefcnt.h"
  61#include "nsCycleCollector.h"
  62
  63////////////////////////////////////////////////////////////////////////////////
  64// Macros to help detect thread-safety:
  65
  66#if defined(NS_DEBUG) && !defined(XPCOM_GLUE_AVOID_NSPR)
  67
  68class nsAutoOwningThread {
  69public:
  70    nsAutoOwningThread() { mThread = PR_GetCurrentThread(); }
  71    void *GetThread() const { return mThread; }
  72
  73private:
  74    void *mThread;
  75};
  76
  77#define NS_DECL_OWNINGTHREAD            nsAutoOwningThread _mOwningThread;
  78#define NS_ASSERT_OWNINGTHREAD(_class) \
  79  NS_CheckThreadSafe(_mOwningThread.GetThread(), #_class " not thread-safe")
  80
  81#else // !NS_DEBUG
  82
  83#define NS_DECL_OWNINGTHREAD            /* nothing */
  84#define NS_ASSERT_OWNINGTHREAD(_class)  ((void)0)
  85
  86#endif // NS_DEBUG
  87
  88#define NS_PURPLE_BIT ((PRUint32)(1 << 31))
  89
  90#define NS_PURPLE_MASK (~NS_PURPLE_BIT)
  91#define NS_PURPLE_BIT_SET(x) ((x) & (NS_PURPLE_BIT))
  92#define NS_CLEAR_PURPLE_BIT(x) ((x) &= (NS_PURPLE_MASK))
  93#define NS_VALUE_WITHOUT_PURPLE_BIT(x) ((x) & (NS_PURPLE_MASK))
  94
  95
  96// Support for ISupports classes which interact with cycle collector.
  97
  98class nsCycleCollectingAutoRefCnt {
  99
 100public:
 101  nsCycleCollectingAutoRefCnt()
 102    : mValue(0)
 103  {}
 104
 105  nsCycleCollectingAutoRefCnt(nsrefcnt aValue)
 106    : mValue(aValue)
 107  {
 108    NS_CLEAR_PURPLE_BIT(mValue);
 109  }
 110
 111  nsrefcnt incr(nsISupports *owner)
 112  {
 113    if (NS_UNLIKELY(mValue == NS_PURPLE_BIT)) {
 114      // The sentinel value "purple bit alone, refcount 0" means
 115      // that we're stabilized, during finalization. In this
 116      // state we lie about our actual refcount if anyone asks
 117      // and say it's 2, which is basically true: the caller who
 118      // is incrementing has a reference, as does the decr() frame
 119      // that stabilized-and-is-deleting us.
 120      return 2;
 121    }
 122
 123    nsrefcnt tmp = get();
 124    PRBool purple = static_cast<PRBool>(NS_PURPLE_BIT_SET(mValue));
 125
 126    if (NS_UNLIKELY(purple)) {
 127      NS_ASSERTION(tmp != 0, "purple ISupports pointer with zero refcnt");
 128      if (!NS_CycleCollectorForget(owner))
 129        tmp |= NS_PURPLE_BIT;
 130    }
 131
 132    mValue = tmp + 1;
 133    return mValue;
 134  }
 135
 136  void stabilizeForDeletion(nsISupports *owner)
 137  {
 138    mValue = NS_PURPLE_BIT;
 139  }
 140
 141  nsrefcnt decr(nsISupports *owner)
 142  {
 143    if (NS_UNLIKELY(mValue == NS_PURPLE_BIT))
 144      return 1;
 145
 146    nsrefcnt tmp = get();
 147    NS_ASSERTION(tmp >= 1, "decr() called with zero refcnt");
 148
 149    PRBool purple = static_cast<PRBool>(NS_PURPLE_BIT_SET(mValue));
 150    PRBool shouldBePurple = tmp > 1;
 151
 152    if (NS_UNLIKELY(shouldBePurple && !purple)) {
 153      if (!NS_CycleCollectorSuspect(owner))
 154        shouldBePurple = PR_FALSE;
 155    } else if (NS_UNLIKELY(tmp == 1 && purple)) {
 156      if (!NS_CycleCollectorForget(owner)) {
 157        NS_NOTREACHED("forget should not fail when reference count hits 0");
 158      }
 159    }
 160
 161    --tmp;
 162
 163    if (shouldBePurple)
 164      mValue = tmp | NS_PURPLE_BIT;
 165    else
 166      mValue = tmp;
 167
 168    return tmp;
 169  }
 170
 171  void unmarkPurple()
 172  {
 173    if (NS_LIKELY(mValue != NS_PURPLE_BIT))
 174      NS_CLEAR_PURPLE_BIT(mValue);
 175  }
 176
 177  nsrefcnt get() const
 178  {
 179    if (NS_UNLIKELY(mValue == NS_PURPLE_BIT))
 180      return 1;
 181
 182    return NS_VALUE_WITHOUT_PURPLE_BIT(mValue);
 183  }
 184
 185  operator nsrefcnt() const
 186  {
 187    return get();
 188  }
 189
 190 private:
 191  nsrefcnt mValue;
 192};
 193
 194class nsAutoRefCnt {
 195
 196 public:
 197    nsAutoRefCnt() : mValue(0) {}
 198    nsAutoRefCnt(nsrefcnt aValue) : mValue(aValue) {}
 199
 200    // only support prefix increment/decrement
 201    nsrefcnt operator++() { return ++mValue; }
 202    nsrefcnt operator--() { return --mValue; }
 203
 204    nsrefcnt operator=(nsrefcnt aValue) { return (mValue = aValue); }
 205    operator nsrefcnt() const { return mValue; }
 206    nsrefcnt get() const { return mValue; }
 207 private:
 208    // do not define these to enforce the faster prefix notation
 209    nsrefcnt operator++(int);
 210    nsrefcnt operator--(int);
 211    nsrefcnt mValue;
 212};
 213
 214///////////////////////////////////////////////////////////////////////////////
 215
 216/**
 217 * Declare the reference count variable and the implementations of the
 218 * AddRef and QueryInterface methods.
 219 */
 220
 221#define NS_DECL_ISUPPORTS                                                     \
 222public:                                                                       \
 223  NS_IMETHOD QueryInterface(REFNSIID aIID,                                    \
 224                            void** aInstancePtr);                             \
 225  NS_IMETHOD_(nsrefcnt) AddRef(void);                                         \
 226  NS_IMETHOD_(nsrefcnt) Release(void);                                        \
 227protected:                                                                    \
 228  nsAutoRefCnt mRefCnt;                                                       \
 229  NS_DECL_OWNINGTHREAD                                                        \
 230public:
 231
 232#define NS_DECL_CYCLE_COLLECTING_ISUPPORTS                                    \
 233public:                                                                       \
 234  NS_IMETHOD QueryInterface(REFNSIID aIID,                                    \
 235                            void** aInstancePtr);                             \
 236  NS_IMETHOD_(nsrefcnt) AddRef(void);                                         \
 237  NS_IMETHOD_(nsrefcnt) Release(void);                                        \
 238  void UnmarkPurple()                                                         \
 239  {                                                                           \
 240    mRefCnt.unmarkPurple();                                                   \
 241  }                                                                           \
 242protected:                                                                    \
 243  nsCycleCollectingAutoRefCnt mRefCnt;                                        \
 244  NS_DECL_OWNINGTHREAD                                                        \
 245public:
 246
 247
 248///////////////////////////////////////////////////////////////////////////////
 249
 250/**
 251 * Previously used to initialize the reference count, but no longer needed.
 252 *
 253 * DEPRECATED.
 254 */
 255#define NS_INIT_ISUPPORTS() ((void)0)
 256
 257/**
 258 * Use this macro to implement the AddRef method for a given <i>_class</i>
 259 * @param _class The name of the class implementing the method
 260 */
 261#define NS_IMPL_ADDREF(_class)                                                \
 262NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void)                                 \
 263{                                                                             \
 264  NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");                   \
 265  NS_ASSERT_OWNINGTHREAD(_class);                                             \
 266  ++mRefCnt;                                                                  \
 267  NS_LOG_ADDREF(this, mRefCnt, #_class, sizeof(*this));                       \
 268  return mRefCnt;                                                             \
 269}
 270
 271/**
 272 * Use this macro to implement the AddRef method for a given <i>_class</i>
 273 * implemented as a wholly owned aggregated object intended to implement
 274 * interface(s) for its owner
 275 * @param _class The name of the class implementing the method
 276 * @param _aggregator the owning/containing object
 277 */
 278#define NS_IMPL_ADDREF_USING_AGGREGATOR(_class, _aggregator)                  \
 279NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void)                                 \
 280{                                                                             \
 281  NS_PRECONDITION(_aggregator, "null aggregator");                            \
 282  return (_aggregator)->AddRef();                                             \
 283}
 284
 285/**
 286 * Use this macro to implement the Release method for a given
 287 * <i>_class</i>.
 288 * @param _class The name of the class implementing the method
 289 * @param _destroy A statement that is executed when the object's
 290 *   refcount drops to zero.
 291 *
 292 * For example,
 293 *
 294 *   NS_IMPL_RELEASE_WITH_DESTROY(Foo, Destroy(this))
 295 *
 296 * will cause
 297 *
 298 *   Destroy(this);
 299 *
 300 * to be invoked when the object's refcount drops to zero. This
 301 * allows for arbitrary teardown activity to occur (e.g., deallocation
 302 * of object allocated with placement new).
 303 */
 304#define NS_IMPL_RELEASE_WITH_DESTROY(_class, _destroy)                        \
 305NS_IMETHODIMP_(nsrefcnt) _class::Release(void)                                \
 306{                                                                             \
 307  NS_PRECONDITION(0 != mRefCnt, "dup release");                               \
 308  NS_ASSERT_OWNINGTHREAD(_class);                                             \
 309  --mRefCnt;                                                                  \
 310  NS_LOG_RELEASE(this, mRefCnt, #_class);                                     \
 311  if (mRefCnt == 0) {                                                         \
 312    mRefCnt = 1; /* stabilize */                                              \
 313    _destroy;                                                                 \
 314    return 0;                                                                 \
 315  }                                                                           \
 316  return mRefCnt;                                                             \
 317}
 318
 319/**
 320 * Use this macro to implement the Release method for a given <i>_class</i>
 321 * @param _class The name of the class implementing the method
 322 *
 323 * A note on the 'stabilization' of the refcnt to one. At that point,
 324 * the object's refcount will have gone to zero. The object's
 325 * destructor may trigger code that attempts to QueryInterface() and
 326 * Release() 'this' again. Doing so will temporarily increment and
 327 * decrement the refcount. (Only a logic error would make one try to
 328 * keep a permanent hold on 'this'.)  To prevent re-entering the
 329 * destructor, we make sure that no balanced refcounting can return
 330 * the refcount to |0|.
 331 */
 332#define NS_IMPL_RELEASE(_class) \
 333  NS_IMPL_RELEASE_WITH_DESTROY(_class, NS_DELETEXPCOM(this))
 334
 335/**
 336 * Use this macro to implement the Release method for a given <i>_class</i>
 337 * implemented as a wholly owned aggregated object intended to implement
 338 * interface(s) for its owner
 339 * @param _class The name of the class implementing the method
 340 * @param _aggregator the owning/containing object
 341 */
 342#define NS_IMPL_RELEASE_USING_AGGREGATOR(_class, _aggregator)                 \
 343NS_IMETHODIMP_(nsrefcnt) _class::Release(void)                                \
 344{                                                                             \
 345  NS_PRECONDITION(_aggregator, "null aggregator");                            \
 346  return (_aggregator)->Release();                                            \
 347}
 348
 349
 350#define NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(_class, _basetype)          \
 351NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void)                                 \
 352{                                                                             \
 353  NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");                   \
 354  NS_ASSERT_OWNINGTHREAD(_class);                                             \
 355  nsrefcnt count =                                                            \
 356    mRefCnt.incr(NS_CYCLE_COLLECTION_CLASSNAME(_class)::Upcast(this));        \
 357  NS_LOG_ADDREF(this, count, #_class, sizeof(*this));                         \
 358  return count;                                                               \
 359}
 360
 361#define NS_IMPL_CYCLE_COLLECTING_ADDREF(_class)      \
 362  NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(_class, _class)
 363
 364#define NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(_class, _basetype, _destroy)    \
 365NS_IMETHODIMP_(nsrefcnt) _class::Release(void)                                \
 366{                                                                             \
 367  NS_PRECONDITION(0 != mRefCnt, "dup release");                               \
 368  NS_ASSERT_OWNINGTHREAD(_class);                                             \
 369  nsISupports *base = NS_CYCLE_COLLECTION_CLASSNAME(_class)::Upcast(this);    \
 370  nsrefcnt count = mRefCnt.decr(base);                                        \
 371  NS_LOG_RELEASE(this, count, #_class);                                       \
 372  if (count == 0) {                                                           \
 373    mRefCnt.stabilizeForDeletion(base);                                       \
 374    _destroy;                                                                 \
 375    return 0;                                                                 \
 376  }                                                                           \
 377  return count;                                                               \
 378}
 379
 380#define NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(_class, _destroy)       \
 381  NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(_class, _class, _destroy)
 382
 383#define NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS_WITH_DESTROY(_class, _basetype, _destroy)         \
 384  NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(_class, _basetype, _destroy)
 385
 386#define NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(_class, _basetype)         \
 387  NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(_class, _basetype, NS_DELETEXPCOM(this))
 388
 389#define NS_IMPL_CYCLE_COLLECTING_RELEASE(_class)       \
 390  NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(_class, _class, NS_DELETEXPCOM(this))
 391
 392
 393///////////////////////////////////////////////////////////////////////////////
 394
 395/**
 396 * There are two ways of implementing QueryInterface, and we use both:
 397 *
 398 * Table-driven QueryInterface uses a static table of IID->offset mappings
 399 * and a shared helper function. Using it tends to reduce codesize and improve
 400 * runtime performance (due to processor cache hits).
 401 *
 402 * Macro-driven QueryInterface generates a QueryInterface function directly
 403 * using common macros. This is necessary if special QueryInterface features
 404 * are being used (such as tearoffs and conditional interfaces).
 405 *
 406 * These methods can be combined into a table-driven function call followed
 407 * by custom code for tearoffs and conditionals.
 408 */
 409
 410struct QITableEntry
 411{
 412  const nsIID *iid;     // null indicates end of the QITableEntry array
 413  PROffset32   offset;
 414};
 415
 416NS_COM_GLUE nsresult NS_FASTCALL
 417NS_TableDrivenQI(void* aThis, const QITableEntry* entries,
 418                 REFNSIID aIID, void **aInstancePtr);
 419
 420/**
 421 * Implement table-driven queryinterface
 422 */
 423
 424#define NS_INTERFACE_TABLE_HEAD(_class)                                       \
 425NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr)      \
 426{                                                                             \
 427  NS_ASSERTION(aInstancePtr,                                                  \
 428               "QueryInterface requires a non-NULL destination!");            \
 429  nsresult rv = NS_ERROR_FAILURE;
 430
 431#define NS_INTERFACE_TABLE_BEGIN                                              \
 432  static const QITableEntry table[] = {
 433
 434#define NS_INTERFACE_TABLE_ENTRY(_class, _interface)                          \
 435  { &_interface::COMTypeInfo<int>::kIID,                                      \
 436    PROffset32(reinterpret_cast<char*>(                                       \
 437                        static_cast<_interface*>((_class*) 0x1000)) -         \
 438               reinterpret_cast<char*>((_class*) 0x1000))                     \
 439  },
 440
 441#define NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, _interface, _implClass)    \
 442  { &_interface::COMTypeInfo<int>::kIID,                                      \
 443    PROffset32(reinterpret_cast<char*>(                                       \
 444                        static_cast<_interface*>(                             \
 445                                       static_cast<_implClass*>(              \
 446                                                      (_class*) 0x1000))) -   \
 447               reinterpret_cast<char*>((_class*) 0x1000))                     \
 448  },
 449
 450#define NS_INTERFACE_TABLE_END_WITH_PTR(_ptr)                                 \
 451  { nsnull, 0 } };                                                            \
 452  rv = NS_TableDrivenQI(static_cast<void*>(_ptr),                             \
 453                        table, aIID, aInstancePtr);
 454
 455#define NS_INTERFACE_TABLE_END                                                \
 456  NS_INTERFACE_TABLE_END_WITH_PTR(this)
 457
 458#define NS_INTERFACE_TABLE_TAIL                                               \
 459  return rv;                                                                  \
 460}
 461
 462#define NS_INTERFACE_TABLE_TAIL_INHERITING(_baseclass)                        \
 463  if (NS_SUCCEEDED(rv))                                                       \
 464    return rv;                                                                \
 465  return _baseclass::QueryInterface(aIID, aInstancePtr);                      \
 466}
 467
 468#define NS_INTERFACE_TABLE_TAIL_USING_AGGREGATOR(_aggregator)                 \
 469  if (NS_SUCCEEDED(rv))                                                       \
 470    return rv;                                                                \
 471  NS_ASSERTION(_aggregator, "null aggregator");                               \
 472  return _aggregator->QueryInterface(aIID, aInstancePtr)                      \
 473}
 474
 475/**
 476 * This implements query interface with two assumptions: First, the
 477 * class in question implements nsISupports and its own interface and
 478 * nothing else. Second, the implementation of the class's primary
 479 * inheritance chain leads to its own interface.
 480 *
 481 * @param _class The name of the class implementing the method
 482 * @param _classiiddef The name of the #define symbol that defines the IID
 483 * for the class (e.g. NS_ISUPPORTS_IID)
 484 */
 485
 486#define NS_IMPL_QUERY_HEAD(_class)                                            \
 487NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr)      \
 488{                                                                             \
 489  NS_ASSERTION(aInstancePtr,                                                  \
 490               "QueryInterface requires a non-NULL destination!");            \
 491  nsISupports* foundInterface;
 492
 493#define NS_IMPL_QUERY_BODY(_interface)                                        \
 494  if ( aIID.Equals(NS_GET_IID(_interface)) )                                  \
 495    foundInterface = static_cast<_interface*>(this);                          \
 496  else
 497
 498#define NS_IMPL_QUERY_BODY_CONDITIONAL(_interface, condition)                 \
 499  if ( (condition) && aIID.Equals(NS_GET_IID(_interface)))                    \
 500    foundInterface = static_cast<_interface*>(this);                          \
 501  else
 502
 503#define NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass)                  \
 504  if ( aIID.Equals(NS_GET_IID(_interface)) )                                  \
 505    foundInterface = static_cast<_interface*>(                                \
 506                                    static_cast<_implClass*>(this));          \
 507  else
 508
 509#define NS_IMPL_QUERY_BODY_AGGREGATED(_interface, _aggregate)                 \
 510  if ( aIID.Equals(NS_GET_IID(_interface)) )                                  \
 511    foundInterface = static_cast<_interface*>(_aggregate);                    \
 512  else
 513
 514#define NS_IMPL_QUERY_TAIL_GUTS                                               \
 515    foundInterface = 0;                                                       \
 516  nsresult status;                                                            \
 517  if ( !foundInterface )                                                      \
 518    status = NS_NOINTERFACE;                                                  \
 519  else                                                                        \
 520    {                                                                         \
 521      NS_ADDREF(foundInterface);                                              \
 522      status = NS_OK;                                                         \
 523    }                                                                         \
 524  *aInstancePtr = foundInterface;                                             \
 525  return status;                                                              \
 526}
 527
 528#define NS_IMPL_QUERY_TAIL_INHERITING(_baseclass)                             \
 529    foundInterface = 0;                                                       \
 530  nsresult status;                                                            \
 531  if ( !foundInterface )                                                      \
 532    status = _baseclass::QueryInterface(aIID, (void**)&foundInterface);       \
 533  else                                                                        \
 534    {                                                                         \
 535      NS_ADDREF(foundInterface);                                              \
 536      status = NS_OK;                                                         \
 537    }                                                                         \
 538  *aInstancePtr = foundInterface;                                             \
 539  return status;                                                              \
 540}
 541
 542#define NS_IMPL_QUERY_TAIL_USING_AGGREGATOR(_aggregator)                      \
 543    foundInterface = 0;                                                       \
 544  nsresult status;                                                            \
 545  if ( !foundInterface ) {                                                    \
 546    NS_ASSERTION(_aggregator, "null aggregator");                             \
 547    status = _aggregator->QueryInterface(aIID, (void**)&foundInterface);      \
 548  } else                                                                      \
 549    {                                                                         \
 550      NS_ADDREF(foundInterface);                                              \
 551      status = NS_OK;                                                         \
 552    }                                                                         \
 553  *aInstancePtr = foundInterface;                                             \
 554  return status;                                                              \
 555}
 556
 557#define NS_IMPL_QUERY_TAIL(_supports_interface)                               \
 558  NS_IMPL_QUERY_BODY_AMBIGUOUS(nsISupports, _supports_interface)              \
 559  NS_IMPL_QUERY_TAIL_GUTS
 560
 561
 562  /*
 563    This is the new scheme.  Using this notation now will allow us to switch to
 564    a table driven mechanism when it's ready.  Note the difference between this
 565    and the (currently) underlying NS_IMPL_QUERY_INTERFACE mechanism.  You must
 566    explicitly mention |nsISupports| when using the interface maps.
 567  */
 568#define NS_INTERFACE_MAP_BEGIN(_implClass)      NS_IMPL_QUERY_HEAD(_implClass)
 569#define NS_INTERFACE_MAP_ENTRY(_interface)      NS_IMPL_QUERY_BODY(_interface)
 570#define NS_INTERFACE_MAP_ENTRY_CONDITIONAL(_interface, condition)             \
 571  NS_IMPL_QUERY_BODY_CONDITIONAL(_interface, condition)
 572#define NS_INTERFACE_MAP_ENTRY_AGGREGATED(_interface,_aggregate)              \
 573  NS_IMPL_QUERY_BODY_AGGREGATED(_interface,_aggregate)
 574
 575#define NS_INTERFACE_MAP_END                    NS_IMPL_QUERY_TAIL_GUTS
 576#define NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(_interface, _implClass)              \
 577  NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass)
 578#define NS_INTERFACE_MAP_END_INHERITING(_baseClass)                           \
 579  NS_IMPL_QUERY_TAIL_INHERITING(_baseClass)
 580#define NS_INTERFACE_MAP_END_AGGREGATED(_aggregator)                          \
 581  NS_IMPL_QUERY_TAIL_USING_AGGREGATOR(_aggregator)
 582
 583#define NS_INTERFACE_TABLE0(_class)                                           \
 584  NS_INTERFACE_TABLE_BEGIN                                                    \
 585    NS_INTERFACE_TABLE_ENTRY(_class, nsISupports)                             \
 586  NS_INTERFACE_TABLE_END
 587
 588#define NS_INTERFACE_TABLE1(_class, _i1)                                      \
 589  NS_INTERFACE_TABLE_BEGIN                                                    \
 590    NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
 591    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1)              \
 592  NS_INTERFACE_TABLE_END
 593
 594#define NS_INTERFACE_TABLE2(_class, _i1, _i2)                                 \
 595  NS_INTERFACE_TABLE_BEGIN                                                    \
 596    NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
 597    NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
 598    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1)              \
 599  NS_INTERFACE_TABLE_END
 600
 601#define NS_INTERFACE_TABLE3(_class, _i1, _i2, _i3)                            \
 602  NS_INTERFACE_TABLE_BEGIN                                                    \
 603    NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
 604    NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
 605    NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
 606    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1)              \
 607  NS_INTERFACE_TABLE_END
 608
 609#define NS_INTERFACE_TABLE4(_class, _i1, _i2, _i3, _i4)                       \
 610  NS_INTERFACE_TABLE_BEGIN                                                    \
 611    NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
 612    NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
 613    NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
 614    NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
 615    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1)              \
 616  NS_INTERFACE_TABLE_END
 617
 618#define NS_INTERFACE_TABLE5(_class, _i1, _i2, _i3, _i4, _i5)                  \
 619  NS_INTERFACE_TABLE_BEGIN                                                    \
 620    NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
 621    NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
 622    NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
 623    NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
 624    NS_INTERFACE_TABLE_ENTRY(_class, _i5)                                     \
 625    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1)              \
 626  NS_INTERFACE_TABLE_END
 627
 628#define NS_INTERFACE_TABLE6(_class, _i1, _i2, _i3, _i4, _i5, _i6)             \
 629  NS_INTERFACE_TABLE_BEGIN                                                    \
 630    NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
 631    NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
 632    NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
 633    NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
 634    NS_INTERFACE_TABLE_ENTRY(_class, _i5)                                     \
 635    NS_INTERFACE_TABLE_ENTRY(_class, _i6)                                     \
 636    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1)              \
 637  NS_INTERFACE_TABLE_END
 638
 639#define NS_INTERFACE_TABLE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7)        \
 640  NS_INTERFACE_TABLE_BEGIN                                                    \
 641    NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
 642    NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
 643    NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
 644    NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
 645    NS_INTERFACE_TABLE_ENTRY(_class, _i5)                                     \
 646    NS_INTERFACE_TABLE_ENTRY(_class, _i6)                                     \
 647    NS_INTERFACE_TABLE_ENTRY(_class, _i7)                                     \
 648    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1)              \
 649  NS_INTERFACE_TABLE_END
 650
 651#define NS_INTERFACE_TABLE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8)   \
 652  NS_INTERFACE_TABLE_BEGIN                                                    \
 653    NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
 654    NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
 655    NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
 656    NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
 657    NS_INTERFACE_TABLE_ENTRY(_class, _i5)                                     \
 658    NS_INTERFACE_TABLE_ENTRY(_class, _i6)                                     \
 659    NS_INTERFACE_TABLE_ENTRY(_class, _i7)                                     \
 660    NS_INTERFACE_TABLE_ENTRY(_class, _i8)                                     \
 661    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1)              \
 662  NS_INTERFACE_TABLE_END
 663
 664#define NS_INTERFACE_TABLE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7,        \
 665                            _i8, _i9)                                         \
 666  NS_INTERFACE_TABLE_BEGIN                                                    \
 667    NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
 668    NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
 669    NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
 670    NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
 671    NS_INTERFACE_TABLE_ENTRY(_class, _i5)                                     \
 672    NS_INTERFACE_TABLE_ENTRY(_class, _i6)                                     \
 673    NS_INTERFACE_TABLE_ENTRY(_class, _i7)                                     \
 674    NS_INTERFACE_TABLE_ENTRY(_class, _i8)                                     \
 675    NS_INTERFACE_TABLE_ENTRY(_class, _i9)                                     \
 676    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1)              \
 677  NS_INTERFACE_TABLE_END
 678
 679#define NS_INTERFACE_TABLE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7,       \
 680                             _i8, _i9, _i10)                                  \
 681  NS_INTERFACE_TABLE_BEGIN                                                    \
 682    NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
 683    NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
 684    NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
 685    NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
 686    NS_INTERFACE_TABLE_ENTRY(_class, _i5)                                     \
 687    NS_INTERFACE_TABLE_ENTRY(_class, _i6)                                     \
 688    NS_INTERFACE_TABLE_ENTRY(_class, _i7)                                     \
 689    NS_INTERFACE_TABLE_ENTRY(_class, _i8)                                     \
 690    NS_INTERFACE_TABLE_ENTRY(_class, _i9)                                     \
 691    NS_INTERFACE_TABLE_ENTRY(_class, _i10)                                    \
 692    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1)              \
 693  NS_INTERFACE_TABLE_END
 694
 695#define NS_INTERFACE_TABLE11(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7,       \
 696                             _i8, _i9, _i10, _i11)                            \
 697  NS_INTERFACE_TABLE_BEGIN                                                    \
 698    NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
 699    NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
 700    NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
 701    NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
 702    NS_INTERFACE_TABLE_ENTRY(_class, _i5)                                     \
 703    NS_INTERFACE_TABLE_ENTRY(_class, _i6)                                     \
 704    NS_INTERFACE_TABLE_ENTRY(_class, _i7)                                     \
 705    NS_INTERFACE_TABLE_ENTRY(_class, _i8)                                     \
 706    NS_INTERFACE_TABLE_ENTRY(_class, _i9)                                     \
 707    NS_INTERFACE_TABLE_ENTRY(_class, _i10)                                    \
 708    NS_INTERFACE_TABLE_ENTRY(_class, _i11)                                    \
 709    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1)              \
 710  NS_INTERFACE_TABLE_END
 711
 712#define NS_IMPL_QUERY_INTERFACE0(_class)                                      \
 713  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 714  NS_INTERFACE_TABLE0(_class)                                                 \
 715  NS_INTERFACE_TABLE_TAIL
 716
 717#define NS_IMPL_QUERY_INTERFACE1(_class, _i1)                                 \
 718  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 719  NS_INTERFACE_TABLE1(_class, _i1)                                            \
 720  NS_INTERFACE_TABLE_TAIL
 721
 722#define NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2)                            \
 723  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 724  NS_INTERFACE_TABLE2(_class, _i1, _i2)                                       \
 725  NS_INTERFACE_TABLE_TAIL
 726
 727#define NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3)                       \
 728  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 729  NS_INTERFACE_TABLE3(_class, _i1, _i2, _i3)                                  \
 730  NS_INTERFACE_TABLE_TAIL
 731
 732#define NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4)                  \
 733  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 734  NS_INTERFACE_TABLE4(_class, _i1, _i2, _i3, _i4)                             \
 735  NS_INTERFACE_TABLE_TAIL
 736
 737#define NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5)             \
 738  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 739  NS_INTERFACE_TABLE5(_class, _i1, _i2, _i3, _i4, _i5)                        \
 740  NS_INTERFACE_TABLE_TAIL
 741
 742#define NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6)        \
 743  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 744  NS_INTERFACE_TABLE6(_class, _i1, _i2, _i3, _i4, _i5, _i6)                   \
 745  NS_INTERFACE_TABLE_TAIL
 746
 747#define NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7)   \
 748  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 749  NS_INTERFACE_TABLE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7)              \
 750  NS_INTERFACE_TABLE_TAIL
 751
 752#define NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6,        \
 753                                 _i7, _i8)                                    \
 754  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 755  NS_INTERFACE_TABLE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8)         \
 756  NS_INTERFACE_TABLE_TAIL
 757
 758#define NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6,        \
 759                                 _i7, _i8, _i9)                               \
 760  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 761  NS_INTERFACE_TABLE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9)    \
 762  NS_INTERFACE_TABLE_TAIL
 763
 764#define NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6,       \
 765                                  _i7, _i8, _i9, _i10)                        \
 766  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 767  NS_INTERFACE_TABLE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8,        \
 768                       _i9, _i10)                                             \
 769  NS_INTERFACE_TABLE_TAIL
 770
 771#define NS_IMPL_QUERY_INTERFACE11(_class, _i1, _i2, _i3, _i4, _i5, _i6,       \
 772                                  _i7, _i8, _i9, _i10, _i11)                  \
 773  NS_INTERFACE_TABLE_HEAD(_class)                                             \
 774  NS_INTERFACE_TABLE11(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8,        \
 775                       _i9, _i10, _i11)                                       \
 776  NS_INTERFACE_TABLE_TAIL
 777
 778
 779#define NS_IMPL_THREADSAFE_QUERY_INTERFACE0  NS_IMPL_QUERY_INTERFACE0
 780#define NS_IMPL_THREADSAFE_QUERY_INTERFACE1  NS_IMPL_QUERY_INTERFACE1
 781#define NS_IMPL_THREADSAFE_QUERY_INTERFACE2  NS_IMPL_QUERY_INTERFACE2
 782#define NS_IMPL_THREADSAFE_QUERY_INTERFACE3  NS_IMPL_QUERY_INTERFACE3
 783#define NS_IMPL_THREADSAFE_QUERY_INTERFACE4  NS_IMPL_QUERY_INTERFACE4
 784#define NS_IMPL_THREADSAFE_QUERY_INTERFACE5  NS_IMPL_QUERY_INTERFACE5
 785#define NS_IMPL_THREADSAFE_QUERY_INTERFACE6  NS_IMPL_QUERY_INTERFACE6
 786#define NS_IMPL_THREADSAFE_QUERY_INTERFACE7  NS_IMPL_QUERY_INTERFACE7
 787#define NS_IMPL_THREADSAFE_QUERY_INTERFACE8  NS_IMPL_QUERY_INTERFACE8
 788#define NS_IMPL_THREADSAFE_QUERY_INTERFACE9  NS_IMPL_QUERY_INTERFACE9
 789#define NS_IMPL_THREADSAFE_QUERY_INTERFACE10  NS_IMPL_QUERY_INTERFACE10
 790#define NS_IMPL_THREADSAFE_QUERY_INTERFACE11  NS_IMPL_QUERY_INTERFACE11
 791
 792/**
 793 * Declare that you're going to inherit from something that already
 794 * implements nsISupports, but also implements an additional interface, thus
 795 * causing an ambiguity. In this case you don't need another mRefCnt, you
 796 * just need to forward the definitions to the appropriate superclass. E.g.
 797 *
 798 * class Bar : public Foo, public nsIBar {  // both provide nsISupports
 799 * public:
 800 *   NS_DECL_ISUPPORTS_INHERITED
 801 *   ...other nsIBar and Bar methods...
 802 * };
 803 */
 804#define NS_DECL_ISUPPORTS_INHERITED                                           \
 805public:                                                                       \
 806  NS_IMETHOD QueryInterface(REFNSIID aIID,                                    \
 807                            void** aInstancePtr);                             \
 808  NS_IMETHOD_(nsrefcnt) AddRef(void);                                         \
 809  NS_IMETHOD_(nsrefcnt) Release(void);                                        \
 810
 811/**
 812 * These macros can be used in conjunction with NS_DECL_ISUPPORTS_INHERITED
 813 * to implement the nsISupports methods, forwarding the invocations to a
 814 * superclass that already implements nsISupports.
 815 *
 816 * Note that I didn't make these inlined because they're virtual methods.
 817 */
 818
 819#define NS_IMPL_ADDREF_INHERITED(Class, Super)                                \
 820NS_IMETHODIMP_(nsrefcnt) Class::AddRef(void)                                  \
 821{                                                                             \
 822  nsrefcnt r = Super::AddRef();                                               \
 823  NS_LOG_ADDREF(this, r, #Class, sizeof(*this));                              \
 824  return r;                                                                   \
 825}                                                                             \
 826
 827#define NS_IMPL_RELEASE_INHERITED(Class, Super)                               \
 828NS_IMETHODIMP_(nsrefcnt) Class::Release(void)                                 \
 829{                                                                             \
 830  nsrefcnt r = Super::Release();                                              \
 831  NS_LOG_RELEASE(this, r, #Class);                                            \
 832  return r;                                                                   \
 833}                                                                             \
 834
 835#define NS_INTERFACE_TABLE_INHERITED0(Class) /* Nothing to do here */
 836
 837#define NS_INTERFACE_TABLE_INHERITED1(Class, i1)                              \
 838  NS_INTERFACE_TABLE_BEGIN                                                    \
 839    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 840  NS_INTERFACE_TABLE_END
 841
 842#define NS_INTERFACE_TABLE_INHERITED2(Class, i1, i2)                          \
 843  NS_INTERFACE_TABLE_BEGIN                                                    \
 844    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 845    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 846  NS_INTERFACE_TABLE_END
 847
 848#define NS_INTERFACE_TABLE_INHERITED3(Class, i1, i2, i3)                      \
 849  NS_INTERFACE_TABLE_BEGIN                                                    \
 850    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 851    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 852    NS_INTERFACE_TABLE_ENTRY(Class, i3)                                       \
 853  NS_INTERFACE_TABLE_END
 854
 855#define NS_INTERFACE_TABLE_INHERITED4(Class, i1, i2, i3, i4)                  \
 856  NS_INTERFACE_TABLE_BEGIN                                                    \
 857    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 858    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 859    NS_INTERFACE_TABLE_ENTRY(Class, i3)                                       \
 860    NS_INTERFACE_TABLE_ENTRY(Class, i4)                                       \
 861  NS_INTERFACE_TABLE_END
 862
 863#define NS_INTERFACE_TABLE_INHERITED5(Class, i1, i2, i3, i4, i5)              \
 864  NS_INTERFACE_TABLE_BEGIN                                                    \
 865    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 866    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 867    NS_INTERFACE_TABLE_ENTRY(Class, i3)                                       \
 868    NS_INTERFACE_TABLE_ENTRY(Class, i4)                                       \
 869    NS_INTERFACE_TABLE_ENTRY(Class, i5)                                       \
 870  NS_INTERFACE_TABLE_END
 871
 872#define NS_INTERFACE_TABLE_INHERITED6(Class, i1, i2, i3, i4, i5, i6)          \
 873  NS_INTERFACE_TABLE_BEGIN                                                    \
 874    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 875    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 876    NS_INTERFACE_TABLE_ENTRY(Class, i3)                                       \
 877    NS_INTERFACE_TABLE_ENTRY(Class, i4)                                       \
 878    NS_INTERFACE_TABLE_ENTRY(Class, i5)                                       \
 879    NS_INTERFACE_TABLE_ENTRY(Class, i6)                                       \
 880  NS_INTERFACE_TABLE_END
 881
 882#define NS_INTERFACE_TABLE_INHERITED7(Class, i1, i2, i3, i4, i5, i6, i7)      \
 883  NS_INTERFACE_TABLE_BEGIN                                                    \
 884    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 885    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 886    NS_INTERFACE_TABLE_ENTRY(Class, i3)                                       \
 887    NS_INTERFACE_TABLE_ENTRY(Class, i4)                                       \
 888    NS_INTERFACE_TABLE_ENTRY(Class, i5)                                       \
 889    NS_INTERFACE_TABLE_ENTRY(Class, i6)                                       \
 890    NS_INTERFACE_TABLE_ENTRY(Class, i7)                                       \
 891  NS_INTERFACE_TABLE_END
 892
 893#define NS_INTERFACE_TABLE_INHERITED8(Class, i1, i2, i3, i4, i5, i6, i7, i8)  \
 894  NS_INTERFACE_TABLE_BEGIN                                                    \
 895    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 896    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 897    NS_INTERFACE_TABLE_ENTRY(Class, i3)                                       \
 898    NS_INTERFACE_TABLE_ENTRY(Class, i4)                                       \
 899    NS_INTERFACE_TABLE_ENTRY(Class, i5)                                       \
 900    NS_INTERFACE_TABLE_ENTRY(Class, i6)                                       \
 901    NS_INTERFACE_TABLE_ENTRY(Class, i7)                                       \
 902    NS_INTERFACE_TABLE_ENTRY(Class, i8)                                       \
 903  NS_INTERFACE_TABLE_END
 904
 905#define NS_INTERFACE_TABLE_INHERITED9(Class, i1, i2, i3, i4, i5, i6, i7,      \
 906                                      i8, i9)                                 \
 907  NS_INTERFACE_TABLE_BEGIN                                                    \
 908    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 909    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 910    NS_INTERFACE_TABLE_ENTRY(Class, i3)                                       \
 911    NS_INTERFACE_TABLE_ENTRY(Class, i4)                                       \
 912    NS_INTERFACE_TABLE_ENTRY(Class, i5)                                       \
 913    NS_INTERFACE_TABLE_ENTRY(Class, i6)                                       \
 914    NS_INTERFACE_TABLE_ENTRY(Class, i7)                                       \
 915    NS_INTERFACE_TABLE_ENTRY(Class, i8)                                       \
 916    NS_INTERFACE_TABLE_ENTRY(Class, i9)                                       \
 917  NS_INTERFACE_TABLE_END
 918
 919#define NS_INTERFACE_TABLE_INHERITED10(Class, i1, i2, i3, i4, i5, i6, i7,     \
 920                                      i8, i9, i10)                            \
 921  NS_INTERFACE_TABLE_BEGIN                                                    \
 922    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 923    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 924    NS_INTERFACE_TABLE_ENTRY(Class, i3)                                       \
 925    NS_INTERFACE_TABLE_ENTRY(Class, i4)                                       \
 926    NS_INTERFACE_TABLE_ENTRY(Class, i5)                                       \
 927    NS_INTERFACE_TABLE_ENTRY(Class, i6)                                       \
 928    NS_INTERFACE_TABLE_ENTRY(Class, i7)                                       \
 929    NS_INTERFACE_TABLE_ENTRY(Class, i8)                                       \
 930    NS_INTERFACE_TABLE_ENTRY(Class, i9)                                       \
 931    NS_INTERFACE_TABLE_ENTRY(Class, i10)                                      \
 932  NS_INTERFACE_TABLE_END
 933
 934#define NS_INTERFACE_TABLE_INHERITED11(Class, i1, i2, i3, i4, i5, i6, i7,     \
 935                                      i8, i9, i10, i11)                       \
 936  NS_INTERFACE_TABLE_BEGIN                                                    \
 937    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 938    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 939    NS_INTERFACE_TABLE_ENTRY(Class, i3)                                       \
 940    NS_INTERFACE_TABLE_ENTRY(Class, i4)                                       \
 941    NS_INTERFACE_TABLE_ENTRY(Class, i5)                                       \
 942    NS_INTERFACE_TABLE_ENTRY(Class, i6)                                       \
 943    NS_INTERFACE_TABLE_ENTRY(Class, i7)                                       \
 944    NS_INTERFACE_TABLE_ENTRY(Class, i8)                                       \
 945    NS_INTERFACE_TABLE_ENTRY(Class, i9)                                       \
 946    NS_INTERFACE_TABLE_ENTRY(Class, i10)                                      \
 947    NS_INTERFACE_TABLE_ENTRY(Class, i11)                                      \
 948  NS_INTERFACE_TABLE_END
 949
 950#define NS_INTERFACE_TABLE_INHERITED12(Class, i1, i2, i3, i4, i5, i6, i7,     \
 951                                      i8, i9, i10, i11, i12)                  \
 952  NS_INTERFACE_TABLE_BEGIN                                                    \
 953    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 954    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 955    NS_INTERFACE_TABLE_ENTRY(Class, i3)                                       \
 956    NS_INTERFACE_TABLE_ENTRY(Class, i4)                                       \
 957    NS_INTERFACE_TABLE_ENTRY(Class, i5)                                       \
 958    NS_INTERFACE_TABLE_ENTRY(Class, i6)                                       \
 959    NS_INTERFACE_TABLE_ENTRY(Class, i7)                                       \
 960    NS_INTERFACE_TABLE_ENTRY(Class, i8)                                       \
 961    NS_INTERFACE_TABLE_ENTRY(Class, i9)                                       \
 962    NS_INTERFACE_TABLE_ENTRY(Class, i10)                                      \
 963    NS_INTERFACE_TABLE_ENTRY(Class, i11)                                      \
 964    NS_INTERFACE_TABLE_ENTRY(Class, i12)                                      \
 965  NS_INTERFACE_TABLE_END
 966
 967#define NS_INTERFACE_TABLE_INHERITED10(Class, i1, i2, i3, i4, i5, i6, i7,     \
 968                                       i8, i9, i10)                           \
 969  NS_INTERFACE_TABLE_BEGIN                                                    \
 970    NS_INTERFACE_TABLE_ENTRY(Class, i1)                                       \
 971    NS_INTERFACE_TABLE_ENTRY(Class, i2)                                       \
 972    NS_INTERFACE_TABLE_ENTRY(Class, i3)                                       \
 973    NS_INTERFACE_TABLE_ENTRY(Class, i4)                                       \
 974    NS_INTERFACE_TABLE_ENTRY(Class, i5)                                       \
 975    NS_INTERFACE_TABLE_ENTRY(Class, i6)                                       \
 976    NS_INTERFACE_TABLE_ENTRY(Class, i7)                                       \
 977    NS_INTERFACE_TABLE_ENTRY(Class, i8)                                       \
 978    NS_INTERFACE_TABLE_ENTRY(Class, i9)                                       \
 979    NS_INTERFACE_TABLE_ENTRY(Class, i10)                                      \
 980  NS_INTERFACE_TABLE_END
 981
 982#define NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super)                      \
 983  NS_INTERFACE_TABLE_HEAD(Class)                                              \
 984  NS_INTERFACE_TABLE_INHERITED0(Class)                                        \
 985  NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
 986
 987#define NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1)                  \
 988  NS_INTERFACE_TABLE_HEAD(Class)                                              \
 989  NS_INTERFACE_TABLE_INHERITED1(Class, i1)                                    \
 990  NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
 991
 992#define NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2)              \
 993  NS_INTERFACE_TABLE_HEAD(Class)                                              \
 994  NS_INTERFACE_TABLE_INHERITED2(Class, i1, i2)                                \
 995  NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
 996
 997#define NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3)          \
 998  NS_INTERFACE_TABLE_HEAD(Class)                                              \
 999  NS_INTERFACE_TABLE_INHERITED3(Class, i1, i2, i3)                            \
1000  NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
1001
1002#define NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4)      \
1003  NS_INTERFACE_TABLE_HEAD(Class)                                              \
1004  NS_INTERFACE_TABLE_INHERITED4(Class, i1, i2, i3, i4)                        \
1005  NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
1006
1007#define NS_IMPL_QUERY_INTERFACE_INHERITED5(Class,Super,i1,i2,i3,i4,i5)        \
1008  NS_INTERFACE_TABLE_HEAD(Class)                                              \
1009  NS_INTERFACE_TABLE_INHERITED5(Class, i1, i2, i3, i4, i5)                    \
1010  NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
1011
1012#define NS_IMPL_QUERY_INTERFACE_INHERITED6(Class,Super,i1,i2,i3,i4,i5,i6)     \
1013  NS_INTERFACE_TABLE_HEAD(Class)                                              \
1014  NS_INTERFACE_TABLE_INHERITED6(Class, i1, i2, i3, i4, i5, i6)                \
1015  NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
1016
1017#define NS_IMPL_QUERY_INTERFACE_INHERITED7(Class,Super,i1,i2,i3,i4,i5,i6,i7)  \
1018  NS_INTERFACE_TABLE_HEAD(Class)                                              \
1019  NS_INTERFACE_TABLE_INHERITED7(Class, i1, i2, i3, i4, i5, i6, i7)            \
1020  NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
1021
1022#define NS_IMPL_QUERY_INTERFACE_INHERITED8(Class,Super,i1,i2,i3,i4,i5,i6,     \
1023                                           i7,i8)                             \
1024  NS_INTERFACE_TABLE_HEAD(Class)                                              \
1025  NS_INTERFACE_TABLE_INHERITED8(Class, i1, i2, i3, i4, i5, i6, i7, i8)        \
1026  NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
1027
1028#define NS_IMPL_QUERY_INTERFACE_INHERITED9(Class,Super,i1,i2,i3,i4,i5,i6,     \
1029                                           i7,i8,i9)                          \
1030  NS_INTERFACE_TABLE_HEAD(Class)                                              \
1031  NS_INTERFACE_TABLE_INHERITED9(Class, i1, i2, i3, i4, i5, i6, i7, i8, i9)    \
1032  NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
1033
1034/**
1035 * Convenience macros for implementing all nsISupports methods for
1036 * a simple class.
1037 * @param _class The name of the class implementing the method
1038 * @param _classiiddef The name of the #define symbol that defines the IID
1039 * for the class (e.g. NS_ISUPPORTS_IID)
1040 */
1041
1042#define NS_IMPL_ISUPPORTS0(_class)                                            \
1043  NS_IMPL_ADDREF(_class)                                                      \
1044  NS_IMPL_RELEASE(_class)                                                     \
1045  NS_IMPL_QUERY_INTERFACE0(_class)
1046
1047#define NS_IMPL_ISUPPORTS1(_class, _interface)                                \
1048  NS_IMPL_ADDREF(_class)                                                      \
1049  NS_IMPL_RELEASE(_class)                                                     \
1050  NS_IMPL_QUERY_INTERFACE1(_class, _interface)
1051
1052#define NS_IMPL_ISUPPORTS2(_class, _i1, _i2)                                  \
1053  NS_IMPL_ADDREF(_class)                                                      \
1054  NS_IMPL_RELEASE(_class)                                                     \
1055  NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2)
1056
1057#define NS_IMPL_ISUPPORTS3(_class, _i1, _i2, _i3)                             \
1058  NS_IMPL_ADDREF(_class)                                                      \
1059  NS_IMPL_RELEASE(_class)                                                     \
1060  NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3)
1061
1062#define NS_IMPL_ISUPPORTS4(_class, _i1, _i2, _i3, _i4)                        \
1063  NS_IMPL_ADDREF(_class)                                                      \
1064  NS_IMPL_RELEASE(_class)                                                     \
1065  NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4)
1066
1067#define NS_IMPL_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5)                   \
1068  NS_IMPL_ADDREF(_class)                                                      \
1069  NS_IMPL_RELEASE(_class)                                                     \
1070  NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5)
1071
1072#define NS_IMPL_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6)              \
1073  NS_IMPL_ADDREF(_class)                                                      \
1074  NS_IMPL_RELEASE(_class)                                                     \
1075  NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6)
1076
1077#define NS_IMPL_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7)         \
1078  NS_IMPL_ADDREF(_class)                                                      \
1079  NS_IMPL_RELEASE(_class)                                                     \
1080  NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7)
1081
1082#define NS_IMPL_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8)    \
1083  NS_IMPL_ADDREF(_class)                                                      \
1084  NS_IMPL_RELEASE(_class)                                                     \
1085  NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8)
1086
1087#define NS_IMPL_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8,    \
1088                           _i9)                                               \
1089  NS_IMPL_ADDREF(_class)                                                      \
1090  NS_IMPL_RELEASE(_class)                                                     \
1091  NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9)
1092
1093#define NS_IMPL_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8,   \
1094                            _i9, _i10)                                        \
1095  NS_IMPL_ADDREF(_class)                                                      \
1096  NS_IMPL_RELEASE(_class)                                                     \
1097  NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8,   \
1098                            _i9, _i10)
1099
1100#define NS_IMPL_ISUPPORTS11(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8,   \
1101                            _i9, _i10, _i11)                                  \
1102  NS_IMPL_ADDREF(_class)                                                      \
1103  NS_IMPL_RELEASE(_class)                                                     \
1104  NS_IMPL_QUERY_INTERFACE11(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8,   \
1105                            _i9, _i10, _i11)
1106
1107#define NS_IMPL_ISUPPORTS_INHERITED0(Class, Super)                            \
1108    NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super)                          \
1109    NS_IMPL_ADDREF_INHERITED(Class, Super)                                    \
1110    NS_IMPL_RELEASE_INHERITED(Class, Super)                                   \
1111
1112#define NS_IMPL_ISUPPORTS_INHERITED1(Class, Super, i1)                        \
1113    NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1)                      \
1114    NS_IMPL_ADDREF_INHERITED(Class, Super)                                    \
1115    NS_IMPL_RELEASE_INHERITED(Class, Super)                                   \
1116
1117#define NS_IMPL_ISUPPORTS_INHERITED2(Class, Super, i1, i2)                    \
1118    NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2)                  \
1119    NS_IMPL_ADDREF_INHERITED(Class, Super)                                    \
1120    NS_IMPL_RELEASE_INHERITED(Class, Super)                                   \
1121
1122#define NS_IMPL_ISUPPORTS_INHERITED3(Class, Super, i1, i2, i3)                \
1123    NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3)              \
1124    NS_IMPL_ADDREF_INHERITED(Class, Super)                                    \
1125    NS_IMPL_RELEASE_INHERITED(Class, Super)                                   \
1126
1127#define NS_IMPL_ISUPPORTS_INHERITED4(Class, Super, i1, i2, i3, i4)            \
1128    NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4)          \
1129    NS_IMPL_ADDREF_INHERITED(Class, Super)                                    \
1130    NS_IMPL_RELEASE_INHERITED(Class, Super)                                   \
1131
1132#define NS_IMPL_ISUPPORTS_INHERITED5(Class, Super, i1, i2, i3, i4, i5)        \
1133    NS_IMPL_QUERY_INTERFACE_INHERITED5(Class, Super, i1, i2, i3, i4, i5)      \
1134    NS_IMPL_ADDREF_INHERITED(Class, Super)                                    \
1135    NS_IMPL_RELEASE_INHERITED(Class, Super)                                   \
1136
1137#define NS_IMPL_ISUPPORTS_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6)    \
1138    NS_IMPL_QUERY_INTERFACE_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6)  \
1139    NS_IMPL_ADDREF_INHERITED(Class, Super)                                    \
1140    NS_IMPL_RELEASE_INHERITED(Class, Super)                                   \
1141
1142#define NS_IMPL_ISUPPORTS_INHERITED7(Class, Super, i1, i2, i3, i4, i5, i6, i7) \
1143    NS_IMPL_QUERY_INTERFACE_INHERITED7(Class, Super, i1, i2, i3, i4, i5, i6, i7) \
1144    NS_IMPL_ADDREF_INHERITED(Class, Super)                                    \
1145    NS_IMPL_RELEASE_INHERITED(Class, Super)                                   \
1146
1147/*
1148 * Macro to glue together a QI that starts with an interface table
1149 * and segues into an interface map (e.g. it uses singleton classinfo
1150 * or tearoffs).
1151 */
1152#define NS_INTERFACE_TABLE_TO_MAP_SEGUE \
1153  if (rv == NS_OK) return rv; \
1154  nsISupports* foundInterface;
1155
1156
1157///////////////////////////////////////////////////////////////////////////////
1158/**
1159 *
1160 * Threadsafe implementations of the ISupports convenience macros.
1161 *
1162 * @note  These are not available when linking against the standalone glue,
1163 *        because the implementation requires PR_ symbols.
1164 */
1165
1166#if !defined(XPCOM_GLUE_AVOID_NSPR)
1167
1168/**
1169 * Use this macro to implement the AddRef method for a given <i>_class</i>
1170 * @param _class The name of the class implementing the method
1171 */
1172
1173#define NS_IMPL_THREADSAFE_ADDREF(_class)                                     \
1174NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void)                                 \
1175{                                                                             \
1176  NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");                   \
1177  nsrefcnt count;                                                             \
1178  count = PR_AtomicIncrement((PRInt32*)&mRefCnt);                             \
1179  NS_LOG_ADDREF(this, count, #_class, sizeof(*this));                         \
1180  return count;                                                               \
1181}
1182
1183/**
1184 * Use this macro to implement the Release method for a given <i>_class</i>
1185 * @param _class The name of the class implementing the method
1186 */
1187
1188#define NS_IMPL_THREADSAFE_RELEASE(_class)                                    \
1189NS_IMETHODIMP_(nsrefcnt) _class::Release(void)                                \
1190{                                                                             \
1191  nsrefcnt count;                                                             \
1192  NS_PRECONDITION(0 != mRefCnt, "dup release");                               \
1193  count = PR_AtomicDecrement((PRInt32 *)&mRefCnt);                            \
1194  NS_LOG_RELEASE(this, count, #_class);                                       \
1195  if (0 == count) {                                                           \
1196    mRefCnt = 1; /* stabilize */                                              \
1197    /* enable this to find non-threadsafe destructors: */                     \
1198    /* NS_ASSERT_OWNINGTHREAD(_class); */                                     \
1199    NS_DELETEXPCOM(this);                                                     \
1200    return 0;                                                                 \
1201  }                                                                           \
1202  return count;                                                               \
1203}
1204
1205#else // XPCOM_GLUE_AVOID_NSPR
1206
1207#define NS_IMPL_THREADSAFE_ADDREF(_class)                                     \
1208  THREADSAFE_ISUPPORTS_NOT_AVAILABLE_IN_STANDALONE_GLUE;
1209
1210#define NS_IMPL_THREADSAFE_RELEASE(_class)                                    \
1211  THREADSAFE_ISUPPORTS_NOT_AVAILABLE_IN_STANDALONE_GLUE;
1212
1213#endif
1214
1215#define NS_IMPL_THREADSAFE_ISUPPORTS0(_class)                                 \
1216  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1217  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1218  NS_IMPL_THREADSAFE_QUERY_INTERFACE0(_class)
1219
1220#define NS_IMPL_THREADSAFE_ISUPPORTS1(_class, _interface)                     \
1221  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1222  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1223  NS_IMPL_THREADSAFE_QUERY_INTERFACE1(_class, _interface)
1224
1225#define NS_IMPL_THREADSAFE_ISUPPORTS2(_class, _i1, _i2)                       \
1226  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1227  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1228  NS_IMPL_THREADSAFE_QUERY_INTERFACE2(_class, _i1, _i2)
1229
1230#define NS_IMPL_THREADSAFE_ISUPPORTS3(_class, _i1, _i2, _i3)                  \
1231  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1232  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1233  NS_IMPL_THREADSAFE_QUERY_INTERFACE3(_class, _i1, _i2, _i3)
1234
1235#define NS_IMPL_THREADSAFE_ISUPPORTS4(_class, _i1, _i2, _i3, _i4)             \
1236  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1237  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1238  NS_IMPL_THREADSAFE_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4)
1239
1240#define NS_IMPL_THREADSAFE_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5)        \
1241  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1242  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1243  NS_IMPL_THREADSAFE_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5)
1244
1245#define NS_IMPL_THREADSAFE_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6)   \
1246  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1247  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1248  NS_IMPL_THREADSAFE_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6)
1249
1250#define NS_IMPL_THREADSAFE_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6,   \
1251                                      _i7)                                    \
1252  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1253  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1254  NS_IMPL_THREADSAFE_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6,   \
1255                                      _i7)
1256
1257#define NS_IMPL_THREADSAFE_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6,   \
1258                                      _i7, _i8)                               \
1259  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1260  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1261  NS_IMPL_THREADSAFE_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6,   \
1262                                      _i7, _i8)
1263
1264#define NS_IMPL_THREADSAFE_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6,   \
1265                                      _i7, _i8, _i9)                          \
1266  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1267  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1268  NS_IMPL_THREADSAFE_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6,   \
1269                                      _i7, _i8, _i9)
1270
1271#define NS_IMPL_THREADSAFE_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6,  \
1272                                       _i7, _i8, _i9, _i10)                   \
1273  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1274  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1275  NS_IMPL_THREADSAFE_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6,  \
1276                                       _i7, _i8, _i9, _i10)
1277
1278#define NS_IMPL_THREADSAFE_ISUPPORTS11(_class, _i1, _i2, _i3, _i4, _i5, _i6,  \
1279                                       _i7, _i8, _i9, _i10, _i11)             \
1280  NS_IMPL_THREADSAFE_ADDREF(_class)                                           \
1281  NS_IMPL_THREADSAFE_RELEASE(_class)                                          \
1282  NS_IMPL_THREADSAFE_QUERY_INTERFACE11(_class, _i1, _i2, _i3, _i4, _i5, _i6,  \
1283                                       _i7, _i8, _i9, _i10, _i11)
1284
1285#define NS_INTERFACE_MAP_END_THREADSAFE NS_IMPL_QUERY_TAIL_GUTS
1286
1287/**
1288 * Macro to generate nsIClassInfo methods for classes which do not have
1289 * corresponding nsIFactory implementations.
1290 */
1291#define NS_IMPL_THREADSAFE_CI(_class)                                         \
1292NS_IMETHODIMP                                                                 \
1293_class::GetInterfaces(PRUint32* _count, nsIID*** _array)                      \
1294{                                                                             \
1295  return NS_CI_INTERFACE_GETTER_NAME(_class)(_count, _array);                 \
1296}                                                                             \
1297                                                                              \
1298NS_IMETHODIMP                                                                 \
1299_class::GetHelperForLanguage(PRUint32 _language, nsISupports** _retval)       \
1300{                                                                             \
1301  *_retval = nsnull;                                                          \
1302  return NS_OK;                                                               \
1303}                                                                             \
1304                                                                              \
1305NS_IMETHODIMP                                                                 \
1306_class::GetContractID(char** _contractID)                                     \
1307{                                                                             \
1308  *_contractID = nsnull;                                                      \
1309  return NS_OK;                                                               \
1310}                                                                             \
1311                                                                              \
1312NS_IMETHODIMP                                                                 \
1313_class::GetClassDescription(char** _classDescription)                         \
1314{                                                                             \
1315  *_classDescription = nsnull;                                                \
1316  return NS_OK;                                                               \
1317}                                                                             \
1318                                                                              \
1319NS_IMETHODIMP                                                                 \
1320_class::GetClassID(nsCID** _classID)                                          \
1321{                                                                             \
1322  *_classID = nsnull;                                                         \
1323  return NS_OK;                                                               \
1324}                                                                             \
1325                                                                              \
1326NS_IMETHODIMP                                                                 \
1327_class::GetImplementationLanguage(PRUint32* _language)                        \
1328{                                                                             \
1329  *_language = nsIProgrammingLanguage::CPLUSPLUS;                             \
1330  return NS_OK;                                                               \
1331}                                                                             \
1332                                                                              \
1333NS_IMETHODIMP                                                                 \
1334_class::GetFlags(PRUint32* _flags)                                            \
1335{                                                                             \
1336  *_flags = nsIClassInfo::THREADSAFE;                                         \
1337  return NS_OK;                                                               \
1338}                                                                             \
1339                                                                              \
1340NS_IMETHODIMP                                                                 \
1341_class::GetClassIDNoAlloc(nsCID* _classIDNoAlloc)                             \
1342{                                                                             \
1343  return NS_ERROR_NOT_AVAILABLE;                                              \
1344}
1345
1346#endif