[pypy-commit] pypy default: Remove the temporary workaround for GCC 4.8. Properly use "[]", i.e. flexible arrays.

arigo noreply at buildbot.pypy.org
Wed Apr 17 09:20:48 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r63441:c9bde493beba
Date: 2013-04-17 09:23 +0200
http://bitbucket.org/pypy/pypy/changeset/c9bde493beba/

Log:	Remove the temporary workaround for GCC 4.8. Properly use "[]",
	i.e. flexible arrays.

diff --git a/rpython/translator/c/database.py b/rpython/translator/c/database.py
--- a/rpython/translator/c/database.py
+++ b/rpython/translator/c/database.py
@@ -64,9 +64,8 @@
 
         self.instrument_ncounter = 0
 
-    def gettypedefnode(self, T, varlength=1):
-        if varlength <= 1:
-            varlength = 1   # it's C after all
+    def gettypedefnode(self, T, varlength=None):
+        if varlength is None:
             key = T
         else:
             key = T, varlength
@@ -94,7 +93,7 @@
             self.pendingsetupnodes.append(node)
         return node
 
-    def gettype(self, T, varlength=1, who_asks=None, argnames=[]):
+    def gettype(self, T, varlength=None, who_asks=None, argnames=[]):
         if isinstance(T, Primitive) or T == GCREF:
             return PrimitiveType[T]
         elif isinstance(T, Typedef):
diff --git a/rpython/translator/c/node.py b/rpython/translator/c/node.py
--- a/rpython/translator/c/node.py
+++ b/rpython/translator/c/node.py
@@ -47,12 +47,12 @@
     typetag = 'struct'
     extra_union_for_varlength = True
 
-    def __init__(self, db, STRUCT, varlength=1):
+    def __init__(self, db, STRUCT, varlength=None):
         NodeWithDependencies.__init__(self, db)
         self.STRUCT = STRUCT
         self.LLTYPE = STRUCT
         self.varlength = varlength
-        if varlength == 1:
+        if varlength is None:
             basename = STRUCT._name
             with_number = True
         else:
@@ -93,7 +93,7 @@
         self.fields = []
         db = self.db
         STRUCT = self.STRUCT
-        if self.varlength != 1:
+        if self.varlength is not None:
             self.normalizedtypename = db.gettype(STRUCT, who_asks=self)
         if needs_gcheader(self.STRUCT):
             HDR = db.gcpolicy.struct_gcheader_definition(self)
@@ -120,7 +120,7 @@
                 rtti = getRuntimeTypeInfo(STRUCT)
             except ValueError:
                 pass
-        if self.varlength == 1:
+        if self.varlength is None:
             self.db.gcpolicy.struct_setup(self, rtti)
         return self.gcinfo
     gcinfo = defaultproperty(computegcinfo)
@@ -160,12 +160,14 @@
             if typename == PrimitiveType[Void]:
                 line = '/* %s */' % line
             else:
+                if is_empty and typename.endswith('[RPY_VARLENGTH]'):
+                    yield '\tRPY_DUMMY_VARLENGTH'
                 is_empty = False
             yield '\t' + line
         if is_empty:
             yield '\t' + 'char _dummy; /* this struct is empty */'
         yield '};'
-        if self.varlength != 1:
+        if self.varlength is not None:
             assert self.typetag == 'struct'
             yield 'union %su {' % self.name
             yield '  struct %s a;' % self.name
@@ -182,7 +184,7 @@
 
     def debug_offsets(self):
         # generate number exprs giving the offset of the elements in the struct
-        assert self.varlength == 1
+        assert self.varlength is None
         for name in self.fieldnames:
             FIELD_T = self.c_struct_field_type(name)
             if FIELD_T is Void:
@@ -196,18 +198,25 @@
                     yield 'offsetof(%s %s, %s)' % (self.typetag,
                                                    self.name, cname)
 
+def deflength(varlength):
+    if varlength is None:
+        return 'RPY_VARLENGTH'
+    elif varlength == 0:
+        return 'RPY_LENGTH0'
+    else:
+        return varlength
 
 class ArrayDefNode(NodeWithDependencies):
     typetag = 'struct'
     extra_union_for_varlength = True
 
