X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=base.py;h=8213403aafccc37043aedac98f4e9410cd0df9eb;hb=dce84c4cbc8176d627c5e7801c2acbd0e2027b86;hp=4afcb577b94e593c845359fe1e790c83a3033ae5;hpb=6d633a935232de1f4e19467ce331b6e5290a378e;p=apitrace diff --git a/base.py b/base.py index 4afcb57..8213403 100644 --- a/base.py +++ b/base.py @@ -37,42 +37,61 @@ class Visitor: def visit(self, type, *args, **kwargs): return type.visit(self, *args, **kwargs) - __call__ = visit + def visit_void(self, void, *args, **kwargs): + raise NotImplementedError + + def visit_literal(self, literal, *args, **kwargs): + raise NotImplementedError + + def visit_string(self, string, *args, **kwargs): + raise NotImplementedError - def visit_void(self, type, *args, **kwargs): + def visit_const(self, const, *args, **kwargs): raise NotImplementedError - def visit_literal(self, type, *args, **kwargs): + def visit_struct(self, struct, *args, **kwargs): raise NotImplementedError - def visit_const(self, type, *args, **kwargs): + def visit_array(self, array, *args, **kwargs): raise NotImplementedError - def visit_struct(self, type, *args, **kwargs): + def visit_blob(self, blob, *args, **kwargs): raise NotImplementedError - def visit_array(self, type, *args, **kwargs): + def visit_enum(self, enum, *args, **kwargs): raise NotImplementedError - def visit_blob(self, type, *args, **kwargs): + def visit_bitmask(self, bitmask, *args, **kwargs): raise NotImplementedError - def visit_enum(self, type, *args, **kwargs): + def visit_pointer(self, pointer, *args, **kwargs): raise NotImplementedError - def visit_bitmask(self, type, *args, **kwargs): + def visit_handle(self, handle, *args, **kwargs): raise NotImplementedError - def visit_pointer(self, type, *args, **kwargs): + def visit_alias(self, alias, *args, **kwargs): raise NotImplementedError - def visit_alias(self, type, *args, **kwargs): + def visit_opaque(self, opaque, *args, **kwargs): raise NotImplementedError - def visit_opaque(self, type, *args, **kwargs): + def visit_interface(self, interface, *args, **kwargs): raise NotImplementedError +class OnceVisitor(Visitor): + + def __init__(self): + self.__visited = set() + + def visit(self, type, *args, **kwargs): + if type not in self.__visited: + self.__visited.add(type) + return type.visit(self, *args, **kwargs) + return None + + class Rebuilder(Visitor): def visit_void(self, void): @@ -81,6 +100,9 @@ class Rebuilder(Visitor): def visit_literal(self, literal): return literal + def visit_string(self, string): + return string + def visit_const(self, const): return Const(const.type) @@ -107,6 +129,10 @@ class Rebuilder(Visitor): type = self.visit(pointer.type) return Pointer(type) + def visit_handle(self, handle): + type = self.visit(handle.type) + return Handle(handle.name, type) + def visit_alias(self, alias): type = self.visit(alias.type) return Alias(alias.expr, type) @@ -142,20 +168,6 @@ class Type: def visit(self, visitor, *args, **kwargs): raise NotImplementedError - def decl(self): - pass - - def impl(self): - pass - - def dump(self, instance): - raise NotImplementedError - - def wrap_instance(self, instance): - pass - - def unwrap_instance(self, instance): - pass class _Void(Type): @@ -187,18 +199,15 @@ class Concrete(Type): print ' Dump%s(%s);' % (self.id, instance) -class Literal(Concrete): +class Literal(Type): def __init__(self, expr, format, base=10): - Concrete.__init__(self, expr) + Type.__init__(self, expr) self.format = format def visit(self, visitor, *args, **kwargs): return visitor.visit_literal(self, *args, **kwargs) - def _dump(self, instance): - print ' Log::Literal%s(%s);' % (self.format, instance) - class Const(Type): @@ -216,9 +225,6 @@ class Const(Type): def visit(self, visitor, *args, **kwargs): return visitor.visit_const(self, *args, **kwargs) - def dump(self, instance): - self.type.dump(instance) - class Pointer(Type): @@ -229,23 +235,16 @@ class Pointer(Type): def visit(self, visitor, *args, **kwargs): return visitor.visit_pointer(self, *args, **kwargs) - def dump(self, instance): - print ' if(%s) {' % instance - print ' Log::BeginPointer("%s", (const void *)%s);' % (self.type, instance) - try: - self.type.dump("*" + instance) - except NotImplementedError: - pass - print ' Log::EndPointer();' - print ' }' - print ' else' - print ' Log::LiteralNull();' - def wrap_instance(self, instance): - self.type.wrap_instance("*" + instance) +class Handle(Type): - def unwrap_instance(self, instance): - self.type.wrap_instance("*" + instance) + def __init__(self, name, type): + Type.__init__(self, type.expr, 'P' + type.id) + self.name = name + self.type = type + + def visit(self, visitor, *args, **kwargs): + return visitor.visit_handle(self, *args, **kwargs) def ConstPointer(type): @@ -261,17 +260,6 @@ class Enum(Concrete): def visit(self, visitor, *args, **kwargs): return visitor.visit_enum(self, *args, **kwargs) - def _dump(self, instance): - print ' switch(%s) {' % instance - for value in self.values: - print ' case %s:' % value - print ' Log::LiteralNamedConstant("%s", %s);' % (value, value) - print ' break;' - print ' default:' - print ' Log::LiteralSInt(%s);' % instance - print ' break;' - print ' }' - def FakeEnum(type, values): return Enum(type.expr, values) @@ -287,19 +275,6 @@ class Bitmask(Concrete): def visit(self, visitor, *args, **kwargs): return visitor.visit_bitmask(self, *args, **kwargs) - def _dump(self, instance): - print ' %s l_Value = %s;' % (self.type, instance) - print ' Log::BeginBitmask("%s");' % (self.type,) - for value in self.values: - print ' if((l_Value & %s) == %s) {' % (value, value) - print ' Log::LiteralNamedConstant("%s", %s);' % (value, value) - print ' l_Value &= ~%s;' % value - print ' }' - print ' if(l_Value) {' - self.type.dump("l_Value"); - print ' }' - print ' Log::EndBitmask();' - Flags = Bitmask @@ -313,22 +288,6 @@ class Array(Type): def visit(self, visitor, *args, **kwargs): return visitor.visit_array(self, *args, **kwargs) - def dump(self, instance): - index = '__i' + self.type.id - print ' Log::BeginArray("%s", %s);' % (self.type, self.length) - print ' for (int %s = 0; %s < %s; ++%s) {' % (index, index, self.length, index) - print ' Log::BeginElement("%s");' % (self.type,) - self.type.dump('(%s)[%s]' % (instance, index)) - print ' Log::EndElement();' - print ' }' - print ' Log::EndArray();' - - def wrap_instance(self, instance): - self.type.wrap_instance("*" + instance) - - def unwrap_instance(self, instance): - self.type.wrap_instance("*" + instance) - class Blob(Type): @@ -340,9 +299,6 @@ class Blob(Type): def visit(self, visitor, *args, **kwargs): return visitor.visit_blob(self, *args, **kwargs) - def dump(self, instance): - print ' Log::LiteralBlob(%s, %s);' % (instance, self.size) - class Struct(Concrete): @@ -354,14 +310,6 @@ class Struct(Concrete): def visit(self, visitor, *args, **kwargs): return visitor.visit_struct(self, *args, **kwargs) - def _dump(self, instance): - print ' Log::BeginStruct("%s");' % (self.name,) - for type, name in self.members: - print ' Log::BeginMember("%s", "%s");' % (type, name) - type.dump('(%s).%s' % (instance, name)) - print ' Log::EndMember();' - print ' Log::EndStruct();' - class Alias(Type): @@ -372,9 +320,6 @@ class Alias(Type): def visit(self, visitor, *args, **kwargs): return visitor.visit_alias(self, *args, **kwargs) - def dump(self, instance): - self.type.dump(instance) - def Out(type, name): arg = Arg(type, name, output=True) @@ -387,6 +332,7 @@ class Arg: self.type = type self.name = name self.output = output + self.index = None def __str__(self): return '%s %s' % (self.type, self.name) @@ -394,19 +340,24 @@ class Arg: class Function: - def __init__(self, type, name, args, call = '__stdcall', fail = None): + def __init__(self, type, name, args, call = '', fail = None, sideeffects=True, hidden=False): self.type = type self.name = name self.args = [] + index = 0 for arg in args: if isinstance(arg, tuple): arg_type, arg_name = arg arg = Arg(arg_type, arg_name) + arg.index = index + index += 1 self.args.append(arg) self.call = call self.fail = fail + self.sideeffects = sideeffects + self.hidden = False def prototype(self, name=None): if name is not None: @@ -427,73 +378,15 @@ class Function: s += ")" return s - def pointer_type(self): - return 'P' + self.name - def pointer_value(self): - return 'p' + self.name +def StdFunction(*args, **kwargs): + kwargs.setdefault('call', 'GLAPIENTRY') + return Function(*args, **kwargs) - def wrap_decl(self): - ptype = self.pointer_type() - pvalue = self.pointer_value() - print 'typedef ' + self.prototype('* %s' % ptype) + ';' - print 'static %s %s = NULL;' % (ptype, pvalue) - print - def get_true_pointer(self): - raise NotImplementedError - - def exit_impl(self): - print ' Log::Abort();' - - def fail_impl(self): - if self.fail is not None: - if self.type is Void: - assert self.fail == '' - print ' return;' - else: - assert self.fail != '' - print ' return %s;' % self.fail - else: - self.exit_impl() - - def wrap_impl(self): - pvalue = self.pointer_value() - print self.prototype() + ' {' - if self.type is Void: - result = '' - else: - print ' %s result;' % self.type - result = 'result = ' - self.get_true_pointer() - print ' Log::BeginCall("%s");' % (self.name) - for arg in self.args: - if not arg.output: - arg.type.unwrap_instance(arg.name) - print ' Log::BeginArg("%s", "%s");' % (arg.type, arg.name) - arg.type.dump(arg.name) - print ' Log::EndArg();' - print ' %s%s(%s);' % (result, pvalue, ', '.join([str(arg.name) for arg in self.args])) - for arg in self.args: - if arg.output: - print ' Log::BeginArg("%s", "%s");' % (arg.type, arg.name) - arg.type.dump(arg.name) - print ' Log::EndArg();' - arg.type.wrap_instance(arg.name) - if self.type is not Void: - print ' Log::BeginReturn("%s");' % self.type - self.type.dump("result") - print ' Log::EndReturn();' - self.type.wrap_instance('result') - print ' Log::EndCall();' - self.post_call_impl() - if self.type is not Void: - print ' return result;' - print '}' - print - - def post_call_impl(self): - pass +def FunctionPointer(type, name, args, **kwargs): + # XXX + return Opaque(name) class Interface(Type): @@ -512,79 +405,6 @@ class Interface(Type): yield method raise StopIteration - def wrap_name(self): - return "Wrap" + self.expr - - def wrap_pre_decl(self): - print "class %s;" % self.wrap_name() - - def wrap_decl(self): - print "class %s : public %s " % (self.wrap_name(), self.name) - print "{" - print "public:" - print " %s(%s * pInstance);" % (self.wrap_name(), self.name) - print " virtual ~%s();" % self.wrap_name() - print - for method in self.itermethods(): - print " " + method.prototype() + ";" - print - #print "private:" - print " %s * m_pInstance;" % (self.name,) - print "};" - print - - def wrap_impl(self): - print '%s::%s(%s * pInstance) {' % (self.wrap_name(), self.wrap_name(), self.name) - print ' m_pInstance = pInstance;' - print '}' - print - print '%s::~%s() {' % (self.wrap_name(), self.wrap_name()) - print '}' - print - for method in self.itermethods(): - print method.prototype(self.wrap_name() + '::' + method.name) + ' {' - if method.type is Void: - result = '' - else: - print ' %s result;' % method.type - result = 'result = ' - print ' Log::BeginCall("%s");' % (self.name + '::' + method.name) - print ' Log::BeginArg("%s *", "this");' % self.name - print ' Log::BeginPointer("%s", (const void *)m_pInstance);' % self.name - print ' Log::EndPointer();' - print ' Log::EndArg();' - for arg in method.args: - if not arg.output: - arg.type.unwrap_instance(arg.name) - print ' Log::BeginArg("%s", "%s");' % (arg.type, arg.name) - arg.type.dump(arg.name) - print ' Log::EndArg();' - print ' %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args])) - for arg in method.args: - if arg.output: - print ' Log::BeginArg("%s", "%s");' % (arg.type, arg.name) - arg.type.dump(arg.name) - print ' Log::EndArg();' - arg.type.wrap_instance(arg.name) - if method.type is not Void: - print ' Log::BeginReturn("%s");' % method.type - method.type.dump("result") - print ' Log::EndReturn();' - method.type.wrap_instance('result') - print ' Log::EndCall();' - if method.name == 'QueryInterface': - print ' if(*ppvObj == m_pInstance)' - print ' *ppvObj = this;' - if method.name == 'Release': - assert method.type is not Void - print ' if(!result)' - print ' delete this;' - if method.type is not Void: - print ' return result;' - print '}' - print - print - class Method(Function): @@ -594,34 +414,21 @@ class Method(Function): towrap = [] -class WrapPointer(Pointer): - - def __init__(self, type): - Pointer.__init__(self, type) - if type not in towrap: - towrap.append(type) - - def wrap_instance(self, instance): - print " if(%s)" % instance - print " %s = new %s(%s);" % (instance, self.type.wrap_name(), instance) - def unwrap_instance(self, instance): - print " if(%s)" % instance - print " %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, self.type.wrap_name(), instance) +def WrapPointer(type): + return Pointer(type) -class _String(Type): +class String(Type): - def __init__(self): - Type.__init__(self, "char *") + def __init__(self, expr = "char *", length = None): + Type.__init__(self, expr) + self.length = length def visit(self, visitor, *args, **kwargs): - return visitor.visit_literal(self, *args, **kwargs) - - def dump(self, instance): - print ' Log::LiteralString((const char *)%s);' % instance + return visitor.visit_string(self, *args, **kwargs) -String = _String() +CString = String() class Opaque(Type): @@ -633,14 +440,105 @@ class Opaque(Type): def visit(self, visitor, *args, **kwargs): return visitor.visit_opaque(self, *args, **kwargs) - def dump(self, instance): - print ' Log::LiteralOpaque((const void *)%s);' % instance - def OpaquePointer(type): return Opaque(type.expr + ' *') +class Collector(Visitor): + '''Collect.''' + + def __init__(self): + self.__visited = set() + self.types = [] + + def visit(self, type): + if type in self.__visited: + return + self.__visited.add(type) + Visitor.visit(self, type) + self.types.append(type) + + def visit_void(self, literal): + pass + + def visit_literal(self, literal): + pass + + def visit_string(self, string): + pass + + def visit_const(self, const): + self.visit(const.type) + + def visit_struct(self, struct): + for type, name in struct.members: + self.visit(type) + + def visit_array(self, array): + self.visit(array.type) + + def visit_blob(self, array): + pass + + def visit_enum(self, enum): + pass + + def visit_bitmask(self, bitmask): + self.visit(bitmask.type) + + def visit_pointer(self, pointer): + self.visit(pointer.type) + + def visit_handle(self, handle): + self.visit(handle.type) + + def visit_alias(self, alias): + self.visit(alias.type) + + def visit_opaque(self, opaque): + pass + + def visit_interface(self, interface): + pass + + +class API: + + def __init__(self, name): + self.name = name + self.headers = [] + self.functions = [] + self.interfaces = [] + + def all_types(self): + collector = Collector() + for function in self.functions: + for arg in function.args: + collector.visit(arg.type) + collector.visit(function.type) + for interface in self.interfaces: + collector.visit(interface) + for method in interface.methods: + for arg in method.args: + collector.visit(arg.type) + collector.visit(method.type) + return collector.types + + def add_function(self, function): + self.functions.append(function) + + def add_functions(self, functions): + for function in functions: + self.add_function(function) + + def add_interface(self, interface): + self.interfaces.append(interface) + + def add_interfaces(self, interfaces): + self.interfaces.extend(interfaces) + + Bool = Literal("bool", "Bool") SChar = Literal("signed char", "SInt") UChar = Literal("unsigned char", "UInt") @@ -651,25 +549,9 @@ LongLong = Literal("long long", "SInt") UShort = Literal("unsigned short", "UInt") UInt = Literal("unsigned int", "UInt") ULong = Literal("unsigned long", "UInt") +ULongLong = Literal("unsigned long long", "UInt") Float = Literal("float", "Float") Double = Literal("double", "Float") SizeT = Literal("size_t", "UInt") WString = Literal("wchar_t *", "WString") - -def wrap(): - for type in all_types.itervalues(): - type.decl() - print - for type in all_types.itervalues(): - type.impl() - print - for type in towrap: - type.wrap_pre_decl() - print - for type in towrap: - type.wrap_decl() - print - for type in towrap: - type.wrap_impl() - print