[pypy-svn] r15370 - in pypy/dist/pypy/translator/c: . test

arigo at codespeak.net arigo at codespeak.net
Fri Jul 29 20:24:25 CEST 2005


Author: arigo
Date: Fri Jul 29 20:24:22 2005
New Revision: 15370

Modified:
   pypy/dist/pypy/translator/c/database.py
   pypy/dist/pypy/translator/c/genc.py
   pypy/dist/pypy/translator/c/node.py
   pypy/dist/pypy/translator/c/test/test_database.py
   pypy/dist/pypy/translator/c/test/test_genc.py
Log:
Reordering of the StructDefNode.setup() and ArrayDefNode.setup().
This ensures that the C source code has the definitions in the correct order,
but it's a bit fragile and head-against-wall-banging kind of ordering issues.



Modified: pypy/dist/pypy/translator/c/database.py
==============================================================================
--- pypy/dist/pypy/translator/c/database.py	(original)
+++ pypy/dist/pypy/translator/c/database.py	Fri Jul 29 20:24:22 2005
@@ -16,7 +16,6 @@
     def __init__(self, translator=None):
         self.translator = translator
         self.structdefnodes = {}
-        self.structdeflist = []
         self.containernodes = {}
         self.containerlist = []
         self.externalfuncs = {}
@@ -40,7 +39,6 @@
                 raise Exception("don't know about %r" % (T,))
             self.structdefnodes[key] = node
             node.setup()
-            self.structdeflist.append(node)
         return node
 
     def gettype(self, T, varlength=1, who_asks=None, argnames=[]):
@@ -160,3 +158,17 @@
             return exceptiondata.lltype_of_exception_value
         else:
             return Ptr(PyObject)
+
+    def getstructdeflist(self):
+        # return the StructDefNodes sorted according to dependencies
+        result = []
+        seen = {}
+        def produce(node):
+            if node not in seen:
+                for othernode in node.dependencies:
+                    produce(othernode)
+                result.append(node)
+                seen[node] = True
+        for node in self.structdefnodes.values():
+            produce(node)
+        return result

Modified: pypy/dist/pypy/translator/c/genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/genc.py	(original)
+++ pypy/dist/pypy/translator/c/genc.py	Fri Jul 29 20:24:22 2005
@@ -55,11 +55,12 @@
     #
     # All declarations
     #
+    structdeflist = database.getstructdeflist()
     print >> f
     print >> f, '/***********************************************************/'
     print >> f, '/***  Structure definitions                              ***/'
     print >> f
-    for node in database.structdeflist:
+    for node in structdeflist:
         for line in node.definition(phase=1):
             print >> f, line
     print >> f
@@ -82,7 +83,7 @@
     print >> f, '#include "src/g_include.h"'
     print >> f
     blank = False
-    for node in database.structdeflist:
+    for node in structdeflist:
         for line in node.definition(phase=2):
             print >> f, line
         blank = True
@@ -138,7 +139,7 @@
         print >> f, '/***  Debugging info                                 ***/'
         print >> f
         print >> f, 'static int debuginfo_offsets[] = {'
-        for node in database.structdeflist:
+        for node in database.structdefnodes.values():
             for expr in symboltable.generate_type_info(database, node):
                 print >> f, '\t%s,' % expr
         print >> f, '\t0 };'

Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py	(original)
+++ pypy/dist/pypy/translator/c/node.py	Fri Jul 29 20:24:22 2005
@@ -30,11 +30,6 @@
         self.STRUCT = STRUCT
         self.LLTYPE = STRUCT
         self.varlength = varlength
-
-    def setup(self):
-        db = self.db
-        STRUCT = self.STRUCT
-        varlength = self.varlength
         if varlength == 1:
             basename = STRUCT._name
             with_number = True
@@ -44,15 +39,7 @@
             with_number = False
         self.name = db.namespace.uniquename(basename, with_number=with_number)
         self.dependencies = {}
-        self.fields = []
         self.prefix = somelettersfrom(STRUCT._name) + '_'