-    def __init__(self, db, ARRAY, varlength=1):
+    def __init__(self, db, ARRAY, varlength=None):
         NodeWithDependencies.__init__(self, db)
         self.ARRAY = ARRAY
         self.LLTYPE = ARRAY
         self.gcfields = []
         self.varlength = varlength
-        if varlength == 1:
+        if varlength is None:
             basename = 'array'
             with_number = True
         else:
@@ -226,7 +235,7 @@
         db = self.db
         ARRAY = self.ARRAY
         self.gcinfo    # force it to be computed
-        if self.varlength != 1:
+        if self.varlength is not None:
             self.normalizedtypename = db.gettype(ARRAY, who_asks=self)
         if needs_gcheader(ARRAY):
             HDR = db.gcpolicy.array_gcheader_definition(self)
@@ -238,7 +247,7 @@
     def computegcinfo(self):
         # let the gcpolicy do its own setup
         self.gcinfo = None   # unless overwritten below
-        if self.varlength == 1:
+        if self.varlength is None:
             self.db.gcpolicy.array_setup(self)
         return self.gcinfo
     gcinfo = defaultproperty(computegcinfo)
@@ -269,21 +278,22 @@
             yield '\t' + cdecl(typename, fname) + ';'
         if not self.ARRAY._hints.get('nolength', False):
             yield '\tlong length;'
-        line = '%s;' % cdecl(self.itemtypename, 'items[%d]'% self.varlength)
+        line = '%s;' % cdecl(self.itemtypename,
+                             'items[%s]' % deflength(self.varlength))
         if self.ARRAY.OF is Void:    # strange
             line = '/* array of void */'
             if self.ARRAY._hints.get('nolength', False):
                 line = 'char _dummy; ' + line
         yield '\t' + line
         yield '};'
-        if self.varlength != 1:
+        if self.varlength is not None:
             yield 'union %su {' % self.name
             yield '  struct %s a;' % self.name
             yield '  %s;' % cdecl(self.normalizedtypename, 'b')
             yield '};'
 
     def visitor_lines(self, prefix, on_item):
-        assert self.varlength == 1
+        assert self.varlength is None
         ARRAY = self.ARRAY
         # we need a unique name for this C variable, or at least one that does
         # not collide with the expression in 'prefix'
@@ -310,7 +320,7 @@
 
     def debug_offsets(self):
         # generate three offsets for debugging inspection
-        assert self.varlength == 1
+        assert self.varlength is None
         if not self.ARRAY._hints.get('nolength', False):
             yield 'offsetof(struct %s, length)' % (self.name,)
         else:
@@ -333,7 +343,7 @@
     forward_decl = None
     extra_union_for_varlength = False
 
-    def __init__(self, db, ARRAY, varlength=1):
+    def __init__(self, db, ARRAY, varlength=None):
         NodeWithDependencies.__init__(self, db)
         self.ARRAY = ARRAY
         self.LLTYPE = ARRAY
@@ -342,8 +352,8 @@
         # There is no such thing as an array of voids:
         # we use a an array of chars instead; only the pointer can be void*.
         self.itemtypename = db.gettype(contained_type, who_asks=self)
-        self.fulltypename = self.itemtypename.replace('@', '(@)[%d]' %
-                                                      (self.varlength,))
+        self.fulltypename = self.itemtypename.replace('@', '(@)[%s]' %
+                                                      deflength(varlength))
         if ARRAY._hints.get("render_as_void"):
             self.fullptrtypename = 'void *@'
         else:
@@ -493,7 +503,8 @@
         Node.__init__(self, db)
         self.obj = obj
         self.typename = db.gettype(T)  #, who_asks=self)
-        self.implementationtypename = db.gettype(T, varlength=self.getlength())
+        self.implementationtypename = db.gettype(
+            T, varlength=self.getvarlength())
         parent, parentindex = parentlink(obj)
         if obj in exports.EXPORTS_obj2name:
             self.name = exports.EXPORTS_obj2name[obj]
