[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 7 of 8] libxl: generate destructors for each libxl defined type



# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1280829586 -3600
# Node ID 6baa8ce2ec5ed5d140a67b87d2514e88464df34e
# Parent  5d51a404379e3e91c08c07c8292abefa1440a655
libxl: generate destructors for each libxl defined type

I chose the name "_destroy" rather than "_free" because the destructor
functions will free only the members of a type recursively but will
not free the actual type structure itself. The allocation of the type
is typically done by the caller and may not be a single allocation,
e.g. lists/arrays of types or embedded in other strucutures etc.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

diff -r 5d51a404379e -r 6baa8ce2ec5e .hgignore
--- a/.hgignore Tue Aug 03 10:59:46 2010 +0100
+++ b/.hgignore Tue Aug 03 10:59:46 2010 +0100
@@ -182,6 +182,7 @@
 ^tools/libxen/test/test_bindings$
 ^tools/libxen/test/test_event_handling$
 ^tools/libxl/_.*\.h$
+^tools/libxl/_.*\.c$
 ^tools/libxl/libxlu_cfg_y\.output$
 ^tools/libxl/xl$
 ^tools/libaio/src/.*\.ol$
diff -r 5d51a404379e -r 6baa8ce2ec5e tools/libxl/Makefile
--- a/tools/libxl/Makefile      Tue Aug 03 10:59:46 2010 +0100
+++ b/tools/libxl/Makefile      Tue Aug 03 10:59:46 2010 +0100
@@ -19,6 +19,7 @@ LIBS = $(LDFLAGS_libxenctrl) $(LDFLAGS_l
 
 LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o
 LIBXL_OBJS = flexarray.o libxl.o libxl_pci.o libxl_dom.o libxl_exec.o 
libxl_xshelp.o libxl_device.o libxl_internal.o xenguest.o libxl_utils.o 
$(LIBXL_OBJS-y)
+LIBXL_OBJS += _libxl_types.c
 
 AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
 AUTOSRCS= libxlu_cfg_y.c libxlu_cfg_l.c
@@ -54,9 +55,10 @@ libxl_paths.c: _libxl_paths.h
 
 libxl.h: _libxl_types.h
 
-_libxl_types.h: gentypes.py libxltypes.py
-       python gentypes.py __libxl_types.h
+_libxl_types.h _libxl_types.c: gentypes.py libxltypes.py
+       python gentypes.py __libxl_types.h __libxl_types.c
        mv __libxl_types.h _libxl_types.h
+       mv __libxl_types.c _libxl_types.c
 
 libxenlight.so: libxenlight.so.$(MAJOR)
        ln -sf $< $@
@@ -115,6 +117,7 @@ install: all
 .PHONY: clean
 clean:
        $(RM) -f _*.h *.o *.so* *.a $(CLIENTS) $(DEPS)
+       $(RM) -f _*.c
 #      $(RM) -f $(AUTOSRCS) $(AUTOINCS)
 
 distclean: clean
diff -r 5d51a404379e -r 6baa8ce2ec5e tools/libxl/gentypes.py
--- a/tools/libxl/gentypes.py   Tue Aug 03 10:59:46 2010 +0100
+++ b/tools/libxl/gentypes.py   Tue Aug 03 10:59:46 2010 +0100
@@ -58,13 +58,46 @@ def libxl_C_type_define(ty, indent = "")
         raise NotImplementedError("%s" % type(ty))
     return s.replace("\n", "\n%s" % indent)
 
+def libxl_C_type_destroy(ty, v, indent = "    ", parent = ""):
+    s = ""
+    s += "// type: \"%s\"\n" % ty.typename
+    if isinstance(ty, libxltypes.KeyedUnion):
+        s += "// Keyed union with key %s%s\n" % (parent, ty.keyvar_name)
+        for f in ty.fields:
+            keyvar_expr = f.keyvar_expr % (parent + ty.keyvar_name)
+            s += "if (" + keyvar_expr + ") {\n"
+            s += "    // Free %s\n" % (v + f.name)
+            s += libxl_C_type_destroy(f.type, v + f.name + ".", indent + "    
", v)
+            s += "\n"
+            s += "}\n"
+    elif isinstance(ty, libxltypes.Aggregate):
+        for f in [f for f in ty.fields if f.type.has_destructor and not 
f.const]:
+            if f.type.passbyref:
+                makeref = "&"
+                deref = "."
+            else:
+                makeref = ""
+                deref = "->"
+                
+            if isinstance(f.type, libxltypes.Aggregate) and f.type.typename is 
None:
+                s += libxl_C_type_destroy(f.type, v + f.name + ".", "", v)
+                s += "\n"
+            else:
+                s += "%s(%s%s%s);\n" % (f.type.destructor, makeref, v, f.name)
+    else:
+        raise NotImplementedError("%s" % type(ty))
+    s = s.rstrip("\n")
+    if s != "":
+        s = indent + s
+    return s.replace("\n", "\n%s" % indent)
+
 if __name__ == '__main__':
-    if len(sys.argv) < 2:
-        print >>sys.stderr, "Usage: gentypes.py <header>"
+    if len(sys.argv) < 3:
+        print >>sys.stderr, "Usage: gentypes.py <header> <implementation>"
         sys.exit(1)
 
     header = sys.argv[1]
-    print "outputting libxl types to %s" % header
+    print "outputting libxl type definitions to %s" % header
 
     f = open(header, "w")
     
@@ -79,8 +112,45 @@ if __name__ == '__main__':
  
 """ % " ".join(sys.argv))
         
-    for t in libxltypes.Types:
-        f.write(libxl_C_type_define(t) + ";\n")
+    for ty in libxltypes.Types:
+        f.write(libxl_C_type_define(ty) + ";\n")
+        if ty.has_destructor:
+            f.write("void %s(%s *p);\n" % (ty.destructor, ty.typename))
         f.write("\n")
 
     f.write("""#endif /* __LIBXL_TYPES_H */\n""")
+    f.close()
+    
+    impl = sys.argv[2]
+    print "outputting libxl type implementations to %s" % impl
+
+    f = open(impl, "w")
+    f.write("""
+/* DO NOT EDIT.
+ *
+ * This file is autogenerated by
+ * "%s"
+ */
+
+#include "libxl_osdeps.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+ 
+#include "libxl.h"
+
+static void __string_string_free(char **p)
+{
+
+}
+
+""" % " ".join(sys.argv))
+
+    for ty in [ty for ty in libxltypes.Types if ty.generated_destructor]:
+        f.write("void %s(%s *p)\n" % (ty.destructor, ty.typename))
+        f.write("{\n")
+        f.write(libxl_C_type_destroy(ty, "p->"))
+        f.write("\n")
+        f.write("}\n")
+        f.write("\n")
+    f.close()
diff -r 5d51a404379e -r 6baa8ce2ec5e tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py Tue Aug 03 10:59:46 2010 +0100
+++ b/tools/libxl/libxltypes.py Tue Aug 03 10:59:46 2010 +0100
@@ -2,6 +2,11 @@ class Type(object):
     def __init__(self, typename, **kwargs):
         self.comment = None        
         self.namespace = "libxl_"
+
+        self.has_destructor = True
+        self.generated_destructor = True
+
+        self.passbyref = False # passbyvalue
         
         if kwargs.has_key('libxl_type'):
             self.comment = kwargs['comment']
@@ -9,6 +14,21 @@ class Type(object):
         if kwargs.has_key('namespace'):
             self.namespace = kwargs['namespace']
 
+        if kwargs.has_key('has_destructor'):
+            self.has_destructor = kwargs['has_destructor']
+
+        if kwargs.has_key('passbyref'):
+            self.passbyref = kwargs['passbyref']
+
+        if not self.has_destructor:
+            self.generated_destructor = False
+    
+        if kwargs.has_key('generated_destructor'):
+            self.generated_destructor = kwargs['generated_destructor']
+
+        if self.generated_destructor and not self.has_destructor:
+            raise Exception("Cannot generate no destructor!")
+        
         if typename is None: # Anonymous type
             self.typename = None
         elif self.namespace is None: # e.g. system provided types
@@ -16,22 +36,33 @@ class Type(object):
         else:
             self.typename = self.namespace + typename
 
+        if kwargs.has_key('destructor'):
+            self.destructor = kwargs['destructor']
+        elif self.typename is not None and self.has_destructor:
+            self.destructor = self.typename + "_destroy"
+        else:
+            self.destructor = None
+
 class Builtin(Type):
     """Builtin type"""
-    def __init__(self, typename, namespace = "libxl_"):
-        Type.__init__(self, typename, namespace = namespace)
+    def __init__(self, typename, **kwargs):
+        if not kwargs.has_key("has_destructor"):
+            kwargs['has_destructor'] = False
+        if not kwargs.has_key("generate_destructor"):
+            kwargs['generate_destructor'] = False
+
+        Type.__init__(self, typename, **kwargs)
 
 class UInt(Type):
     def __init__(self, w):
        typename = "uint%d_t" % w
-        Type.__init__(self, typename, namespace = None)
+        Type.__init__(self, typename, namespace = None, has_destructor = False)
         self.width = w
 
 class BitField(Type):
     def __init__(self, ty, w):
-        Type.__init__(self, ty.typename, namespace = ty.namespace)
+        Type.__init__(self, ty.typename, namespace = ty.namespace, 
has_destructor = False)
         self.width = w
-
 
 class Field(Type):
     """An element of an Aggregate type"""
@@ -45,11 +76,11 @@ class Field(Type):
 
 class Aggregate(Type):
     """A type containing a collection of other types"""
-    def __init__(self, kind, name, fields, comment = None):
-        Type.__init__(self, name)
+    def __init__(self, kind, name, fields, comment = None, destructor = True):
+        Type.__init__(self, name, has_destructor = destructor, 
generate_destructor = destructor, passbyref = True)
         self.kind = kind
         self.name = name
-       self.comment = comment
+        self.comment = comment
         self.fields = []
         for f in fields:
             # (name, type[, const=False[, comment=None]])
@@ -66,11 +97,11 @@ class Aggregate(Type):
 
 class Struct(Aggregate):
     def __init__(self, name, fields, comment = None):
-        Aggregate.__init__(self, "struct", name, fields, comment)
+        Aggregate.__init__(self, "struct", name, fields, comment, True)
 
 class Union(Aggregate):
     def __init__(self, name, fields, comment = None):
-        Aggregate.__init__(self, "union", name, fields, comment)
+        Aggregate.__init__(self, "union", name, fields, comment, False)
     
 class KeyValueList(Type):
     """A map type"""
@@ -78,12 +109,12 @@ class KeyValueList(Type):
         if ktype != string and vtype != string:
             raise NotImplementedError("Only KeyValueList string -> string is 
supported")
         
-        Type.__init__(self, "char **", namespace = None)
+        Type.__init__(self, "char **", namespace = None, destructor = 
"__string_string_free")
 
 class KeyedUnion(Aggregate):
     """A union which is keyed of another variable"""
     def __init__(self, name, keyvar_name, fields, comment = None):
-        self.keyvar = keyvar_name
+        self.keyvar_name = keyvar_name
         Aggregate.__init__(self, "union", name, [], comment)
         for f in fields:
             # (name, keyvar_expr, type)
@@ -97,7 +128,7 @@ class Reference(Type):
     """A reference to another type"""
     def __init__(self, ty):
         # Ugh
-        Type.__init__(self, ty.name + " *")
+        Type.__init__(self, ty.name + " *", destructor = ty.destructor, 
generated_destructor = False, passbyref = False)
 
 #
 # Standard Types
@@ -119,7 +150,7 @@ uint64 = UInt(64)
 
 domid = UInt(32)
 
-string = Builtin("char *", namespace = None)
+string = Builtin("char *", namespace = None, has_destructor = True, destructor 
= "free")
 string_list = Builtin("char **", namespace = None)
 
 inaddr_ip = Builtin("struct in_addr", namespace = None)
@@ -159,7 +190,9 @@ SHUTDOWN_* constant."""),
     ("vcpu_online", uint32),
     ])
 
-libxl_poolinfo = Struct("poolinfo", [("poolid", uint32)])
+libxl_poolinfo = Struct("poolinfo", [
+    ("poolid", uint32)
+    ])
 
 libxl_vminfo = Struct("vminfo", [
     ("uuid", libxl_uuid),

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.