Trace::Call *call;
while ((call = parser.parse_call())) {
- if (call->name == "glFlush") {
+ if (call->name() == "glFlush") {
glFlush();
return;
}
- if (call->name == "glXSwapBuffers" ||
- call->name == "wglSwapBuffers") {
+ if (call->name() == "glXSwapBuffers" ||
+ call->name() == "wglSwapBuffers") {
if (double_buffer)
glutSwapBuffers();
else
retrace_call(*call);
- if (call->name == "glBegin") {
+ if (call->name() == "glBegin") {
insideGlBeginEnd = true;
}
- if (call->name == "glEnd") {
+ if (call->name() == "glEnd") {
insideGlBeginEnd = false;
}
print 'static bool retrace_call(Trace::Call &call) {'
for function in functions:
if not function.sideeffects:
- print ' if (call.name == "%s") {' % function.name
+ print ' if (call.name() == "%s") {' % function.name
print ' return true;'
print ' }'
print
print
for function in functions:
if function.sideeffects:
- print ' if (call.name == "%s") {' % function.name
+ print ' if (call.name() == "%s") {' % function.name
print ' retrace_%s(call);' % function.name
print ' return true;'
print ' }'
- print ' std::cerr << "warning: unknown call " << call.name << "\\n";'
+ print ' std::cerr << "warning: unknown call " << call.name() << "\\n";'
print ' return false;'
print '}'
print
Trace::Call *call;
while ((call = parser.parse_call())) {
- if (call->name == "glFlush" ||
- call->name == "glXSwapBuffers" ||
- call->name == "wglSwapBuffers") {
+ if (call->name() == "glFlush" ||
+ call->name() == "glXSwapBuffers" ||
+ call->name() == "wglSwapBuffers") {
glFlush();
return;
}
retrace_call(*call);
- if (call->name == "glBegin") {
+ if (call->name() == "glBegin") {
insideGlBeginEnd = true;
}
- if (call->name == "glEnd") {
+ if (call->name() == "glEnd") {
insideGlBeginEnd = false;
}
class Function:
+ __id = 0
+
def __init__(self, type, name, args, call = '', fail = None, sideeffects=True, hidden=False):
+ self.id = Function.__id
+ Function.__id += 1
+
self.type = type
self.name = name
SizeT = Literal("size_t", "UInt")
WString = Literal("wchar_t *", "WString")
+Int8 = Literal("int8_t", "SInt")
+UInt8 = Literal("uint8_t", "UInt")
+Int16 = Literal("int16_t", "SInt")
+UInt16 = Literal("uint16_t", "UInt")
+Int32 = Literal("int32_t", "SInt")
+UInt32 = Literal("uint32_t", "UInt")
+Int64 = Literal("int64_t", "SInt")
+UInt64 = Literal("uint64_t", "UInt")
print 'typedef ' + function.prototype('* %s' % ptype) + ';'
print 'static %s %s = NULL;' % (ptype, pvalue)
print
+ print 'static const char * __%s_args[] = {' % (function.name)
+ for arg in function.args:
+ print ' "%s",' % (arg.name,)
+ print '};'
+ print
+ print 'static const Trace::FunctionSig __%s_sig = {' % (function.name)
+ print ' %u, "%s", %u, __%s_args' % (int(function.id), function.name, len(function.args), function.name)
+ print '};'
+ print
+
def trace_function_fail(self, function):
if function.fail is not None:
print ' %s __result;' % function.type
result = '__result = '
self._get_true_pointer(function)
- print ' unsigned __call = Trace::BeginEnter("%s");' % (function.name)
+ print ' unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name)
for arg in function.args:
if not arg.output:
self.unwrap_arg(function, arg)
print
def dump_arg(self, function, arg):
- print ' Trace::BeginArg(%u, "%s");' % (arg.index, arg.name,)
+ print ' Trace::BeginArg(%u);' % (arg.index,)
dump_instance(arg.type, arg.name)
print ' Trace::EndArg();'
print ' %s __result;' % method.type
result = '__result = '
print ' Trace::BeginCall("%s");' % (interface.name + '::' + method.name)
- print ' Trace::BeginArg(0, "this");'
+ print ' Trace::BeginArg(0);'
print ' Trace::LiteralOpaque((const void *)m_pInstance);'
print ' Trace::EndArg();'
for arg in method.args:
void visit(Call *call) {
const char *sep = "";
- os << bold << call->name << normal << "(";
- for (std::vector<Arg>::iterator it = call->args.begin(); it != call->args.end(); ++it) {
- os << sep << italic << it->first << normal << " = ";
- _visit(it->second);
+ os << bold << call->sig->name << normal << "(";
+ for (unsigned i = 0; i < call->args.size(); ++i) {
+ os << sep << italic << call->sig->arg_names[i] << normal << " = ";
+ _visit(call->args[i]);
sep = ", ";
}
os << ")";
double asFloat(const Value &node);
-typedef std::pair<std::string, Value *> Arg;
-
class Call
{
public:
+ struct Signature {
+ std::string name;
+ std::vector<std::string> arg_names;
+ };
+
unsigned no;
- std::string name;
- std::vector<Arg> args;
+ const Signature *sig;
+ std::vector<Value *> args;
Value *ret;
- Call() : ret(0) { }
+ Call(Signature *_sig) : sig(_sig), ret(0) { }
+
+ inline const std::string name(void) const {
+ return sig->name;
+ }
inline Value & arg(unsigned index) {
- return *(args[index].second);
+ return *(args[index]);
}
};
typedef std::map<unsigned, Call *> callmap;
callmap calls;
+ typedef std::map<size_t, Call::Signature *> FunctionMap;
+ FunctionMap functions;
+
typedef std::map<size_t, Bitmask::Signature *> BitmaskMap;
BitmaskMap bitmasks;
}
void parse_enter(void) {
- Call *call = new Call;
+ size_t id = read_uint();
+
+ Call::Signature *sig;
+ FunctionMap::const_iterator it = functions.find(id);
+ if (it == functions.end()) {
+ sig = new Call::Signature;
+ sig->name = read_string();
+ unsigned size = read_uint();
+ for (unsigned i = 0; i < size; ++i) {
+ sig->arg_names.push_back(read_string());
+ }
+ functions[id] = sig;
+ } else {
+ sig = it->second;
+ }
+ assert(sig);
+
+ Call *call = new Call(sig);
call->no = next_call_no++;
- call->name = read_name();
+
parse_call_details(call);
calls[call->no] = call;
}
void parse_arg(Call *call) {
unsigned index = read_uint();
- std::string name = read_name();
Value *value = parse_value();
if (index >= call->args.size()) {
call->args.resize(index + 1);
}
- call->args[index] = Arg(name, value);
+ call->args[index] = value;
}
Value *parse_value(void) {
static unsigned call_no = 0;
-unsigned BeginEnter(const char *function) {
+static std::map<Id, bool> functions;
+static std::map<Id, bool> bitmasks;
+
+
+unsigned BeginEnter(const FunctionSig &function) {
OS::AcquireMutex();
Open();
WriteByte(Trace::EVENT_ENTER);
- WriteName(function);
+ WriteUInt(function.id);
+ if (!functions[function.id]) {
+ WriteString(function.name);
+ WriteUInt(function.num_args);
+ for (unsigned i = 0; i < function.num_args; ++i) {
+ WriteString(function.args[i]);
+ }
+ functions[function.id] = true;
+ }
return call_no++;
}
OS::ReleaseMutex();
}
-void BeginArg(unsigned index, const char *name) {
+void BeginArg(unsigned index) {
WriteByte(Trace::CALL_ARG);
WriteUInt(index);
- WriteName(name);
}
void BeginReturn(void) {
LiteralSInt(value);
}
-static std::map<Id, bool> bitmasks;
-
void LiteralBitmask(const BitmaskSig &bitmask, unsigned long long value) {
WriteByte(Trace::TYPE_BITMASK);
WriteUInt(bitmask.id);
typedef unsigned Id;
+ struct FunctionSig {
+ Id id;
+ const char *name;
+ unsigned num_args;
+ const char **args;
+ };
+
struct BitmaskVal {
const char *name;
unsigned long long value;
void Open(void);
void Close(void);
- unsigned BeginEnter(const char *function);
+ unsigned BeginEnter(const FunctionSig &function);
void EndEnter(void);
void BeginLeave(unsigned call);
void EndLeave(void);
- void BeginArg(unsigned index, const char *name);
+ void BeginArg(unsigned index);
inline void EndArg(void) {}
void BeginReturn(void);