@@ -559,8 +570,8 @@
     def startupcode(self):
         return []
 
-    def getlength(self):
-        return 1
+    def getvarlength(self):
+        return None
 
 assert not USESLOTS or '__dict__' not in dir(ContainerNode)
 
@@ -578,10 +589,10 @@
         for name in T._names:
             yield getattr(self.obj, name)
 
-    def getlength(self):
+    def getvarlength(self):
         T = self.getTYPE()
         if T._arrayfld is None:
-            return 1
+            return None
         else:
             array = getattr(self.obj, T._arrayfld)
             return len(array.items)
@@ -696,7 +707,7 @@
     def enum_dependencies(self):
         return self.obj.items
 
-    def getlength(self):
+    def getvarlength(self):
         return len(self.obj.items)
 
     def initializationexpr(self, decoration=''):
@@ -765,8 +776,8 @@
         for i in range(self.obj.getlength()):
             yield self.obj.getitem(i)
 
-    def getlength(self):
-        return 1    # not variable-sized!
+    def getvarlength(self):
+        return None    # not variable-sized!
 
     def initializationexpr(self, decoration=''):
         T = self.getTYPE()
diff --git a/rpython/translator/c/src/g_prerequisite.h b/rpython/translator/c/src/g_prerequisite.h
--- a/rpython/translator/c/src/g_prerequisite.h
+++ b/rpython/translator/c/src/g_prerequisite.h
@@ -14,8 +14,14 @@
 
 #ifdef __GNUC__       /* other platforms too, probably */
 typedef _Bool bool_t;
+# define RPY_VARLENGTH   /* nothing: [RPY_VARLENGTH] => [] */
+# define RPY_LENGTH0     0       /* array decl [0] are ok  */
+# define RPY_DUMMY_VARLENGTH     char _dummy[0];
 #else
 typedef unsigned char bool_t;
+# define RPY_VARLENGTH   1       /* [RPY_VARLENGTH] => [1] */
+# define RPY_LENGTH0     1       /* array decl [0] are bad */
+# define RPY_DUMMY_VARLENGTH     /* nothing */
 #endif
 
 
diff --git a/rpython/translator/c/src/support.h b/rpython/translator/c/src/support.h
--- a/rpython/translator/c/src/support.h
+++ b/rpython/translator/c/src/support.h
@@ -2,16 +2,6 @@
 /************************************************************/
  /***  C header subsection: support functions              ***/
 
-/* a temporary(?) workaround for GCC 4.8.  See:
-    http://stackoverflow.com/questions/16016627/
-*/
-#ifdef __GNUC__
-# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
-#  pragma GCC optimize("no-aggressive-loop-optimizations")
-# endif
-#endif
-
-
 #define RUNNING_ON_LLINTERP	0
 #define OP_JIT_RECORD_KNOWN_CLASS(i, c, r)  /* nothing */
 
diff --git a/rpython/translator/c/test/test_lltyped.py b/rpython/translator/c/test/test_lltyped.py
--- a/rpython/translator/c/test/test_lltyped.py
+++ b/rpython/translator/c/test/test_lltyped.py
@@ -919,3 +919,25 @@
             return x
         fn = self.getcompiled(llf, [int])
         assert fn(5) == 42
+
+    def test_raw_array_field_prebuilt(self):
+        from rpython.rtyper.lltypesystem import rffi
+        S = Struct('S', ('array', rffi.CArray(Signed)))
+        s0 = malloc(S, 0, flavor='raw', immortal=True)
+        s1 = malloc(S, 1, flavor='raw', immortal=True)
+        s1.array[0] = 521
+        s2 = malloc(S, 2, flavor='raw', immortal=True)
+        s2.array[0] = 12
+        s2.array[1] = 34
+        def llf(i):
+            if   i == 0: s = s0
+            elif i == 1: s = s1
+            else:        s = s2
+            x = 10
+            if i > 0:
+                x += s.array[i-1]
+            return x
+        fn = self.getcompiled(llf, [int])
+        assert fn(0) == 10
+        assert fn(1) == 10 + 521
+        assert fn(2) == 10 + 34


More information about the pypy-commit mailing list