Bug 412320 - generate QI for additional classes which, according to stats, show up in profiles as frequent callers of nsID::Equals, r=biesi,ted,sicking

This commit is contained in:
benjamin@smedbergs.us 2008-02-12 11:46:26 -08:00
Родитель f680c5756b
Коммит c00f226f8e
20 изменённых файлов: 316 добавлений и 150 удалений

Просмотреть файл

@ -1199,7 +1199,7 @@ endif # COMPILER_DEPEND
endif # MOZ_AUTO_DEPS endif # MOZ_AUTO_DEPS
%QI.cpp: %.gqi $(topsrcdir)/xpcom/base/gqi.py %QI.cpp: %.gqi $(topsrcdir)/xpcom/base/gqi.py
$(PYTHON) $(topsrcdir)/xpcom/base/gqi.py $(INCLUDES) -I $(IDL_DIR) -o $@ -D $(MDDEPDIR)/$(@F).pp $< $(PYTHON) $(topsrcdir)/xpcom/base/gqi.py $(GQIFLAGS) $(INCLUDES) -I $(IDL_DIR) -o $@ -D $(MDDEPDIR)/$(@F).pp $<
# Rules for building native targets must come first because of the host_ prefix # Rules for building native targets must come first because of the host_ prefix
host_%.$(OBJ_SUFFIX): %.c Makefile Makefile.in host_%.$(OBJ_SUFFIX): %.c Makefile Makefile.in

Просмотреть файл

@ -81,6 +81,8 @@ CPPSRCS = \
nsXMLPrettyPrinter.cpp \ nsXMLPrettyPrinter.cpp \
$(NULL) $(NULL)
GQI_SRCS = xmldocument.gqi
# we don't want the shared lib, but we want to force the creation of a static lib. # we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1 FORCE_STATIC_LIB = 1

Просмотреть файл

@ -193,17 +193,6 @@ nsXMLDocument::~nsXMLDocument()
mLoopingForSyncLoad = PR_FALSE; mLoopingForSyncLoad = PR_FALSE;
} }
// QueryInterface implementation for nsXMLDocument
NS_INTERFACE_TABLE_HEAD(nsXMLDocument)
NS_INTERFACE_TABLE_INHERITED3(nsXMLDocument,
nsIInterfaceRequestor,
nsIChannelEventSink,
nsIDOMXMLDocument)
NS_INTERFACE_TABLE_TO_MAP_SEGUE
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XMLDocument)
NS_INTERFACE_MAP_END_INHERITING(nsDocument)
NS_IMPL_ADDREF_INHERITED(nsXMLDocument, nsDocument) NS_IMPL_ADDREF_INHERITED(nsXMLDocument, nsDocument)
NS_IMPL_RELEASE_INHERITED(nsXMLDocument, nsDocument) NS_IMPL_RELEASE_INHERITED(nsXMLDocument, nsDocument)

Просмотреть файл

@ -0,0 +1,16 @@
%import "contentbase.gqi"
%import-idl "nsIDOMXMLDocument.idl"
%import-idl "nsIInterfaceRequestor.idl"
%import-idl "nsIChannelEventSink.idl"
%{C++
#include "nsXMLDocument.h"
%}
NS_INTERFACE_MAP_BEGIN(nsXMLDocument, nsDocument)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
NS_INTERFACE_MAP_ENTRY(nsIDOMXMLDocument)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XMLDocument)
NS_INTERFACE_MAP_END

Просмотреть файл

@ -77,6 +77,8 @@ REQUIRES = xpcom \
CPPSRCS = nsXULControllers.cpp CPPSRCS = nsXULControllers.cpp
GQI_SRCS = xuldocument.gqi
ifdef MOZ_XUL ifdef MOZ_XUL
CPPSRCS += \ CPPSRCS += \
nsElementMap.cpp \ nsElementMap.cpp \

Просмотреть файл

@ -357,19 +357,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_ADDREF_INHERITED(nsXULDocument, nsXMLDocument) NS_IMPL_ADDREF_INHERITED(nsXULDocument, nsXMLDocument)
NS_IMPL_RELEASE_INHERITED(nsXULDocument, nsXMLDocument) NS_IMPL_RELEASE_INHERITED(nsXULDocument, nsXMLDocument)
// QueryInterface implementation for nsXULDocument
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsXULDocument)
NS_INTERFACE_TABLE_INHERITED4(nsXULDocument,
nsIXULDocument,
nsIDOMXULDocument,
nsIStreamLoaderObserver,
nsICSSLoaderObserver)
NS_INTERFACE_TABLE_TO_MAP_SEGUE
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XULDocument)
NS_INTERFACE_MAP_END_INHERITING(nsXMLDocument)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// //
// nsIDocument interface // nsIDocument interface

Просмотреть файл

