[Python-checkins] python/dist/src/Parser asdl_c.py, 1.1.2.7, 1.1.2.8

nnorwitz@users.sourceforge.net nnorwitz at users.sourceforge.net
Sat Oct 15 21:19:24 CEST 2005


Update of /cvsroot/python/python/dist/src/Parser
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29663/Parser

Modified Files:
      Tag: ast-branch
	asdl_c.py 
Log Message:
Implement memory leak fixes in the code generator.
The generated code contains some warnings in the marshal_*() functions
for unused variable (int i).  This needs to be cleaned up some.


Index: asdl_c.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Parser/Attic/asdl_c.py,v
retrieving revision 1.1.2.7
retrieving revision 1.1.2.8
diff -u -d -r1.1.2.7 -r1.1.2.8
--- asdl_c.py	13 Apr 2005 19:59:20 -0000	1.1.2.7
+++ asdl_c.py	15 Oct 2005 19:19:21 -0000	1.1.2.8
@@ -68,17 +68,16 @@
     return lines
 
 def is_simple(sum):
-    """Return true if a sum is a simple.
+    """Return True if a sum is a simple.
 
     A sum is simple if its types have no fields, e.g.
     unaryop = Invert | Not | UAdd | USub
     """
-    simple = True
+
     for t in sum.types:
         if t.fields:
-            simple = False
-            break
-    return simple
+            return False
+    return True
 
 class EmitVisitor(asdl.VisitorBase):
     """Visit that emits lines"""
@@ -348,19 +347,53 @@
 
     visitProduct = visitSum = prototype
 
-def find_sequence(fields):
+_SPECIALIZED_SEQUENCES = ('stmt', 'expr')
+
+def find_sequence(fields, doing_specialization):
     """Return True if any field uses a sequence."""
     for f in fields:
         if f.seq:
-            return True
+            if not doing_specialization:
+                return True
+            if str(f.type) not in _SPECIALIZED_SEQUENCES:
+                return True
     return False
 
-def has_sequence(types):
+def has_sequence(types, doing_specialization):
     for t in types:
-        if find_sequence(t.fields):
+        if find_sequence(t.fields, doing_specialization):
             return True
     return False
 
+
+class StaticVisitor(PickleVisitor):
+    '''Very simple, always emit this static code'''
+
+    CODE = '''static void
+free_seq_exprs(asdl_seq *seq)
+{
+        int i, n;
+        n = asdl_seq_LEN(seq);
+        for (i = 0; i < n; i++)
+                free_expr((expr_ty)asdl_seq_GET(seq, i));
+        asdl_seq_free(seq);
+}
+
+static void
+free_seq_stmts(asdl_seq *seq)
+{
+        int i, n;
+        n = asdl_seq_LEN(seq);
+        for (i = 0; i < n; i++)
+                free_stmt((stmt_ty)asdl_seq_GET(seq, i));
+        asdl_seq_free(seq);
+}
+'''
+
+    def visit(self, object):
+        self.emit(self.CODE, 0, reflow=False)
+
+
 class FreeVisitor(PickleVisitor):
 
     def func_begin(self, name, has_seq):
@@ -371,7 +404,7 @@
         if has_seq:
             self.emit("int i, n;", 1)
             self.emit("asdl_seq *seq;", 1)
-        self.emit('', 0)
+            self.emit('', 0)
         self.emit('if (!o)', 1)
         self.emit('return;', 2)
         self.emit('', 0)
@@ -381,7 +414,7 @@
         self.emit("", 0)
 
     def visitSum(self, sum, name):
-        has_seq = has_sequence(sum.types)
+        has_seq = has_sequence(sum.types, True)
         self.func_begin(name, has_seq)
         if not is_simple(sum):
             self.emit("switch (o->kind) {", 1)
@@ -389,12 +422,16 @@
                 t = sum.types[i]
                 self.visitConstructor(t, i + 1, name)
             self.emit("}", 1)
+            self.emit("", 0)
+            self.emit("free(o);", 1)
         self.func_end()
 
     def visitProduct(self, prod, name):
-        self.func_begin(name, find_sequence(prod.fields))
+        self.func_begin(name, find_sequence(prod.fields, True))
         for field in prod.fields:
             self.visitField(field, name, 1, True)
+        self.emit("", 0)
+        self.emit("free(o);", 1)
         self.func_end()
         
     def visitConstructor(self, cons, enum, name):
@@ -411,10 +448,7 @@
         else:
             value = "o->v.%s.%s" % (name, field.name)
         if field.seq:
-            emit("seq = %s;" % value, 0)
-            emit("n = asdl_seq_LEN(seq);", 0)
-            emit("for (i = 0; i < n; i++)", 0)
-            self.free(field, "asdl_seq_GET(seq, i)", depth + 1)
+            self.emitSeq(field, value, depth, emit)
 
         # XXX need to know the simple types in advance, so that we
         # don't call free_TYPE() for them.
@@ -426,6 +460,18 @@
         else:
             self.free(field, value, depth)
 
+    def emitSeq(self, field, value, depth, emit):
+        # specialize for freeing sequences of statements and expressions
+        if str(field.type) in _SPECIALIZED_SEQUENCES:
+            c_code = "free_seq_%ss(%s);" % (field.type, value)
+            emit(c_code, 0)
+        else:
+            emit("seq = %s;" % value, 0)
+            emit("n = asdl_seq_LEN(seq);", 0)
+            emit("for (i = 0; i < n; i++)", 0)
+            self.free(field, "asdl_seq_GET(seq, i)", depth + 1)
+            emit("asdl_seq_free(seq);", 0)
+
     def free(self, field, value, depth):
         if str(field.type) in ("identifier", "string", "object"):
             ctype = get_c_type(field.type)
@@ -433,7 +479,6 @@
         elif str(field.type) == "bool":
             return
         else:
-            print >> sys.stderr, field.type
             ctype = get_c_type(field.type)
             self.emit("free_%s((%s)%s);" % (field.type, ctype, value), depth)
         
@@ -446,7 +491,8 @@
         self.emit("marshal_write_%s(PyObject **buf, int *off, %s o)" %
                   (name, ctype), 0)
         self.emit("{", 0)
-        if has_seq:
+        # XXX: add declaration of "int i;" properly
+        if has_seq or True:
             self.emit("int i;", 1) # XXX only need it for sequences
 
     def func_end(self):
@@ -455,7 +501,7 @@
         self.emit("", 0)
     
     def visitSum(self, sum, name):
-        has_seq = has_sequence(sum.types)
+        has_seq = has_sequence(sum.types, False)
         self.func_begin(name, has_seq)
         simple = is_simple(sum)
         if simple:
@@ -469,7 +515,7 @@
         self.func_end()
 
     def visitProduct(self, prod, name):
-        self.func_begin(name, find_sequence(prod.fields))
+        self.func_begin(name, find_sequence(prod.fields, True))
         for field in prod.fields:
             self.visitField(field, name, 1, 1)
         self.func_end()
@@ -551,6 +597,7 @@
     print >> f, '#include "%s-ast.h"' % mod.name
     print >> f
     v = ChainOfVisitors(FunctionVisitor(f),
+                        StaticVisitor(f),
                         FreeVisitor(f),
                         MarshalFunctionVisitor(f),
                         )



More information about the Python-checkins mailing list