[pypy-svn] r47087 - pypy/dist/pypy/translator/c

arigo at codespeak.net arigo at codespeak.net
Tue Oct 2 10:57:43 CEST 2007


Author: arigo
Date: Tue Oct  2 10:57:43 2007
New Revision: 47087

Modified:
   pypy/dist/pypy/translator/c/database.py
   pypy/dist/pypy/translator/c/node.py
   pypy/dist/pypy/translator/c/support.py
Log:
Never use 'typedef' in generated C code.  Just don't.  You work like
type macros in that we can always spell out the whole type instead
whenever it's used - and they *don't* work like macros in that some C
compilers don't like typedefs that involve arrays of not-yet-defined
structures so you'd have to carefully order declarations.  Don't bother.

This fixes test_structarray_nolength which failed on gcc 4 (but not gcc 3).


Modified: pypy/dist/pypy/translator/c/database.py
==============================================================================
--- pypy/dist/pypy/translator/c/database.py	(original)
+++ pypy/dist/pypy/translator/c/database.py	Tue Oct  2 10:57:43 2007
@@ -9,10 +9,10 @@
 from pypy.translator.c.primitive import PrimitiveName, PrimitiveType
 from pypy.translator.c.primitive import PrimitiveErrorValue
 from pypy.translator.c.node import StructDefNode, ArrayDefNode
-from pypy.translator.c.node import FixedSizeArrayDefNode
+from pypy.translator.c.node import FixedSizeArrayDefNode, BareBoneArrayDefNode
 from pypy.translator.c.node import ContainerNodeFactory, ExtTypeOpaqueDefNode
 from pypy.translator.c.support import cdecl, CNameManager, ErrorValue
-from pypy.translator.c.support import log
+from pypy.translator.c.support import log, barebonearray
 from pypy.translator.c.extfunc import do_the_getting
 from pypy import conftest
 from pypy.translator.c import gc
@@ -83,7 +83,10 @@
                 else:
                     node = StructDefNode(self, T, varlength)
             elif isinstance(T, Array):
-                node = ArrayDefNode(self, T, varlength)
+                if barebonearray(T):
+                    node = BareBoneArrayDefNode(self, T, varlength)
+                else:
+                    node = ArrayDefNode(self, T, varlength)
             elif isinstance(T, OpaqueType) and hasattr(T, '_exttypeinfo'):
                 node = ExtTypeOpaqueDefNode(self, T)
             elif T == WeakRef:

Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py	(original)
+++ pypy/dist/pypy/translator/c/node.py	Tue Oct  2 10:57:43 2007
@@ -214,15 +214,6 @@
          self.name) = db.namespace.uniquename(basename, with_number=with_number,
                                               bare=True)
         self.dependencies = {}
-        # a non-gc array with no length doesn't need a 'struct' wrapper at
-        # all; rffi kind of expects such arrays to be "bare" C arrays.
-        self.barebone = barebonearray(ARRAY)
-        if self.barebone:
-            self.setup()     # to get self.itemtypename
-            typename = self.itemtypename.replace('@', '(@)[%d]' % (
-                self.varlength,))
-            self.forward_decl = 'typedef %s;' % (cdecl(typename, self.name),)
-            self.typetag = ''
 
     def setup(self):
         if hasattr(self, 'itemtypename'):
@@ -247,32 +238,22 @@
         return '%s %s @' % (self.typetag, self.name)
 
     def getptrtype(self):
-        if self.barebone:
-            return self.itemtypename.replace('@', '*@')
-        else:
-            return '%s %s *@' % (self.typetag, self.name)
+        return '%s %s *@' % (self.typetag, self.name)
 
     def access_expr(self, baseexpr, index):
-        if self.barebone:
-            return '%s[%d]' % (baseexpr, index)
-        else:
-            return '%s.items[%d]' % (baseexpr, index)
+        return '%s.items[%d]' % (baseexpr, index)
 
     def ptr_access_expr(self, baseexpr, index):
         assert 0 <= index <= sys.maxint, "invalid constant index %r" % (index,)
         return self.itemindex_access_expr(baseexpr, index)
 
     def itemindex_access_expr(self, baseexpr, indexexpr):
