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: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set ts=8 sts=4 et sw=4 tw=99: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* Manage the shared info about interfaces for use by wrappedNatives. */
9 #include "xpcprivate.h"
10 #include "jswrapper.h"
11 #include "nsCxPusher.h"
13 #include "mozilla/MemoryReporting.h"
14 #include "mozilla/XPTInterfaceInfoManager.h"
16 using namespace JS;
17 using namespace mozilla;
19 /***************************************************************************/
21 // XPCNativeMember
23 // static
24 bool
25 XPCNativeMember::GetCallInfo(JSObject* funobj,
26 XPCNativeInterface** pInterface,
27 XPCNativeMember** pMember)
28 {
29 funobj = js::UncheckedUnwrap(funobj);
30 jsval ifaceVal = js::GetFunctionNativeReserved(funobj, 0);
31 jsval memberVal = js::GetFunctionNativeReserved(funobj, 1);
33 *pInterface = (XPCNativeInterface*) JSVAL_TO_PRIVATE(ifaceVal);
34 *pMember = (XPCNativeMember*) JSVAL_TO_PRIVATE(memberVal);
36 return true;
37 }
39 bool
40 XPCNativeMember::NewFunctionObject(XPCCallContext& ccx,
41 XPCNativeInterface* iface, HandleObject parent,
42 jsval* pval)
43 {
44 MOZ_ASSERT(!IsConstant(), "Only call this if you're sure this is not a constant!");
46 return Resolve(ccx, iface, parent, pval);
47 }
49 bool
50 XPCNativeMember::Resolve(XPCCallContext& ccx, XPCNativeInterface* iface,
51 HandleObject parent, jsval *vp)
52 {
53 if (IsConstant()) {
54 const nsXPTConstant* constant;
55 if (NS_FAILED(iface->GetInterfaceInfo()->GetConstant(mIndex, &constant)))
56 return false;
58 const nsXPTCMiniVariant& mv = *constant->GetValue();
60 // XXX Big Hack!
61 nsXPTCVariant v;
62 v.flags = 0;
63 v.type = constant->GetType();
64 memcpy(&v.val, &mv.val, sizeof(mv.val));
66 RootedValue resultVal(ccx);
68 if (!XPCConvert::NativeData2JS(&resultVal, &v.val, v.type, nullptr, nullptr))
69 return false;
71 *vp = resultVal;
73 return true;
74 }
75 // else...
77 // This is a method or attribute - we'll be needing a function object
79 int argc;
80 JSNative callback;
82 if (IsMethod()) {
83 const nsXPTMethodInfo* info;
84 if (NS_FAILED(iface->GetInterfaceInfo()->GetMethodInfo(mIndex, &info)))
85 return false;
87 // Note: ASSUMES that retval is last arg.
88 argc = (int) info->GetParamCount();
89 if (argc && info->GetParam((uint8_t)(argc-1)).IsRetval())
90 argc-- ;
92 callback = XPC_WN_CallMethod;
93 } else {
94 argc = 0;
95 callback = XPC_WN_GetterSetter;
96 }
98 JSFunction *fun = js::NewFunctionByIdWithReserved(ccx, callback, argc, 0, parent, GetName());
99 if (!fun)
100 return false;
102 JSObject* funobj = JS_GetFunctionObject(fun);
103 if (!funobj)
104 return false;
106 js::SetFunctionNativeReserved(funobj, 0, PRIVATE_TO_JSVAL(iface));
107 js::SetFunctionNativeReserved(funobj, 1, PRIVATE_TO_JSVAL(this));
109 *vp = OBJECT_TO_JSVAL(funobj);
111 return true;
112 }
114 /***************************************************************************/
115 // XPCNativeInterface
117 // static
118 XPCNativeInterface*
119 XPCNativeInterface::GetNewOrUsed(const nsIID* iid)
120 {
121 AutoJSContext cx;
122 AutoMarkingNativeInterfacePtr iface(cx);
123 XPCJSRuntime* rt = XPCJSRuntime::Get();
125 IID2NativeInterfaceMap* map = rt->GetIID2NativeInterfaceMap();
126 if (!map)
127 return nullptr;
129 iface = map->Find(*iid);
131 if (iface)
132 return iface;
134 nsCOMPtr<nsIInterfaceInfo> info;
135 XPTInterfaceInfoManager::GetSingleton()->GetInfoForIID(iid, getter_AddRefs(info));
136 if (!info)
137 return nullptr;
139 iface = NewInstance(info);
140 if (!iface)
141 return nullptr;
143 XPCNativeInterface* iface2 = map->Add(iface);
144 if (!iface2) {
145 NS_ERROR("failed to add our interface!");
146 DestroyInstance(iface);
147 iface = nullptr;
148 } else if (iface2 != iface) {
149 DestroyInstance(iface);
150 iface = iface2;
151 }
153 return iface;
154 }
156 // static
157 XPCNativeInterface*
158 XPCNativeInterface::GetNewOrUsed(nsIInterfaceInfo* info)
159 {
160 AutoJSContext cx;
161 AutoMarkingNativeInterfacePtr iface(cx);
163 const nsIID* iid;
164 if (NS_FAILED(info->GetIIDShared(&iid)) || !iid)
165 return nullptr;
167 XPCJSRuntime* rt = XPCJSRuntime::Get();
169 IID2NativeInterfaceMap* map = rt->GetIID2NativeInterfaceMap();
170 if (!map)
171 return nullptr;
173 iface = map->Find(*iid);
175 if (iface)
176 return iface;
178 iface = NewInstance(info);
179 if (!iface)
180 return nullptr;
182 XPCNativeInterface* iface2 = map->Add(iface);
183 if (!iface2) {
184 NS_ERROR("failed to add our interface!");
185 DestroyInstance(iface);
186 iface = nullptr;
187 } else if (iface2 != iface) {
188 DestroyInstance(iface);
189 iface = iface2;
190 }
192 return iface;
193 }
195 // static
196 XPCNativeInterface*
197 XPCNativeInterface::GetNewOrUsed(const char* name)
198 {
199 nsCOMPtr<nsIInterfaceInfo> info;
200 XPTInterfaceInfoManager::GetSingleton()->GetInfoForName(name, getter_AddRefs(info));
201 return info ? GetNewOrUsed(info) : nullptr;
202 }
204 // static
205 XPCNativeInterface*
206 XPCNativeInterface::GetISupports()
207 {
208 // XXX We should optimize this to cache this common XPCNativeInterface.
209 return GetNewOrUsed(&NS_GET_IID(nsISupports));
210 }
212 // static
213 XPCNativeInterface*
214 XPCNativeInterface::NewInstance(nsIInterfaceInfo* aInfo)
215 {
216 AutoJSContext cx;
217 static const uint16_t MAX_LOCAL_MEMBER_COUNT = 16;
218 XPCNativeMember local_members[MAX_LOCAL_MEMBER_COUNT];
219 XPCNativeInterface* obj = nullptr;
220 XPCNativeMember* members = nullptr;
222 int i;
223 bool failed = false;
224 uint16_t constCount;
225 uint16_t methodCount;
226 uint16_t totalCount;
227 uint16_t realTotalCount = 0;
228 XPCNativeMember* cur;
229 RootedString str(cx);
230 RootedId interfaceName(cx);
232 // XXX Investigate lazy init? This is a problem given the
233 // 'placement new' scheme - we need to at least know how big to make
234 // the object. We might do a scan of methods to determine needed size,
235 // then make our object, but avoid init'ing *any* members until asked?
236 // Find out how often we create these objects w/o really looking at
237 // (or using) the members.
239 bool canScript;
240 if (NS_FAILED(aInfo->IsScriptable(&canScript)) || !canScript)
241 return nullptr;
243 if (NS_FAILED(aInfo->GetMethodCount(&methodCount)) ||
244 NS_FAILED(aInfo->GetConstantCount(&constCount)))
245 return nullptr;
247 // If the interface does not have nsISupports in its inheritance chain
248 // then we know we can't reflect its methods. However, some interfaces that
249 // are used just to reflect constants are declared this way. We need to
250 // go ahead and build the thing. But, we'll ignore whatever methods it may
251 // have.
252 if (!nsXPConnect::IsISupportsDescendant(aInfo))
253 methodCount = 0;
255 totalCount = methodCount + constCount;
257 if (totalCount > MAX_LOCAL_MEMBER_COUNT) {
258 members = new XPCNativeMember[totalCount];
259 if (!members)
260 return nullptr;
261 } else {
262 members = local_members;
263 }
265 // NOTE: since getters and setters share a member, we might not use all
266 // of the member objects.
268 for (i = 0; i < methodCount; i++) {
269 const nsXPTMethodInfo* info;
270 if (NS_FAILED(aInfo->GetMethodInfo(i, &info))) {
271 failed = true;
272 break;
273 }
275 // don't reflect Addref or Release
276 if (i == 1 || i == 2)
277 continue;
279 if (!XPCConvert::IsMethodReflectable(*info))
280 continue;
282 str = JS_InternString(cx, info->GetName());
283 if (!str) {
284 NS_ERROR("bad method name");
285 failed = true;
286 break;
287 }
288 jsid name = INTERNED_STRING_TO_JSID(cx, str);
290 if (info->IsSetter()) {
291 MOZ_ASSERT(realTotalCount,"bad setter");
292 // Note: ASSUMES Getter/Setter pairs are next to each other
293 // This is a rule of the typelib spec.
294 cur = &members[realTotalCount-1];
295 MOZ_ASSERT(cur->GetName() == name,"bad setter");
296 MOZ_ASSERT(cur->IsReadOnlyAttribute(),"bad setter");
297 MOZ_ASSERT(cur->GetIndex() == i-1,"bad setter");
298 cur->SetWritableAttribute();
299 } else {
300 // XXX need better way to find dups
301 // MOZ_ASSERT(!LookupMemberByID(name),"duplicate method name");
302 cur = &members[realTotalCount++];
303 cur->SetName(name);
304 if (info->IsGetter())
305 cur->SetReadOnlyAttribute(i);
306 else
307 cur->SetMethod(i);
308 }
309 }
311 if (!failed) {
312 for (i = 0; i < constCount; i++) {
313 const nsXPTConstant* constant;
314 if (NS_FAILED(aInfo->GetConstant(i, &constant))) {
315 failed = true;
316 break;
317 }
319 str = JS_InternString(cx, constant->GetName());
320 if (!str) {
321 NS_ERROR("bad constant name");
322 failed = true;
323 break;
324 }
325 jsid name = INTERNED_STRING_TO_JSID(cx, str);
327 // XXX need better way to find dups
328 //MOZ_ASSERT(!LookupMemberByID(name),"duplicate method/constant name");
330 cur = &members[realTotalCount++];
331 cur->SetName(name);
332 cur->SetConstant(i);
333 }
334 }
336 if (!failed) {
337 const char* bytes;
338 if (NS_FAILED(aInfo->GetNameShared(&bytes)) || !bytes ||
339 nullptr == (str = JS_InternString(cx, bytes))) {
340 failed = true;
341 }
342 interfaceName = INTERNED_STRING_TO_JSID(cx, str);
343 }
345 if (!failed) {
346 // Use placement new to create an object with the right amount of space
347 // to hold the members array
348 int size = sizeof(XPCNativeInterface);
349 if (realTotalCount > 1)
350 size += (realTotalCount - 1) * sizeof(XPCNativeMember);
351 void* place = new char[size];
352 if (place)
353 obj = new(place) XPCNativeInterface(aInfo, interfaceName);
355 if (obj) {
356 obj->mMemberCount = realTotalCount;
357 // copy valid members
358 if (realTotalCount)
359 memcpy(obj->mMembers, members,
360 realTotalCount * sizeof(XPCNativeMember));
361 }
362 }
364 if (members && members != local_members)
365 delete [] members;
367 return obj;
368 }
370 // static
371 void
372 XPCNativeInterface::DestroyInstance(XPCNativeInterface* inst)
373 {
374 inst->~XPCNativeInterface();
375 delete [] (char*) inst;
376 }
378 size_t
379 XPCNativeInterface::SizeOfIncludingThis(MallocSizeOf mallocSizeOf)
380 {
381 return mallocSizeOf(this);
382 }
384 void
385 XPCNativeInterface::DebugDump(int16_t depth)
386 {
387 #ifdef DEBUG
388 depth--;
389 XPC_LOG_ALWAYS(("XPCNativeInterface @ %x", this));
390 XPC_LOG_INDENT();
391 XPC_LOG_ALWAYS(("name is %s", GetNameString()));
392 XPC_LOG_ALWAYS(("mMemberCount is %d", mMemberCount));
393 XPC_LOG_ALWAYS(("mInfo @ %x", mInfo.get()));
394 XPC_LOG_OUTDENT();
395 #endif
396 }
398 /***************************************************************************/
399 // XPCNativeSet
401 // static
402 XPCNativeSet*
403 XPCNativeSet::GetNewOrUsed(const nsIID* iid)
404 {
405 AutoJSContext cx;
406 AutoMarkingNativeSetPtr set(cx);
408 AutoMarkingNativeInterfacePtr iface(cx);
409 iface = XPCNativeInterface::GetNewOrUsed(iid);
410 if (!iface)
411 return nullptr;
413 XPCNativeSetKey key(nullptr, iface, 0);
415 XPCJSRuntime* rt = XPCJSRuntime::Get();
416 NativeSetMap* map = rt->GetNativeSetMap();
417 if (!map)
418 return nullptr;
420 set = map->Find(&key);
422 if (set)
423 return set;
425 // hacky way to get a XPCNativeInterface** using the AutoPtr
426 XPCNativeInterface* temp[] = {iface};
427 set = NewInstance(temp, 1);
428 if (!set)
429 return nullptr;
431 XPCNativeSet* set2 = map->Add(&key, set);
432 if (!set2) {
433 NS_ERROR("failed to add our set!");
434 DestroyInstance(set);
435 set = nullptr;
436 } else if (set2 != set) {
437 DestroyInstance(set);
438 set = set2;
439 }
441 return set;
442 }
444 // static
445 XPCNativeSet*
446 XPCNativeSet::GetNewOrUsed(nsIClassInfo* classInfo)
447 {
448 AutoJSContext cx;
449 AutoMarkingNativeSetPtr set(cx);
450 XPCJSRuntime* rt = XPCJSRuntime::Get();
452 ClassInfo2NativeSetMap* map = rt->GetClassInfo2NativeSetMap();
453 if (!map)
454 return nullptr;
456 set = map->Find(classInfo);
458 if (set)
459 return set;
461 nsIID** iidArray = nullptr;
462 AutoMarkingNativeInterfacePtrArrayPtr interfaceArray(cx);
463 uint32_t iidCount = 0;
465 if (NS_FAILED(classInfo->GetInterfaces(&iidCount, &iidArray))) {
466 // Note: I'm making it OK for this call to fail so that one can add
467 // nsIClassInfo to classes implemented in script without requiring this
468 // method to be implemented.
470 // Make sure these are set correctly...
471 iidArray = nullptr;
472 iidCount = 0;
473 }
475 MOZ_ASSERT((iidCount && iidArray) || !(iidCount || iidArray), "GetInterfaces returned bad array");
477 // !!! from here on we only exit through the 'out' label !!!
479 if (iidCount) {
480 AutoMarkingNativeInterfacePtrArrayPtr
481 arr(cx, new XPCNativeInterface*[iidCount], iidCount, true);
483 interfaceArray = arr;
485 XPCNativeInterface** currentInterface = interfaceArray;
486 nsIID** currentIID = iidArray;
487 uint16_t interfaceCount = 0;
489 for (uint32_t i = 0; i < iidCount; i++) {
490 nsIID* iid = *(currentIID++);
491 if (!iid) {
492 NS_ERROR("Null found in classinfo interface list");
493 continue;
494 }
496 XPCNativeInterface* iface =
497 XPCNativeInterface::GetNewOrUsed(iid);
499 if (!iface) {
500 // XXX warn here
501 continue;
502 }
504 *(currentInterface++) = iface;
505 interfaceCount++;
506 }
508 if (interfaceCount) {
509 set = NewInstance(interfaceArray, interfaceCount);
510 if (set) {
511 NativeSetMap* map2 = rt->GetNativeSetMap();
512 if (!map2)
513 goto out;
515 XPCNativeSetKey key(set, nullptr, 0);
517 XPCNativeSet* set2 = map2->Add(&key, set);
518 if (!set2) {
519 NS_ERROR("failed to add our set!");
520 DestroyInstance(set);
521 set = nullptr;
522 goto out;
523 }
524 if (set2 != set) {
525 DestroyInstance(set);
526 set = set2;
527 }
528 }
529 } else
530 set = GetNewOrUsed(&NS_GET_IID(nsISupports));
531 } else
532 set = GetNewOrUsed(&NS_GET_IID(nsISupports));
534 if (set) {
535 #ifdef DEBUG
536 XPCNativeSet* set2 =
537 #endif
538 map->Add(classInfo, set);
539 MOZ_ASSERT(set2, "failed to add our set!");
540 MOZ_ASSERT(set2 == set, "hashtables inconsistent!");
541 }
543 out:
544 if (iidArray)
545 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(iidCount, iidArray);
546 if (interfaceArray)
547 delete [] interfaceArray.get();
549 return set;
550 }
552 // static
553 void
554 XPCNativeSet::ClearCacheEntryForClassInfo(nsIClassInfo* classInfo)
555 {
556 XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
557 ClassInfo2NativeSetMap* map = rt->GetClassInfo2NativeSetMap();
558 if (map)
559 map->Remove(classInfo);
560 }
562 // static
563 XPCNativeSet*
564 XPCNativeSet::GetNewOrUsed(XPCNativeSet* otherSet,
565 XPCNativeInterface* newInterface,
566 uint16_t position)
567 {
568 AutoJSContext cx;
569 AutoMarkingNativeSetPtr set(cx);
570 XPCJSRuntime* rt = XPCJSRuntime::Get();
571 NativeSetMap* map = rt->GetNativeSetMap();
572 if (!map)
573 return nullptr;
575 XPCNativeSetKey key(otherSet, newInterface, position);
577 set = map->Find(&key);
579 if (set)
580 return set;
582 if (otherSet)
583 set = NewInstanceMutate(otherSet, newInterface, position);
584 else
585 set = NewInstance(&newInterface, 1);
587 if (!set)
588 return nullptr;
590 XPCNativeSet* set2 = map->Add(&key, set);
591 if (!set2) {
592 NS_ERROR("failed to add our set!");
593 DestroyInstance(set);
594 set = nullptr;
595 } else if (set2 != set) {
596 DestroyInstance(set);
597 set = set2;
598 }
600 return set;
601 }
603 // static
604 XPCNativeSet*
605 XPCNativeSet::GetNewOrUsed(XPCNativeSet* firstSet,
606 XPCNativeSet* secondSet,
607 bool preserveFirstSetOrder)
608 {
609 // Figure out how many interfaces we'll need in the new set.
610 uint32_t uniqueCount = firstSet->mInterfaceCount;
611 for (uint32_t i = 0; i < secondSet->mInterfaceCount; ++i) {
612 if (!firstSet->HasInterface(secondSet->mInterfaces[i]))
613 uniqueCount++;
614 }
616 // If everything in secondSet was a duplicate, we can just use the first
617 // set.
618 if (uniqueCount == firstSet->mInterfaceCount)
619 return firstSet;
621 // If the secondSet is just a superset of the first, we can use it provided
622 // that the caller doesn't care about ordering.
623 if (!preserveFirstSetOrder && uniqueCount == secondSet->mInterfaceCount)
624 return secondSet;
626 // Ok, darn. Now we have to make a new set.
627 //
628 // It would be faster to just create the new set all at once, but that
629 // would involve wrangling with some pretty hairy code - especially since
630 // a lot of stuff assumes that sets are created by adding one interface to an
631 // existing set. So let's just do the slow and easy thing and hope that the
632 // above optimizations handle the common cases.
633 XPCNativeSet* currentSet = firstSet;
634 for (uint32_t i = 0; i < secondSet->mInterfaceCount; ++i) {
635 XPCNativeInterface* iface = secondSet->mInterfaces[i];
636 if (!currentSet->HasInterface(iface)) {
637 // Create a new augmented set, inserting this interface at the end.
638 uint32_t pos = currentSet->mInterfaceCount;
639 currentSet = XPCNativeSet::GetNewOrUsed(currentSet, iface, pos);
640 if (!currentSet)
641 return nullptr;
642 }
643 }
645 // We've got the union set. Hand it back to the caller.
646 MOZ_ASSERT(currentSet->mInterfaceCount == uniqueCount);
647 return currentSet;
648 }
650 // static
651 XPCNativeSet*
652 XPCNativeSet::NewInstance(XPCNativeInterface** array,
653 uint16_t count)
654 {
655 XPCNativeSet* obj = nullptr;
657 if (!array || !count)
658 return nullptr;
660 // We impose the invariant:
661 // "All sets have exactly one nsISupports interface and it comes first."
662 // This is the place where we impose that rule - even if given inputs
663 // that don't exactly follow the rule.
665 XPCNativeInterface* isup = XPCNativeInterface::GetISupports();
666 uint16_t slots = count+1;
668 uint16_t i;
669 XPCNativeInterface** pcur;
671 for (i = 0, pcur = array; i < count; i++, pcur++) {
672 if (*pcur == isup)
673 slots--;
674 }
676 // Use placement new to create an object with the right amount of space
677 // to hold the members array
678 int size = sizeof(XPCNativeSet);
679 if (slots > 1)
680 size += (slots - 1) * sizeof(XPCNativeInterface*);
681 void* place = new char[size];
682 if (place)
683 obj = new(place) XPCNativeSet();
685 if (obj) {
686 // Stick the nsISupports in front and skip additional nsISupport(s)
687 XPCNativeInterface** inp = array;
688 XPCNativeInterface** outp = (XPCNativeInterface**) &obj->mInterfaces;
689 uint16_t memberCount = 1; // for the one member in nsISupports
691 *(outp++) = isup;
693 for (i = 0; i < count; i++) {
694 XPCNativeInterface* cur;
696 if (isup == (cur = *(inp++)))
697 continue;
698 *(outp++) = cur;
699 memberCount += cur->GetMemberCount();
700 }
701 obj->mMemberCount = memberCount;
702 obj->mInterfaceCount = slots;
703 }
705 return obj;
706 }
708 // static
709 XPCNativeSet*
710 XPCNativeSet::NewInstanceMutate(XPCNativeSet* otherSet,
711 XPCNativeInterface* newInterface,
712 uint16_t position)
713 {
714 XPCNativeSet* obj = nullptr;
716 if (!newInterface)
717 return nullptr;
718 if (otherSet && position > otherSet->mInterfaceCount)
719 return nullptr;
721 // Use placement new to create an object with the right amount of space
722 // to hold the members array
723 int size = sizeof(XPCNativeSet);
724 if (otherSet)
725 size += otherSet->mInterfaceCount * sizeof(XPCNativeInterface*);
726 void* place = new char[size];
727 if (place)
728 obj = new(place) XPCNativeSet();
730 if (obj) {
731 if (otherSet) {
732 obj->mMemberCount = otherSet->GetMemberCount() +
733 newInterface->GetMemberCount();
734 obj->mInterfaceCount = otherSet->mInterfaceCount + 1;
736 XPCNativeInterface** src = otherSet->mInterfaces;
737 XPCNativeInterface** dest = obj->mInterfaces;
738 for (uint16_t i = 0; i < obj->mInterfaceCount; i++) {
739 if (i == position)
740 *dest++ = newInterface;
741 else
742 *dest++ = *src++;
743 }
744 } else {
745 obj->mMemberCount = newInterface->GetMemberCount();
746 obj->mInterfaceCount = 1;
747 obj->mInterfaces[0] = newInterface;
748 }
749 }
751 return obj;
752 }
754 // static
755 void
756 XPCNativeSet::DestroyInstance(XPCNativeSet* inst)
757 {
758 inst->~XPCNativeSet();
759 delete [] (char*) inst;
760 }
762 size_t
763 XPCNativeSet::SizeOfIncludingThis(MallocSizeOf mallocSizeOf)
764 {
765 return mallocSizeOf(this);
766 }
768 void
769 XPCNativeSet::DebugDump(int16_t depth)
770 {
771 #ifdef DEBUG
772 depth--;
773 XPC_LOG_ALWAYS(("XPCNativeSet @ %x", this));
774 XPC_LOG_INDENT();
776 XPC_LOG_ALWAYS(("mInterfaceCount of %d", mInterfaceCount));
777 if (depth) {
778 for (uint16_t i = 0; i < mInterfaceCount; i++)
779 mInterfaces[i]->DebugDump(depth);
780 }
781 XPC_LOG_ALWAYS(("mMemberCount of %d", mMemberCount));
782 XPC_LOG_OUTDENT();
783 #endif
784 }