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

arigo at codespeak.net arigo at codespeak.net
Tue Sep 18 11:58:30 CEST 2007


Author: arigo
Date: Tue Sep 18 11:58:29 2007
New Revision: 46716

Modified:
   pypy/dist/pypy/translator/c/node.py
   pypy/dist/pypy/translator/c/primitive.py
   pypy/dist/pypy/translator/c/src/support.h
   pypy/dist/pypy/translator/c/support.py
   pypy/dist/pypy/translator/c/test/test_lltyped.py
Log:
Fix most gcc type warnings by special-casing arrays with no length
and no gc headers.


Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py	(original)
+++ pypy/dist/pypy/translator/c/node.py	Tue Sep 18 11:58:29 2007
@@ -9,7 +9,7 @@
 from pypy.translator.c.external import CExternalFunctionCodeGenerator
 from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
 from pypy.translator.c.support import cdecl, forward_cdecl, somelettersfrom
-from pypy.translator.c.support import c_char_array_constant
+from pypy.translator.c.support import c_char_array_constant, barebonearray
 from pypy.translator.c.primitive import PrimitiveType, isinf, isnan
 from pypy.translator.c import extfunc
 
@@ -214,15 +214,26 @@
          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'):
+            return      # setup() was already called, likely by __init__
         db = self.db
         ARRAY = self.ARRAY
-        self.itemtypename = db.gettype(ARRAY.OF, who_asks=self)
         self.gcinfo    # force it to be computed
         if needs_gcheader(ARRAY):
             for fname, T in db.gcpolicy.array_gcheader_definition(self):
                 self.gcfields.append((fname, db.gettype(T, who_asks=self)))
+        self.itemtypename = db.gettype(ARRAY.OF, who_asks=self)
 
     def computegcinfo(self):
         # let the gcpolicy do its own setup
@@ -233,7 +244,13 @@
     gcinfo = defaultproperty(computegcinfo)
 
     def gettype(self):
-        return 'struct %s @' % self.name
+        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)
 
     def access_expr(self, baseexpr, index):
         return '%s.items[%d]' % (baseexpr, index)
@@ -243,12 +260,16 @@
         return self.itemindex_access_expr(baseexpr, index)
 
     def itemindex_access_expr(self, baseexpr, indexexpr):
-        if self.ARRAY._hints.get('nolength', False):
+        if self.barebone:
+            return 'RPyBareItem(%s, %s)' % (baseexpr, indexexpr)
+        elif 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:
@@ -292,7 +313,7 @@
             yield 'offsetof(struct %s, length)' % (self.name,)
         else:
             yield '-1'
-        if self.ARRAY.OF is not Void:
+        if self.ARRAY.OF is not Void and not self.barebone:
             yield 'offsetof(struct %s, items[0])' % (self.name,)
             yield 'offsetof(struct %s, items[1])' % (self.name,)
         else:
@@ -504,6 +525,11 @@
     if USESLOTS:
         __slots__ = ()
 
+    def __init__(self, db, T, obj):
+        ContainerNode.__init__(self, db, T, obj)
+        if barebonearray(T):
+            self.ptrname = self.name
+
     def basename(self):
         return 'array'
 
@@ -514,6 +540,7 @@
         return len(self.obj.items)
 
     def initializationexpr(self, decoration=''):
+        defnode = self.db.gettypedefnode(self.T)
         yield '{'
         if needs_gcheader(self.T):
             for i, thing in enumerate(self.db.gcpolicy.array_gcheader_initdata(self)):
@@ -536,7 +563,9 @@
             yield '\t%s%s' % (length, c_char_array_constant(s))
             yield '}'
         else:
-            yield '\t%s{' % length
+            barebone = barebonearray(self.T)
+            if not barebone:
+                yield '\t%s{' % length
             for j in range(len(self.obj.items)):
                 value = self.obj.items[j]
                 lines = generic_initializationexpr(self.db, value,
@@ -544,7 +573,10 @@
                                                 '%s%d' % (decoration, j))
                 for line in lines:
                     yield '\t' + line
-            yield '} }'
+            if not barebone:
+                yield '} }'
+            else:
+                yield '}'
 
 assert not USESLOTS or '__dict__' not in dir(ArrayNode)
 

Modified: pypy/dist/pypy/translator/c/primitive.py
==============================================================================
--- pypy/dist/pypy/translator/c/primitive.py	(original)
+++ pypy/dist/pypy/translator/c/primitive.py	Tue Sep 18 11:58:29 2007
@@ -7,7 +7,7 @@
      AddressOffset, ItemOffset, ArrayItemsOffset, FieldOffset, \
      CompositeOffset, ArrayLengthOffset, \
      GCHeaderOffset
