[pypy-svn] pypy default: merge heads
arigo
commits-noreply at bitbucket.org
Fri Apr 15 11:14:11 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r43380:556eef428694
Date: 2011-04-15 11:13 +0200
http://bitbucket.org/pypy/pypy/changeset/556eef428694/
Log: merge heads
diff --git a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
--- a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
@@ -1354,6 +1354,12 @@
log = self.run(main, [], threshold=200)
assert log.result == 9895050.0
loop, = log.loops_by_filename(self.filepath)
+ #
+ # check that the overloaded __getitem__ does not introduce double
+ # array bound checks.
+ #
+ # The force_token()s are still there, but will be eliminated by the
+ # backend regalloc, so they are harmless
assert loop.match("""
...
i20 = int_ge(i18, i8)
@@ -1378,9 +1384,6 @@
f39 = getarrayitem_raw(i13, i36, descr=...)
...
""")
- # XXX: what do we want to check here?
- # We want to make sure that the overloaded __getitem__
- # not introduceds double array bound checks
def test_circular(self):
def main():
@@ -1404,6 +1407,11 @@
log = self.run(main, [], threshold=200)
assert log.result == 1239690.0
loop, = log.loops_by_filename(self.filepath)
+ #
+ # check that the array bound checks are removed
+ #
+ # The force_token()s are still there, but will be eliminated by the
+ # backend regalloc, so they are harmless
assert loop.match("""
...
i17 = int_and(i14, 255)
@@ -1425,7 +1433,50 @@
f37 = getarrayitem_raw(i8, i36, descr=...)
...
""")
+
+ def test_min_max(self):
+ def main():
+ i=0
+ sa=0
+ while i < 300:
+ sa+=min(max(i, 3000), 4000)
+ i+=1
+ return sa
+ log = self.run(main, [], threshold=200)
+ assert log.result == 300*3000
+ loop, = log.loops_by_filename(self.filepath)
+ assert loop.match("""
+ i7 = int_lt(i4, 300)
+ guard_true(i7, descr=...)
+ i9 = int_add_ovf(i5, 3000)
+ guard_no_overflow(descr=...)
+ i11 = int_add(i4, 1)
+ --TICK--
+ jump(p0, p1, p2, p3, i11, i9, descr=<Loop0>)
+ """)
+
+ def test_silly_max(self):
+ def main():
+ i=2
+ sa=0
+ while i < 300:
+ sa+=max(*range(i))
+ i+=1
+ return sa
+ log = self.run(main, [], threshold=200)
+ assert log.result == main()
+ loop, = log.loops_by_filename(self.filepath)
# XXX: what do we want to check here?
- # We want to check that the array bound checks are removed,
- # so it's this part of the trace. However we dont care about
- # the force_token()'s. Can they be ignored?
+
+ def test_iter_max(self):
+ def main():
+ i=2
+ sa=0
+ while i < 300:
+ sa+=max(range(i))
+ i+=1
+ return sa
+ log = self.run(main, [], threshold=200)
+ assert log.result == main()
+ loop, = log.loops_by_filename(self.filepath)
+ # XXX: what do we want to check here?
diff --git a/pypy/translator/c/test/test_database.py b/pypy/translator/c/test/test_database.py
--- a/pypy/translator/c/test/test_database.py
+++ b/pypy/translator/c/test/test_database.py
@@ -5,7 +5,7 @@
from pypy.objspace.flow.model import Constant, Variable, SpaceOperation
from pypy.objspace.flow.model import Block, Link, FunctionGraph
from pypy.rpython.typesystem import getfunctionptr
-from pypy.rpython.lltypesystem.rffi import VOIDP, INT_real, INT
+from pypy.rpython.lltypesystem.rffi import VOIDP, INT_real, INT, CArrayPtr
def dump_on_stdout(database):
@@ -244,3 +244,15 @@
db.get(p)
db.complete()
dump_on_stdout(db)
+
+def test_typedef():
+ A = Typedef(Signed, 'test4')
+ db = LowLevelDatabase()
+ assert db.gettype(A) == "test4 @"
+
+ PA = CArrayPtr(A)
+ assert db.gettype(PA) == "test4 *@"
+
+ F = FuncType((A,), A)
+ assert db.gettype(F) == "test4 (@)(test4)"
+
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -37,7 +37,7 @@
DEBUG_WRAPPER = True
# update these for other platforms
-Py_ssize_t = lltype.Signed
+Py_ssize_t = lltype.Typedef(rffi.SSIZE_T, 'Py_ssize_t')
Py_ssize_tP = rffi.CArrayPtr(Py_ssize_t)
size_t = rffi.ULONG
ADDR = lltype.Signed
@@ -192,14 +192,19 @@
- set `external` to False to get a C function pointer, but not exported by
the API headers.
"""
+ if isinstance(restype, lltype.Typedef):
+ real_restype = restype.OF
+ else:
+ real_restype = restype
+
if error is _NOT_SPECIFIED:
- if isinstance(restype, lltype.Ptr):
- error = lltype.nullptr(restype.TO)
- elif restype is lltype.Void:
+ if isinstance(real_restype, lltype.Ptr):
+ error = lltype.nullptr(real_restype.TO)
+ elif real_restype is lltype.Void:
error = CANNOT_FAIL
if type(error) is int:
- error = rffi.cast(restype, error)
- expect_integer = (isinstance(restype, lltype.Primitive) and
+ error = rffi.cast(real_restype, error)
+ expect_integer = (isinstance(real_restype, lltype.Primitive) and
rffi.cast(restype, 0) == 0)
def decorate(func):
diff --git a/pypy/module/pypyjit/test/test_pypy_c.py b/pypy/module/pypyjit/test/test_pypy_c.py
--- a/pypy/module/pypyjit/test/test_pypy_c.py
+++ b/pypy/module/pypyjit/test/test_pypy_c.py
@@ -223,39 +223,6 @@
return total
''' % startvalue, 170, ([], startvalue + 4999450000L))
- def test_min_max(self):
- self.run_source('''
- def main():
- i=0
- sa=0
- while i < 2000:
- sa+=min(max(i, 3000), 4000)
- i+=1
- return sa
- ''', 51, ([], 2000*3000))
-
- def test_silly_max(self):
- self.run_source('''
- def main():
- i=2
- sa=0
- while i < 2000:
- sa+=max(*range(i))
- i+=1
- return sa
- ''', 125, ([], 1997001))
-
- def test_iter_max(self):
- self.run_source('''
- def main():
- i=2
- sa=0
- while i < 2000:
- sa+=max(range(i))
- i+=1
- return sa
- ''', 88, ([], 1997001))
-
def test__ffi_call(self):
from pypy.rlib.test.test_libffi import get_libm_name
libm_name = get_libm_name(sys.platform)
diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -818,6 +818,8 @@
"""Similar to llmemory.sizeof() but tries hard to return a integer
instead of a symbolic value.
"""
+ if isinstance(tp, lltype.Typedef):
+ tp = tp.OF
if isinstance(tp, lltype.FixedSizeArray):
return sizeof(tp.OF) * tp.length
if isinstance(tp, lltype.Struct):
diff --git a/pypy/module/cpyext/test/test_api.py b/pypy/module/cpyext/test/test_api.py
--- a/pypy/module/cpyext/test/test_api.py
+++ b/pypy/module/cpyext/test/test_api.py
@@ -70,11 +70,35 @@
if self.check_and_print_leaks():
assert False, "Test leaks or loses object(s)."
+ at api.cpython_api([api.Py_ssize_t], api.Py_ssize_t, error=-1)
+def PyPy_TypedefTest1(space, arg):
+ assert lltype.typeOf(arg) == api.Py_ssize_t
+ return 0
+
+ at api.cpython_api([api.Py_ssize_tP], api.Py_ssize_tP)
+def PyPy_TypedefTest2(space, arg):
+ assert lltype.typeOf(arg) == api.Py_ssize_tP
+ return None
+
class TestConversion(BaseApiTest):
def test_conversions(self, space, api):
api.PyPy_GetWrapped(space.w_None)
api.PyPy_GetReference(space.w_None)
+ def test_typedef(self, space):
+ from pypy.translator.c.database import LowLevelDatabase
+ db = LowLevelDatabase()
+ assert (api.c_function_signature(db, api.FUNCTIONS['PyPy_TypedefTest1'])
+ == ('Py_ssize_t', 'Py_ssize_t arg0'))
+ assert (api.c_function_signature(db, api.FUNCTIONS['PyPy_TypedefTest2'])
+ == ('Py_ssize_t *', 'Py_ssize_t *arg0'))
+
+ PyPy_TypedefTest1(space, 0)
+ ppos = lltype.malloc(api.Py_ssize_tP.TO, 1, flavor='raw')
+ ppos[0] = 0
+ PyPy_TypedefTest2(space, ppos)
+ lltype.free(ppos, flavor='raw')
+
def test_copy_header_files(tmpdir):
api.copy_header_files(tmpdir)
diff --git a/pypy/rpython/lltypesystem/ll2ctypes.py b/pypy/rpython/lltypesystem/ll2ctypes.py
--- a/pypy/rpython/lltypesystem/ll2ctypes.py
+++ b/pypy/rpython/lltypesystem/ll2ctypes.py
@@ -255,6 +255,9 @@
return cls
def build_new_ctypes_type(T, delayed_builders):
+ if isinstance(T, lltype.Typedef):
+ T = T.OF
+
if isinstance(T, lltype.Ptr):
if isinstance(T.TO, lltype.FuncType):
argtypes = [get_ctypes_type(ARG) for ARG in T.TO.ARGS
@@ -758,6 +761,8 @@
"""
if T is lltype.Void:
return None
+ if isinstance(T, lltype.Typedef):
+ T = T.OF
if isinstance(T, lltype.Ptr):
if not cobj or not ctypes.cast(cobj, ctypes.c_void_p).value: # NULL pointer
# CFunctionType.__nonzero__ is broken before Python 2.6
diff --git a/pypy/rpython/lltypesystem/module/test/test_ll_math.py b/pypy/rpython/lltypesystem/module/test/test_ll_math.py
--- a/pypy/rpython/lltypesystem/module/test/test_ll_math.py
+++ b/pypy/rpython/lltypesystem/module/test/test_ll_math.py
@@ -3,6 +3,7 @@
from pypy.rpython.lltypesystem.module import ll_math
from pypy.module.math.test.test_direct import MathTests, get_tester
+from pypy.translator.c.test.test_genc import compile
class TestMath(MathTests):
@@ -21,6 +22,13 @@
assert ll_math.ll_math_isnan(nan)
assert not ll_math.ll_math_isnan(inf)
+ def test_compiled_isinf(self):
+ def f(x):
+ return ll_math.ll_math_isinf(1. / x)
+ f = compile(f, [float], backendopt=False)
+ assert f(5.5e-309)
+
+
def make_test_case((fnname, args, expected), dict):
#
def test_func(self):
diff --git a/pypy/rpython/lltypesystem/module/ll_math.py b/pypy/rpython/lltypesystem/module/ll_math.py
--- a/pypy/rpython/lltypesystem/module/ll_math.py
+++ b/pypy/rpython/lltypesystem/module/ll_math.py
@@ -20,8 +20,7 @@
separate_module_files=[cdir.join('src', 'll_math.c')],
export_symbols=['_pypy_math_acosh', '_pypy_math_asinh',
'_pypy_math_atanh',
- '_pypy_math_expm1', '_pypy_math_log1p',
- '_pypy_math_isinf'],
+ '_pypy_math_expm1', '_pypy_math_log1p'],
)
math_prefix = '_pypy_math_'
else:
@@ -95,9 +94,9 @@
# are awesome.
return y != y
- at jit.purefunction
def ll_math_isinf(y):
- return bool(math_isinf(y))
+ # Use a bitwise OR so the JIT doesn't produce 2 different guards.
+ return (y == INFINITY) | (y == -INFINITY)
ll_math_copysign = math_copysign
diff --git a/pypy/rpython/lltypesystem/test/test_ll2ctypes.py b/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
--- a/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
+++ b/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
@@ -1000,6 +1000,13 @@
p = ctypes2lltype(lltype.Ptr(NODE), ctypes.pointer(pc))
assert p.pong.ping == p
+ def test_typedef(self):
+ assert ctypes2lltype(lltype.Typedef(lltype.Signed, 'test'), 6) == 6
+ assert ctypes2lltype(lltype.Typedef(lltype.Float, 'test2'), 3.4) == 3.4
+
+ assert get_ctypes_type(lltype.Signed) == get_ctypes_type(
+ lltype.Typedef(lltype.Signed, 'test3'))
+
def test_cast_adr_to_int(self):
class someaddr(object):
def _cast_to_int(self):
diff --git a/pypy/rpython/lltypesystem/test/test_rffi.py b/pypy/rpython/lltypesystem/test/test_rffi.py
--- a/pypy/rpython/lltypesystem/test/test_rffi.py
+++ b/pypy/rpython/lltypesystem/test/test_rffi.py
@@ -728,6 +728,7 @@
for ll, ctp in cache.items():
assert sizeof(ll) == ctypes.sizeof(ctp)
+ assert sizeof(lltype.Typedef(ll, 'test')) == sizeof(ll)
assert not size_and_sign(lltype.Signed)[1]
assert not size_and_sign(lltype.Char)[1]
assert not size_and_sign(lltype.UniChar)[1]
diff --git a/pypy/translator/c/src/ll_math.h b/pypy/translator/c/src/ll_math.h
--- a/pypy/translator/c/src/ll_math.h
+++ b/pypy/translator/c/src/ll_math.h
@@ -1,8 +1,6 @@
/* Definitions of some C99 math library functions, for those platforms
that don't implement these functions already. */
-int _pypy_math_isinf(double x);
-
double _pypy_math_acosh(double x);
double _pypy_math_asinh(double x);
double _pypy_math_atanh(double x);
diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py
--- a/pypy/annotation/model.py
+++ b/pypy/annotation/model.py
@@ -641,6 +641,8 @@
except TypeError:
s = None # unhashable T, e.g. a Ptr(GcForwardReference())
if s is None:
+ if isinstance(T, lltype.Typedef):
+ return lltype_to_annotation(T.OF)
if isinstance(T, lltype.Number):
return SomeInteger(knowntype=T._type)
if isinstance(T, (ootype.Instance, ootype.BuiltinType)):
diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py
--- a/pypy/rpython/lltypesystem/lltype.py
+++ b/pypy/rpython/lltypesystem/lltype.py
@@ -95,6 +95,8 @@
__slots__ = ['__dict__', '__cached_hash']
def __eq__(self, other):
+ if isinstance(other, Typedef):
+ return other.__eq__(self)
return self.__class__ is other.__class__ and (
self is other or safe_equal(self.__dict__, other.__dict__))
@@ -194,6 +196,36 @@
raise NotImplementedError
+class Typedef(LowLevelType):
+ """A typedef is just another name for an existing type"""
+ def __init__(self, OF, c_name):
+ """
+ @param OF: the equivalent rffi type
+ @param c_name: the name we want in C code
+ """
+ assert isinstance(OF, LowLevelType)
+ # Look through typedefs, so other places don't have to
+ if isinstance(OF, Typedef):
+ OF = OF.OF # haha
+ self.OF = OF
+ self.c_name = c_name
+
+ def __repr__(self):
+ return '<Typedef "%s" of %r>' % (self.c_name, self.OF)
+
+ def __eq__(self, other):
+ return other == self.OF
+
+ def __getattr__(self, name):
+ return self.OF.get(name)
+
+ def _defl(self, parent=None, parentindex=None):
+ return self.OF._defl()
+
+ def _allocate(self, initialization, parent=None, parentindex=None):
+ return self.OF._allocate(initialization, parent, parentindex)
+
+
class Struct(ContainerType):
_gckind = 'raw'
diff --git a/pypy/translator/c/src/ll_math.c b/pypy/translator/c/src/ll_math.c
--- a/pypy/translator/c/src/ll_math.c
+++ b/pypy/translator/c/src/ll_math.c
@@ -22,12 +22,6 @@
#endif
#define PyPy_NAN (HUGE_VAL * 0.)
-int
-_pypy_math_isinf(double x)
-{
- return PyPy_IS_INFINITY(x);
-}
-
/* The following copyright notice applies to the original
implementations of acosh, asinh and atanh. */
diff --git a/pypy/translator/c/database.py b/pypy/translator/c/database.py
--- a/pypy/translator/c/database.py
+++ b/pypy/translator/c/database.py
@@ -1,7 +1,7 @@
-from pypy.rpython.lltypesystem.lltype import \
- Primitive, Ptr, typeOf, RuntimeTypeInfo, \
- Struct, Array, FuncType, PyObject, Void, \
- ContainerType, OpaqueType, FixedSizeArray, _uninitialized
+
+from pypy.rpython.lltypesystem.lltype import (
+ Primitive, Ptr, typeOf, RuntimeTypeInfo, Struct, Array, FuncType, PyObject,
+ Void, ContainerType, OpaqueType, FixedSizeArray, _uninitialized, Typedef)
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rpython.lltypesystem.llmemory import WeakRef, _WeakRefType, GCREF
from pypy.rpython.lltypesystem.rffi import CConstant
@@ -100,6 +100,8 @@
def gettype(self, T, varlength=1, who_asks=None, argnames=[]):
if isinstance(T, Primitive) or T == GCREF:
return PrimitiveType[T]
+ elif isinstance(T, Typedef):
+ return '%s @' % T.c_name
elif isinstance(T, Ptr):
if (isinstance(T.TO, OpaqueType) and
T.TO.hints.get('c_pointer_typedef') is not None):
diff --git a/pypy/rpython/lltypesystem/test/test_lltype.py b/pypy/rpython/lltypesystem/test/test_lltype.py
--- a/pypy/rpython/lltypesystem/test/test_lltype.py
+++ b/pypy/rpython/lltypesystem/test/test_lltype.py
@@ -804,6 +804,21 @@
hints={'immutable_fields': FieldListAccessor({'x':'[*]'})})
assert S._immutable_field('x') == '[*]'
+def test_typedef():
+ T = Typedef(Signed, 'T')
+ assert T == Signed
+ assert Signed == T
+ T2 = Typedef(T, 'T2')
+ assert T2 == T
+ assert T2.OF is Signed
+ py.test.raises(TypeError, Ptr, T)
+ assert rffi.CArrayPtr(T) == rffi.CArrayPtr(Signed)
+ assert rffi.CArrayPtr(Signed) == rffi.CArrayPtr(T)
+
+ F = FuncType((T,), T)
+ assert F.RESULT == Signed
+ assert F.ARGS == (Signed,)
+
class TestTrackAllocation:
def test_automatic_tracking(self):
More information about the Pypy-commit
mailing list