@ -0,0 +1,19 @@
%import "xmldocument.gqi"
%import-idl "nsIDOMXULDocument.idl"
%import-idl "nsIStreamLoader.idl"
%pseudo-iid nsICSSLoaderObserver f5e8eb0f-4c44-49d5-b1e9-ab392393c0f8
%pseudo-iid nsIXULDocument 57314526-f749-4cf0-b6b6-3723eba21480
%{C++
#include "nsXULDocument.h"
%}
NS_INTERFACE_MAP_BEGIN(nsXULDocument, nsXMLDocument)
NS_INTERFACE_MAP_ENTRY(nsIXULDocument)
NS_INTERFACE_MAP_ENTRY(nsIDOMXULDocument)
NS_INTERFACE_MAP_ENTRY(nsIStreamLoaderObserver)
NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XULDocument)
NS_INTERFACE_MAP_END

Просмотреть файл

@ -117,6 +117,8 @@ CPPSRCS = \
nsDOMScriptObjectFactory.cpp \ nsDOMScriptObjectFactory.cpp \
$(NULL) $(NULL)
GQI_SRCS = dombase.gqi
# we don't want the shared lib, but we want to force the creation of a # we don't want the shared lib, but we want to force the creation of a
# static lib. # static lib.
FORCE_STATIC_LIB = 1 FORCE_STATIC_LIB = 1

44
dom/src/base/dombase.gqi Normal file
Просмотреть файл

@ -0,0 +1,44 @@
%import-idl "nsIDOMWindowInternal.idl"
%import-idl "nsIDOMWindow2.idl"
%import-idl "nsIDOMJSWindow.idl"
%import-idl "nsIDOMEventTarget.idl"
%import-idl "nsIDOM3EventTarget.idl"
%import-idl "nsIDOMNSEventTarget.idl"
%import-idl "nsIDOMViewCSS.idl"
%import-idl "nsIDOMAbstractView.idl"
%import-idl "nsIDOMStorageWindow.idl"
%import-idl "nsIWeakReference.idl"
%import-idl "nsIInterfaceRequestor.idl"
%pseudo-iid nsIScriptGlobalObject 6afecd40-0b9a-4cfd-8c42-0f645cd91829
%pseudo-iid nsIScriptObjectPrincipal 3eedba38-8d22-41e1-817a-0e43e165b664
%pseudo-iid nsPIDOMEventTarget 44a6597b-9fc3-4a8d-b7a4-d9009abf9d15
%pseudo-iid nsPIDOMWindow 909852b5-b9e6-4d94-8de3-051634800b73
%{C++
#include "nsGlobalWindow.h"
#include "nsDOMClassInfo.h"
%}
// QueryInterface implementation for nsGlobalWindow
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
// Make sure this matches the cast in nsGlobalWindow::FromWrapper()
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptGlobalObject)
NS_INTERFACE_MAP_ENTRY(nsIDOMWindowInternal)
NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)
NS_INTERFACE_MAP_ENTRY(nsIDOMWindow2)
NS_INTERFACE_MAP_ENTRY(nsIDOMJSWindow)
NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)
NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
NS_INTERFACE_MAP_ENTRY(nsPIDOMEventTarget)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
NS_INTERFACE_MAP_ENTRY(nsIDOM3EventTarget)
NS_INTERFACE_MAP_ENTRY(nsIDOMNSEventTarget)
NS_INTERFACE_MAP_ENTRY(nsPIDOMWindow)
NS_INTERFACE_MAP_ENTRY(nsIDOMViewCSS)
NS_INTERFACE_MAP_ENTRY(nsIDOMAbstractView)
NS_INTERFACE_MAP_ENTRY(nsIDOMStorageWindow)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Window)
NS_INTERFACE_MAP_END

Просмотреть файл

@ -913,30 +913,6 @@ nsGlobalWindow::FreeInnerObjects(PRBool aClearScope)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalWindow) NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalWindow)
// QueryInterface implementation for nsGlobalWindow
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
// Make sure this matches the cast in nsGlobalWindow::FromWrapper()
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptGlobalObject)
NS_INTERFACE_MAP_ENTRY(nsIDOMWindowInternal)
NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)
NS_INTERFACE_MAP_ENTRY(nsIDOMWindow2)
NS_INTERFACE_MAP_ENTRY(nsIDOMJSWindow)
NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)
NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
NS_INTERFACE_MAP_ENTRY(nsPIDOMEventTarget)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
NS_INTERFACE_MAP_ENTRY(nsIDOM3EventTarget)
NS_INTERFACE_MAP_ENTRY(nsIDOMNSEventTarget)
NS_INTERFACE_MAP_ENTRY(nsPIDOMWindow)
NS_INTERFACE_MAP_ENTRY(nsIDOMViewCSS)
NS_INTERFACE_MAP_ENTRY(nsIDOMAbstractView)
NS_INTERFACE_MAP_ENTRY(nsIDOMStorageWindow)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Window)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsGlobalWindow, nsIScriptGlobalObject) NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsGlobalWindow, nsIScriptGlobalObject)
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsGlobalWindow, NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsGlobalWindow,
nsIScriptGlobalObject) nsIScriptGlobalObject)