-from pypy.translator.c.support import cdecl
+from pypy.translator.c.support import cdecl, barebonearray
 
 # ____________________________________________________________
 #
@@ -21,13 +21,16 @@
                 cdecl(db.gettype(value.TYPE), ''),
                 structnode.c_struct_field_name(value.fldname))
         elif isinstance(value, ItemOffset):
-            if value.TYPE != Void:
-                return '(sizeof(%s) * %s)'%(
-                    cdecl(db.gettype(value.TYPE), ''), value.repeat)
+            if value.TYPE != Void and value.repeat != 0:
+                size = 'sizeof(%s)' % (cdecl(db.gettype(value.TYPE), ''),)
+                if value.repeat != 1:
+                    size = '(%s * %s)' % (size, value.repeat)
+                return size
             else:
                 return '0'
         elif isinstance(value, ArrayItemsOffset):
-            if isinstance(value.TYPE, FixedSizeArray):
+            if (isinstance(value.TYPE, FixedSizeArray) or
+                barebonearray(value.TYPE)):
                 return '0'
             elif value.TYPE.OF != Void:
                 return 'offsetof(%s, items)'%(

Modified: pypy/dist/pypy/translator/c/src/support.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/support.h	(original)
+++ pypy/dist/pypy/translator/c/src/support.h	Tue Sep 18 11:58:29 2007
@@ -67,7 +67,7 @@
  * it's a "guaranteed" segfault and not one that can be used by
  * attackers.
  */
-#  define RPyCHECK(x)           ((x) || (abort(), 0))
+#  define RPyCHECK(x)           ((x) || RPyAbort())
 #  define RPyField(ptr, name)   ((RPyCHECK(ptr), (ptr))->name)
 #  define RPyItem(array, index)                                             \
      ((RPyCHECK((index) >= 0 && (index) < (array)->length),                 \
@@ -77,11 +77,24 @@
       (ptr))[index])
 #  define RPyNLenItem(array, index)                                         \
      ((RPyCHECK((array) && (index) >= 0), (array))->items[index])
+#  define RPyBareItem(array, index)                                         \
+     ((RPyCHECK((array) && (index) >= 0), (array)[index])
+
+int RPyAbort(void);
+#ifndef PYPY_NOT_MAIN_FILE
+int RPyAbort(void) {
+  fprintf(stderr, "Invalid RPython operation (NULL ptr or bad array index)\n");
+  abort();
+  return 0;
+}
+#endif
+
 #else
 #  define RPyField(ptr, name)                ((ptr)->name)
 #  define RPyItem(array, index)              ((array)->items[index])
 #  define RPyFxItem(ptr, index, fixedsize)   ((ptr)[index])
 #  define RPyNLenItem(array, index)          ((array)->items[index])
+#  define RPyBareItem(array, index)          ((array)[index])
 #endif
 
 #ifndef PYPY_STANDALONE

Modified: pypy/dist/pypy/translator/c/support.py
==============================================================================
--- pypy/dist/pypy/translator/c/support.py	(original)
+++ pypy/dist/pypy/translator/c/support.py	Tue Sep 18 11:58:29 2007
@@ -14,6 +14,11 @@
     def __init__(self, TYPE):
         self.TYPE = TYPE
 
+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'
+
 
 #
 # helpers

Modified: pypy/dist/pypy/translator/c/test/test_lltyped.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_lltyped.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_lltyped.py	Tue Sep 18 11:58:29 2007
@@ -347,11 +347,16 @@
         a1[0] = 30
         a1[1] = 300
         a1[2] = 3000
+        a1dummy = malloc(A, 2, immortal=True)
 
         def f(n):
+            if n & 1:
+                src = a1dummy
+            else:
+                src = a1
             a2 = malloc(A, n, flavor='raw')
             for i in range(n):
-                a2[i] = a1[i % 3] + i
+                a2[i] = src[i % 3] + i
             res = a2[n // 2]
             free(a2, flavor='raw')
             return res
@@ -366,11 +371,16 @@
         a1[0] = 30
         a1[1] = 300
         a1[2] = 3000
+        a1dummy = malloc(A, 2, immortal=True)
 
         def f(n):
+            if n & 1:
+                src = a1dummy
+            else:
+                src = a1
             a2 = malloc(A, n)
             for i in range(n):
-                a2[i] = a1[i % 3] + i
+                a2[i] = src[i % 3] + i
             res = a2[n // 2]
             return res
 



More information about the Pypy-commit mailing list