-        for name in STRUCT._names:
-            T = self.c_struct_field_type(name)
-            if name == STRUCT._arrayfld:
-                typename = db.gettype(T, varlength=varlength, who_asks=self)
-            else:
-                typename = db.gettype(T, who_asks=self)
-            self.fields.append((self.c_struct_field_name(name), typename))
 
         # look up the reference counter field
         if needs_refcount(STRUCT):
@@ -61,14 +48,29 @@
             # refcount in the first field
             T = self.c_struct_field_type(STRUCT._names[0])
             assert isinstance(T, GC_CONTAINER)
-            firstfieldname, firstfieldtype = self.fields[0]
             firstdefnode = db.gettypedefnode(T)
+            firstfieldname = self.c_struct_field_name(STRUCT._names[0])
             self.refcount = '%s.%s' % (firstfieldname, firstdefnode.refcount)
             # check here that there is enough run-time type information to
             # handle this case
             getRuntimeTypeInfo(STRUCT)
             getRuntimeTypeInfo(T)
 
+    def setup(self):
+        # this computes self.fields
+        self.fields = []
+        db = self.db
+        STRUCT = self.STRUCT
+        varlength = self.varlength
+        for name in STRUCT._names:
+            T = self.c_struct_field_type(name)
+            if name == STRUCT._arrayfld:
+                typename = db.gettype(T, varlength=self.varlength,
+                                         who_asks=self)
+            else:
+                typename = db.gettype(T, who_asks=self)
+            self.fields.append((self.c_struct_field_name(name), typename))
+
         # do we need deallocator(s)?
         if self.refcount and varlength == 1:
             self.deallocator = db.namespace.uniquename('dealloc_'+self.name)
@@ -173,16 +175,11 @@
         self.db = db
         self.ARRAY = ARRAY
         self.LLTYPE = ARRAY
-        self.varlength = varlength
-        self.original_varlength = varlength
+        original_varlength = varlength
         if ARRAY is STR.chars:
-            self.varlength += 1   # for the NULL char at the end of the string
-
-    def setup(self):
-        db = self.db
-        ARRAY = self.ARRAY
-        varlength = self.varlength
-        if self.original_varlength == 1:
+            varlength += 1   # for the NULL char at the end of the string
+        self.varlength = varlength
+        if original_varlength == 1:
             basename = 'array'
             with_number = True
         else:
@@ -191,12 +188,17 @@
             with_number = False
         self.name = db.namespace.uniquename(basename, with_number=with_number)
         self.dependencies = {}
-        self.itemtypename = db.gettype(ARRAY.OF, who_asks=self)
 
         # look up the reference counter field
         if needs_refcount(ARRAY):
             self.refcount = 'refcount'
 
+    def setup(self):
+        db = self.db
+        ARRAY = self.ARRAY
+        varlength = self.varlength
+        self.itemtypename = db.gettype(ARRAY.OF, who_asks=self)
+
         # is a specific deallocator needed?
         if self.refcount and varlength == 1 and list(self.deallocator_lines('')):
             self.deallocator = db.namespace.uniquename('dealloc_'+self.name)

Modified: pypy/dist/pypy/translator/c/test/test_database.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_database.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_database.py	Fri Jul 29 20:24:22 2005
@@ -9,10 +9,11 @@
 
 def dump_on_stdout(database):
     print '/*********************************/'
-    for node in database.structdeflist:
+    structdeflist = database.getstructdeflist()
+    for node in structdeflist:
         for line in node.definition(phase=1):
             print line
-    for node in database.structdeflist:
+    for node in structdeflist:
         for line in node.definition(phase=2):
             print line
     print

Modified: pypy/dist/pypy/translator/c/test/test_genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_genc.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_genc.py	Fri Jul 29 20:24:22 2005
@@ -182,3 +182,20 @@
     f1 = compile(fn, [int])
     res = f1(1)
     assert res == 'e'
+
+
+def test_recursive_struct():
+    # B has an A as its super field, and A has a pointer to B.
+    class A:
+        pass
+    class B(A):
+        pass
+    def fn(i):
+        a = A()
+        b = B()
+        a.b = b
+        b.i = i
+        return a.b.i
+    f1 = compile(fn, [int])
+    res = f1(42)
+    assert res == 42



More information about the Pypy-commit mailing list