Просмотреть файл

@ -95,6 +95,9 @@ CPPSRCS = \
nsSerializationHelper.cpp \ nsSerializationHelper.cpp \
$(NULL) $(NULL)
GQI_SRCS = neckobase.gqi
LOCAL_INCLUDES = -I$(topsrcdir)/xpcom/ds
ifeq ($(MOZ_WIDGET_TOOLKIT),os2) ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
CPPSRCS += nsURLHelperOS2.cpp CPPSRCS += nsURLHelperOS2.cpp
else else

Просмотреть файл

@ -0,0 +1,82 @@
%import-idl "nsIStandardURL.idl"
%import-idl "nsIURL.idl"
%import-idl "nsIFileURL.idl"
%import-idl "nsISerializable.idl"
%import-idl "nsIClassInfo.idl"
%import-idl "nsIIOService2.idl"
%import-idl "nsINetUtil.idl"
%import-idl "nsIObserver.idl"
%import-idl "nsIWeakReference.idl"
%import-idl "nsIChannel.idl"
%import-idl "nsIInterfaceRequestor.idl"
%import-idl "nsITransport.idl"
%import-idl "nsIStreamListener.idl"
%import-idl "nsISocketTransportService.idl"
%import-idl "nsIEventTarget.idl"
%import-idl "nsIThreadInternal.idl"
%import-idl "nsIRunnable.idl"
%import-idl "nsPISocketTransportService.idl"
%import-idl "nsISocketTransport.idl"
%import-idl "nsIDNSListener.idl"
%import "xpcomds.gqi"
%{C++
#include "nsStandardURL.h"
#include "nsIOService.h"
#include "nsBaseChannel.h"
#include "nsSocketTransportService2.h"
#include "nsSocketTransport2.h"
%}
// See nsStandardURL.h
%pseudo-cid nsStandardURL b8e3e97b-1ccd-4b45-af5a-79596770f5d7 NS_THIS_STANDARDURL_IMPL_CID
NS_INTERFACE_MAP_BEGIN(nsStandardURL)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStandardURL)
NS_INTERFACE_MAP_ENTRY(nsIURI)
NS_INTERFACE_MAP_ENTRY(nsIURL)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFileURL, mSupportsFileURL)
NS_INTERFACE_MAP_ENTRY(nsIStandardURL)
NS_INTERFACE_MAP_ENTRY(nsISerializable)
NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
NS_INTERFACE_MAP_ENTRY(nsIMutable)
NS_INTERFACE_MAP_ENTRY(NS_THIS_STANDARDURL_IMPL_CID)
NS_INTERFACE_MAP_END
NS_IMPL_THREADSAFE_ISUPPORTS5(nsIOService,
nsIIOService,
nsIIOService2,
nsINetUtil,
nsIObserver,
nsISupportsWeakReference)
NS_IMPL_ISUPPORTS_INHERITED6(nsBaseChannel,
nsHashPropertyBag,
nsIRequest,
nsIChannel,
nsIInterfaceRequestor,
nsITransportEventSink,
nsIRequestObserver,
nsIStreamListener)
NS_IMPL_THREADSAFE_ISUPPORTS5(nsSocketTransportService,
nsISocketTransportService,
nsIEventTarget,
nsIThreadObserver,
nsIRunnable,
nsPISocketTransportService)
NS_IMPL_THREADSAFE_ISUPPORTS4(nsSocketTransport,
nsISocketTransport,
nsITransport,
nsIDNSListener,
nsIClassInfo)
%{C++
NS_IMPL_CI_INTERFACE_GETTER3(nsSocketTransport,
nsISocketTransport,
nsITransport,
nsIDNSListener)
%}

Просмотреть файл

@ -234,18 +234,6 @@ nsBaseChannel::BeginPumpingData()
return rv; return rv;
} }
//-----------------------------------------------------------------------------
// nsBaseChannel::nsISupports
NS_IMPL_ISUPPORTS_INHERITED6(nsBaseChannel,
nsHashPropertyBag,
nsIRequest,
nsIChannel,
nsIInterfaceRequestor,
nsITransportEventSink,
nsIRequestObserver,
nsIStreamListener)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// nsBaseChannel::nsIRequest // nsBaseChannel::nsIRequest

Просмотреть файл

@ -278,13 +278,6 @@ nsIOService::GetInstance() {
return gIOService; return gIOService;
} }
NS_IMPL_THREADSAFE_ISUPPORTS5(nsIOService,
nsIIOService,
nsIIOService2,
nsINetUtil,
nsIObserver,
nsISupportsWeakReference)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
nsresult nsresult

