Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsWrapperCache_h___
7 #define nsWrapperCache_h___
9 #include "nsCycleCollectionParticipant.h"
10 #include "mozilla/Assertions.h"
11 #include "js/Id.h" // must come before js/RootingAPI.h
12 #include "js/Value.h" // must come before js/RootingAPI.h
13 #include "js/RootingAPI.h"
14 #include "js/TracingAPI.h"
16 class XPCWrappedNativeScope;
18 #define NS_WRAPPERCACHE_IID \
19 { 0x6f3179a1, 0x36f7, 0x4a5c, \
20 { 0x8c, 0xf1, 0xad, 0xc8, 0x7c, 0xde, 0x3e, 0x87 } }
22 /**
23 * Class to store the wrapper for an object. This can only be used with objects
24 * that only have one non-security wrapper at a time (for an XPCWrappedNative
25 * this is usually ensured by setting an explicit parent in the PreCreate hook
26 * for the class).
27 *
28 * An instance of nsWrapperCache can be gotten from an object that implements
29 * a wrapper cache by calling QueryInterface on it. Note that this breaks XPCOM
30 * rules a bit (this object doesn't derive from nsISupports).
31 *
32 * The cache can store objects other than wrappers. We allow wrappers to use a
33 * separate JSObject to store their state (mostly expandos). If the wrapper is
34 * collected and we want to preserve this state we actually store the state
35 * object in the cache.
36 *
37 * The cache can store 2 types of objects:
38 *
39 * If WRAPPER_IS_DOM_BINDING is not set (IsDOMBinding() returns false):
40 * - a slim wrapper or the JSObject of an XPCWrappedNative wrapper
41 *
42 * If WRAPPER_IS_DOM_BINDING is set (IsDOMBinding() returns true):
43 * - a DOM binding object (regular JS object or proxy)
44 *
45 * The finalizer for the wrapper clears the cache.
46 *
47 * A number of the methods are implemented in nsWrapperCacheInlines.h because we
48 * have to include some JS headers that don't play nicely with the rest of the
49 * codebase. Include nsWrapperCacheInlines.h if you need to call those methods.
50 */
51 class nsWrapperCache
52 {
53 public:
54 NS_DECLARE_STATIC_IID_ACCESSOR(NS_WRAPPERCACHE_IID)
56 nsWrapperCache() : mWrapper(nullptr), mFlags(0)
57 {
58 }
59 ~nsWrapperCache()
60 {
61 MOZ_ASSERT(!PreservingWrapper(),
62 "Destroying cache with a preserved wrapper!");
63 }
65 /**
66 * Get the cached wrapper.
67 *
68 * This getter clears the gray bit before handing out the JSObject which means
69 * that the object is guaranteed to be kept alive past the next CC.
70 */
71 JSObject* GetWrapper() const;
73 /**
74 * Get the cached wrapper.
75 *
76 * This getter does not change the color of the JSObject meaning that the
77 * object returned is not guaranteed to be kept alive past the next CC.
78 *
79 * This should only be called if you are certain that the return value won't
80 * be passed into a JS API function and that it won't be stored without being
81 * rooted (or otherwise signaling the stored value to the CC).
82 */
83 JSObject* GetWrapperPreserveColor() const
84 {
85 return GetWrapperJSObject();
86 }
88 void SetWrapper(JSObject* aWrapper)
89 {
90 MOZ_ASSERT(!PreservingWrapper(), "Clearing a preserved wrapper!");
91 MOZ_ASSERT(aWrapper, "Use ClearWrapper!");
93 SetWrapperJSObject(aWrapper);
94 }
96 /**
97 * Clear the wrapper. This should be called from the finalizer for the
98 * wrapper.
99 */
100 void ClearWrapper()
101 {
102 MOZ_ASSERT(!PreservingWrapper(), "Clearing a preserved wrapper!");
104 SetWrapperJSObject(nullptr);
105 }
107 bool PreservingWrapper()
108 {
109 return HasWrapperFlag(WRAPPER_BIT_PRESERVED);
110 }
112 void SetIsDOMBinding()
113 {
114 MOZ_ASSERT(!mWrapper && !(GetWrapperFlags() & ~WRAPPER_IS_DOM_BINDING),
115 "This flag should be set before creating any wrappers.");
116 SetWrapperFlags(WRAPPER_IS_DOM_BINDING);
117 }
119 bool IsDOMBinding() const
120 {
121 return HasWrapperFlag(WRAPPER_IS_DOM_BINDING);
122 }
124 /**
125 * Wrap the object corresponding to this wrapper cache. If non-null is
126 * returned, the object has already been stored in the wrapper cache.
127 */
128 virtual JSObject* WrapObject(JSContext* cx)
129 {
130 MOZ_ASSERT(!IsDOMBinding(), "Someone forgot to override WrapObject");
131 return nullptr;
132 }
134 /**
135 * Returns true if the object has a non-gray wrapper.
136 */
137 bool IsBlack();
139 /**
140 * Returns true if the object has a black wrapper,
141 * and all the GC things it is keeping alive are black too.
142 */
143 bool IsBlackAndDoesNotNeedTracing(nsISupports* aThis);
145 bool HasNothingToTrace(nsISupports* aThis);
147 // Only meant to be called by code that preserves a wrapper.
148 void SetPreservingWrapper(bool aPreserve)
149 {
150 if(aPreserve) {
151 SetWrapperFlags(WRAPPER_BIT_PRESERVED);
152 }
153 else {
154 UnsetWrapperFlags(WRAPPER_BIT_PRESERVED);
155 }
156 }
158 void TraceWrapper(const TraceCallbacks& aCallbacks, void* aClosure)
159 {
160 if (PreservingWrapper() && mWrapper) {
161 aCallbacks.Trace(&mWrapper, "Preserved wrapper", aClosure);
162 }
163 }
165 /*
166 * The following methods for getting and manipulating flags allow the unused
167 * bits of mFlags to be used by derived classes.
168 */
170 uint32_t GetFlags() const
171 {
172 return mFlags & ~kWrapperFlagsMask;
173 }
175 bool HasFlag(uint32_t aFlag) const
176 {
177 MOZ_ASSERT((aFlag & kWrapperFlagsMask) == 0, "Bad flag mask");
178 return !!(mFlags & aFlag);
179 }
181 void SetFlags(uint32_t aFlagsToSet)
182 {
183 MOZ_ASSERT((aFlagsToSet & kWrapperFlagsMask) == 0, "Bad flag mask");
184 mFlags |= aFlagsToSet;
185 }
187 void UnsetFlags(uint32_t aFlagsToUnset)
188 {
189 MOZ_ASSERT((aFlagsToUnset & kWrapperFlagsMask) == 0, "Bad flag mask");
190 mFlags &= ~aFlagsToUnset;
191 }
193 void PreserveWrapper(nsISupports* aScriptObjectHolder)
194 {
195 if (PreservingWrapper()) {
196 return;
197 }
199 nsISupports* ccISupports;
200 aScriptObjectHolder->QueryInterface(NS_GET_IID(nsCycleCollectionISupports),
201 reinterpret_cast<void**>(&ccISupports));
202 MOZ_ASSERT(ccISupports);
204 nsXPCOMCycleCollectionParticipant* participant;
205 CallQueryInterface(ccISupports, &participant);
206 PreserveWrapper(ccISupports, participant);
207 }
209 void PreserveWrapper(void* aScriptObjectHolder, nsScriptObjectTracer* aTracer)
210 {
211 if (PreservingWrapper()) {
212 return;
213 }
215 HoldJSObjects(aScriptObjectHolder, aTracer);
216 SetPreservingWrapper(true);
217 #ifdef DEBUG
218 // Make sure the cycle collector will be able to traverse to the wrapper.
219 CheckCCWrapperTraversal(aScriptObjectHolder, aTracer);
220 #endif
221 }
223 void ReleaseWrapper(void* aScriptObjectHolder);
225 protected:
226 void TraceWrapper(JSTracer* aTrc, const char* name)
227 {
228 if (mWrapper) {
229 JS_CallHeapObjectTracer(aTrc, &mWrapper, name);
230 }
231 }
233 void PoisonWrapper()
234 {
235 if (mWrapper) {
236 mWrapper.setToCrashOnTouch();
237 }
238 }
240 private:
241 JSObject *GetWrapperJSObject() const
242 {
243 return mWrapper;
244 }
246 void SetWrapperJSObject(JSObject* aWrapper)
247 {
248 mWrapper = aWrapper;
249 UnsetWrapperFlags(kWrapperFlagsMask & ~WRAPPER_IS_DOM_BINDING);
250 }
252 void TraceWrapperJSObject(JSTracer* aTrc, const char* aName);
254 uint32_t GetWrapperFlags() const
255 {
256 return mFlags & kWrapperFlagsMask;
257 }
259 bool HasWrapperFlag(uint32_t aFlag) const
260 {
261 MOZ_ASSERT((aFlag & ~kWrapperFlagsMask) == 0, "Bad wrapper flag bits");
262 return !!(mFlags & aFlag);
263 }
265 void SetWrapperFlags(uint32_t aFlagsToSet)
266 {
267 MOZ_ASSERT((aFlagsToSet & ~kWrapperFlagsMask) == 0, "Bad wrapper flag bits");
268 mFlags |= aFlagsToSet;
269 }
271 void UnsetWrapperFlags(uint32_t aFlagsToUnset)
272 {
273 MOZ_ASSERT((aFlagsToUnset & ~kWrapperFlagsMask) == 0, "Bad wrapper flag bits");
274 mFlags &= ~aFlagsToUnset;
275 }
277 static void HoldJSObjects(void* aScriptObjectHolder,
278 nsScriptObjectTracer* aTracer);
280 #ifdef DEBUG
281 void CheckCCWrapperTraversal(void* aScriptObjectHolder,
282 nsScriptObjectTracer* aTracer);
283 #endif // DEBUG
285 /**
286 * If this bit is set then we're preserving the wrapper, which in effect ties
287 * the lifetime of the JS object stored in the cache to the lifetime of the
288 * native object. We rely on the cycle collector to break the cycle that this
289 * causes between the native object and the JS object, so it is important that
290 * any native object that supports preserving of its wrapper
291 * traces/traverses/unlinks the cached JS object (see
292 * NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER,
293 * NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS and
294 * NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER).
295 */
296 enum { WRAPPER_BIT_PRESERVED = 1 << 0 };
298 /**
299 * If this bit is set then the wrapper for the native object is a DOM binding
300 * (regular JS object or proxy).
301 */
302 enum { WRAPPER_IS_DOM_BINDING = 1 << 1 };
304 enum { kWrapperFlagsMask = (WRAPPER_BIT_PRESERVED | WRAPPER_IS_DOM_BINDING) };
306 JS::Heap<JSObject*> mWrapper;
307 uint32_t mFlags;
308 };
310 enum { WRAPPER_CACHE_FLAGS_BITS_USED = 2 };
312 NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID)
314 #define NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY \
315 if ( aIID.Equals(NS_GET_IID(nsWrapperCache)) ) { \
316 *aInstancePtr = static_cast<nsWrapperCache*>(this); \
317 return NS_OK; \
318 }
321 // Cycle collector macros for wrapper caches.
323 #define NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
324 tmp->TraceWrapper(aCallbacks, aClosure);
326 #define NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
327 tmp->ReleaseWrapper(p);
329 #define NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) \
330 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class) \
331 NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
332 NS_IMPL_CYCLE_COLLECTION_TRACE_END
334 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(_class) \
335 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
336 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
337 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
338 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
339 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
340 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
341 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
342 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
344 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(_class, _field) \
345 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
346 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
347 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field) \
348 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
349 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
350 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
351 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field) \
352 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
353 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
354 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
356 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(_class, _field1,\
357 _field2) \
358 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
359 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
360 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
361 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
362 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
363 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
364 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
365 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
366 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
367 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
368 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
369 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
371 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(_class, _field1,\
372 _field2, \
373 _field3) \
374 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
375 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
376 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
377 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
378 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
379 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
380 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
381 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
382 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
383 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
384 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
385 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
386 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
387 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
389 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_4(_class, _field1,\
390 _field2, \
391 _field3, \
392 _field4) \
393 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
394 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
395 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
396 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
397 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
398 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \
399 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
400 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
401 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
402 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
403 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
404 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
405 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \
406 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
407 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
408 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
410 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_5(_class, _field1,\
411 _field2, \
412 _field3, \
413 _field4, \
414 _field5) \
415 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
416 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
417 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
418 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
419 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
420 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \
421 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \
422 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
423 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
424 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
425 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
426 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
427 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
428 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \
429 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \
430 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
431 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
432 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
434 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_6(_class, _field1,\
435 _field2, \
436 _field3, \
437 _field4, \
438 _field5, \
439 _field6) \
440 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
441 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
442 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
443 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
444 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
445 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \
446 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \
447 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \
448 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
449 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
450 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
451 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
452 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
453 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
454 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \
455 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \
456 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \
457 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
458 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
459 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
461 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_7(_class, _field1,\
462 _field2, \
463 _field3, \
464 _field4, \
465 _field5, \
466 _field6, \
467 _field7) \
468 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
469 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
470 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
471 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
472 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
473 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \
474 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \
475 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \
476 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7) \
477 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
478 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
479 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
480 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
481 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
482 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
483 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \
484 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \
485 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \
486 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \
487 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
488 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
489 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
491 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_8(_class, _field1,\
492 _field2, \
493 _field3, \
494 _field4, \
495 _field5, \
496 _field6, \
497 _field7, \
498 _field8) \
499 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
500 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
501 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
502 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
503 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
504 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \
505 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \
506 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \
507 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7) \
508 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field8) \
509 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
510 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
511 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
512 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
513 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
514 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
515 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \
516 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \
517 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \
518 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \
519 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8) \
520 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
521 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
522 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
524 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_9(_class, _field1,\
525 _field2, \
526 _field3, \
527 _field4, \
528 _field5, \
529 _field6, \
530 _field7, \
531 _field8, \
532 _field9) \
533 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
534 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
535 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
536 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
537 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
538 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \
539 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \
540 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \
541 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7) \
542 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field8) \
543 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field9) \
544 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
545 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
546 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
547 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
548 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
549 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
550 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \
551 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \
552 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \
553 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \
554 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8) \
555 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9) \
556 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
557 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
558 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
560 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_10(_class, _field1,\
561 _field2, \
562 _field3, \
563 _field4, \
564 _field5, \
565 _field6, \
566 _field7, \
567 _field8, \
568 _field9, \
569 _field10) \
570 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
571 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
572 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
573 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
574 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
575 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \
576 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \
577 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \
578 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7) \
579 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field8) \
580 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field9) \
581 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field10) \
582 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
583 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
584 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
585 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
586 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
587 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
588 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \
589 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \
590 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \
591 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \
592 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8) \
593 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9) \
594 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field10) \
595 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
596 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
597 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
599 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_11(_class, \
600 _field1, \
601 _field2, \
602 _field3, \
603 _field4, \
604 _field5, \
605 _field6, \
606 _field7, \
607 _field8, \
608 _field9, \
609 _field10, \
610 _field11) \
611 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
612 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
613 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
614 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
615 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
616 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \
617 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \
618 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \
619 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7) \
620 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field8) \
621 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field9) \
622 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field10) \
623 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field11) \
624 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
625 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
626 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
627 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
628 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
629 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
630 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \
631 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \
632 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \
633 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \
634 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8) \
635 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9) \
636 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field10) \
637 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field11) \
638 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
639 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
640 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
642 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_12(_class, \
643 _field1, \
644 _field2, \
645 _field3, \
646 _field4, \
647 _field5, \
648 _field6, \
649 _field7, \
650 _field8, \
651 _field9, \
652 _field10, \
653 _field11, \
654 _field12) \
655 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
656 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
657 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
658 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
659 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
660 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \
661 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \
662 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \
663 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7) \
664 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field8) \
665 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field9) \
666 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field10) \
667 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field11) \
668 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field12) \
669 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
670 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
671 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
672 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
673 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
674 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
675 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \
676 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \
677 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \
678 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \
679 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8) \
680 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9) \
681 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field10) \
682 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field11) \
683 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field12) \
684 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
685 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
686 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
688 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_13(_class, \
689 _field1, \
690 _field2, \
691 _field3, \
692 _field4, \
693 _field5, \
694 _field6, \
695 _field7, \
696 _field8, \
697 _field9, \
698 _field10, \
699 _field11, \
700 _field12, \
701 _field13) \
702 NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
703 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
704 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
705 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
706 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
707 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \
708 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \
709 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \
710 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7) \
711 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field8) \
712 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field9) \
713 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field10) \
714 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field11) \
715 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field12) \
716 NS_IMPL_CYCLE_COLLECTION_UNLINK(_field13) \
717 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
718 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
719 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
720 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
721 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
722 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
723 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \
724 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \
725 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \
726 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \
727 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8) \
728 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9) \
729 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field10) \
730 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field11) \
731 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field12) \
732 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field13) \
733 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
734 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
735 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
737 #endif /* nsWrapperCache_h___ */