[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