Просмотреть файл

@ -1597,16 +1597,6 @@ nsSocketTransport::OnSocketDetached(PRFileDesc *fd)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// xpcom api // xpcom api
NS_IMPL_THREADSAFE_ISUPPORTS4(nsSocketTransport,
nsISocketTransport,
nsITransport,
nsIDNSListener,
nsIClassInfo)
NS_IMPL_CI_INTERFACE_GETTER3(nsSocketTransport,
nsISocketTransport,
nsITransport,
nsIDNSListener)
NS_IMETHODIMP NS_IMETHODIMP
nsSocketTransport::OpenInputStream(PRUint32 flags, nsSocketTransport::OpenInputStream(PRUint32 flags,
PRUint32 segsize, PRUint32 segsize,

Просмотреть файл

@ -54,7 +54,7 @@
#include "nsIDNSListener.h" #include "nsIDNSListener.h"
#include "nsIDNSRecord.h" #include "nsIDNSRecord.h"
#include "nsICancelable.h" #include "nsICancelable.h"
#include "nsIClassInfo.h" #include "nsIClassInfoImpl.h"
class nsSocketTransport; class nsSocketTransport;
@ -319,4 +319,6 @@ private:
#endif #endif
}; };
NS_DECL_CI_INTERFACE_GETTER(nsSocketTransport);
#endif // !nsSocketTransport_h__ #endif // !nsSocketTransport_h__

Просмотреть файл

@ -354,16 +354,6 @@ nsSocketTransportService::Poll(PRBool wait, PRUint32 *interval)
return rv; return rv;
} }
//-----------------------------------------------------------------------------
// xpcom api
NS_IMPL_THREADSAFE_ISUPPORTS5(nsSocketTransportService,
nsISocketTransportService,
nsIEventTarget,
nsIThreadObserver,
nsIRunnable,
nsPISocketTransportService)
// called from main thread only // called from main thread only
NS_IMETHODIMP NS_IMETHODIMP
nsSocketTransportService::Init() nsSocketTransportService::Init()

Просмотреть файл

@ -848,21 +848,6 @@ nsStandardURL::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
NS_IMPL_ADDREF(nsStandardURL) NS_IMPL_ADDREF(nsStandardURL)
NS_IMPL_RELEASE(nsStandardURL) NS_IMPL_RELEASE(nsStandardURL)
NS_INTERFACE_MAP_BEGIN(nsStandardURL)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStandardURL)
NS_INTERFACE_MAP_ENTRY(nsIURI)
NS_INTERFACE_MAP_ENTRY(nsIURL)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFileURL, mSupportsFileURL)
NS_INTERFACE_MAP_ENTRY(nsIStandardURL)
NS_INTERFACE_MAP_ENTRY(nsISerializable)
NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
NS_INTERFACE_MAP_ENTRY(nsIMutable)
// see nsStandardURL::Equals
if (aIID.Equals(kThisImplCID))
foundInterface = static_cast<nsIURI *>(this);
else
NS_INTERFACE_MAP_END
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// nsStandardURL::nsIURI // nsStandardURL::nsIURI
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

Просмотреть файл

