]> git.cworth.org Git - apitrace/blobdiff - wrappers/trace.py
Improve tracing of ID3D11DeviceContext::CheckFeatureSupport.
[apitrace] / wrappers / trace.py
index 706d3479dcb15473d5254b1ad56e6a840e179571..0064d86667afe5d48337b1fa23a56c6c022e1c80 100644 (file)
@@ -136,6 +136,8 @@ class ComplexValueSerializer(stdapi.OnceVisitor):
         pass
 
     def visitPolymorphic(self, polymorphic):
+        if not polymorphic.contextLess:
+            return
         print 'static void _write__%s(int selector, const %s & value) {' % (polymorphic.tag, polymorphic.expr)
         print '    switch (selector) {'
         for cases, type in polymorphic.iterSwitch():
@@ -218,13 +220,13 @@ class ValueSerializer(stdapi.Visitor):
         print '    }'
 
     def visitIntPointer(self, pointer, instance):
-        print '    trace::localWriter.writeOpaque((const void *)%s);' % instance
+        print '    trace::localWriter.writePointer((uintptr_t)%s);' % instance
 
     def visitObjPointer(self, pointer, instance):
-        print '    trace::localWriter.writeOpaque((const void *)%s);' % instance
+        print '    trace::localWriter.writePointer((uintptr_t)%s);' % instance
 
     def visitLinearPointer(self, pointer, instance):
-        print '    trace::localWriter.writeOpaque((const void *)%s);' % instance
+        print '    trace::localWriter.writePointer((uintptr_t)%s);' % instance
 
     def visitReference(self, reference, instance):
         self.visit(reference.type, instance)
@@ -236,13 +238,22 @@ class ValueSerializer(stdapi.Visitor):
         self.visit(alias.type, instance)
 
     def visitOpaque(self, opaque, instance):
-        print '    trace::localWriter.writeOpaque((const void *)%s);' % instance
+        print '    trace::localWriter.writePointer((uintptr_t)%s);' % instance
 
     def visitInterface(self, interface, instance):
-        print '    trace::localWriter.writeOpaque((const void *)&%s);' % instance
+        assert False
 
     def visitPolymorphic(self, polymorphic, instance):
-        print '    _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
+        if polymorphic.contextLess:
+            print '    _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
+        else:
+            print '    switch (%s) {' % polymorphic.switchExpr
+            for cases, type in polymorphic.iterSwitch():
+                for case in cases:
+                    print '    %s:' % case
+                self.visit(type, 'static_cast<%s>(%s)' % (type, instance))
+                print '        break;'
+            print '    }'
 
 
 class WrapDecider(stdapi.Traverser):
@@ -348,7 +359,7 @@ class Tracer:
 
         return ValueSerializer()
 
-    def trace_api(self, api):
+    def traceApi(self, api):
         self.api = api
 
         self.header(api)
@@ -365,10 +376,7 @@ class Tracer:
         print
 
         # Interfaces wrapers
-        interfaces = api.getAllInterfaces()
-        map(self.declareWrapperInterface, interfaces)
-        map(self.implementWrapperInterface, interfaces)
-        print
+        self.traceInterfaces(api)
 
         # Function wrappers
         self.interface = None
@@ -496,6 +504,15 @@ class Tracer:
             visitor = ValueUnwrapper()
             visitor.visit(type, instance)
 
+    def traceInterfaces(self, api):
+        interfaces = api.getAllInterfaces()
+        if not interfaces:
+            return
+        map(self.declareWrapperInterface, interfaces)
+        self.implementIidWrapper(api)
+        map(self.implementWrapperInterface, interfaces)
+        print
+
     def declareWrapperInterface(self, interface):
         print "class %s : public %s " % (getWrapperInterfaceName(interface), interface.name)
         print "{"
@@ -550,7 +567,7 @@ class Tracer:
         print '    static const trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1)
         print '    unsigned __call = trace::localWriter.beginEnter(&__sig);'
         print '    trace::localWriter.beginArg(0);'
-        print '    trace::localWriter.writeOpaque((const void *)m_pInstance);'
+        print '    trace::localWriter.writePointer((uintptr_t)m_pInstance);'
         print '    trace::localWriter.endArg();'
         for arg in method.args:
             if not arg.output:
