class CglTracer(GlTracer):
- def is_public_function(self, function):
+ def isFunctionPublic(self, function):
# The symbols visible in libGL.dylib can vary, so expose them all
return True
print
api = API()
- api.add_api(cglapi)
- api.add_api(glapi)
+ api.addApi(cglapi)
+ api.addApi(glapi)
tracer = CglTracer()
tracer.trace_api(api)
from specs.d3d10misc import d3d10
-from trace import DllTracer
+from dlltrace import DllTracer
if __name__ == '__main__':
from specs.d3d8 import d3d8
-from trace import DllTracer
+from dlltrace import DllTracer
class D3D8Tracer(DllTracer):
- def dump_arg_instance(self, function, arg):
+ def serializeArgValue(self, function, arg):
# Dump shaders as strings
if function.name in ('CreateVertexShader', 'CreatePixelShader') and arg.name == 'pFunction':
print ' DumpShader(trace::localWriter, %s);' % (arg.name)
return
- DllTracer.dump_arg_instance(self, function, arg)
+ DllTracer.serializeArgValue(self, function, arg)
if __name__ == '__main__':
##########################################################################/
-from trace import DllTracer
+from dlltrace import DllTracer
from specs.d3d9 import d3d9
class D3D9Tracer(DllTracer):
- def dump_arg_instance(self, function, arg):
+ def serializeArgValue(self, function, arg):
# Dump shaders as strings
if function.name in ('CreateVertexShader', 'CreatePixelShader') and arg.name == 'pFunction':
print ' DumpShader(trace::localWriter, %s);' % (arg.name)
return
- DllTracer.dump_arg_instance(self, function, arg)
+ DllTracer.serializeArgValue(self, function, arg)
if __name__ == '__main__':
from specs.d3d import ddraw, interfaces
-from trace import DllTracer
+from dlltrace import DllTracer
class DDrawTracer(DllTracer):
- def trace_function_impl_body(self, function):
+ def traceFunctionImplBody(self, function):
if function.name in ('AcquireDDThreadLock', 'ReleaseDDThreadLock'):
- self.dispatch_function(function)
+ self.invokeFunction(function)
return
- DllTracer.trace_function_impl_body(self, function)
+ DllTracer.traceFunctionImplBody(self, function)
- def wrap_arg(self, function, arg):
+ def serializeArg(self, function, arg):
if function.name == 'DirectDrawCreateEx' and arg.name == 'lplpDD':
print ' if (*lplpDD) {'
for iface in interfaces:
print ' }'
print ' }'
- DllTracer.wrap_arg(self, function, arg)
+ DllTracer.serializeArg(self, function, arg)
if __name__ == '__main__':
def dispatch_api(self, api):
for function in api.functions:
- self.dispatch_function(function)
+ self.invokeFunction(function)
# define standard name aliases for convenience, but only when not
# tracing, as that would cause symbol clashing with the tracing
print '#endif /* RETRACE */'
print
- def dispatch_function(self, function):
+ def invokeFunction(self, function):
ptype = function_pointer_type(function)
pvalue = function_pointer_value(function)
print 'typedef ' + function.prototype('* %s' % ptype) + ';'
print '}'
print
- def is_public_function(self, function):
+ def isFunctionPublic(self, function):
return True
def get_true_pointer(self, function):
ptype = function_pointer_type(function)
pvalue = function_pointer_value(function)
- if self.is_public_function(function):
+ if self.isFunctionPublic(function):
get_proc_address = '__getPublicProcAddress'
else:
get_proc_address = '__getPrivateProcAddress'
print ' if (!%s) {' % (pvalue,)
print ' %s = (%s)%s(__name);' % (pvalue, ptype, get_proc_address)
print ' if (!%s) {' % (pvalue,)
- self.fail_function(function)
+ self.failFunction(function)
print ' }'
print ' }'
- def fail_function(self, function):
+ def failFunction(self, function):
if function.type is stdapi.Void or function.fail is not None:
print r' os::log("warning: ignoring call to unavailable function %s\n", __name);'
if function.type is stdapi.Void:
--- /dev/null
+##########################################################################
+#
+# Copyright 2008-2010 VMware, Inc.
+# All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+##########################################################################/
+
+"""Trace code generation for Windows DLLs."""
+
+
+from dispatch import Dispatcher
+from trace import Tracer
+
+
+class DllTracer(Tracer):
+
+ def __init__(self, dllname):
+ self.dllname = dllname
+
+ def header(self, api):
+ print '''
+static HINSTANCE g_hDll = NULL;
+
+static PROC
+__getPublicProcAddress(LPCSTR lpProcName)
+{
+ if (!g_hDll) {
+ char szDll[MAX_PATH] = {0};
+
+ if (!GetSystemDirectoryA(szDll, MAX_PATH)) {
+ return NULL;
+ }
+
+ strcat(szDll, "\\\\%s");
+
+ g_hDll = LoadLibraryA(szDll);
+ if (!g_hDll) {
+ return NULL;
+ }
+ }
+
+ return GetProcAddress(g_hDll, lpProcName);
+}
+
+''' % self.dllname
+
+ dispatcher = Dispatcher()
+ dispatcher.dispatch_api(api)
+
+ Tracer.header(self, api)
+
class EglTracer(GlTracer):
- def is_public_function(self, function):
+ def isFunctionPublic(self, function):
# The symbols visible in libEGL.so can vary, so expose them all
return True
- def trace_function_impl_body(self, function):
- GlTracer.trace_function_impl_body(self, function)
+ def traceFunctionImplBody(self, function):
+ GlTracer.traceFunctionImplBody(self, function)
if function.name == 'eglMakeCurrent':
print ' // update the profile'
print ' tr->profile = PROFILE_ES2;'
print ' }'
- def wrap_ret(self, function, instance):
- GlTracer.wrap_ret(self, function, instance)
+ def wrapRet(self, function, instance):
+ GlTracer.wrapRet(self, function, instance)
if function.name == "eglGetProcAddress":
print ' %s = __unwrap_proc_addr(procname, %s);' % (instance, instance)
print
api = API()
- api.add_api(eglapi)
- api.add_api(glapi)
- api.add_api(glesapi)
+ api.addApi(eglapi)
+ api.addApi(glapi)
+ api.addApi(glesapi)
tracer = EglTracer()
tracer.trace_api(api)
void * __getPrivateProcAddress(const char *procName);
'''
- def is_public_function(self, function):
+ def isFunctionPublic(self, function):
return function.name in public_symbols or function.name.startswith('CGL')
table_name = 'glretrace::gl_callbacks'
- def retrace_function(self, function):
- Retracer.retrace_function(self, function)
+ def retraceFunction(self, function):
+ Retracer.retraceFunction(self, function)
array_pointer_function_names = set((
"glVertexPointer",
'glUnmapNamedBufferEXT',
])
- def retrace_function_body(self, function):
+ def retraceFunctionBody(self, function):
is_array_pointer = function.name in self.array_pointer_function_names
is_draw_array = function.name in self.draw_array_function_names
is_draw_elements = function.name in self.draw_elements_function_names
print ' GLint __array_buffer = 0;'
print ' glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
print ' if (!__array_buffer) {'
- self.fail_function(function)
+ self.failFunction(function)
print ' }'
if is_draw_elements:
print ' GLint __element_array_buffer = 0;'
print ' glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
print ' if (!__element_array_buffer) {'
- self.fail_function(function)
+ self.failFunction(function)
print ' }'
print ' }'
print ' glretrace::frame_complete(call);'
return
- Retracer.retrace_function_body(self, function)
+ Retracer.retraceFunctionBody(self, function)
# Post-snapshots
if function.name in ('glFlush', 'glFinish'):
print ' }'
- def call_function(self, function):
+ def invokeFunction(self, function):
# Infer the drawable size from GL calls
if function.name == "glViewport":
print ' glretrace::updateDrawable(x + width, y + height);'
if function.name == 'memcpy':
print ' if (!dest || !src || !n) return;'
- Retracer.call_function(self, function)
+ Retracer.invokeFunction(self, function)
# Error checking
if function.name == "glBegin":
print r' retrace::delRegionByPointer(ptr);'
print r' }'
- def extract_arg(self, function, arg, arg_type, lvalue, rvalue):
+ def extractArg(self, function, arg, arg_type, lvalue, rvalue):
if function.name in self.array_pointer_function_names and arg.name == 'pointer':
print ' %s = static_cast<%s>(retrace::toPointer(%s, true));' % (lvalue, arg_type, rvalue)
return
if function.name in self.draw_elements_function_names and arg.name == 'indices' or\
function.name in self.draw_indirect_function_names and arg.name == 'indirect':
- self.extract_opaque_arg(function, arg, arg_type, lvalue, rvalue)
+ self.extractOpaqueArg(function, arg, arg_type, lvalue, rvalue)
return
# Handle pointer with offsets into the current pack pixel buffer
# object.
if function.name in self.pack_function_names and arg.output:
- self.extract_opaque_arg(function, arg, arg_type, lvalue, rvalue)
+ self.extractOpaqueArg(function, arg, arg_type, lvalue, rvalue)
return
if arg.type is glapi.GLlocation \
and 'programObj' not in [arg.name for arg in function.args]:
print ' GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);'
- Retracer.extract_arg(self, function, arg, arg_type, lvalue, rvalue)
+ Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue)
# Don't try to use more samples than the implementation supports
if arg.name == 'samples':
'''
api = glapi.glapi
- api.add_api(glesapi.glesapi)
+ api.addApi(glesapi.glesapi)
retracer = GlRetracer()
- retracer.retrace_api(api)
+ retracer.retraceApi(api)
return pname[3:].lower()
- def visit_const(self, const, args):
+ def visitConst(self, const, args):
return self.visit(const.type, args)
- def visit_scalar(self, type, args):
+ def visitScalar(self, type, args):
temp_name = self.temp_name(args)
elem_type = self.inflector.reduced_type(type)
inflection = self.inflector.inflect(type)
print ' %s %s = %s(%s);' % (elem_type, temp_name, inflection + self.suffix, ', '.join(args))
return temp_name
- def visit_string(self, string, args):
+ def visitString(self, string, args):
temp_name = self.temp_name(args)
inflection = self.inflector.inflect(string)
assert not inflection.endswith('v')
print ' %s %s = (%s)%s(%s);' % (string, temp_name, string, inflection + self.suffix, ', '.join(args))
return temp_name
- def visit_alias(self, alias, args):
- return self.visit_scalar(alias, args)
+ def visitAlias(self, alias, args):
+ return self.visitScalar(alias, args)
- def visit_enum(self, enum, args):
+ def visitEnum(self, enum, args):
return self.visit(GLint, args)
- def visit_bitmask(self, bitmask, args):
+ def visitBitmask(self, bitmask, args):
return self.visit(GLint, args)
- def visit_array(self, array, args):
+ def visitArray(self, array, args):
temp_name = self.temp_name(args)
if array.length == '1':
return self.visit(array.type)
print ' assert(%s[%s] == (%s)0xdeadc0de);' % (temp_name, array.length, elem_type)
return temp_name
- def visit_opaque(self, pointer, args):
+ def visitOpaque(self, pointer, args):
temp_name = self.temp_name(args)
inflection = self.inflector.inflect(pointer)
assert inflection.endswith('v')
It expects a previously declared JSONWriter instance named "json".'''
- def visit_literal(self, literal, instance):
+ def visitLiteral(self, literal, instance):
if literal.kind == 'Bool':
print ' json.writeBool(%s);' % instance
elif literal.kind in ('SInt', 'Uint', 'Float', 'Double'):
else:
raise NotImplementedError
- def visit_string(self, string, instance):
+ def visitString(self, string, instance):
assert string.length is None
print ' json.writeString((const char *)%s);' % instance
- def visit_enum(self, enum, instance):
+ def visitEnum(self, enum, instance):
if enum.expr == 'GLenum':
print ' dumpEnum(json, %s);' % instance
else:
print ' json.writeNumber(%s);' % instance
- def visit_bitmask(self, bitmask, instance):
+ def visitBitmask(self, bitmask, instance):
raise NotImplementedError
- def visit_alias(self, alias, instance):
+ def visitAlias(self, alias, instance):
self.visit(alias.type, instance)
- def visit_opaque(self, opaque, instance):
+ def visitOpaque(self, opaque, instance):
print ' json.writeNumber((size_t)%s);' % instance
__index = 0
- def visit_array(self, array, instance):
+ def visitArray(self, array, instance):
index = '__i%u' % JsonWriter.__index
JsonWriter.__index += 1
print ' json.beginArray();'
import specs.glapi as glapi
import specs.glparams as glparams
from specs.glxapi import glxapi
-from trace import Tracer, dump_instance
+from trace import Tracer
class TypeGetter(stdapi.Visitor):
self.long_suffix = long_suffix
self.ext_suffix = ext_suffix
- def visit_const(self, const):
+ def visitConst(self, const):
return self.visit(const.type)
- def visit_alias(self, alias):
+ def visitAlias(self, alias):
if alias.expr == 'GLboolean':
if self.long_suffix:
suffix = 'Booleanv'
function_name = self.prefix + suffix + self.ext_suffix
return function_name, arg_type
- def visit_enum(self, enum):
+ def visitEnum(self, enum):
return self.visit(glapi.GLint)
- def visit_bitmask(self, bitmask):
+ def visitBitmask(self, bitmask):
return self.visit(glapi.GLint)
- def visit_opaque(self, pointer):
+ def visitOpaque(self, pointer):
return self.prefix + 'Pointerv' + self.ext_suffix, 'GLvoid *'
'GL_T4F_C4F_N3F_V4F',
]
- def trace_function_impl_body(self, function):
+ def traceFunctionImplBody(self, function):
# Defer tracing of user array pointers...
if function.name in self.array_pointer_function_names:
print ' GLint __array_buffer = 0;'
print ' ctx->user_arrays_arb = true;'
if function.name == "glVertexAttribPointerNV":
print ' ctx->user_arrays_nv = true;'
- self.dispatch_function(function)
+ self.invokeFunction(function)
# And also break down glInterleavedArrays into the individual calls
if function.name == 'glInterleavedArrays':
print ' static const trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
print ' trace::localWriter.beginArg(0);'
- dump_instance(glapi.GLenum, enable_name)
+ self.serializeValue(glapi.GLenum, enable_name)
print ' trace::localWriter.endArg();'
print ' trace::localWriter.endEnter();'
print ' trace::localWriter.beginLeave(__call);'
# be an herculian task given that vertex attrib locations appear in
# many entry-points, including non-shader related ones.
if function.name == 'glLinkProgram':
- Tracer.dispatch_function(self, function)
+ Tracer.invokeFunction(self, function)
print ' GLint active_attributes = 0;'
print ' __glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
print ' }'
print ' }'
if function.name == 'glLinkProgramARB':
- Tracer.dispatch_function(self, function)
+ Tracer.invokeFunction(self, function)
print ' GLint active_attributes = 0;'
print ' __glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
print ' }'
print ' }'
- Tracer.trace_function_impl_body(self, function)
+ Tracer.traceFunctionImplBody(self, function)
gremedy_functions = [
'glStringMarkerGREMEDY',
'glFrameTerminatorGREMEDY',
]
- def dispatch_function(self, function):
+ def invokeFunction(self, function):
if function.name in ('glLinkProgram', 'glLinkProgramARB'):
# These functions have been dispatched already
return
print ' }'
if_ = 'else if'
print ' else {'
- Tracer.dispatch_function(self, function)
+ Tracer.invokeFunction(self, function)
print ' }'
return
# Override GL extensions
if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'):
- Tracer.dispatch_function(self, function, prefix = 'gltrace::__', suffix = '_override')
+ Tracer.invokeFunction(self, function, prefix = 'gltrace::__', suffix = '_override')
return
- Tracer.dispatch_function(self, function)
+ Tracer.invokeFunction(self, function)
def emit_memcpy(self, dest, src, length):
print ' unsigned __call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
'ATOMIC_COUNTER_BUFFER',
]
- def wrap_ret(self, function, instance):
- Tracer.wrap_ret(self, function, instance)
+ def wrapRet(self, function, instance):
+ Tracer.wrapRet(self, function, instance)
if function.name in ('glMapBuffer', 'glMapBufferARB'):
'glTextureSubImage3DEXT',
])
- def dump_arg_instance(self, function, arg):
+ def serializeArgValue(self, function, arg):
if function.name in self.draw_function_names and arg.name == 'indices':
print ' GLint __element_array_buffer = 0;'
print ' __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
else:
print ' trace::localWriter.writeBlob(%s, count*__gl_type_size(type));' % (arg.name)
print ' } else {'
- Tracer.dump_arg_instance(self, function, arg)
+ Tracer.serializeArgValue(self, function, arg)
print ' }'
return
print ' if (__unpack_buffer) {'
print ' trace::localWriter.writeOpaque(%s);' % arg.name
print ' } else {'
- Tracer.dump_arg_instance(self, function, arg)
+ Tracer.serializeArgValue(self, function, arg)
print ' }'
print ' }'
return
assert function.args[arg.index - 1].name == 'pname'
assert function.args[arg.index - 1].type == glapi.GLenum
print ' if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
- dump_instance(glapi.GLenum, arg.name)
+ self.serializeValue(glapi.GLenum, arg.name)
print ' } else {'
- Tracer.dump_arg_instance(self, function, arg)
+ Tracer.serializeArgValue(self, function, arg)
print ' }'
return
- Tracer.dump_arg_instance(self, function, arg)
+ Tracer.serializeArgValue(self, function, arg)
def footer(self, api):
Tracer.footer(self, api)
assert not arg.output
print ' trace::localWriter.beginArg(%u);' % (arg.index,)
if arg.name != 'pointer':
- dump_instance(arg.type, arg.name)
+ self.serializeValue(arg.type, arg.name)
else:
print ' trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
print ' trace::localWriter.endArg();'
assert not arg.output
print ' trace::localWriter.beginArg(%u);' % (arg.index,)
if arg.name != 'pointer':
- dump_instance(arg.type, arg.name)
+ self.serializeValue(arg.type, arg.name)
else:
print ' trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
print ' trace::localWriter.endArg();'
for arg, instance in zip(function.args, args):
assert not arg.output
print ' trace::localWriter.beginArg(%u);' % (arg.index,)
- dump_instance(arg.type, instance)
+ self.serializeValue(arg.type, instance)
print ' trace::localWriter.endArg();'
print ' trace::localWriter.endEnter();'
print ' trace::localWriter.beginLeave(__fake_call);'
class GlxTracer(GlTracer):
- def is_public_function(self, function):
+ def isFunctionPublic(self, function):
# The symbols visible in libGL.so can vary, so expose them all
return True
- def wrap_ret(self, function, instance):
- GlTracer.wrap_ret(self, function, instance)
+ def wrapRet(self, function, instance):
+ GlTracer.wrapRet(self, function, instance)
if function.name in ("glXGetProcAddress", "glXGetProcAddressARB"):
print ' %s = __unwrap_proc_addr(procName, %s);' % (instance, instance)
print
api = API()
- api.add_api(glxapi)
- api.add_api(glapi)
+ api.addApi(glxapi)
+ api.addApi(glapi)
tracer = GlxTracer()
tracer.trace_api(api)
class ConstRemover(stdapi.Rebuilder):
+ '''Type visitor which strips out const qualifiers from types.'''
- def visit_const(self, const):
+ def visitConst(self, const):
return const.type
- def visit_opaque(self, opaque):
+ def visitOpaque(self, opaque):
return opaque
-def handle_entry(handle, value):
+def lookupHandle(handle, value):
if handle.key is None:
return "__%s_map[%s]" % (handle.name, value)
else:
return "__%s_map[%s][%s]" % (handle.name, key_name, value)
-class ValueExtractor(stdapi.Visitor):
+class ValueDeserializer(stdapi.Visitor):
- def visit_literal(self, literal, lvalue, rvalue):
+ def visitLiteral(self, literal, lvalue, rvalue):
print ' %s = (%s).to%s();' % (lvalue, rvalue, literal.kind)
- def visit_const(self, const, lvalue, rvalue):
+ def visitConst(self, const, lvalue, rvalue):
self.visit(const.type, lvalue, rvalue)
- def visit_alias(self, alias, lvalue, rvalue):
+ def visitAlias(self, alias, lvalue, rvalue):
self.visit(alias.type, lvalue, rvalue)
- def visit_enum(self, enum, lvalue, rvalue):
+ def visitEnum(self, enum, lvalue, rvalue):
print ' %s = (%s).toSInt();' % (lvalue, rvalue)
- def visit_bitmask(self, bitmask, lvalue, rvalue):
+ def visitBitmask(self, bitmask, lvalue, rvalue):
self.visit(bitmask.type, lvalue, rvalue)
- def visit_array(self, array, lvalue, rvalue):
+ def visitArray(self, array, lvalue, rvalue):
print ' const trace::Array *__a%s = dynamic_cast<const trace::Array *>(&%s);' % (array.tag, rvalue)
print ' if (__a%s) {' % (array.tag)
length = '__a%s->values.size()' % array.tag
print ' %s = NULL;' % lvalue
print ' }'
- def visit_pointer(self, pointer, lvalue, rvalue):
+ def visitPointer(self, pointer, lvalue, rvalue):
print ' const trace::Array *__a%s = dynamic_cast<const trace::Array *>(&%s);' % (pointer.tag, rvalue)
print ' if (__a%s) {' % (pointer.tag)
print ' %s = new %s;' % (lvalue, pointer.type)
print ' %s = NULL;' % lvalue
print ' }'
- def visit_handle(self, handle, lvalue, rvalue):
- OpaqueValueExtractor().visit(handle.type, lvalue, rvalue);
- new_lvalue = handle_entry(handle, lvalue)
+ def visitHandle(self, handle, lvalue, rvalue):
+ OpaqueValueDeserializer().visit(handle.type, lvalue, rvalue);
+ new_lvalue = lookupHandle(handle, lvalue)
print ' if (retrace::verbosity >= 2) {'
print ' std::cout << "%s " << size_t(%s) << " <- " << size_t(%s) << "\\n";' % (handle.name, lvalue, new_lvalue)
print ' }'
print ' %s = %s;' % (lvalue, new_lvalue)
- def visit_blob(self, blob, lvalue, rvalue):
+ def visitBlob(self, blob, lvalue, rvalue):
print ' %s = static_cast<%s>((%s).toPointer());' % (lvalue, blob, rvalue)
- def visit_string(self, string, lvalue, rvalue):
+ def visitString(self, string, lvalue, rvalue):
print ' %s = (%s)((%s).toString());' % (lvalue, string.expr, rvalue)
-class OpaqueValueExtractor(ValueExtractor):
+class OpaqueValueDeserializer(ValueDeserializer):
'''Value extractor that also understands opaque values.
Normally opaque values can't be retraced, unless they are being extracted
in the context of handles.'''
- def visit_opaque(self, opaque, lvalue, rvalue):
+ def visitOpaque(self, opaque, lvalue, rvalue):
print ' %s = static_cast<%s>(retrace::toPointer(%s));' % (lvalue, opaque, rvalue)
-class ValueWrapper(stdapi.Visitor):
+class SwizzledValueRegistrator(stdapi.Visitor):
+ '''Type visitor which will register (un)swizzled value pairs, to later be
+ swizzled.'''
- def visit_literal(self, literal, lvalue, rvalue):
+ def visitLiteral(self, literal, lvalue, rvalue):
pass
- def visit_alias(self, alias, lvalue, rvalue):
+ def visitAlias(self, alias, lvalue, rvalue):
self.visit(alias.type, lvalue, rvalue)
- def visit_enum(self, enum, lvalue, rvalue):
+ def visitEnum(self, enum, lvalue, rvalue):
pass
- def visit_bitmask(self, bitmask, lvalue, rvalue):
+ def visitBitmask(self, bitmask, lvalue, rvalue):
pass
- def visit_array(self, array, lvalue, rvalue):
+ def visitArray(self, array, lvalue, rvalue):
print ' const trace::Array *__a%s = dynamic_cast<const trace::Array *>(&%s);' % (array.tag, rvalue)
print ' if (__a%s) {' % (array.tag)
length = '__a%s->values.size()' % array.tag
print ' }'
print ' }'
- def visit_pointer(self, pointer, lvalue, rvalue):
+ def visitPointer(self, pointer, lvalue, rvalue):
print ' const trace::Array *__a%s = dynamic_cast<const trace::Array *>(&%s);' % (pointer.tag, rvalue)
print ' if (__a%s) {' % (pointer.tag)
try:
finally:
print ' }'
- def visit_handle(self, handle, lvalue, rvalue):
+ def visitHandle(self, handle, lvalue, rvalue):
print ' %s __orig_result;' % handle.type
- OpaqueValueExtractor().visit(handle.type, '__orig_result', rvalue);
+ OpaqueValueDeserializer().visit(handle.type, '__orig_result', rvalue);
if handle.range is None:
rvalue = "__orig_result"
- entry = handle_entry(handle, rvalue)
+ entry = lookupHandle(handle, rvalue)
print " %s = %s;" % (entry, lvalue)
print ' if (retrace::verbosity >= 2) {'
print ' std::cout << "{handle.name} " << {rvalue} << " -> " << {lvalue} << "\\n";'.format(**locals())
i = '__h' + handle.tag
lvalue = "%s + %s" % (lvalue, i)
rvalue = "__orig_result + %s" % (i,)
- entry = handle_entry(handle, rvalue)
+ entry = lookupHandle(handle, rvalue)
print ' for ({handle.type} {i} = 0; {i} < {handle.range}; ++{i}) {{'.format(**locals())
print ' {entry} = {lvalue};'.format(**locals())
print ' if (retrace::verbosity >= 2) {'
print ' }'
print ' }'
- def visit_blob(self, blob, lvalue, rvalue):
+ def visitBlob(self, blob, lvalue, rvalue):
pass
- def visit_string(self, string, lvalue, rvalue):
+ def visitString(self, string, lvalue, rvalue):
pass
class Retracer:
- def retrace_function(self, function):
+ def retraceFunction(self, function):
print 'static void retrace_%s(trace::Call &call) {' % function.name
- self.retrace_function_body(function)
+ self.retraceFunctionBody(function)
print '}'
print
- def retrace_function_body(self, function):
+ def retraceFunctionBody(self, function):
if not function.sideeffects:
print ' (void)call;'
return
rvalue = 'call.arg(%u)' % (arg.index,)
lvalue = arg.name
try:
- self.extract_arg(function, arg, arg_type, lvalue, rvalue)
+ self.extractArg(function, arg, arg_type, lvalue, rvalue)
except NotImplementedError:
success = False
print ' %s = 0; // FIXME' % arg.name
if not success:
print ' if (1) {'
- self.fail_function(function)
+ self.failFunction(function)
print ' }'
- self.call_function(function)
+ self.invokeFunction(function)
for arg in function.args:
if arg.output:
arg_type = ConstRemover().visit(arg.type)
rvalue = 'call.arg(%u)' % (arg.index,)
lvalue = arg.name
try:
- ValueWrapper().visit(arg_type, lvalue, rvalue)
+ self.regiterSwizzledValue(arg_type, lvalue, rvalue)
except NotImplementedError:
print ' // XXX: %s' % arg.name
if function.type is not stdapi.Void:
rvalue = '*call.ret'
lvalue = '__result'
try:
- ValueWrapper().visit(function.type, lvalue, rvalue)
+ self.regiterSwizzledValue(function.type, lvalue, rvalue)
except NotImplementedError:
print ' // XXX: result'
if not success:
if function.name[-1].islower():
sys.stderr.write('warning: unsupported %s call\n' % function.name)
- def fail_function(self, function):
+ def failFunction(self, function):
print ' if (retrace::verbosity >= 0) {'
print ' retrace::unsupported(call);'
print ' }'
print ' return;'
- def extract_arg(self, function, arg, arg_type, lvalue, rvalue):
- ValueExtractor().visit(arg_type, lvalue, rvalue)
+ def extractArg(self, function, arg, arg_type, lvalue, rvalue):
+ ValueDeserializer().visit(arg_type, lvalue, rvalue)
- def extract_opaque_arg(self, function, arg, arg_type, lvalue, rvalue):
- OpaqueValueExtractor().visit(arg_type, lvalue, rvalue)
+ def extractOpaqueArg(self, function, arg, arg_type, lvalue, rvalue):
+ OpaqueValueDeserializer().visit(arg_type, lvalue, rvalue)
- def call_function(self, function):
+ def regiterSwizzledValue(self, type, lvalue, rvalue):
+ visitor = SwizzledValueRegistrator()
+ visitor.visit(type, lvalue, rvalue)
+
+ def invokeFunction(self, function):
arg_names = ", ".join([arg.name for arg in function.args])
if function.type is not stdapi.Void:
print ' %s __result;' % (function.type)
else:
print ' %s(%s);' % (function.name, arg_names)
- def filter_function(self, function):
+ def filterFunction(self, function):
return True
table_name = 'retrace::callbacks'
- def retrace_functions(self, functions):
- functions = filter(self.filter_function, functions)
+ def retraceFunctions(self, functions):
+ functions = filter(self.filterFunction, functions)
for function in functions:
- self.retrace_function(function)
+ self.retraceFunction(function)
print 'const retrace::Entry %s[] = {' % self.table_name
for function in functions:
print
- def retrace_api(self, api):
+ def retraceApi(self, api):
print '#include "trace_parser.hpp"'
print '#include "retrace.hpp"'
handle_names.add(handle.name)
print
- self.retrace_functions(api.functions)
+ self.retraceFunctions(api.functions)
def visit(self, node, *args, **kwargs):
if isinstance(node, dict):
- return self.visit_object(node, *args, **kwargs)
+ return self.visitObject(node, *args, **kwargs)
elif isinstance(node, list):
- return self.visit_array(node, *args, **kwargs)
+ return self.visitArray(node, *args, **kwargs)
else:
- return self.visit_value(node, *args, **kwargs)
+ return self.visitValue(node, *args, **kwargs)
- def visit_object(self, node, *args, **kwargs):
+ def visitObject(self, node, *args, **kwargs):
pass
- def visit_array(self, node, *args, **kwargs):
+ def visitArray(self, node, *args, **kwargs):
pass
- def visit_value(self, node, *args, **kwargs):
+ def visitValue(self, node, *args, **kwargs):
pass
def _newline(self):
self._write('\n')
- def visit_object(self, node):
+ def visitObject(self, node):
self.enter_object()
members = node.keys()
if self.level <= 0:
self._newline()
- def visit_array(self, node):
+ def visitArray(self, node):
self.enter_array()
for i in range(len(node)):
value = node[i]
self._indent()
self._write(']')
- def visit_value(self, node):
+ def visitValue(self, node):
self._write(json.dumps(node))
self.ignore_added = ignore_added
self.tolerance = tolerance
- def visit_object(self, a, b):
+ def visitObject(self, a, b):
if not isinstance(b, dict):
return False
if len(a) != len(b) and not self.ignore_added:
return False
return True
- def visit_array(self, a, b):
+ def visitArray(self, a, b):
if not isinstance(b, list):
return False
if len(a) != len(b):
return False
return True
- def visit_value(self, a, b):
+ def visitValue(self, a, b):
if isinstance(a, float) or isinstance(b, float):
if a == 0:
return abs(b) < self.tolerance
return
Visitor.visit(self, a, b)
- def visit_object(self, a, b):
+ def visitObject(self, a, b):
if not isinstance(b, dict):
self.replace(a, b)
else:
self.dumper.leave_object()
- def visit_array(self, a, b):
+ def visitArray(self, a, b):
if not isinstance(b, list):
self.replace(a, b)
else:
self.dumper.leave_array()
- def visit_value(self, a, b):
+ def visitValue(self, a, b):
if a != b:
self.replace(a, b)
cglapi = API("CGL")
-cglapi.add_functions([
+cglapi.addFunctions([
# CGLCurrent.h, libGL.dylib
Function(CGLError, "CGLSetCurrentContext", [(CGLContextObj, "ctx")]),
Function(CGLContextObj, "CGLGetCurrentContext", []),
IDirect3D7,
]
-ddraw.add_interfaces(interfaces)
+ddraw.addInterfaces(interfaces)
d3d10 = API("d3d10")
-d3d10.add_functions([
+d3d10.addFunctions([
StdFunction(HRESULT, "D3D10CreateDevice", [(Pointer(IDXGIAdapter), "pAdapter"), (D3D10_DRIVER_TYPE, "DriverType"), (HMODULE, "Software"), (UINT, "Flags"), (UINT, "SDKVersion"), Out(Pointer(Pointer(ID3D10Device)), "ppDevice")]),
StdFunction(HRESULT, "D3D10CreateDeviceAndSwapChain", [(Pointer(IDXGIAdapter), "pAdapter"), (D3D10_DRIVER_TYPE, "DriverType"), (HMODULE, "Software"), (UINT, "Flags"), (UINT, "SDKVersion"), (Pointer(DXGI_SWAP_CHAIN_DESC), "pSwapChainDesc"), Out(Pointer(Pointer(IDXGISwapChain)), "ppSwapChain"), Out(Pointer(Pointer(ID3D10Device)), "ppDevice")]),
StdFunction(HRESULT, "D3D10CreateBlob", [(SIZE_T, "NumBytes"), Out(Pointer(LPD3D10BLOB), "ppBuffer")]),
]
d3d8 = API("d3d8")
-d3d8.add_functions([
+d3d8.addFunctions([
StdFunction(PDIRECT3D8, "Direct3DCreate8", [(UINT, "SDKVersion")]),
])
]
d3d9 = API("d3d9")
-d3d9.add_functions([
+d3d9.addFunctions([
StdFunction(PDIRECT3D9, "Direct3DCreate9", [(UINT, "SDKVersion")], fail='NULL'),
StdFunction(HRESULT, "Direct3DCreate9Ex", [(UINT, "SDKVersion"), Out(Pointer(PDIRECT3D9EX), "ppD3D")], fail='D3DERR_NOTAVAILABLE'),
StdFunction(Int, "D3DPERF_BeginEvent", [(D3DCOLOR, "col"), (LPCWSTR, "wszName")], fail='-1'),
])
D3DRENDERSTATETYPE = Enum("D3DRENDERSTATETYPE", [
- expr for expr, types in D3DRENDERSTATEVALUE.switch_types
+ expr for expr, types in D3DRENDERSTATEVALUE.switchTypes
])
D3DTSS_TCI = Flags(DWORD, [
])
D3DTEXTURESTAGESTATETYPE = Enum("D3DTEXTURESTAGESTATETYPE", [
- expr for expr, types in D3DTEXTURESTAGESTATEVALUE.switch_types
+ expr for expr, types in D3DTEXTURESTAGESTATEVALUE.switchTypes
])
D3DTEXTUREFILTERTYPE = Enum("D3DTEXTUREFILTERTYPE", [
])
D3DSAMPLERSTATETYPE = Enum("D3DSAMPLERSTATETYPE", [
- expr for expr, types in D3DSAMPLERSTATEVALUE.switch_types
+ expr for expr, types in D3DSAMPLERSTATEVALUE.switchTypes
])
D3DPV = Flags(DWORD, [
])
ddraw = API("ddraw")
-ddraw.add_functions([
+ddraw.addFunctions([
StdFunction(HRESULT, "DirectDrawEnumerateW", [(LPDDENUMCALLBACKW, "lpCallback"), (LPVOID, "lpContext")]),
StdFunction(HRESULT, "DirectDrawEnumerateA", [(LPDDENUMCALLBACKA, "lpCallback"), (LPVOID, "lpContext")]),
StdFunction(HRESULT, "DirectDrawEnumerateExW", [(LPDDENUMCALLBACKEXW, "lpCallback"), (LPVOID, "lpContext"), (DDENUM, "dwFlags")]),
kwargs.setdefault('call', 'GL_APIENTRY')
return Function(*args, **kwargs)
-eglapi.add_functions([
+eglapi.addFunctions([
# EGL 1.4
Function(EGLError, "eglGetError", [], sideeffects=False),
glapi = API('GL')
-glapi.add_functions([
+glapi.addFunctions([
# GL_VERSION_1_0
GlFunction(Void, "glCullFace", [(GLenum, "mode")]),
GlFunction(Void, "glFrontFace", [(GLenum, "mode")]),
# OpenGL ES specific functions
-glesapi.add_functions([
+glesapi.addFunctions([
# GL_VERSION_ES_CM_1_1: GL_OES_single_precision
GlFunction(Void, "glFrustumf", [(GLfloat, "left"), (GLfloat, "right"), (GLfloat, "bottom"), (GLfloat, "top"), (GLfloat, "zNear"), (GLfloat, "zFar")]),
GlFunction(Void, "glOrthof", [(GLfloat, "left"), (GLfloat, "right"), (GLfloat, "bottom"), (GLfloat, "top"), (GLfloat, "zNear"), (GLfloat, "zFar")]),
PROC = Opaque("__GLXextFuncPtr")
-glxapi.add_functions([
+glxapi.addFunctions([
# GLX
Function(Pointer(XVisualInfo), "glXChooseVisual", [(Display, "dpy"), (Int, "screen"), (Array(GLXAttrib, "__AttribList_size(attribList)"), "attribList")]),
Function(GLXContext, "glXCreateContext", [(Display, "dpy"), (Pointer(XVisualInfo), "vis"), (GLXContext, "shareList"), (Bool, "direct")]),
Type.__init__(self, "void")
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_void(self, *args, **kwargs)
+ return visitor.visitVoid(self, *args, **kwargs)
Void = _Void()
self.kind = kind
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_literal(self, *args, **kwargs)
+ return visitor.visitLiteral(self, *args, **kwargs)
class Const(Type):
self.type = type
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_const(self, *args, **kwargs)
+ return visitor.visitConst(self, *args, **kwargs)
class Pointer(Type):
self.type = type
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_pointer(self, *args, **kwargs)
+ return visitor.visitPointer(self, *args, **kwargs)
class Handle(Type):
self.key = key
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_handle(self, *args, **kwargs)
+ return visitor.visitHandle(self, *args, **kwargs)
def ConstPointer(type):
self.values = list(values)
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_enum(self, *args, **kwargs)
+ return visitor.visitEnum(self, *args, **kwargs)
def FakeEnum(type, values):
self.values = values
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_bitmask(self, *args, **kwargs)
+ return visitor.visitBitmask(self, *args, **kwargs)
Flags = Bitmask
self.length = length
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_array(self, *args, **kwargs)
+ return visitor.visitArray(self, *args, **kwargs)
class Blob(Type):
self.size = size
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_blob(self, *args, **kwargs)
+ return visitor.visitBlob(self, *args, **kwargs)
class Struct(Type):
self.members = members
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_struct(self, *args, **kwargs)
+ return visitor.visitStruct(self, *args, **kwargs)
class Alias(Type):
self.type = type
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_alias(self, *args, **kwargs)
+ return visitor.visitAlias(self, *args, **kwargs)
def Out(type, name):
self.methods = []
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_interface(self, *args, **kwargs)
+ return visitor.visitInterface(self, *args, **kwargs)
- def itermethods(self):
+ def iterMethods(self):
if self.base is not None:
- for method in self.base.itermethods():
+ for method in self.base.iterMethods():
yield method
for method in self.methods:
yield method
self.length = length
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_string(self, *args, **kwargs)
+ return visitor.visitString(self, *args, **kwargs)
# C string (i.e., zero terminated)
CString = String()
Type.__init__(self, expr)
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_opaque(self, *args, **kwargs)
+ return visitor.visitOpaque(self, *args, **kwargs)
def OpaquePointer(type, *args):
class Polymorphic(Type):
- def __init__(self, default_type, switch_expr, switch_types):
- Type.__init__(self, default_type.expr)
- self.default_type = default_type
- self.switch_expr = switch_expr
- self.switch_types = switch_types
+ def __init__(self, defaultType, switchExpr, switchTypes):
+ Type.__init__(self, defaultType.expr)
+ self.defaultType = defaultType
+ self.switchExpr = switchExpr
+ self.switchTypes = switchTypes
def visit(self, visitor, *args, **kwargs):
- return visitor.visit_polymorphic(self, *args, **kwargs)
+ return visitor.visitPolymorphic(self, *args, **kwargs)
- def iterswitch(self):
+ def iterSwitch(self):
cases = [['default']]
- types = [self.default_type]
+ types = [self.defaultType]
- for expr, type in self.switch_types:
+ for expr, type in self.switchTypes:
case = 'case %s' % expr
try:
i = types.index(type)
def visit(self, type, *args, **kwargs):
return type.visit(self, *args, **kwargs)
- def visit_void(self, void, *args, **kwargs):
+ def visitVoid(self, void, *args, **kwargs):
raise NotImplementedError
- def visit_literal(self, literal, *args, **kwargs):
+ def visitLiteral(self, literal, *args, **kwargs):
raise NotImplementedError
- def visit_string(self, string, *args, **kwargs):
+ def visitString(self, string, *args, **kwargs):
raise NotImplementedError
- def visit_const(self, const, *args, **kwargs):
+ def visitConst(self, const, *args, **kwargs):
raise NotImplementedError
- def visit_struct(self, struct, *args, **kwargs):
+ def visitStruct(self, struct, *args, **kwargs):
raise NotImplementedError
- def visit_array(self, array, *args, **kwargs):
+ def visitArray(self, array, *args, **kwargs):
raise NotImplementedError
- def visit_blob(self, blob, *args, **kwargs):
+ def visitBlob(self, blob, *args, **kwargs):
raise NotImplementedError
- def visit_enum(self, enum, *args, **kwargs):
+ def visitEnum(self, enum, *args, **kwargs):
raise NotImplementedError
- def visit_bitmask(self, bitmask, *args, **kwargs):
+ def visitBitmask(self, bitmask, *args, **kwargs):
raise NotImplementedError
- def visit_pointer(self, pointer, *args, **kwargs):
+ def visitPointer(self, pointer, *args, **kwargs):
raise NotImplementedError
- def visit_handle(self, handle, *args, **kwargs):
+ def visitHandle(self, handle, *args, **kwargs):
raise NotImplementedError
- def visit_alias(self, alias, *args, **kwargs):
+ def visitAlias(self, alias, *args, **kwargs):
raise NotImplementedError
- def visit_opaque(self, opaque, *args, **kwargs):
+ def visitOpaque(self, opaque, *args, **kwargs):
raise NotImplementedError
- def visit_interface(self, interface, *args, **kwargs):
+ def visitInterface(self, interface, *args, **kwargs):
raise NotImplementedError
- def visit_polymorphic(self, polymorphic, *args, **kwargs):
+ def visitPolymorphic(self, polymorphic, *args, **kwargs):
raise NotImplementedError
- #return self.visit(polymorphic.default_type, *args, **kwargs)
+ #return self.visit(polymorphic.defaultType, *args, **kwargs)
class OnceVisitor(Visitor):
By itself it is a no-op -- it is intended to be overwritten.
'''
- def visit_void(self, void):
+ def visitVoid(self, void):
return void
- def visit_literal(self, literal):
+ def visitLiteral(self, literal):
return literal
- def visit_string(self, string):
+ def visitString(self, string):
return string
- def visit_const(self, const):
+ def visitConst(self, const):
return Const(const.type)
- def visit_struct(self, struct):
+ def visitStruct(self, struct):
members = [(self.visit(type), name) for type, name in struct.members]
return Struct(struct.name, members)
- def visit_array(self, array):
+ def visitArray(self, array):
type = self.visit(array.type)
return Array(type, array.length)
- def visit_blob(self, blob):
+ def visitBlob(self, blob):
type = self.visit(blob.type)
return Blob(type, blob.size)
- def visit_enum(self, enum):
+ def visitEnum(self, enum):
return enum
- def visit_bitmask(self, bitmask):
+ def visitBitmask(self, bitmask):
type = self.visit(bitmask.type)
return Bitmask(type, bitmask.values)
- def visit_pointer(self, pointer):
+ def visitPointer(self, pointer):
type = self.visit(pointer.type)
return Pointer(type)
- def visit_handle(self, handle):
+ def visitHandle(self, handle):
type = self.visit(handle.type)
return Handle(handle.name, type, range=handle.range, key=handle.key)
- def visit_alias(self, alias):
+ def visitAlias(self, alias):
type = self.visit(alias.type)
return Alias(alias.expr, type)
- def visit_opaque(self, opaque):
+ def visitOpaque(self, opaque):
return opaque
- def visit_polymorphic(self, polymorphic):
- default_type = self.visit(polymorphic.default_type)
- switch_expr = polymorphic.switch_expr
- switch_types = [(expr, self.visit(type)) for expr, type in polymorphic.switch_types]
- return Polymorphic(default_type, switch_expr, switch_types)
+ def visitPolymorphic(self, polymorphic):
+ defaultType = self.visit(polymorphic.defaultType)
+ switchExpr = polymorphic.switchExpr
+ switchTypes = [(expr, self.visit(type)) for expr, type in polymorphic.switchTypes]
+ return Polymorphic(defaultType, switchExpr, switchTypes)
class Collector(Visitor):
Visitor.visit(self, type)
self.types.append(type)
- def visit_void(self, literal):
+ def visitVoid(self, literal):
pass
- def visit_literal(self, literal):
+ def visitLiteral(self, literal):
pass
- def visit_string(self, string):
+ def visitString(self, string):
pass
- def visit_const(self, const):
+ def visitConst(self, const):
self.visit(const.type)
- def visit_struct(self, struct):
+ def visitStruct(self, struct):
for type, name in struct.members:
self.visit(type)
- def visit_array(self, array):
+ def visitArray(self, array):
self.visit(array.type)
- def visit_blob(self, array):
+ def visitBlob(self, array):
pass
- def visit_enum(self, enum):
+ def visitEnum(self, enum):
pass
- def visit_bitmask(self, bitmask):
+ def visitBitmask(self, bitmask):
self.visit(bitmask.type)
- def visit_pointer(self, pointer):
+ def visitPointer(self, pointer):
self.visit(pointer.type)
- def visit_handle(self, handle):
+ def visitHandle(self, handle):
self.visit(handle.type)
- def visit_alias(self, alias):
+ def visitAlias(self, alias):
self.visit(alias.type)
- def visit_opaque(self, opaque):
+ def visitOpaque(self, opaque):
pass
- def visit_interface(self, interface):
+ def visitInterface(self, interface):
if interface.base is not None:
self.visit(interface.base)
- for method in interface.itermethods():
+ for method in interface.iterMethods():
for arg in method.args:
self.visit(arg.type)
self.visit(method.type)
- def visit_polymorphic(self, polymorphic):
- self.visit(polymorphic.default_type)
- for expr, type in polymorphic.switch_types:
+ def visitPolymorphic(self, polymorphic):
+ self.visit(polymorphic.defaultType)
+ for expr, type in polymorphic.switchTypes:
self.visit(type)
collector.visit(function.type)
for interface in self.interfaces:
collector.visit(interface)
- for method in interface.itermethods():
+ for method in interface.iterMethods():
for arg in method.args:
collector.visit(arg.type)
collector.visit(method.type)
return collector.types
- def add_function(self, function):
+ def addFunction(self, function):
self.functions.append(function)
- def add_functions(self, functions):
+ def addFunctions(self, functions):
for function in functions:
- self.add_function(function)
+ self.addFunction(function)
- def add_interface(self, interface):
+ def addInterface(self, interface):
self.interfaces.append(interface)
- def add_interfaces(self, interfaces):
+ def addInterfaces(self, interfaces):
self.interfaces.extend(interfaces)
- def add_api(self, api):
+ def addApi(self, api):
self.headers.extend(api.headers)
- self.add_functions(api.functions)
- self.add_interfaces(api.interfaces)
+ self.addFunctions(api.functions)
+ self.addInterfaces(api.interfaces)
def get_function_by_name(self, name):
for function in self.functions:
HPBUFFERARB = Alias("HPBUFFERARB", HANDLE)
-wglapi.add_functions([
+wglapi.addFunctions([
# WGL
StdFunction(HGLRC, "wglCreateContext", [(HDC, "hdc")]),
StdFunction(BOOL, "wglDeleteContext", [(HGLRC, "hglrc")]),
import specs.stdapi as stdapi
-from dispatch import Dispatcher
def interface_wrap_name(interface):
return "Wrap" + interface.expr
-class DumpDeclarator(stdapi.OnceVisitor):
- '''Declare helper functions to dump complex types.'''
+class ComplexValueSerializer(stdapi.OnceVisitor):
+ '''Type visitors which generates serialization functions for
+ complex types.
+
+ Simple types are serialized inline.
+ '''
+
+ def __init__(self, serializer):
+ stdapi.OnceVisitor.__init__(self)
+ self.serializer = serializer
- def visit_void(self, literal):
+ def visitVoid(self, literal):
pass
- def visit_literal(self, literal):
+ def visitLiteral(self, literal):
pass
- def visit_string(self, string):
+ def visitString(self, string):
pass
- def visit_const(self, const):
+ def visitConst(self, const):
self.visit(const.type)
- def visit_struct(self, struct):
+ def visitStruct(self, struct):
for type, name in struct.members:
self.visit(type)
print 'static void _write__%s(const %s &value) {' % (struct.tag, struct.expr)
print ' };'
print ' trace::localWriter.beginStruct(&sig);'
for type, name in struct.members:
- dump_instance(type, 'value.%s' % (name,))
+ self.serializer.visit(type, 'value.%s' % (name,))
print ' trace::localWriter.endStruct();'
print '}'
print
- def visit_array(self, array):
+ def visitArray(self, array):
self.visit(array.type)
- def visit_blob(self, array):
+ def visitBlob(self, array):
pass
- def visit_enum(self, enum):
+ def visitEnum(self, enum):
print 'static const trace::EnumValue __enum%s_values[] = {' % (enum.tag)
for value in enum.values:
print ' {"%s", %s},' % (value, value)
print '};'
print
- def visit_bitmask(self, bitmask):
+ def visitBitmask(self, bitmask):
print 'static const trace::BitmaskFlag __bitmask%s_flags[] = {' % (bitmask.tag)
for value in bitmask.values:
print ' {"%s", %s},' % (value, value)
print '};'
print
- def visit_pointer(self, pointer):
+ def visitPointer(self, pointer):
self.visit(pointer.type)
- def visit_handle(self, handle):
+ def visitHandle(self, handle):
self.visit(handle.type)
- def visit_alias(self, alias):
+ def visitAlias(self, alias):
self.visit(alias.type)
- def visit_opaque(self, opaque):
+ def visitOpaque(self, opaque):
pass
- def visit_interface(self, interface):
+ def visitInterface(self, interface):
print "class %s : public %s " % (interface_wrap_name(interface), interface.name)
print "{"
print "public:"
print " %s(%s * pInstance);" % (interface_wrap_name(interface), interface.name)
print " virtual ~%s();" % interface_wrap_name(interface)
print
- for method in interface.itermethods():
+ for method in interface.iterMethods():
print " " + method.prototype() + ";"
print
#print "private:"
print "};"
print
- def visit_polymorphic(self, polymorphic):
+ def visitPolymorphic(self, polymorphic):
print 'static void _write__%s(int selector, const %s & value) {' % (polymorphic.tag, polymorphic.expr)
print ' switch (selector) {'
- for cases, type in polymorphic.iterswitch():
+ for cases, type in polymorphic.iterSwitch():
for case in cases:
print ' %s:' % case
- dump_instance(type, 'static_cast<%s>(value)' % (type,))
+ self.serializer.visit(type, 'static_cast<%s>(value)' % (type,))
print ' break;'
print ' }'
print '}'
print
-class DumpImplementer(stdapi.Visitor):
- '''Dump an instance.'''
+class ValueSerializer(stdapi.Visitor):
+ '''Visitor which generates code to serialize any type.
+
+ Simple types are serialized inline here, whereas the serialization of
+ complex types is dispatched to the serialization functions generated by
+ ComplexValueSerializer visitor above.
+ '''
- def visit_literal(self, literal, instance):
+ def visitLiteral(self, literal, instance):
print ' trace::localWriter.write%s(%s);' % (literal.kind, instance)
- def visit_string(self, string, instance):
+ def visitString(self, string, instance):
if string.length is not None:
print ' trace::localWriter.writeString((const char *)%s, %s);' % (instance, string.length)
else:
print ' trace::localWriter.writeString((const char *)%s);' % instance
- def visit_const(self, const, instance):
+ def visitConst(self, const, instance):
self.visit(const.type, instance)
- def visit_struct(self, struct, instance):
+ def visitStruct(self, struct, instance):
print ' _write__%s(%s);' % (struct.tag, instance)
- def visit_array(self, array, instance):
+ def visitArray(self, array, instance):
length = '__c' + array.type.tag
index = '__i' + array.type.tag
print ' if (%s) {' % instance
print ' trace::localWriter.writeNull();'
print ' }'
- def visit_blob(self, blob, instance):
+ def visitBlob(self, blob, instance):
print ' trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size)
- def visit_enum(self, enum, instance):
+ def visitEnum(self, enum, instance):
print ' trace::localWriter.writeEnum(&__enum%s_sig, %s);' % (enum.tag, instance)
- def visit_bitmask(self, bitmask, instance):
+ def visitBitmask(self, bitmask, instance):
print ' trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.tag, instance)
- def visit_pointer(self, pointer, instance):
+ def visitPointer(self, pointer, instance):
print ' if (%s) {' % instance
print ' trace::localWriter.beginArray(1);'
print ' trace::localWriter.beginElement();'
- dump_instance(pointer.type, "*" + instance)
+ self.visit(pointer.type, "*" + instance)
print ' trace::localWriter.endElement();'
print ' trace::localWriter.endArray();'
print ' } else {'
print ' trace::localWriter.writeNull();'
print ' }'
- def visit_handle(self, handle, instance):
+ def visitHandle(self, handle, instance):
self.visit(handle.type, instance)
- def visit_alias(self, alias, instance):
+ def visitAlias(self, alias, instance):
self.visit(alias.type, instance)
- def visit_opaque(self, opaque, instance):
+ def visitOpaque(self, opaque, instance):
print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
- def visit_interface(self, interface, instance):
+ def visitInterface(self, interface, instance):
print ' trace::localWriter.writeOpaque((const void *)&%s);' % instance
- def visit_polymorphic(self, polymorphic, instance):
- print ' _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switch_expr, instance)
-
-
-dump_instance = DumpImplementer().visit
-
+ def visitPolymorphic(self, polymorphic, instance):
+ print ' _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
-class Wrapper(stdapi.Visitor):
- '''Wrap an instance.'''
+class ValueWrapper(stdapi.Visitor):
+ '''Type visitor which will generate the code to wrap an instance.
+
+ Wrapping is necessary mostly for interfaces, however interface pointers can
+ appear anywhere inside complex types.
+ '''
- def visit_void(self, type, instance):
+ def visitVoid(self, type, instance):
raise NotImplementedError
- def visit_literal(self, type, instance):
+ def visitLiteral(self, type, instance):
pass
- def visit_string(self, type, instance):
+ def visitString(self, type, instance):
pass
- def visit_const(self, type, instance):
+ def visitConst(self, type, instance):
pass
- def visit_struct(self, struct, instance):
+ def visitStruct(self, struct, instance):
for type, name in struct.members:
self.visit(type, "(%s).%s" % (instance, name))
- def visit_array(self, array, instance):
+ def visitArray(self, array, instance):
# XXX: actually it is possible to return an array of pointers
pass
- def visit_blob(self, blob, instance):
+ def visitBlob(self, blob, instance):
pass
- def visit_enum(self, enum, instance):
+ def visitEnum(self, enum, instance):
pass
- def visit_bitmask(self, bitmask, instance):
+ def visitBitmask(self, bitmask, instance):
pass
- def visit_pointer(self, pointer, instance):
+ def visitPointer(self, pointer, instance):
print " if (%s) {" % instance
self.visit(pointer.type, "*" + instance)
print " }"
- def visit_handle(self, handle, instance):
+ def visitHandle(self, handle, instance):
self.visit(handle.type, instance)
- def visit_alias(self, alias, instance):
+ def visitAlias(self, alias, instance):
self.visit(alias.type, instance)
- def visit_opaque(self, opaque, instance):
+ def visitOpaque(self, opaque, instance):
pass
- def visit_interface(self, interface, instance):
+ def visitInterface(self, interface, instance):
assert instance.startswith('*')
instance = instance[1:]
print " if (%s) {" % instance
print " %s = new %s(%s);" % (instance, interface_wrap_name(interface), instance)
print " }"
- def visit_polymorphic(self, type, instance):
+ def visitPolymorphic(self, type, instance):
# XXX: There might be polymorphic values that need wrapping in the future
pass
-class Unwrapper(Wrapper):
+class ValueUnwrapper(ValueWrapper):
+ '''Reverse of ValueWrapper.'''
- def visit_interface(self, interface, instance):
+ def visitInterface(self, interface, instance):
assert instance.startswith('*')
instance = instance[1:]
print " if (%s) {" % instance
print " }"
-wrap_instance = Wrapper().visit
-unwrap_instance = Unwrapper().visit
-
-
class Tracer:
+ '''Base class to orchestrate the code generation of API tracing.'''
def __init__(self):
self.api = None
+ def serializerFactory(self):
+ '''Create a serializer.
+
+ Can be overriden by derived classes to inject their own serialzer.
+ '''
+
+ return ValueSerializer()
+
def trace_api(self, api):
self.api = api
print header
print
- # Type dumpers
+ # Generate the serializer functions
types = api.all_types()
- visitor = DumpDeclarator()
+ visitor = ComplexValueSerializer(self.serializerFactory())
map(visitor.visit, types)
print
# Interfaces wrapers
interfaces = [type for type in types if isinstance(type, stdapi.Interface)]
- map(self.interface_wrap_impl, interfaces)
+ map(self.traceInterfaceImpl, interfaces)
print
# Function wrappers
- map(self.trace_function_decl, api.functions)
- map(self.trace_function_impl, api.functions)
+ map(self.traceFunctionDecl, api.functions)
+ map(self.traceFunctionImpl, api.functions)
print
self.footer(api)
def footer(self, api):
pass
- def trace_function_decl(self, function):
+ def traceFunctionDecl(self, function):
# Per-function declarations
if function.args:
print 'static const trace::FunctionSig __%s_sig = {%u, "%s", %u, __%s_args};' % (function.name, function.id, function.name, len(function.args), function.name)
print
- def is_public_function(self, function):
+ def isFunctionPublic(self, function):
return True
- def trace_function_impl(self, function):
- if self.is_public_function(function):
+ def traceFunctionImpl(self, function):
+ if self.isFunctionPublic(function):
print 'extern "C" PUBLIC'
else:
print 'extern "C" PRIVATE'
print function.prototype() + ' {'
if function.type is not stdapi.Void:
print ' %s __result;' % function.type
- self.trace_function_impl_body(function)
+ self.traceFunctionImplBody(function)
if function.type is not stdapi.Void:
- self.wrap_ret(function, "__result")
+ self.wrapRet(function, "__result")
print ' return __result;'
print '}'
print
- def trace_function_impl_body(self, function):
+ def traceFunctionImplBody(self, function):
print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
for arg in function.args:
if not arg.output:
- self.unwrap_arg(function, arg)
- self.dump_arg(function, arg)
+ self.unwrapArg(function, arg)
+ self.serializeArg(function, arg)
print ' trace::localWriter.endEnter();'
- self.dispatch_function(function)
+ self.invokeFunction(function)
print ' trace::localWriter.beginLeave(__call);'
for arg in function.args:
if arg.output:
- self.dump_arg(function, arg)
- self.wrap_arg(function, arg)
+ self.serializeArg(function, arg)
+ self.wrapArg(function, arg)
if function.type is not stdapi.Void:
- self.dump_ret(function, "__result")
+ self.serializeRet(function, "__result")
print ' trace::localWriter.endLeave();'
- def dispatch_function(self, function, prefix='__', suffix=''):
+ def invokeFunction(self, function, prefix='__', suffix=''):
if function.type is stdapi.Void:
result = ''
else:
dispatch = prefix + function.name + suffix
print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
- def dump_arg(self, function, arg):
+ def serializeArg(self, function, arg):
print ' trace::localWriter.beginArg(%u);' % (arg.index,)
- self.dump_arg_instance(function, arg)
+ self.serializeArgValue(function, arg)
print ' trace::localWriter.endArg();'
- def dump_arg_instance(self, function, arg):
- dump_instance(arg.type, arg.name)
+ def serializeArgValue(self, function, arg):
+ self.serializeValue(arg.type, arg.name)
- def wrap_arg(self, function, arg):
- wrap_instance(arg.type, arg.name)
+ def wrapArg(self, function, arg):
+ self.wrapValue(arg.type, arg.name)
- def unwrap_arg(self, function, arg):
- unwrap_instance(arg.type, arg.name)
+ def unwrapArg(self, function, arg):
+ self.unwrapValue(arg.type, arg.name)
- def dump_ret(self, function, instance):
+ def serializeRet(self, function, instance):
print ' trace::localWriter.beginReturn();'
- dump_instance(function.type, instance)
+ self.serializeValue(function.type, instance)
print ' trace::localWriter.endReturn();'
- def wrap_ret(self, function, instance):
- wrap_instance(function.type, instance)
+ def serializeValue(self, type, instance):
+ serializer = self.serializerFactory()
+ serializer.visit(type, instance)
+
+ def wrapRet(self, function, instance):
+ self.wrapValue(function.type, instance)
- def unwrap_ret(self, function, instance):
- unwrap_instance(function.type, instance)
+ def unwrapRet(self, function, instance):
+ self.unwrapValue(function.type, instance)
- def interface_wrap_impl(self, interface):
+ def wrapValue(self, type, instance):
+ visitor = ValueWrapper()
+ visitor.visit(type, instance)
+
+ def unwrapValue(self, type, instance):
+ visitor = ValueUnwrapper()
+ visitor.visit(type, instance)
+
+ def traceInterfaceImpl(self, interface):
print '%s::%s(%s * pInstance) {' % (interface_wrap_name(interface), interface_wrap_name(interface), interface.name)
print ' m_pInstance = pInstance;'
print '}'
print '%s::~%s() {' % (interface_wrap_name(interface), interface_wrap_name(interface))
print '}'
print
- for method in interface.itermethods():
- self.trace_method(interface, method)
+ for method in interface.iterMethods():
+ self.traceMethod(interface, method)
print
- def trace_method(self, interface, method):
+ def traceMethod(self, interface, method):
print method.prototype(interface_wrap_name(interface) + '::' + method.name) + ' {'
print ' static const char * __args[%u] = {%s};' % (len(method.args) + 1, ', '.join(['"this"'] + ['"%s"' % arg.name for arg in method.args]))
print ' static const trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1)
print ' trace::localWriter.endArg();'
for arg in method.args:
if not arg.output:
- self.unwrap_arg(method, arg)
- self.dump_arg(method, arg)
+ self.unwrapArg(method, arg)
+ self.serializeArg(method, arg)
if method.type is stdapi.Void:
result = ''
else:
print ' trace::localWriter.beginLeave(__call);'
for arg in method.args:
if arg.output:
- self.dump_arg(method, arg)
- self.wrap_arg(method, arg)
+ self.serializeArg(method, arg)
+ self.wrapArg(method, arg)
if method.type is not stdapi.Void:
print ' trace::localWriter.beginReturn();'
- dump_instance(method.type, "__result")
+ self.serializeValue(method.type, "__result")
print ' trace::localWriter.endReturn();'
- wrap_instance(method.type, '__result')
+ self.wrapValue(method.type, '__result')
print ' trace::localWriter.endLeave();'
if method.name == 'QueryInterface':
print ' if (ppvObj && *ppvObj) {'
print '}'
print
-
-class DllTracer(Tracer):
-
- def __init__(self, dllname):
- self.dllname = dllname
-
- def header(self, api):
- print '''
-static HINSTANCE g_hDll = NULL;
-
-static PROC
-__getPublicProcAddress(LPCSTR lpProcName)
-{
- if (!g_hDll) {
- char szDll[MAX_PATH] = {0};
-
- if (!GetSystemDirectoryA(szDll, MAX_PATH)) {
- return NULL;
- }
-
- strcat(szDll, "\\\\%s");
-
- g_hDll = LoadLibraryA(szDll);
- if (!g_hDll) {
- return NULL;
- }
- }
-
- return GetProcAddress(g_hDll, lpProcName);
-}
-
-''' % self.dllname
-
- dispatcher = Dispatcher()
- dispatcher.dispatch_api(api)
-
- Tracer.header(self, api)
-
class WglTracer(GlTracer):
- def wrap_ret(self, function, instance):
- GlTracer.wrap_ret(self, function, instance)
+ def wrapRet(self, function, instance):
+ GlTracer.wrapRet(self, function, instance)
if function.name == "wglGetProcAddress":
print ' if (%s) {' % instance
print '#include "glsize.hpp"'
print
api = API()
- api.add_api(glapi)
- api.add_api(wglapi)
+ api.addApi(glapi)
+ api.addApi(wglapi)
tracer = WglTracer()
tracer.trace_api(api)