PageRenderTime 87ms CodeModel.GetById 41ms app.highlight 13ms RepoModel.GetById 27ms app.codeStats 0ms

/gecko_api/include/nsCycleCollectionParticipant.h

http://firefox-mac-pdf.googlecode.com/
C++ Header | 675 lines | 493 code | 101 blank | 81 comment | 8 complexity | 9170c9dc2e0073ea857658faa9c68b88 MD5 | raw file
  1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  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 mozilla.org code.
 16 *
 17 * The Initial Developer of the Original Code is
 18 * The Mozilla Foundation.
 19 * Portions created by the Initial Developer are Copyright (C) 2006
 20 * the Initial Developer. All Rights Reserved.
 21 *
 22 * Contributor(s):
 23 *
 24 * Alternatively, the contents of this file may be used under the terms of
 25 * either of the GNU General Public License Version 2 or later (the "GPL"),
 26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 27 * in which case the provisions of the GPL or the LGPL are applicable instead
 28 * of those above. If you wish to allow use of your version of this file only
 29 * under the terms of either the GPL or the LGPL, and not to allow others to
 30 * use your version of this file under the terms of the MPL, indicate your
 31 * decision by deleting the provisions above and replace them with the notice
 32 * and other provisions required by the GPL or the LGPL. If you do not delete
 33 * the provisions above, a recipient may use your version of this file under
 34 * the terms of any one of the MPL, the GPL or the LGPL.
 35 *
 36 * ***** END LICENSE BLOCK ***** */
 37
 38#ifndef nsCycleCollectionParticipant_h__
 39#define nsCycleCollectionParticipant_h__
 40
 41#include "nsISupports.h"
 42
 43// NOTE: If you use header files to define DEBUG_CC, you must do so here
 44// *and* in nsCycleCollector.h
 45//#define DEBUG_CC
 46
 47#ifdef DEBUG_CC
 48#define IF_DEBUG_CC_PARAM(_p) , _p
 49#define IF_DEBUG_CC_ONLY_PARAM(_p) _p
 50#else
 51#define IF_DEBUG_CC_PARAM(_p)
 52#define IF_DEBUG_CC_ONLY_PARAM(_p)
 53#endif
 54
 55#define NS_CYCLECOLLECTIONPARTICIPANT_IID                                      \
 56{                                                                              \
 57    0x9674489b,                                                                \
 58    0x1f6f,                                                                    \
 59    0x4550,                                                                    \
 60    { 0xa7, 0x30, 0xcc, 0xae, 0xdd, 0x10, 0x4c, 0xf9 }                         \
 61}
 62
 63/**
 64 * Special IID to get at the base nsISupports for a class. Usually this is the
 65 * canonical nsISupports pointer, but in the case of tearoffs for example it is
 66 * the base nsISupports pointer of the tearoff. This allow the cycle collector
 67 * to have separate nsCycleCollectionParticipant's for tearoffs or aggregated
 68 * classes.
 69 */
 70#define NS_CYCLECOLLECTIONISUPPORTS_IID                                        \
 71{                                                                              \
 72    0xc61eac14,                                                                \
 73    0x5f7a,                                                                    \
 74    0x4481,                                                                    \
 75    { 0x96, 0x5e, 0x7e, 0xaa, 0x6e, 0xff, 0xa8, 0x5f }                         \
 76}
 77
 78/**
 79 * Just holds the IID so NS_GET_IID works.
 80 */
 81class nsCycleCollectionISupports
 82{
 83public:
 84    NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONISUPPORTS_IID)
 85};
 86
 87NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionISupports, 
 88                              NS_CYCLECOLLECTIONISUPPORTS_IID)
 89
 90class nsCycleCollectionParticipant;
 91
 92enum CCNodeType { RefCounted, GCMarked, GCUnmarked };
 93
 94class NS_NO_VTABLE nsCycleCollectionTraversalCallback
 95{
 96public:
 97    // If type is RefCounted you must call DescribeNode() with an accurate
 98    // refcount, otherwise cycle collection will fail, and probably crash.
 99    // If type is not refcounted then the refcount will be ignored.
100#ifdef DEBUG_CC
101    NS_IMETHOD_(void) DescribeNode(CCNodeType type,
102                                   nsrefcnt refcount,
103                                   size_t objsz,
104                                   const char *objname) = 0;
105#else
106    NS_IMETHOD_(void) DescribeNode(CCNodeType type,
107                                   nsrefcnt refcount) = 0;
108#endif
109    NS_IMETHOD_(void) NoteXPCOMRoot(nsISupports *root) = 0;
110    NS_IMETHOD_(void) NoteRoot(PRUint32 langID, void *root,
111                               nsCycleCollectionParticipant* helper) = 0;
112    NS_IMETHOD_(void) NoteScriptChild(PRUint32 langID, void *child) = 0;
113    NS_IMETHOD_(void) NoteXPCOMChild(nsISupports *child) = 0;
114    NS_IMETHOD_(void) NoteNativeChild(void *child,
115                                      nsCycleCollectionParticipant *helper) = 0;
116#ifdef DEBUG_CC
117    // Give a name to the edge associated with the next call to
118    // NoteScriptChild, NoteXPCOMChild, or NoteNativeChild.
119    NS_IMETHOD_(void) NoteNextEdgeName(const char* name) = 0;
120#endif
121};
122
123class NS_NO_VTABLE nsCycleCollectionParticipant
124{
125public:
126    NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONPARTICIPANT_IID)
127
128    NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb) = 0;
129
130    NS_IMETHOD RootAndUnlinkJSObjects(void *p) = 0;
131    NS_IMETHOD Unlink(void *p) = 0;
132    NS_IMETHOD Unroot(void *p) = 0;
133};
134
135NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionParticipant, 
136                              NS_CYCLECOLLECTIONPARTICIPANT_IID)
137
138#undef IMETHOD_VISIBILITY
139#define IMETHOD_VISIBILITY NS_COM_GLUE
140
141typedef void
142(* PR_CALLBACK TraceCallback)(PRUint32 langID, void *p, void *closure);
143
144class NS_NO_VTABLE nsScriptObjectTracer : public nsCycleCollectionParticipant
145{
146public:
147    NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure) = 0;
148    void NS_COM_GLUE TraverseScriptObjects(void *p,
149                                        nsCycleCollectionTraversalCallback &cb);
150};
151
152class NS_COM_GLUE nsXPCOMCycleCollectionParticipant
153    : public nsScriptObjectTracer
154{
155public:
156    NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb);
157
158    NS_IMETHOD RootAndUnlinkJSObjects(void *p);
159    NS_IMETHOD Unlink(void *p);
160    NS_IMETHOD Unroot(void *p);
161
162    NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure);
163
164    NS_IMETHOD_(void) UnmarkPurple(nsISupports *p);
165
166    PRBool CheckForRightISupports(nsISupports *s);
167};
168
169#undef IMETHOD_VISIBILITY
170#define IMETHOD_VISIBILITY NS_VISIBILITY_HIDDEN
171
172///////////////////////////////////////////////////////////////////////////////
173// Helpers for implementing a QI to nsXPCOMCycleCollectionParticipant
174///////////////////////////////////////////////////////////////////////////////
175
176#define NS_CYCLE_COLLECTION_INNERCLASS                                         \
177        cycleCollection
178
179#define NS_CYCLE_COLLECTION_CLASSNAME(_class)                                  \
180        _class::NS_CYCLE_COLLECTION_INNERCLASS
181
182#define NS_CYCLE_COLLECTION_INNERNAME                                          \
183        _cycleCollectorGlobal
184
185#define NS_CYCLE_COLLECTION_NAME(_class)                                       \
186        _class::NS_CYCLE_COLLECTION_INNERNAME
187
188#define NS_IMPL_QUERY_CYCLE_COLLECTION(_class)                                 \
189  if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) {          \
190    *aInstancePtr = & NS_CYCLE_COLLECTION_NAME(_class);                        \
191    return NS_OK;                                                              \
192  } else
193
194#define NS_IMPL_QUERY_CYCLE_COLLECTION_ISUPPORTS(_class)                       \
195  if ( aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) )                   \
196    foundInterface = NS_CYCLE_COLLECTION_CLASSNAME(_class)::Upcast(this);      \
197  else
198
199#define NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class)                        \
200  NS_IMPL_QUERY_CYCLE_COLLECTION(_class)
201
202#define NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION_ISUPPORTS(_class)              \
203  NS_IMPL_QUERY_CYCLE_COLLECTION_ISUPPORTS(_class)
204
205#define NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class)                      \
206  NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class)                              \
207  NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION_ISUPPORTS(_class)
208
209#define NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(_class)                        \
210  NS_INTERFACE_MAP_BEGIN(_class)                                               \
211    NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class)
212
213#define NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(_class)              \
214  NS_INTERFACE_MAP_BEGIN(_class)                                               \
215    NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class)
216
217#define NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(_class)  \
218  if (rv == NS_OK) return rv; \
219  nsISupports* foundInterface; \
220  NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class)
221
222#define NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(_class)            \
223  NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr)    \
224  {                                                                           \
225    NS_PRECONDITION(aInstancePtr, "null out param");                          \
226                                                                              \
227    if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) {       \
228      *aInstancePtr = &NS_CYCLE_COLLECTION_NAME(_class);                      \
229      return NS_OK;                                                           \
230    }                                                                         \
231    nsresult rv;
232
233#define NS_CYCLE_COLLECTION_UPCAST(obj, clazz)                                 \
234  NS_CYCLE_COLLECTION_CLASSNAME(clazz)::Upcast(obj)
235
236///////////////////////////////////////////////////////////////////////////////
237// Helpers for implementing nsCycleCollectionParticipant::RootAndUnlinkJSObjects
238///////////////////////////////////////////////////////////////////////////////
239
240#define NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(_class)                            \
241  NS_IMETHODIMP                                                                \
242  NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootAndUnlinkJSObjects(void *p)       \
243  {                                                                            \
244    nsISupports *s = static_cast<nsISupports*>(p);                             \
245    NS_ASSERTION(CheckForRightISupports(s),                                    \
246                 "not the nsISupports pointer we expect");                     \
247    nsXPCOMCycleCollectionParticipant::RootAndUnlinkJSObjects(s);              \
248    _class *tmp = Downcast(s);
249
250#define NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN_NATIVE(_class, _root_function)     \
251  NS_IMETHODIMP                                                                \
252  NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootAndUnlinkJSObjects(void *p)       \
253  {                                                                            \
254    _class *tmp = static_cast<_class*>(p);                                     \
255    tmp->_root_function();
256
257#define NS_IMPL_CYCLE_COLLECTION_ROOT_END                                      \
258    return NS_OK;                                                              \
259  }
260
261///////////////////////////////////////////////////////////////////////////////
262// Helpers for implementing nsCycleCollectionParticipant::Unlink
263///////////////////////////////////////////////////////////////////////////////
264
265#define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)                          \
266  NS_IMETHODIMP                                                                \
267  NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p)                       \
268  {                                                                            \
269    nsISupports *s = static_cast<nsISupports*>(p);                             \
270    NS_ASSERTION(CheckForRightISupports(s),                                    \
271                 "not the nsISupports pointer we expect");                     \
272    _class *tmp = Downcast(s);
273
274#define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(_class, _base_class)   \
275  NS_IMETHODIMP                                                                \
276  NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p)                       \
277  {                                                                            \
278    nsISupports *s = static_cast<nsISupports*>(p);                             \
279    NS_ASSERTION(CheckForRightISupports(s),                                    \
280                 "not the nsISupports pointer we expect");                     \
281    _class *tmp = static_cast<_class*>(Downcast(s));                           \
282    NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Unlink(s);
283
284#define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(_class)                   \
285  NS_IMETHODIMP                                                                \
286  NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p)                       \
287  {                                                                            \
288    _class *tmp = static_cast<_class*>(p);
289
290#define NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_field)                       \
291    tmp->_field = NULL;    
292
293#define NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(_field)                     \
294    tmp->_field.Clear();
295
296#define NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(_field)                       \
297    tmp->_field.Clear();
298
299#define NS_IMPL_CYCLE_COLLECTION_UNLINK_END                                    \
300    return NS_OK;                                                              \
301  }
302
303#define NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_class)                              \
304  NS_IMETHODIMP                                                                \
305  NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p)                       \
306  {                                                                            \
307    NS_ASSERTION(CheckForRightISupports(static_cast<nsISupports*>(p)),         \
308                 "not the nsISupports pointer we expect");                     \
309    return NS_OK;                                                              \
310  }
311
312#define NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(_class)                       \
313  NS_IMETHODIMP                                                                \
314  NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p)                       \
315  {                                                                            \
316    return NS_OK;                                                              \
317  }
318
319
320///////////////////////////////////////////////////////////////////////////////
321// Helpers for implementing nsCycleCollectionParticipant::Traverse
322///////////////////////////////////////////////////////////////////////////////
323
324#ifdef DEBUG_CC
325#define NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class)                              \
326    cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), sizeof(_class), #_class);
327#else
328#define NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class)                              \
329    cb.DescribeNode(RefCounted, tmp->mRefCnt.get());
330#endif
331
332#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class)                        \
333  NS_IMETHODIMP                                                                \
334  NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse                              \
335                         (void *p,                                             \
336                          nsCycleCollectionTraversalCallback &cb)              \
337  {                                                                            \
338    nsISupports *s = static_cast<nsISupports*>(p);                             \
339    NS_ASSERTION(CheckForRightISupports(s),                                    \
340                 "not the nsISupports pointer we expect");                     \
341    _class *tmp = Downcast(s);                                                 \
342    NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class)
343
344#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(_class, _base_class) \
345  NS_IMETHODIMP                                                                \
346  NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse                              \
347                         (void *p,                                             \
348                          nsCycleCollectionTraversalCallback &cb)              \
349  {                                                                            \
350    nsISupports *s = static_cast<nsISupports*>(p);                             \
351    NS_ASSERTION(CheckForRightISupports(s),                                    \
352                 "not the nsISupports pointer we expect");                     \
353    _class *tmp = static_cast<_class*>(Downcast(s));                           \
354    NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Traverse(s, cb);
355
356#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(_class)                 \
357  NS_IMETHODIMP                                                                \
358  NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse                              \
359                         (void *p,                                             \
360                          nsCycleCollectionTraversalCallback &cb)              \
361  {                                                                            \
362    _class *tmp = static_cast<_class*>(p);                                     \
363    NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class)
364
365#ifdef DEBUG_CC
366  #define NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(_cb, _name)                       \
367    PR_BEGIN_MACRO (_cb).NoteNextEdgeName(_name); PR_END_MACRO
368#else
369  #define NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(_cb, _name)                       \
370    PR_BEGIN_MACRO PR_END_MACRO
371#endif
372
373#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(_field)                       \
374  PR_BEGIN_MACRO                                                               \
375    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field);                           \
376    cb.NoteXPCOMChild(tmp->_field);                                            \
377  PR_END_MACRO;
378
379#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_field)                     \
380  PR_BEGIN_MACRO                                                               \
381    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field);                           \
382    cb.NoteXPCOMChild(tmp->_field.get());                                      \
383  PR_END_MACRO;
384
385#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(_field, _base)    \
386  PR_BEGIN_MACRO                                                               \
387    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field);                           \
388    cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(_base*, tmp->_field));                 \
389  PR_END_MACRO;
390
391#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(_field)                   \
392    {                                                                          \
393      PRInt32 i;                                                               \
394      for (i = 0; i < tmp->_field.Count(); ++i) {                              \
395        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field "[i]");                 \
396        cb.NoteXPCOMChild(tmp->_field[i]);                                     \
397      }                                                                        \
398    }
399
400#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(_ptr, _ptr_class, _name)  \
401  PR_BEGIN_MACRO                                                               \
402    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, _name);                             \
403    cb.NoteNativeChild(_ptr, &NS_CYCLE_COLLECTION_NAME(_ptr_class));           \
404  PR_END_MACRO;
405
406#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(_field, _field_class)  \
407  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->_field, _field_class,      \
408                                               #_field)
409
410#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY(_array, _element_class,     \
411                                                   _name)                      \
412    {                                                                          \
413      PRUint32 i, length = (_array).Length();                                  \
414      for (i = 0; i < length; ++i)                                             \
415        NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR((_array)[i],              \
416                                                     _element_class,           \
417                                                     _name "[i]");             \
418    }
419
420#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_MEMBER(_field,              \
421                                                          _element_class)      \
422    NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY(tmp->_field, _element_class,    \
423                                               #_field)
424
425#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS                       \
426    TraverseScriptObjects(tmp, cb);
427
428#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END                                  \
429    return NS_OK;                                                              \
430  }
431
432///////////////////////////////////////////////////////////////////////////////
433// Helpers for implementing nsScriptObjectTracer::Trace
434///////////////////////////////////////////////////////////////////////////////
435
436#define NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class)                           \
437  void                                                                         \
438  NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p,                        \
439                                               TraceCallback aCallback,        \
440                                               void *aClosure)                 \
441  {                                                                            \
442    nsISupports *s = static_cast<nsISupports*>(p);                             \
443    NS_ASSERTION(CheckForRightISupports(s),                                    \
444                 "not the nsISupports pointer we expect");                     \
445    _class *tmp = Downcast(s);
446
447#define NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(_class)                    \
448  void                                                                         \
449  NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p,                        \
450                                               TraceCallback aCallback,        \
451                                               void *aClosure)                 \
452  {                                                                            \
453    _class *tmp = static_cast<_class*>(p);
454
455#define NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(_langID, _object)              \
456  if (_object)                                                                 \
457    aCallback(_langID, _object, aClosure);
458
459#define NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(_langID, _field)        \
460  NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(_langID, tmp->_field)
461
462#define NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(_object)                    \
463  NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(nsIProgrammingLanguage::JAVASCRIPT,  \
464                                          _object)
465
466#define NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(_field)              \
467  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->_field)
468
469#define NS_IMPL_CYCLE_COLLECTION_TRACE_END                                     \
470  }
471
472///////////////////////////////////////////////////////////////////////////////
473// Helpers for implementing a concrete nsCycleCollectionParticipant 
474///////////////////////////////////////////////////////////////////////////////
475
476#define NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE                               \
477  static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
478
479#define NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base)           \
480public:                                                                        \
481  NS_IMETHOD Traverse(void *p,                                                 \
482                      nsCycleCollectionTraversalCallback &cb);                 \
483  NS_IMETHOD_(void) UnmarkPurple(nsISupports *s)                               \
484  {                                                                            \
485    Downcast(s)->UnmarkPurple();                                               \
486  }                                                                            \
487  static _class* Downcast(nsISupports* s)                                      \
488  {                                                                            \
489    return static_cast<_class*>(static_cast<_base*>(s));                       \
490  }                                                                            \
491  static nsISupports* Upcast(_class *p)                                        \
492  {                                                                            \
493    return NS_ISUPPORTS_CAST(_base*, p);                                       \
494  }
495
496#define NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                     \
497  NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base)                 \
498  NS_IMETHOD Unlink(void *p);
499
500#define NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _base)                \
501class NS_CYCLE_COLLECTION_INNERCLASS                                           \
502 : public nsXPCOMCycleCollectionParticipant                                    \
503{                                                                              \
504  NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                           \
505};                                                                             \
506NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
507
508#define NS_DECL_CYCLE_COLLECTION_CLASS(_class)                                 \
509  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _class)
510
511// Cycle collector helper for classes that don't want to unlink anything.
512// Note: if this is used a lot it might make sense to have a base class that
513//       doesn't do anything in RootAndUnlinkJSObjects/Unlink/Unroot.
514#define NS_DECL_CYCLE_COLLECTION_CLASS_NO_UNLINK(_class)                       \
515class NS_CYCLE_COLLECTION_INNERCLASS                                           \
516 : public nsXPCOMCycleCollectionParticipant                                    \
517{                                                                              \
518  NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _class)                \
519  NS_IMETHOD RootAndUnlinkJSObjects(void *p)                                   \
520  {                                                                            \
521    return NS_OK;                                                              \
522  }                                                                            \
523  NS_IMETHOD Unlink(void *p)                                                   \
524  {                                                                            \
525    return NS_OK;                                                              \
526  }                                                                            \
527  NS_IMETHOD Unroot(void *p)                                                   \
528  {                                                                            \
529    return NS_OK;                                                              \
530  }                                                                            \
531};                                                                             \
532NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
533
534#define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _base)  \
535class NS_CYCLE_COLLECTION_INNERCLASS                                           \
536 : public nsXPCOMCycleCollectionParticipant                                    \
537{                                                                              \
538  NS_IMETHOD RootAndUnlinkJSObjects(void *p);                                  \
539  NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                           \
540  NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure);           \
541};                                                                             \
542NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
543
544#define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(_class)  \
545  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _class)
546
547#define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(_class, _base_class)          \
548class NS_CYCLE_COLLECTION_INNERCLASS                                           \
549 : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class)                           \
550{                                                                              \
551public:                                                                        \
552  NS_IMETHOD Unlink(void *p);                                                  \
553  NS_IMETHOD Traverse(void *p,                                                 \
554                      nsCycleCollectionTraversalCallback &cb);                 \
555  static _class* Downcast(nsISupports* s)                                      \
556  {                                                                            \
557    return static_cast<_class*>(static_cast<_base_class*>(                     \
558      NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Downcast(s)));               \
559  }                                                                            \
560};                                                                             \
561NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
562
563#define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(_class,             \
564                                                           _base_class)        \
565class NS_CYCLE_COLLECTION_INNERCLASS                                           \
566 : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class)                           \
567{                                                                              \
568public:                                                                        \
569  NS_IMETHOD Traverse(void *p,                                                 \
570                      nsCycleCollectionTraversalCallback &cb);                 \
571  static _class* Downcast(nsISupports* s)                                      \
572  {                                                                            \
573    return static_cast<_class*>(static_cast<_base_class*>(                     \
574      NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Downcast(s)));               \
575  }                                                                            \
576};                                                                             \
577NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
578
579/**
580 * This implements a stub UnmarkPurple function for classes that want to be
581 * traversed but whose AddRef/Release functions don't add/remove them to/from
582 * the purple buffer. If you're just using NS_DECL_CYCLE_COLLECTING_ISUPPORTS
583 * then you don't need this.
584 */
585#define NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(_class)                    \
586  NS_IMETHODIMP_(void) UnmarkPurple()                                          \
587  {                                                                            \
588  }                                                                            \
589
590#define NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                                 \
591  NS_CYCLE_COLLECTION_CLASSNAME(_class) NS_CYCLE_COLLECTION_NAME(_class);
592
593#define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY                             \
594  public:                                                                      \
595    NS_IMETHOD RootAndUnlinkJSObjects(void *n);                                \
596    NS_IMETHOD Unlink(void *n);                                                \
597    NS_IMETHOD Unroot(void *n);                                                \
598    NS_IMETHOD Traverse(void *n,                                               \
599                      nsCycleCollectionTraversalCallback &cb);
600
601#define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(_class)                          \
602  class NS_CYCLE_COLLECTION_INNERCLASS                                         \
603   : public nsCycleCollectionParticipant                                       \
604  {                                                                            \
605     NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY                                \
606  };                                                                           \
607  NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
608
609#define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(_class)            \
610  class NS_CYCLE_COLLECTION_INNERCLASS                                         \
611   : public nsScriptObjectTracer                                               \
612  {                                                                            \
613    NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY                                 \
614    NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure);         \
615  };                                                                           \
616  NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
617
618#define NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(_class, _root_function)           \
619  NS_IMETHODIMP                                                                \
620  NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootAndUnlinkJSObjects(void *p)       \
621  {                                                                            \
622    _class *tmp = static_cast<_class*>(p);                                     \
623    tmp->_root_function();                                                     \
624    return NS_OK;                                                              \
625  }
626
627#define NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(_class, _unroot_function)       \
628  NS_IMETHODIMP                                                                \
629  NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unroot(void *p)                       \
630  {                                                                            \
631    _class *tmp = static_cast<_class*>(p);                                     \
632    tmp->_unroot_function();                                                   \
633    return NS_OK;                                                              \
634  }
635
636#define NS_IMPL_CYCLE_COLLECTION_0(_class)                                     \
637 NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                                        \
638 NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_class)                                     \
639 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class)                               \
640 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
641
642#define NS_IMPL_CYCLE_COLLECTION_1(_class, _f)                                 \
643 NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                                        \
644 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)                                 \
645 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f)                                  \
646 NS_IMPL_CYCLE_COLLECTION_UNLINK_END                                           \
647 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class)                               \
648 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f)                                \
649 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
650
651#define NS_IMPL_CYCLE_COLLECTION_2(_class, _f1, _f2)                           \
652 NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                                        \
653 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)                                 \
654 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f1)                                 \
655 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f2)                                 \
656 NS_IMPL_CYCLE_COLLECTION_UNLINK_END                                           \
657 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class)                               \
658 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f1)                               \
659 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f2)                               \
660 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
661
662#define NS_IMPL_CYCLE_COLLECTION_3(_class, _f1, _f2, _f3)                      \
663 NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                                        \
664 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)                                 \
665 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f1)                                 \
666 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f2)                                 \
667 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f3)                                 \
668 NS_IMPL_CYCLE_COLLECTION_UNLINK_END                                           \
669 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class)                               \
670 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f1)                               \
671 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f2)                               \
672 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f3)                               \
673 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
674
675#endif // nsCycleCollectionParticipant_h__