Make better use of C++ implicit casts. Support arrays.
authorJosé Fonseca <jfonseca@vmware.com>
Sat, 20 Nov 2010 09:03:10 +0000 (09:03 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 20 Nov 2010 09:03:10 +0000 (09:03 +0000)
base.py
gl.py
glretrace.py
trace_model.cpp
trace_model.hpp

diff --git a/base.py b/base.py
index ab2382f..2f2b1d0 100644 (file)
--- a/base.py
+++ b/base.py
@@ -70,6 +70,44 @@ class Visitor:
         raise NotImplementedError
 
 
+class Rebuilder(Visitor):
+
+    def visit_void(self, void):
+        return void
+
+    def visit_literal(self, literal):
+        return literal
+
+    def visit_const(self, const):
+        return Const(const.type)
+
+    def visit_struct(self, struct):
+        members = [self.visit(member) for member in struct.members]
+        return Struct(struct.name, members)
+
+    def visit_array(self, array):
+        type = self.visit(array.type)
+        return Array(type, array.length)
+
+    def visit_enum(self, enum):
+        return enum
+
+    def visit_bitmask(self, bitmask):
+        type = self.visit(bitmask.type)
+        return Bitmask(type, bitmask.values)
+
+    def visit_pointer(self, pointer):
+        type = self.visit(pointer.type)
+        return Pointer(type)
+
+    def visit_alias(self, alias):
+        type = self.visit(alias.type)
+        return Alias(alias.expr, type)
+
+    def visit_opaque(self, opaque):
+        return opaque
+
+
 class Type:
 
     __seq = 0
@@ -321,8 +359,8 @@ class Struct(Concrete):
 
 class Alias(Type):
 
-    def __init__(self, name, type):
-        Type.__init__(self, name)
+    def __init__(self, expr, type):
+        Type.__init__(self, expr)
         self.type = type
 
     def visit(self, visitor, *args, **kwargs):
diff --git a/gl.py b/gl.py
index 4db1041..7f74380 100644 (file)
--- a/gl.py
+++ b/gl.py
@@ -25,7 +25,7 @@
 
 from base import *
 
-GLboolean = Enum("GLboolean", ["GL_FALSE", "GL_TRUE"])
+GLboolean = Alias("GLboolean", Bool)
 GLvoid = Alias("GLvoid", Void)
 GLbyte = Alias("GLbyte", SChar)
 GLshort = Alias("GLshort", Short)
index 5644e36..a689cc1 100644 (file)
@@ -28,22 +28,34 @@ import base
 from glx import libgl
 
 
+
+class ConstRemover(base.Rebuilder):
+
+    def visit_const(self, const):
+        return const.type
+
+
 class ValueExtractor(base.Visitor):
 
     def visit_literal(self, type, lvalue, rvalue):
-        #print '    %s = static_cast<%s>(Trace::as%s(%s));' % (lvalue, type, type.format, rvalue)
-        print '    %s = Trace::as%s(%s);' % (lvalue, type.format, rvalue)
+        print '    %s = %s;' % (lvalue, rvalue)
 
     def visit_alias(self, type, lvalue, rvalue):
         self.visit(type.type, lvalue, rvalue)
     
     def visit_enum(self, type, lvalue, rvalue):
-        #print '    %s = static_cast<%s>(Trace::as%s(%s));' % (lvalue, type, 'SInt', rvalue)
-        print '    %s = Trace::as%s(%s);' % (lvalue, 'SInt', rvalue)
+        print '    %s = %s;' % (lvalue, rvalue)
 
     def visit_bitmask(self, type, lvalue, rvalue):
         self.visit(type.type, lvalue, rvalue)
 
+    def visit_array(self, array, lvalue, rvalue):
+        print '    %s = new %s[%s];' % (lvalue, array.type, array.length)
+        index = '__i' + array.id
+        print '    for(size_t {i} = 0; {i} < {length}; ++{i}) {{'.format(i = index, length = array.length)
+        self.visit(array.type, '%s[%s]' % (lvalue, index), '%s[%s]' % (rvalue, index))
+        print '    }'
+
 
 
 def retrace_function(function):
@@ -51,8 +63,8 @@ def retrace_function(function):
     if not function.name.startswith('glX'):
         success = True
         for arg_type, arg_name in function.args:
+            arg_type = ConstRemover().visit(arg_type)
             print '    %s %s;' % (arg_type, arg_name)
-        for arg_type, arg_name in function.args:
             rvalue = 'call.arg("%s")' % (arg_name,)
             lvalue = arg_name
             try:
index 8f10224..b832587 100644 (file)
@@ -121,26 +121,27 @@ std::ostream & operator <<(std::ostream &os, Value *value) {
 }
 
 
-static const Value *unwrap(const Value &node) {
-   const Const *c = dynamic_cast<const Const *>(&node);
+static inline const Value *unwrap(const Value *node) {
+   const Const *c = dynamic_cast<const Const *>(node);
    if (c)
       return c->value;
-   return &node;
+   return node;
 }
 
-signed long long asSInt(const Value &node) {
-   const SInt *sint = dynamic_cast<const SInt *>(unwrap(node));
+
+Value::operator signed long long(void) const {
+   const SInt *sint = dynamic_cast<const SInt *>(unwrap(this));
    if (sint)
       return sint->value;
-   const UInt *uint = dynamic_cast<const UInt *>(unwrap(node));
+   const UInt *uint = dynamic_cast<const UInt *>(unwrap(this));
    if (uint)
       return uint->value;
    assert(0);
    return 0;
 }
 
-unsigned long long asUInt(const Value &node) {
-   const UInt *uint = dynamic_cast<const UInt *>(unwrap(node));
+Value::operator unsigned long long(void) const {
+   const UInt *uint = dynamic_cast<const UInt *>(unwrap(this));
    if (uint)
       return uint->value;
    assert(0);
@@ -148,14 +149,24 @@ unsigned long long asUInt(const Value &node) {
 }
 
 
-double asFloat(const Value &node) {
-   const Float *fl = dynamic_cast<const Float *>(unwrap(node));
+Value::operator double(void) const {
+   const Float *fl = dynamic_cast<const Float *>(unwrap(this));
    assert(fl);
    return fl->value;
 }
 
 static Void void_;
 
+const Value & Value::operator[](size_t index) const {
+    const Array *array = dynamic_cast<const Array *>(unwrap(this));
+    if (array) {
+        if (index < array->values.size()) {
+            return *array->values[index];
+        }
+    }
+    return void_;
+}
+
 Value & Call::arg(const char *name) {
    for (std::list<Arg>::iterator it = args.begin(); it != args.end(); ++it) {
       if (it->first == name) {
index 8702374..26a378d 100644 (file)
@@ -48,6 +48,48 @@ class Value
 {
 public:
    virtual void visit(Visitor &visitor) = 0;
+
+   operator signed long long (void) const;
+   operator unsigned long long (void) const;
+   operator double (void) const;
+
+   inline operator signed char (void) const { 
+      return static_cast<signed long long>(*this);
+   }
+
+   inline operator unsigned char (void) const { 
+      return static_cast<signed long long>(*this);
+   }
+
+   inline operator signed short (void) const { 
+      return static_cast<signed long long>(*this);
+   }
+
+   inline operator unsigned short (void) const { 
+      return static_cast<unsigned long long>(*this);
+   }
+
+   inline operator signed (void) const { 
+      return static_cast<signed long long>(*this);
+   }
+
+   inline operator unsigned (void) const { 
+      return static_cast<unsigned long long>(*this);
+   }
+
+   inline operator signed long (void) const { 
+      return static_cast<signed long long>(*this);
+   }
+
+   inline operator unsigned long (void) const { 
+      return static_cast<unsigned long long>(*this);
+   }
+
+   inline operator float (void) const { 
+      return static_cast<double>(*this);
+   }
+
+   const Value & operator[](size_t index) const;
 };