WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 7 of 8] libxl: generate destructors for each libxl defined type
From: Ian Campbell <ian.campbell@xxxxxxxxxx>
Date: Tue, 03 Aug 2010 12:00:22 +0100
Cc: Ian Campbell <ian.campbell@xxxxxxxxxx>
Delivery-date: Tue, 03 Aug 2010 04:10:58 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1280833215@xxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>