[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