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
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/
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
15 * The Original Code is XPCOM.
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.
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.
35 * ***** END LICENSE BLOCK ***** */
38 #ifndef nsISupportsImpl_h__
39 #define nsISupportsImpl_h__
45 #ifndef nsISupportsBase_h__
46 #include "nsISupportsBase.h"
49 #ifndef nsISupportsUtils_h__
50 #include "nsISupportsUtils.h"
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 */
60 #include "nsTraceRefcnt.h"
61 #include "nsCycleCollector.h"
63 ////////////////////////////////////////////////////////////////////////////////
64 // Macros to help detect thread-safety:
66 #if defined(NS_DEBUG) && !defined(XPCOM_GLUE_AVOID_NSPR)
68 class nsAutoOwningThread
{
70 nsAutoOwningThread() { mThread
= PR_GetCurrentThread(); }
71 void *GetThread() const { return mThread
; }
77 #define NS_DECL_OWNINGTHREAD nsAutoOwningThread _mOwningThread;
78 #define NS_ASSERT_OWNINGTHREAD(_class) \
79 NS_CheckThreadSafe(_mOwningThread.GetThread(), #_class " not thread-safe")
83 #define NS_DECL_OWNINGTHREAD /* nothing */
84 #define NS_ASSERT_OWNINGTHREAD(_class) ((void)0)
88 #define NS_PURPLE_BIT ((PRUint32)(1 << 31))
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))
96 // Support for ISupports classes which interact with cycle collector.
98 class nsCycleCollectingAutoRefCnt
{
101 nsCycleCollectingAutoRefCnt()
105 nsCycleCollectingAutoRefCnt(nsrefcnt aValue
)
108 NS_CLEAR_PURPLE_BIT(mValue
);
111 nsrefcnt
incr(nsISupports
*owner
)
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.
123 nsrefcnt tmp
= get();
124 PRBool purple
= static_cast<PRBool
>(NS_PURPLE_BIT_SET(mValue
));
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
;
136 void stabilizeForDeletion(nsISupports
*owner
)
138 mValue
= NS_PURPLE_BIT
;
141 nsrefcnt
decr(nsISupports
*owner
)
143 if (NS_UNLIKELY(mValue
== NS_PURPLE_BIT
))
146 nsrefcnt tmp
= get();
147 NS_ASSERTION(tmp
>= 1, "decr() called with zero refcnt");
149 PRBool purple
= static_cast<PRBool
>(NS_PURPLE_BIT_SET(mValue
));
150 PRBool shouldBePurple
= tmp
> 1;
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");
164 mValue
= tmp
| NS_PURPLE_BIT
;
173 if (NS_LIKELY(mValue
!= NS_PURPLE_BIT
))
174 NS_CLEAR_PURPLE_BIT(mValue
);
179 if (NS_UNLIKELY(mValue
== NS_PURPLE_BIT
))
182 return NS_VALUE_WITHOUT_PURPLE_BIT(mValue
);
185 operator nsrefcnt() const
197 nsAutoRefCnt() : mValue(0) {}
198 nsAutoRefCnt(nsrefcnt aValue
) : mValue(aValue
) {}
200 // only support prefix increment/decrement
201 nsrefcnt
operator++() { return ++mValue
; }
202 nsrefcnt
operator--() { return --mValue
; }
204 nsrefcnt
operator=(nsrefcnt aValue
) { return (mValue
= aValue
); }
205 operator nsrefcnt() const { return mValue
; }
206 nsrefcnt
get() const { return mValue
; }
208 // do not define these to enforce the faster prefix notation
209 nsrefcnt
operator++(int);
210 nsrefcnt
operator--(int);
214 ///////////////////////////////////////////////////////////////////////////////
217 * Declare the reference count variable and the implementations of the
218 * AddRef and QueryInterface methods.
221 #define NS_DECL_ISUPPORTS \
223 NS_IMETHOD QueryInterface(REFNSIID aIID, \
224 void** aInstancePtr); \
225 NS_IMETHOD_(nsrefcnt) AddRef(void); \
226 NS_IMETHOD_(nsrefcnt) Release(void); \
228 nsAutoRefCnt mRefCnt; \
229 NS_DECL_OWNINGTHREAD \
232 #define NS_DECL_CYCLE_COLLECTING_ISUPPORTS \
234 NS_IMETHOD QueryInterface(REFNSIID aIID, \
235 void** aInstancePtr); \
236 NS_IMETHOD_(nsrefcnt) AddRef(void); \
237 NS_IMETHOD_(nsrefcnt) Release(void); \
238 void UnmarkPurple() \
240 mRefCnt.unmarkPurple(); \
243 nsCycleCollectingAutoRefCnt mRefCnt; \
244 NS_DECL_OWNINGTHREAD \
248 ///////////////////////////////////////////////////////////////////////////////
251 * Previously used to initialize the reference count, but no longer needed.
255 #define NS_INIT_ISUPPORTS() ((void)0)
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
261 #define NS_IMPL_ADDREF(_class) \
262 NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
264 NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
265 NS_ASSERT_OWNINGTHREAD(_class); \
267 NS_LOG_ADDREF(this, mRefCnt, #_class, sizeof(*this)); \
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
278 #define NS_IMPL_ADDREF_USING_AGGREGATOR(_class, _aggregator) \
279 NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
281 NS_PRECONDITION(_aggregator, "null aggregator"); \
282 return (_aggregator)->AddRef(); \
286 * Use this macro to implement the Release method for a given
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.
294 * NS_IMPL_RELEASE_WITH_DESTROY(Foo, Destroy(this))
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).
304 #define NS_IMPL_RELEASE_WITH_DESTROY(_class, _destroy) \
305 NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
307 NS_PRECONDITION(0 != mRefCnt, "dup release"); \
308 NS_ASSERT_OWNINGTHREAD(_class); \
310 NS_LOG_RELEASE(this, mRefCnt, #_class); \
311 if (mRefCnt == 0) { \
312 mRefCnt = 1; /* stabilize */ \
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
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|.
332 #define NS_IMPL_RELEASE(_class) \
333 NS_IMPL_RELEASE_WITH_DESTROY(_class, NS_DELETEXPCOM(this))
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
342 #define NS_IMPL_RELEASE_USING_AGGREGATOR(_class, _aggregator) \
343 NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
345 NS_PRECONDITION(_aggregator, "null aggregator"); \
346 return (_aggregator)->Release(); \
350 #define NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(_class, _basetype) \
351 NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
353 NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
354 NS_ASSERT_OWNINGTHREAD(_class); \
356 mRefCnt.incr(NS_CYCLE_COLLECTION_CLASSNAME(_class)::Upcast(this)); \
357 NS_LOG_ADDREF(this, count, #_class, sizeof(*this)); \
361 #define NS_IMPL_CYCLE_COLLECTING_ADDREF(_class) \
362 NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(_class, _class)
364 #define NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(_class, _basetype, _destroy) \
365 NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
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); \
373 mRefCnt.stabilizeForDeletion(base); \
380 #define NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(_class, _destroy) \
381 NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(_class, _class, _destroy)
383 #define NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS_WITH_DESTROY(_class, _basetype, _destroy) \
384 NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(_class, _basetype, _destroy)
386 #define NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(_class, _basetype) \
387 NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(_class, _basetype, NS_DELETEXPCOM(this))
389 #define NS_IMPL_CYCLE_COLLECTING_RELEASE(_class) \
390 NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(_class, _class, NS_DELETEXPCOM(this))
393 ///////////////////////////////////////////////////////////////////////////////
396 * There are two ways of implementing QueryInterface, and we use both:
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).
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).
406 * These methods can be combined into a table-driven function call followed
407 * by custom code for tearoffs and conditionals.
412 const nsIID
*iid
; // null indicates end of the QITableEntry array
416 NS_COM_GLUE nsresult NS_FASTCALL
417 NS_TableDrivenQI(void* aThis
, const QITableEntry
* entries
,
418 REFNSIID aIID
, void **aInstancePtr
);
421 * Implement table-driven queryinterface
424 #define NS_INTERFACE_TABLE_HEAD(_class) \
425 NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
427 NS_ASSERTION(aInstancePtr, \
428 "QueryInterface requires a non-NULL destination!"); \
429 nsresult rv = NS_ERROR_FAILURE;
431 #define NS_INTERFACE_TABLE_BEGIN \
432 static const QITableEntry table[] = {
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)) \
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)) \
450 #define NS_INTERFACE_TABLE_END_WITH_PTR(_ptr) \
452 rv = NS_TableDrivenQI(static_cast<void*>(_ptr), \
453 table, aIID, aInstancePtr);
455 #define NS_INTERFACE_TABLE_END \
456 NS_INTERFACE_TABLE_END_WITH_PTR(this)
458 #define NS_INTERFACE_TABLE_TAIL \
462 #define NS_INTERFACE_TABLE_TAIL_INHERITING(_baseclass) \
463 if (NS_SUCCEEDED(rv)) \
465 return _baseclass::QueryInterface(aIID, aInstancePtr); \
468 #define NS_INTERFACE_TABLE_TAIL_USING_AGGREGATOR(_aggregator) \
469 if (NS_SUCCEEDED(rv)) \
471 NS_ASSERTION(_aggregator, "null aggregator"); \
472 return _aggregator->QueryInterface(aIID, aInstancePtr) \
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.
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)
486 #define NS_IMPL_QUERY_HEAD(_class) \
487 NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
489 NS_ASSERTION(aInstancePtr, \
490 "QueryInterface requires a non-NULL destination!"); \
491 nsISupports* foundInterface;
493 #define NS_IMPL_QUERY_BODY(_interface) \
494 if ( aIID.Equals(NS_GET_IID(_interface)) ) \
495 foundInterface = static_cast<_interface*>(this); \
498 #define NS_IMPL_QUERY_BODY_CONDITIONAL(_interface, condition) \
499 if ( (condition) && aIID.Equals(NS_GET_IID(_interface))) \
500 foundInterface = static_cast<_interface*>(this); \
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)); \
509 #define NS_IMPL_QUERY_BODY_AGGREGATED(_interface, _aggregate) \
510 if ( aIID.Equals(NS_GET_IID(_interface)) ) \
511 foundInterface = static_cast<_interface*>(_aggregate); \
514 #define NS_IMPL_QUERY_TAIL_GUTS \
515 foundInterface = 0; \
517 if ( !foundInterface ) \
518 status = NS_NOINTERFACE; \
521 NS_ADDREF(foundInterface); \
524 *aInstancePtr = foundInterface; \
528 #define NS_IMPL_QUERY_TAIL_INHERITING(_baseclass) \
529 foundInterface = 0; \
531 if ( !foundInterface ) \
532 status = _baseclass::QueryInterface(aIID, (void**)&foundInterface); \
535 NS_ADDREF(foundInterface); \
538 *aInstancePtr = foundInterface; \
542 #define NS_IMPL_QUERY_TAIL_USING_AGGREGATOR(_aggregator) \
543 foundInterface = 0; \
545 if ( !foundInterface ) { \
546 NS_ASSERTION(_aggregator, "null aggregator"); \
547 status = _aggregator->QueryInterface(aIID, (void**)&foundInterface); \
550 NS_ADDREF(foundInterface); \
553 *aInstancePtr = foundInterface; \
557 #define NS_IMPL_QUERY_TAIL(_supports_interface) \
558 NS_IMPL_QUERY_BODY_AMBIGUOUS(nsISupports, _supports_interface) \
559 NS_IMPL_QUERY_TAIL_GUTS
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.
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)
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)
583 #define NS_INTERFACE_TABLE0(_class) \
584 NS_INTERFACE_TABLE_BEGIN \
585 NS_INTERFACE_TABLE_ENTRY(_class, nsISupports) \
586 NS_INTERFACE_TABLE_END
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
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
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
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
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
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
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
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
664 #define NS_INTERFACE_TABLE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
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
679 #define NS_INTERFACE_TABLE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
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
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
712 #define NS_IMPL_QUERY_INTERFACE0(_class) \
713 NS_INTERFACE_TABLE_HEAD(_class) \
714 NS_INTERFACE_TABLE0(_class) \
715 NS_INTERFACE_TABLE_TAIL
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
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
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
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
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
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
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
752 #define NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
754 NS_INTERFACE_TABLE_HEAD(_class) \
755 NS_INTERFACE_TABLE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \
756 NS_INTERFACE_TABLE_TAIL
758 #define NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
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
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, \
769 NS_INTERFACE_TABLE_TAIL
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, \
776 NS_INTERFACE_TABLE_TAIL
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
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.
798 * class Bar : public Foo, public nsIBar { // both provide nsISupports
800 * NS_DECL_ISUPPORTS_INHERITED
801 * ...other nsIBar and Bar methods...
804 #define NS_DECL_ISUPPORTS_INHERITED \
806 NS_IMETHOD QueryInterface(REFNSIID aIID, \
807 void** aInstancePtr); \
808 NS_IMETHOD_(nsrefcnt) AddRef(void); \
809 NS_IMETHOD_(nsrefcnt) Release(void); \
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.
816 * Note that I didn't make these inlined because they're virtual methods.
819 #define NS_IMPL_ADDREF_INHERITED(Class, Super) \
820 NS_IMETHODIMP_(nsrefcnt) Class::AddRef(void) \
822 nsrefcnt r = Super::AddRef(); \
823 NS_LOG_ADDREF(this, r, #Class, sizeof(*this)); \
827 #define NS_IMPL_RELEASE_INHERITED(Class, Super) \
828 NS_IMETHODIMP_(nsrefcnt) Class::Release(void) \
830 nsrefcnt r = Super::Release(); \
831 NS_LOG_RELEASE(this, r, #Class); \
835 #define NS_INTERFACE_TABLE_INHERITED0(Class) /* Nothing to do here */
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
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
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
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
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
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
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
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
905 #define NS_INTERFACE_TABLE_INHERITED9(Class, i1, i2, i3, i4, i5, i6, i7, \
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
919 #define NS_INTERFACE_TABLE_INHERITED10(Class, i1, i2, i3, i4, i5, i6, i7, \
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
934 #define NS_INTERFACE_TABLE_INHERITED11(Class, i1, i2, i3, i4, i5, i6, i7, \
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
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
967 #define NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \
968 NS_INTERFACE_TABLE_HEAD(Class) \
969 NS_INTERFACE_TABLE_INHERITED0(Class) \
970 NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
972 #define NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \
973 NS_INTERFACE_TABLE_HEAD(Class) \
974 NS_INTERFACE_TABLE_INHERITED1(Class, i1) \
975 NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
977 #define NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \
978 NS_INTERFACE_TABLE_HEAD(Class) \
979 NS_INTERFACE_TABLE_INHERITED2(Class, i1, i2) \
980 NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
982 #define NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \
983 NS_INTERFACE_TABLE_HEAD(Class) \
984 NS_INTERFACE_TABLE_INHERITED3(Class, i1, i2, i3) \
985 NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
987 #define NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \
988 NS_INTERFACE_TABLE_HEAD(Class) \
989 NS_INTERFACE_TABLE_INHERITED4(Class, i1, i2, i3, i4) \
990 NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
992 #define NS_IMPL_QUERY_INTERFACE_INHERITED5(Class,Super,i1,i2,i3,i4,i5) \
993 NS_INTERFACE_TABLE_HEAD(Class) \
994 NS_INTERFACE_TABLE_INHERITED5(Class, i1, i2, i3, i4, i5) \
995 NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
997 #define NS_IMPL_QUERY_INTERFACE_INHERITED6(Class,Super,i1,i2,i3,i4,i5,i6) \
998 NS_INTERFACE_TABLE_HEAD(Class) \
999 NS_INTERFACE_TABLE_INHERITED6(Class, i1, i2, i3, i4, i5, i6) \
1000 NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
1002 #define NS_IMPL_QUERY_INTERFACE_INHERITED7(Class,Super,i1,i2,i3,i4,i5,i6,i7) \
1003 NS_INTERFACE_TABLE_HEAD(Class) \
1004 NS_INTERFACE_TABLE_INHERITED7(Class, i1, i2, i3, i4, i5, i6, i7) \
1005 NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
1007 #define NS_IMPL_QUERY_INTERFACE_INHERITED8(Class,Super,i1,i2,i3,i4,i5,i6, \
1009 NS_INTERFACE_TABLE_HEAD(Class) \
1010 NS_INTERFACE_TABLE_INHERITED8(Class, i1, i2, i3, i4, i5, i6, i7, i8) \
1011 NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
1013 #define NS_IMPL_QUERY_INTERFACE_INHERITED9(Class,Super,i1,i2,i3,i4,i5,i6, \
1015 NS_INTERFACE_TABLE_HEAD(Class) \
1016 NS_INTERFACE_TABLE_INHERITED9(Class, i1, i2, i3, i4, i5, i6, i7, i8, i9) \
1017 NS_INTERFACE_TABLE_TAIL_INHERITING(Super)
1020 * Convenience macros for implementing all nsISupports methods for
1022 * @param _class The name of the class implementing the method
1023 * @param _classiiddef The name of the #define symbol that defines the IID
1024 * for the class (e.g. NS_ISUPPORTS_IID)
1027 #define NS_IMPL_ISUPPORTS0(_class) \
1028 NS_IMPL_ADDREF(_class) \
1029 NS_IMPL_RELEASE(_class) \
1030 NS_IMPL_QUERY_INTERFACE0(_class)
1032 #define NS_IMPL_ISUPPORTS1(_class, _interface) \
1033 NS_IMPL_ADDREF(_class) \
1034 NS_IMPL_RELEASE(_class) \
1035 NS_IMPL_QUERY_INTERFACE1(_class, _interface)
1037 #define NS_IMPL_ISUPPORTS2(_class, _i1, _i2) \
1038 NS_IMPL_ADDREF(_class) \
1039 NS_IMPL_RELEASE(_class) \
1040 NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2)
1042 #define NS_IMPL_ISUPPORTS3(_class, _i1, _i2, _i3) \
1043 NS_IMPL_ADDREF(_class) \
1044 NS_IMPL_RELEASE(_class) \
1045 NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3)
1047 #define NS_IMPL_ISUPPORTS4(_class, _i1, _i2, _i3, _i4) \
1048 NS_IMPL_ADDREF(_class) \
1049 NS_IMPL_RELEASE(_class) \
1050 NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4)
1052 #define NS_IMPL_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5) \
1053 NS_IMPL_ADDREF(_class) \
1054 NS_IMPL_RELEASE(_class) \
1055 NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5)
1057 #define NS_IMPL_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \
1058 NS_IMPL_ADDREF(_class) \
1059 NS_IMPL_RELEASE(_class) \
1060 NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6)
1062 #define NS_IMPL_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \
1063 NS_IMPL_ADDREF(_class) \
1064 NS_IMPL_RELEASE(_class) \
1065 NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7)
1067 #define NS_IMPL_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \
1068 NS_IMPL_ADDREF(_class) \
1069 NS_IMPL_RELEASE(_class) \
1070 NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8)
1072 #define NS_IMPL_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
1074 NS_IMPL_ADDREF(_class) \
1075 NS_IMPL_RELEASE(_class) \
1076 NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9)
1078 #define NS_IMPL_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
1080 NS_IMPL_ADDREF(_class) \
1081 NS_IMPL_RELEASE(_class) \
1082 NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
1085 #define NS_IMPL_ISUPPORTS11(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
1087 NS_IMPL_ADDREF(_class) \
1088 NS_IMPL_RELEASE(_class) \
1089 NS_IMPL_QUERY_INTERFACE11(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
1092 #define NS_IMPL_ISUPPORTS_INHERITED0(Class, Super) \
1093 NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \
1094 NS_IMPL_ADDREF_INHERITED(Class, Super) \
1095 NS_IMPL_RELEASE_INHERITED(Class, Super) \
1097 #define NS_IMPL_ISUPPORTS_INHERITED1(Class, Super, i1) \
1098 NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \
1099 NS_IMPL_ADDREF_INHERITED(Class, Super) \
1100 NS_IMPL_RELEASE_INHERITED(Class, Super) \
1102 #define NS_IMPL_ISUPPORTS_INHERITED2(Class, Super, i1, i2) \
1103 NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \
1104 NS_IMPL_ADDREF_INHERITED(Class, Super) \
1105 NS_IMPL_RELEASE_INHERITED(Class, Super) \
1107 #define NS_IMPL_ISUPPORTS_INHERITED3(Class, Super, i1, i2, i3) \
1108 NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \
1109 NS_IMPL_ADDREF_INHERITED(Class, Super) \
1110 NS_IMPL_RELEASE_INHERITED(Class, Super) \
1112 #define NS_IMPL_ISUPPORTS_INHERITED4(Class, Super, i1, i2, i3, i4) \
1113 NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \
1114 NS_IMPL_ADDREF_INHERITED(Class, Super) \
1115 NS_IMPL_RELEASE_INHERITED(Class, Super) \
1117 #define NS_IMPL_ISUPPORTS_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \
1118 NS_IMPL_QUERY_INTERFACE_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \
1119 NS_IMPL_ADDREF_INHERITED(Class, Super) \
1120 NS_IMPL_RELEASE_INHERITED(Class, Super) \
1122 #define NS_IMPL_ISUPPORTS_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \
1123 NS_IMPL_QUERY_INTERFACE_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \
1124 NS_IMPL_ADDREF_INHERITED(Class, Super) \
1125 NS_IMPL_RELEASE_INHERITED(Class, Super) \
1127 #define NS_IMPL_ISUPPORTS_INHERITED7(Class, Super, i1, i2, i3, i4, i5, i6, i7) \
1128 NS_IMPL_QUERY_INTERFACE_INHERITED7(Class, Super, i1, i2, i3, i4, i5, i6, i7) \
1129 NS_IMPL_ADDREF_INHERITED(Class, Super) \
1130 NS_IMPL_RELEASE_INHERITED(Class, Super) \
1133 * Macro to glue together a QI that starts with an interface table
1134 * and segues into an interface map (e.g. it uses singleton classinfo
1137 #define NS_INTERFACE_TABLE_TO_MAP_SEGUE \
1138 if (rv == NS_OK) return rv; \
1139 nsISupports* foundInterface;
1142 ///////////////////////////////////////////////////////////////////////////////
1145 * Threadsafe implementations of the ISupports convenience macros.
1147 * @note These are not available when linking against the standalone glue,
1148 * because the implementation requires PR_ symbols.
1151 #if !defined(XPCOM_GLUE_AVOID_NSPR)
1154 * Use this macro to implement the AddRef method for a given <i>_class</i>
1155 * @param _class The name of the class implementing the method
1158 #define NS_IMPL_THREADSAFE_ADDREF(_class) \
1159 NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
1161 NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
1163 count = PR_AtomicIncrement((PRInt32*)&mRefCnt); \
1164 NS_LOG_ADDREF(this, count, #_class, sizeof(*this)); \
1169 * Use this macro to implement the Release method for a given <i>_class</i>
1170 * @param _class The name of the class implementing the method
1173 #define NS_IMPL_THREADSAFE_RELEASE(_class) \
1174 NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
1177 NS_PRECONDITION(0 != mRefCnt, "dup release"); \
1178 count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); \
1179 NS_LOG_RELEASE(this, count, #_class); \
1181 mRefCnt = 1; /* stabilize */ \
1182 /* enable this to find non-threadsafe destructors: */ \
1183 /* NS_ASSERT_OWNINGTHREAD(_class); */ \
1184 NS_DELETEXPCOM(this); \
1190 #else // XPCOM_GLUE_AVOID_NSPR
1192 #define NS_IMPL_THREADSAFE_ADDREF(_class) \
1193 THREADSAFE_ISUPPORTS_NOT_AVAILABLE_IN_STANDALONE_GLUE;
1195 #define NS_IMPL_THREADSAFE_RELEASE(_class) \
1196 THREADSAFE_ISUPPORTS_NOT_AVAILABLE_IN_STANDALONE_GLUE;
1200 #define NS_IMPL_THREADSAFE_ISUPPORTS0(_class) \
1201 NS_IMPL_THREADSAFE_ADDREF(_class) \
1202 NS_IMPL_THREADSAFE_RELEASE(_class) \
1203 NS_IMPL_THREADSAFE_QUERY_INTERFACE0(_class)
1205 #define NS_IMPL_THREADSAFE_ISUPPORTS1(_class, _interface) \
1206 NS_IMPL_THREADSAFE_ADDREF(_class) \
1207 NS_IMPL_THREADSAFE_RELEASE(_class) \
1208 NS_IMPL_THREADSAFE_QUERY_INTERFACE1(_class, _interface)
1210 #define NS_IMPL_THREADSAFE_ISUPPORTS2(_class, _i1, _i2) \
1211 NS_IMPL_THREADSAFE_ADDREF(_class) \
1212 NS_IMPL_THREADSAFE_RELEASE(_class) \
1213 NS_IMPL_THREADSAFE_QUERY_INTERFACE2(_class, _i1, _i2)
1215 #define NS_IMPL_THREADSAFE_ISUPPORTS3(_class, _i1, _i2, _i3) \
1216 NS_IMPL_THREADSAFE_ADDREF(_class) \
1217 NS_IMPL_THREADSAFE_RELEASE(_class) \
1218 NS_IMPL_THREADSAFE_QUERY_INTERFACE3(_class, _i1, _i2, _i3)
1220 #define NS_IMPL_THREADSAFE_ISUPPORTS4(_class, _i1, _i2, _i3, _i4) \
1221 NS_IMPL_THREADSAFE_ADDREF(_class) \
1222 NS_IMPL_THREADSAFE_RELEASE(_class) \
1223 NS_IMPL_THREADSAFE_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4)
1225 #define NS_IMPL_THREADSAFE_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5) \
1226 NS_IMPL_THREADSAFE_ADDREF(_class) \
1227 NS_IMPL_THREADSAFE_RELEASE(_class) \
1228 NS_IMPL_THREADSAFE_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5)
1230 #define NS_IMPL_THREADSAFE_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \
1231 NS_IMPL_THREADSAFE_ADDREF(_class) \
1232 NS_IMPL_THREADSAFE_RELEASE(_class) \
1233 NS_IMPL_THREADSAFE_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6)
1235 #define NS_IMPL_THREADSAFE_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1237 NS_IMPL_THREADSAFE_ADDREF(_class) \
1238 NS_IMPL_THREADSAFE_RELEASE(_class) \
1239 NS_IMPL_THREADSAFE_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1242 #define NS_IMPL_THREADSAFE_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1244 NS_IMPL_THREADSAFE_ADDREF(_class) \
1245 NS_IMPL_THREADSAFE_RELEASE(_class) \
1246 NS_IMPL_THREADSAFE_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1249 #define NS_IMPL_THREADSAFE_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1251 NS_IMPL_THREADSAFE_ADDREF(_class) \
1252 NS_IMPL_THREADSAFE_RELEASE(_class) \
1253 NS_IMPL_THREADSAFE_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1256 #define NS_IMPL_THREADSAFE_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1257 _i7, _i8, _i9, _i10) \
1258 NS_IMPL_THREADSAFE_ADDREF(_class) \
1259 NS_IMPL_THREADSAFE_RELEASE(_class) \
1260 NS_IMPL_THREADSAFE_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1261 _i7, _i8, _i9, _i10)
1263 #define NS_IMPL_THREADSAFE_ISUPPORTS11(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1264 _i7, _i8, _i9, _i10, _i11) \
1265 NS_IMPL_THREADSAFE_ADDREF(_class) \
1266 NS_IMPL_THREADSAFE_RELEASE(_class) \
1267 NS_IMPL_THREADSAFE_QUERY_INTERFACE11(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1268 _i7, _i8, _i9, _i10, _i11)
1270 #define NS_INTERFACE_MAP_END_THREADSAFE NS_IMPL_QUERY_TAIL_GUTS
1273 * Macro to generate nsIClassInfo methods for classes which do not have
1274 * corresponding nsIFactory implementations.
1276 #define NS_IMPL_THREADSAFE_CI(_class) \
1278 _class::GetInterfaces(PRUint32* _count, nsIID*** _array) \
1280 return NS_CI_INTERFACE_GETTER_NAME(_class)(_count, _array); \
1284 _class::GetHelperForLanguage(PRUint32 _language, nsISupports** _retval) \
1286 *_retval = nsnull; \
1291 _class::GetContractID(char** _contractID) \
1293 *_contractID = nsnull; \
1298 _class::GetClassDescription(char** _classDescription) \
1300 *_classDescription = nsnull; \
1305 _class::GetClassID(nsCID** _classID) \
1307 *_classID = nsnull; \
1312 _class::GetImplementationLanguage(PRUint32* _language) \
1314 *_language = nsIProgrammingLanguage::CPLUSPLUS; \
1319 _class::GetFlags(PRUint32* _flags) \
1321 *_flags = nsIClassInfo::THREADSAFE; \
1326 _class::GetClassIDNoAlloc(nsCID* _classIDNoAlloc) \
1328 return NS_ERROR_NOT_AVAILABLE; \