-        if self.barebone:
-            return 'RPyBareItem(%s, %s)' % (baseexpr, indexexpr)
-        elif self.ARRAY._hints.get('nolength', False):
+        if self.ARRAY._hints.get('nolength', False):
             return 'RPyNLenItem(%s, %s)' % (baseexpr, indexexpr)
         else:
             return 'RPyItem(%s, %s)' % (baseexpr, indexexpr)
 
     def definition(self):
-        if self.barebone:
-            return
         gcpolicy = self.db.gcpolicy
         yield 'struct %s {' % self.name
         for fname, typename in self.gcfields:
@@ -316,7 +297,7 @@
             yield 'offsetof(struct %s, length)' % (self.name,)
         else:
             yield '-1'
-        if self.ARRAY.OF is not Void and not self.barebone:
+        if self.ARRAY.OF is not Void:
             yield 'offsetof(struct %s, items[0])' % (self.name,)
             yield 'offsetof(struct %s, items[1])' % (self.name,)
         else:
@@ -324,6 +305,56 @@
             yield '-1'
 
 
+class BareBoneArrayDefNode:
+    """For 'simple' array types which don't need a length nor GC headers.
+    Implemented directly as a C array instead of a struct with an items field.
+    rffi kind of expects such arrays to be 'bare' C arrays.
+    """
+    gcinfo = None
+    name = None
+    forward_decl = None
+
+    def __init__(self, db, ARRAY, varlength=1):
+        self.db = db
+        self.ARRAY = ARRAY
+        self.LLTYPE = ARRAY
+        self.varlength = varlength
+        self.dependencies = {}
+        self.itemtypename = db.gettype(ARRAY.OF, who_asks=self)
+
+    def setup(self):
+        """Array loops are forbidden by ForwardReference.become() because
+        there is no way to declare them in C."""
+
+    def gettype(self):
+        return self.itemtypename.replace('@', '(@)[%d]' % (self.varlength,))
+
+    def getptrtype(self):
+        return self.itemtypename.replace('@', '*@')
+
+    def access_expr(self, baseexpr, index):
+        return '%s[%d]' % (baseexpr, index)
+
+    def ptr_access_expr(self, baseexpr, index):
+        assert 0 <= index <= sys.maxint, "invalid constant index %r" % (index,)
+        return self.itemindex_access_expr(baseexpr, index)
+
+    def itemindex_access_expr(self, baseexpr, indexexpr):
+        return 'RPyBareItem(%s, %s)' % (baseexpr, indexexpr)
+
+    def definition(self):
+        return []    # no declaration is needed
+
+    def visitor_lines(self, prefix, on_item):
+        raise Exception("cannot visit C arrays - don't know the length")
+
+    def debug_offsets(self):
+        # generate three offsets for debugging inspection,
+        yield '-1'     # no length
+        yield '0'      # first element is immediately at the start of the array
+        yield 'sizeof(%s)' % (cdecl(self.itemtypename, ''),)
+
+
 class FixedSizeArrayDefNode:
     gcinfo = None
     name = None

Modified: pypy/dist/pypy/translator/c/support.py
==============================================================================
--- pypy/dist/pypy/translator/c/support.py	(original)
+++ pypy/dist/pypy/translator/c/support.py	Tue Oct  2 10:57:43 2007
@@ -17,7 +17,8 @@
 def barebonearray(ARRAY):
     """Check if ARRAY is a 'simple' array type,
     i.e. doesn't need a length nor GC headers."""
-    return ARRAY._hints.get('nolength', False) and ARRAY._gckind != 'gc'
+    return (ARRAY._hints.get('nolength', False) and ARRAY._gckind != 'gc'
+            and ARRAY.OF is not lltype.Void)
 
 
 #



More information about the Pypy-commit mailing list