@@ -577,33 +594,47 @@ class Tracer:
             print '    if (!__result)'
             print '        delete this;'
 
+    def implementIidWrapper(self, api):
+        print r'static void'
+        print r'warnIID(const char *functionName, REFIID riid, const char *reason) {'
+        print r'    os::log("apitrace: warning: %s: %s IID {0x%08lX,0x%04X,0x%04X,{0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X}}\n",'
+        print r'            functionName, reason,'
+        print r'            riid.Data1, riid.Data2, riid.Data3,'
+        print r'            riid.Data4[0], riid.Data4[1], riid.Data4[2], riid.Data4[3], riid.Data4[4], riid.Data4[5], riid.Data4[6], riid.Data4[7]);'
+        print r'}'
+        print 
+        print r'static void'
+        print r'wrapIID(const char *functionName, REFIID riid, void * * ppvObj) {'
+        print r'    if (!ppvObj || !*ppvObj) {'
+        print r'        return;'
+        print r'    }'
+        else_ = ''
+        for iface in api.getAllInterfaces():
+            print r'    %sif (riid == IID_%s) {' % (else_, iface.name)
+            print r'        *ppvObj = new Wrap%s((%s *) *ppvObj);' % (iface.name, iface.name)
+            print r'    }'
+            else_ = 'else '
+        print r'    %s{' % else_
+        print r'        warnIID(functionName, riid, "unknown");'
+        print r'    }'
+        print r'}'
+        print
+
     def wrapIid(self, function, riid, out):
         print r'    if (%s && *%s) {' % (out.name, out.name)
-        function_name = function.name
+        functionName = function.name
         else_ = ''
         if self.interface is not None:
-            function_name = self.interface.name + '::' + function_name
+            functionName = self.interface.name + '::' + functionName
             print r'        %sif (*%s == m_pInstance) {' % (else_, out.name,)
             print r'            *%s = this;' % (out.name,)
-            print r'        }'
-            else_ = 'else '
-        for iface in self.api.getAllInterfaces():
-            print r'        %sif (%s == IID_%s) {' % (else_, riid.name, iface.name)
-            print r'            *%s = new Wrap%s((%s *) *%s);' % (out.name, iface.name, iface.name, out.name)
+            print r'            if (%s) {' % ' && '.join('%s != IID_%s' % (riid.name, iface.name) for iface in self.interface.iterBases()) 
+            print r'                warnIID("%s", %s, "unexpected");' % (functionName, riid.name)
+            print r'            }'
             print r'        }'
             else_ = 'else '
         print r'        %s{' % else_
-        print r'            os::log("apitrace: warning: %s: unknown IID {0x%08lX,0x%04X,0x%04X,{0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X}}\n",'
-        print r'                    "%s",' % (function_name)
-        print r'                    %s.Data1, %s.Data2, %s.Data3,' % (riid.name, riid.name, riid.name)
-        print r'                    %s.Data4[0],' % (riid.name,)
-        print r'                    %s.Data4[1],' % (riid.name,)
-        print r'                    %s.Data4[2],' % (riid.name,)
-        print r'                    %s.Data4[3],' % (riid.name,)
-        print r'                    %s.Data4[4],' % (riid.name,)
-        print r'                    %s.Data4[5],' % (riid.name,)
-        print r'                    %s.Data4[6],' % (riid.name,)
-        print r'                    %s.Data4[7]);' % (riid.name,)
+        print r'             wrapIID("%s", %s, %s);' % (functionName, riid.name, out.name) 
         print r'        }'
         print r'    }'
 
@@ -617,7 +648,7 @@ class Tracer:
     def emit_memcpy(self, dest, src, length):
         print '        unsigned __call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
         print '        trace::localWriter.beginArg(0);'
-        print '        trace::localWriter.writeOpaque(%s);' % dest
+        print '        trace::localWriter.writePointer((uintptr_t)%s);' % dest
         print '        trace::localWriter.endArg();'
         print '        trace::localWriter.beginArg(1);'
         print '        trace::localWriter.writeBlob(%s, %s);' % (src, length)