@ -273,6 +273,7 @@ private:
static PRBool gEncodeQueryInUTF8; static PRBool gEncodeQueryInUTF8;
}; };
/* If you change this CID, make sure you also update neckobase.gqi */
#define NS_THIS_STANDARDURL_IMPL_CID \ #define NS_THIS_STANDARDURL_IMPL_CID \
{ /* b8e3e97b-1ccd-4b45-af5a-79596770f5d7 */ \ { /* b8e3e97b-1ccd-4b45-af5a-79596770f5d7 */ \
0xb8e3e97b, \ 0xb8e3e97b, \

Просмотреть файл

@ -66,10 +66,11 @@ def dump_hex_tuple(t):
return "(%s)" % ", ".join(["%#x" % i for i in t]) return "(%s)" % ", ".join(["%#x" % i for i in t])
class UUID(object): class UUID(object):
def __init__(self, name, iidstr, pseudo=False, base=None): type = 'UUID'
def __init__(self, name, iidstr, base=None):
"""This method *assumes* that the UUID is validly formed.""" """This method *assumes* that the UUID is validly formed."""
self.name = name self.name = name
self.pseudo = pseudo
self.base = base self.base = base
# iid is in 32-16-16-8*8 format, as hex *strings* # iid is in 32-16-16-8*8 format, as hex *strings*
@ -99,25 +100,59 @@ class UUID(object):
return self.iid == uuid.iid and self.name == uuid.name return self.iid == uuid.iid and self.name == uuid.name
def __repr__(self): def __repr__(self):
return """UUID(%r, "%s-%s-%s-%s-%s", pseudo=%r, base=%r)""" % ( return """%s(%r, "%s-%s-%s-%s-%s", base=%r)""" % (
self.name, self.iid[0], self.iid[1], self.iid[2], self.iid[3] + self.iid[4], self.type, self.name,
"".join([self.iid[i] for i in xrange(5, 11)]), self.pseudo, self.base) self.iid[0], self.iid[1], self.iid[2], self.iid[3] + self.iid[4],
"".join([self.iid[i] for i in xrange(5, 11)]), self.base)
def asstruct(self): def asstruct(self):
return "{ 0x%s, 0x%s, 0x%s, { 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s } }" % self.iid return "{ 0x%s, 0x%s, 0x%s, { 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s } }" % self.iid
def runtime_assertion(self): def decl(self):
if self.pseudo: return ""
return """
static const nsID kGQI_%(iname)s = %(struct)s; def ref(self):
NS_ASSERTION(NS_GET_IID(%(iname)s).Equals(kGQI_%(iname)s), return "NS_GET_IID(%s)" % self.name
"GQI pseudo-IID doesn't match reality.");
""" % { class PseudoUUID(UUID):
'iname': self.name, type = 'PseudoUUID'
'struct': self.asstruct()
} # No special init method needed
else:
return "" def decl(self):
return """
#ifdef DEBUG
static const nsID kGQI_%(iname)s = %(struct)s;
NS_ASSERTION(NS_GET_IID(%(iname)s).Equals(kGQI_%(iname)s),
"GQI pseudo-IID doesn't match reality.");
#endif
""" % {
'iname': self.name,
'struct': self.asstruct()
}
class CID(UUID):
type = 'CID'
def __init__(self, name, iid, decl):
UUID.__init__(self, name, iid)
self.pdecl = decl
def decl(self):
return """
static const nsID kGQI_%(pdecl)s = %(struct)s;
#ifdef DEBUG
static const nsID kGQI_TEST_%(pdecl)s = %(pdecl)s;
#endif
NS_ASSERTION(kGQI_%(pdecl)s.Equals(kGQI_TEST_%(pdecl)s),
"GQI pseudo-IID doesn't match reality.");
""" % {
'pdecl': self.pdecl,
'struct': self.asstruct()
}
def ref(self):
return "kGQI_%s" % self.pdecl
_uuid_pattern_string = r'[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}' _uuid_pattern_string = r'[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}'
@ -167,24 +202,24 @@ def importidl(file, includedirs):
def gqi(ifaces, endian): def gqi(ifaces, endian):
"""Find an algorithm that uniquely identifies interfaces by a single """Find an algorithm that uniquely identifies interfaces by a single
word. Returns (indexfunction, table)""" word. Returns (indexfunction, table)"""
for bits in xrange(3, 10): for bits in xrange(3, 11):
bitmask = (1 << bits) - 1 bitmask = (1 << bits) - 1
for word in xrange(0, 4): for word in xrange(0, 4):
for sh in xrange(0, 33 - bits): for sh in xrange(0, 33 - bits):
shmask = bitmask << sh shmask = bitmask << sh
# print "Trying word: %i, bits: %i, shift: %i" % (word, bits, sh) if debug:
# print "Bitmask: %x" % (bitmask) print "Trying word: %i, bits: %i, shift: %i" % (word, bits, sh)
# print "Shifter mask: %x" % (shmask)
l = list([None for i in xrange(0, 1 << bits)]) l = list([None for i in xrange(0, 1 << bits)])
try: try:
for i in xrange(0, len(ifaces)): for i in xrange(0, len(ifaces)):
n = (ifaces[i].uuid.words[endian][word] & shmask) >> sh n = (ifaces[i].uuid.words[endian][word] & shmask) >> sh
if l[n] is not None: if l[n] is not None:
# print "found conflict, index %i" % n if debug:
# print "old iface: %s" % l[n].uuid print "found conflict, index %i" % n
# print "new iface: %s" % i.uuid print "old iface: %s" % ifaces[l[n]].uuid
print "new iface: %s" % ifaces[i].uuid
raise IndexError() raise IndexError()
l[n] = i l[n] = i
@ -196,7 +231,7 @@ def gqi(ifaces, endian):
indexfunc = "(reinterpret_cast<const PRUint32*>(&aIID)[%i] & 0x%x) >> %i" % (word, shmask, sh) indexfunc = "(reinterpret_cast<const PRUint32*>(&aIID)[%i] & 0x%x) >> %i" % (word, shmask, sh)
return indexfunc, l return indexfunc, l
raise Exception("No run of 9 bits within a word was unique!: interfaces: %s" % [i.uuid for i in ifaces]) raise Exception("No run of 10 bits within a word was unique!: interfaces: %s" % [i.uuid for i in ifaces])
def basecast(item, baselist): def basecast(item, baselist):
"""Returns a string where an item is static_cast through a list of bases.""" """Returns a string where an item is static_cast through a list of bases."""
@ -227,9 +262,7 @@ class QIImpl(object):
NS_IMETHODIMP %(cname)s::QueryInterface(REFNSIID aIID, void **aResult) NS_IMETHODIMP %(cname)s::QueryInterface(REFNSIID aIID, void **aResult)
{ {
#ifdef DEBUG %(uuiddecls)s
%(pseudoassertions)s
#endif
static const PRUint8 kLookupTable[] = { static const PRUint8 kLookupTable[] = {
#ifdef IS_BIG_ENDIAN #ifdef IS_BIG_ENDIAN
@ -282,7 +315,7 @@ class QIImpl(object):
_actiontable_entry = """ _actiontable_entry = """
{ {
&NS_GET_IID(%(iname)s), &(%(iref)s),
%(enumtype)s %(enumtype)s
%(emitTable)s %(emitTable)s
}, },
@ -319,11 +352,6 @@ class QIImpl(object):
self.ifaces = ifaces self.ifaces = ifaces
self.unfound = unfound self.unfound = unfound
# ensure that interfaces are not duplicated
ifdict = uniqdict()
for i, baselist in self.iter_all_ifaces():
ifdict[i.uuid.name] = i
def iter_self_and_bases(self): def iter_self_and_bases(self):
"""yields (impl, baselist) for all bases""" """yields (impl, baselist) for all bases"""
impl = self impl = self
@ -339,7 +367,8 @@ class QIImpl(object):
"""yields (iface, baselist) for all interfaces""" """yields (iface, baselist) for all interfaces"""
for impl, baselist in self.iter_self_and_bases(): for impl, baselist in self.iter_self_and_bases():
for i in impl.ifaces: for i in impl.ifaces:
yield i, baselist if len(baselist) == 1 or i.inherit:
yield i, baselist
def output(self, fd): def output(self, fd):
unfound = None unfound = None
@ -373,11 +402,20 @@ class QIImpl(object):
'name': name} 'name': name}
for name, type in types.iteritems()]) for name, type in types.iteritems()])
# list of (i, baselist) # ensure that interfaces are not duplicated
ilist = [i for i in self.iter_all_ifaces()] # maps name -> (uuid, baselist)
ifdict = uniqdict()
for i, baselist in self.iter_all_ifaces():
if i.uuid.name in ifdict:
print >>sys.stderr, "warning: interface '%s' from derived class '%s' overrides base class '%s'" % (i.uuid.name, baselist[0], baselist[len(baselist) - 1])
else:
ifdict[i.uuid.name] = (i, baselist)
pseudoassertions = "".join([i.uuid.runtime_assertion() # list of (i, baselist)
for i, baselist in ilist]) ilist = [i for i in ifdict.itervalues()]
uuiddecls = "".join([i.uuid.decl()
for i, baselist in ilist])
bigindexfunc, bigitable = gqi([iface for iface, baselist in ilist], False) bigindexfunc, bigitable = gqi([iface for iface, baselist in ilist], False)
littleindexfunc, littleitable = gqi([iface for iface, baselist in ilist], True) littleindexfunc, littleitable = gqi([iface for iface, baselist in ilist], True)
@ -400,6 +438,7 @@ class QIImpl(object):
{'enumtype': enumtype % {'cname': self.cname, {'enumtype': enumtype % {'cname': self.cname,
'enumtype': iface.action.enumtype}, 'enumtype': iface.action.enumtype},
'iname': iface.uuid.name, 'iname': iface.uuid.name,
'iref': iface.uuid.ref(),
'emitTable': iface.emitTable(self.cname, baselist)} 'emitTable': iface.emitTable(self.cname, baselist)}
for iface, baselist in ilist]) for iface, baselist in ilist])
@ -426,7 +465,7 @@ class QIImpl(object):
'actionenums': actionenums, 'actionenums': actionenums,
'actiontype': actiontype, 'actiontype': actiontype,
'actiondata': actiondata, 'actiondata': actiondata,
'pseudoassertions': pseudoassertions, 'uuiddecls': uuiddecls,
'biglookup': biglookup, 'biglookup': biglookup,
'littlelookup': littlelookup, 'littlelookup': littlelookup,
'actiontable': actiontable, 'actiontable': actiontable,
@ -451,10 +490,11 @@ class PointerAction(object):
return NS_OK;""" return NS_OK;"""
needsnullcheck = False needsnullcheck = False
nsCycleCollectionParticipant = UUID("nsCycleCollectionParticipant", "9674489b-1f6f-4550-a730-ccaedd104cf9", pseudo=True) nsCycleCollectionParticipant = PseudoUUID("nsCycleCollectionParticipant", "9674489b-1f6f-4550-a730-ccaedd104cf9")
class CCParticipantResponse(object): class CCParticipantResponse(object):
action = PointerAction action = PointerAction
inherit = True
def __init__(self, classname): def __init__(self, classname):
self.classname = classname self.classname = classname
@ -467,6 +507,7 @@ class TearoffResponse(object):
"""Because each tearoff is different, this response is its own action.""" """Because each tearoff is different, this response is its own action."""
datatype = None datatype = None
needsnullcheck = True needsnullcheck = True
inherit = True
def __init__(self, uuid, allocator): def __init__(self, uuid, allocator):
self.setResult = """ self.setResult = """
@ -480,7 +521,29 @@ class TearoffResponse(object):
def emitTable(self, classname, baselist): def emitTable(self, classname, baselist):
return "{0}" return "{0}"
nsCycleCollectionISupports = UUID("nsCycleCollectionISupports", "c61eac14-5f7a-4481-965e-7eaa6effa85f", pseudo=True) class ConditionalResponse(object):
"""Because each condition is different, this response is its own action."""
datatype = None
needsnullcheck = False
inherit = True
def __init__(self, uuid, condition):
self.setResult = """
if (!(%s)) {
goto unfound;
}
found = static_cast<%s*>(this);
goto exit_addref;
""" % (condition, uuid.name);
self.uuid = uuid
self.action = self
self.enumtype = "NS_CONDITIONAL_%s" % uuid.name
def emitTable(self, classname, baselist):
return "{0}"
nsCycleCollectionISupports = PseudoUUID("nsCycleCollectionISupports", "c61eac14-5f7a-4481-965e-7eaa6effa85f")
class CCSupportsAction(object): class CCSupportsAction(object):
enumtype = "CC_ISUPPORTS" enumtype = "CC_ISUPPORTS"
@ -493,6 +556,7 @@ class CCSupportsAction(object):
class CCISupportsResponse(object): class CCISupportsResponse(object):
action = CCSupportsAction action = CCSupportsAction
inherit = True
def __init__(self, classname): def __init__(self, classname):
self.classname = classname self.classname = classname
@ -501,12 +565,13 @@ class CCISupportsResponse(object):
def emitTable(self, classname, baselist): def emitTable(self, classname, baselist):
return "{ 0 }" return "{ 0 }"
nsIClassInfo = UUID("nsIClassInfo", "986c11d0-f340-11d4-9075-0010a4e73d9a", pseudo=True) nsIClassInfo = PseudoUUID("nsIClassInfo", "986c11d0-f340-11d4-9075-0010a4e73d9a")
class DOMCIResult(object): class DOMCIResult(object):
datatype = None datatype = None
enumtype = "DOMCI" enumtype = "DOMCI"
needsnullcheck = True needsnullcheck = True
inherit = False
def __init__(self, domciname): def __init__(self, domciname):
self.action = self self.action = self
@ -531,6 +596,7 @@ class OffsetAction(object):
class OffsetThisQIResponse(object): class OffsetThisQIResponse(object):
action = OffsetAction action = OffsetAction
inherit = True
def __init__(self, uuid): def __init__(self, uuid):
self.uuid = uuid self.uuid = uuid
@ -548,6 +614,7 @@ class OffsetThisQIResponse(object):
class OffsetFutureThisQIResponse(OffsetThisQIResponse): class OffsetFutureThisQIResponse(OffsetThisQIResponse):
action = OffsetAction action = OffsetAction
inherit = True
def __init__(self, uuid): def __init__(self, uuid):
self.uuid = uuid self.uuid = uuid
@ -590,6 +657,8 @@ class LiteralAction(object):
self.needsnullcheck = code.find('exit_nullcheck_addref') != -1 self.needsnullcheck = code.find('exit_nullcheck_addref') != -1
class LiteralResponse(object): class LiteralResponse(object):
inherit = True
def __init__(self, action, uuid): def __init__(self, action, uuid):
self.action = action self.action = action
self.uuid = uuid self.uuid = uuid
@ -641,6 +710,9 @@ def build_map(f, cname, iids):
elif action == 'NS_INTERFACE_MAP_ENTRY_TEAROFF': elif action == 'NS_INTERFACE_MAP_ENTRY_TEAROFF':
iname, allocator = items iname, allocator = items
members.append(TearoffResponse(iids[iname], allocator)) members.append(TearoffResponse(iids[iname], allocator))
elif action == 'NS_INTERFACE_MAP_ENTRY_CONDITIONAL':
iname, condition = items
members.append(ConditionalResponse(iids[iname], condition))
elif action == 'NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO': elif action == 'NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO':
domciname, = items domciname, = items
members.append(DOMCIResult(domciname)) members.append(DOMCIResult(domciname))
@ -661,8 +733,9 @@ def build_map(f, cname, iids):
raise Exception("%s: Unexpected EOF" % f.loc()) raise Exception("%s: Unexpected EOF" % f.loc())
_import = re.compile(r'%(?P<type>import|import-idl)\s+(?:"|\<)(?P<filename>[a-z\.\-\_0-9]+)(?:"|\>)\s*$', re.I) _import = re.compile(r'%(?P<type>import|import-idl)\s+(?:"|\<)(?P<filename>[a-z\.\-\_0-9]+)(?:"|\>)\s*$', re.I)
_impl_qi = re.compile(r'NS_IMPL_(?P<threadsafe>THREADSAFE_)?(?P<type>QUERY_INTERFACE|ISUPPORTS)(?:\d+)\((?P<bases>.*)\)\s*$') _impl_qi = re.compile(r'NS_IMPL_(?P<threadsafe>THREADSAFE_)?(?P<type>QUERY_INTERFACE|ISUPPORTS)(?P<inherited>_INHERITED)?(?:\d+)\((?P<bases>.*)\)\s*$')
_pseudoiid = re.compile(r'%pseudo-iid\s+(?P<name>[a-z_0-9]+)\s+(?P<iid>' + _uuid_pattern_string + r')\s*$', re.I) _pseudoiid = re.compile(r'%pseudo-iid\s+(?P<name>[a-z_0-9]+)\s+(?P<iid>' + _uuid_pattern_string + r')\s*$', re.I)
_pseudocid = re.compile(r'%pseudo-cid\s+(?P<name>[a-z_0-9]+)\s+(?P<iid>' + _uuid_pattern_string + r')\s+(?P<decl>[a-z_0-9]+)$', re.I)
_map_begin = re.compile(r'NS_INTERFACE_MAP_BEGIN(?P<cc>_CYCLE_COLLECTION)?\((?P<classname>[A-Za-z0-9+]+)(?:\s*,\s*(?P<base>[A-Za-z0-9+]+))?\)$') _map_begin = re.compile(r'NS_INTERFACE_MAP_BEGIN(?P<cc>_CYCLE_COLLECTION)?\((?P<classname>[A-Za-z0-9+]+)(?:\s*,\s*(?P<base>[A-Za-z0-9+]+))?\)$')
def parsefile(file, fd, includedirs): def parsefile(file, fd, includedirs):
@ -689,10 +762,16 @@ def parsefile(file, fd, includedirs):
m = _pseudoiid.match(line) m = _pseudoiid.match(line)
if m is not None: if m is not None:
uuid = UUID(m.group('name'), m.group('iid'), pseudo=True) uuid = PseudoUUID(m.group('name'), m.group('iid'))
iids[m.group('name')] = uuid iids[m.group('name')] = uuid
continue continue
m = _pseudocid.match(line)
if m is not None:
uuid = CID(m.group('name'), m.group('iid'), m.group('decl'))
iids[m.group('decl')] = uuid
continue
m = _import.match(line) m = _import.match(line)
if m is not None: if m is not None:
if m.group('type') == 'import': if m.group('type') == 'import':
@ -722,12 +801,22 @@ def parsefile(file, fd, includedirs):
bases = _split_commas.split(m.group('bases')) bases = _split_commas.split(m.group('bases'))
cname = bases.pop(0) cname = bases.pop(0)
if m.group('inherited'):
inherited = bases.pop(0)
if inherited in impls:
base = impls[inherited]
else:
base = imported[inherited]
else:
base = None
baseuuids = [iids[name] for name in bases] baseuuids = [iids[name] for name in bases]
ifaces = [OffsetThisQIResponse(uuid) for uuid in baseuuids] ifaces = [OffsetThisQIResponse(uuid) for uuid in baseuuids]
ifaces.append(OffsetThisQIResponseAmbiguous(iids['nsISupports'], ifaces[0].uuid)) ifaces.append(OffsetThisQIResponseAmbiguous(iids['nsISupports'], ifaces[0].uuid))
q = QIImpl(cname, ifaces, q = QIImpl(cname, ifaces,
emitrefcount=(m.group('type') == 'ISUPPORTS'), emitrefcount=(m.group('type') == 'ISUPPORTS'),
threadsafe=m.group('threadsafe') or '') threadsafe=m.group('threadsafe') or '',
base=base)
impls[cname] = q impls[cname] = q
continue continue
@ -761,9 +850,15 @@ def main():
help="Write dependencies to a file") help="Write dependencies to a file")
o.add_option("-o", dest="out_file", o.add_option("-o", dest="out_file",
help="Write output to file. Required") help="Write output to file. Required")
o.add_option("-v", dest="verbose", action="store_true",
help="Print verbose debugging output.")
(options, files) = o.parse_args() (options, files) = o.parse_args()
if options.verbose:
global debug
debug = True
if options.out_file is None: if options.out_file is None:
o.print_help() o.print_help()
sys.exit(1) sys.exit(1)