[pypy-commit] pypy release-1.7.x: merge in default
fijal
noreply at buildbot.pypy.org
Fri Nov 18 10:52:43 CET 2011
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: release-1.7.x
Changeset: r49519:7773f8fc4223
Date: 2011-11-18 11:52 +0200
http://bitbucket.org/pypy/pypy/changeset/7773f8fc4223/
Log: merge in default
diff --git a/lib-python/2.7/test/test_os.py b/lib-python/2.7/test/test_os.py
--- a/lib-python/2.7/test/test_os.py
+++ b/lib-python/2.7/test/test_os.py
@@ -74,7 +74,8 @@
self.assertFalse(os.path.exists(name),
"file already exists for temporary file")
# make sure we can create the file
- open(name, "w")
+ f = open(name, "w")
+ f.close()
self.files.append(name)
def test_tempnam(self):
diff --git a/lib-python/2.7/pkgutil.py b/lib-python/modified-2.7/pkgutil.py
copy from lib-python/2.7/pkgutil.py
copy to lib-python/modified-2.7/pkgutil.py
--- a/lib-python/2.7/pkgutil.py
+++ b/lib-python/modified-2.7/pkgutil.py
@@ -244,7 +244,8 @@
return mod
def get_data(self, pathname):
- return open(pathname, "rb").read()
+ with open(pathname, "rb") as f:
+ return f.read()
def _reopen(self):
if self.file and self.file.closed:
diff --git a/lib-python/modified-2.7/test/test_import.py b/lib-python/modified-2.7/test/test_import.py
--- a/lib-python/modified-2.7/test/test_import.py
+++ b/lib-python/modified-2.7/test/test_import.py
@@ -64,6 +64,7 @@
except ImportError, err:
self.fail("import from %s failed: %s" % (ext, err))
else:
+ # XXX importing .pyw is missing on Windows
self.assertEqual(mod.a, a,
"module loaded (%s) but contents invalid" % mod)
self.assertEqual(mod.b, b,
diff --git a/lib-python/modified-2.7/test/test_repr.py b/lib-python/modified-2.7/test/test_repr.py
--- a/lib-python/modified-2.7/test/test_repr.py
+++ b/lib-python/modified-2.7/test/test_repr.py
@@ -254,8 +254,14 @@
eq = self.assertEqual
touch(os.path.join(self.subpkgname, self.pkgname + os.extsep + 'py'))
from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
- eq(repr(areallylongpackageandmodulenametotestreprtruncation),
- "<module '%s' from '%s'>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
+ # On PyPy, we use %r to format the file name; on CPython it is done
+ # with '%s'. It seems to me that %r is safer <arigo>.
+ if '__pypy__' in sys.builtin_module_names:
+ eq(repr(areallylongpackageandmodulenametotestreprtruncation),
+ "<module %r from %r>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
+ else:
+ eq(repr(areallylongpackageandmodulenametotestreprtruncation),
+ "<module '%s' from '%s'>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
eq(repr(sys), "<module 'sys' (built-in)>")
def test_type(self):
diff --git a/lib-python/2.7/test/test_subprocess.py b/lib-python/modified-2.7/test/test_subprocess.py
copy from lib-python/2.7/test/test_subprocess.py
copy to lib-python/modified-2.7/test/test_subprocess.py
--- a/lib-python/2.7/test/test_subprocess.py
+++ b/lib-python/modified-2.7/test/test_subprocess.py
@@ -16,11 +16,11 @@
# Depends on the following external programs: Python
#
-if mswindows:
- SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
- 'os.O_BINARY);')
-else:
- SETBINARY = ''
+#if mswindows:
+# SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
+# 'os.O_BINARY);')
+#else:
+# SETBINARY = ''
try:
@@ -420,8 +420,9 @@
self.assertStderrEqual(stderr, "")
def test_universal_newlines(self):
- p = subprocess.Popen([sys.executable, "-c",
- 'import sys,os;' + SETBINARY +
+ # NB. replaced SETBINARY with the -u flag
+ p = subprocess.Popen([sys.executable, "-u", "-c",
+ 'import sys,os;' + #SETBINARY +
'sys.stdout.write("line1\\n");'
'sys.stdout.flush();'
'sys.stdout.write("line2\\r");'
@@ -448,8 +449,9 @@
def test_universal_newlines_communicate(self):
# universal newlines through communicate()
- p = subprocess.Popen([sys.executable, "-c",
- 'import sys,os;' + SETBINARY +
+ # NB. replaced SETBINARY with the -u flag
+ p = subprocess.Popen([sys.executable, "-u", "-c",
+ 'import sys,os;' + #SETBINARY +
'sys.stdout.write("line1\\n");'
'sys.stdout.flush();'
'sys.stdout.write("line2\\r");'
diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py
--- a/lib_pypy/pyrepl/unix_console.py
+++ b/lib_pypy/pyrepl/unix_console.py
@@ -412,7 +412,12 @@
e.args[4] == 'unexpected end of data':
pass
else:
- raise
+ # was: "raise". But it crashes pyrepl, and by extension the
+ # pypy currently running, in which we are e.g. in the middle
+ # of some debugging session. Argh. Instead just print an
+ # error message to stderr and continue running, for now.
+ self.partial_char = ''
+ sys.stderr.write('\n%s: %s\n' % (e.__class__.__name__, e))
else:
self.partial_char = ''
self.event_queue.push(c)
diff --git a/lib_pypy/syslog.py b/lib_pypy/syslog.py
--- a/lib_pypy/syslog.py
+++ b/lib_pypy/syslog.py
@@ -38,9 +38,27 @@
_setlogmask.argtypes = (c_int,)
_setlogmask.restype = c_int
+_S_log_open = False
+_S_ident_o = None
+
+def _get_argv():
+ try:
+ import sys
+ script = sys.argv[0]
+ if isinstance(script, str):
+ return script[script.rfind('/')+1:] or None
+ except Exception:
+ pass
+ return None
+
@builtinify
-def openlog(ident, option, facility):
- _openlog(ident, option, facility)
+def openlog(ident=None, logoption=0, facility=LOG_USER):
+ global _S_ident_o, _S_log_open
+ if ident is None:
+ ident = _get_argv()
+ _S_ident_o = c_char_p(ident) # keepalive
+ _openlog(_S_ident_o, logoption, facility)
+ _S_log_open = True
@builtinify
def syslog(arg1, arg2=None):
@@ -48,11 +66,18 @@
priority, message = arg1, arg2
else:
priority, message = LOG_INFO, arg1
+ # if log is not opened, open it now
+ if not _S_log_open:
+ openlog()
_syslog(priority, "%s", message)
@builtinify
def closelog():
- _closelog()
+ global _S_log_open, S_ident_o
+ if _S_log_open:
+ _closelog()
+ _S_log_open = False
+ _S_ident_o = None
@builtinify
def setlogmask(mask):
diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py
--- a/pypy/interpreter/test/test_executioncontext.py
+++ b/pypy/interpreter/test/test_executioncontext.py
@@ -292,7 +292,7 @@
import os, sys
print sys.executable, self.tmpfile
if sys.platform == "win32":
- cmdformat = '""%s" "%s""' # excellent! tons of "!
+ cmdformat = '"%s" "%s"'
else:
cmdformat = "'%s' '%s'"
g = os.popen(cmdformat % (sys.executable, self.tmpfile), 'r')
diff --git a/pypy/interpreter/test/test_typedef.py b/pypy/interpreter/test/test_typedef.py
--- a/pypy/interpreter/test/test_typedef.py
+++ b/pypy/interpreter/test/test_typedef.py
@@ -2,7 +2,7 @@
from pypy.interpreter import typedef
from pypy.tool.udir import udir
from pypy.interpreter.baseobjspace import Wrappable
-from pypy.interpreter.gateway import ObjSpace
+from pypy.interpreter.gateway import ObjSpace, interp2app
# this test isn't so much to test that the objspace interface *works*
# -- it's more to test that it's *there*
@@ -260,6 +260,50 @@
gc.collect(); gc.collect()
assert space.unwrap(w_seen) == [6, 2]
+ def test_multiple_inheritance(self):
+ class W_A(Wrappable):
+ a = 1
+ b = 2
+ class W_C(W_A):
+ b = 3
+ W_A.typedef = typedef.TypeDef("A",
+ a = typedef.interp_attrproperty("a", cls=W_A),
+ b = typedef.interp_attrproperty("b", cls=W_A),
+ )
+ class W_B(Wrappable):
+ pass
+ def standalone_method(space, w_obj):
+ if isinstance(w_obj, W_A):
+ return space.w_True
+ else:
+ return space.w_False
+ W_B.typedef = typedef.TypeDef("B",
+ c = interp2app(standalone_method)
+ )
+ W_C.typedef = typedef.TypeDef("C", (W_A.typedef, W_B.typedef,))
+
+ w_o1 = self.space.wrap(W_C())
+ w_o2 = self.space.wrap(W_B())
+ w_c = self.space.gettypefor(W_C)
+ w_b = self.space.gettypefor(W_B)
+ w_a = self.space.gettypefor(W_A)
+ assert w_c.mro_w == [
+ w_c,
+ w_a,
+ w_b,
+ self.space.w_object,
+ ]
+ for w_tp in w_c.mro_w:
+ assert self.space.isinstance_w(w_o1, w_tp)
+ def assert_attr(w_obj, name, value):
+ assert self.space.unwrap(self.space.getattr(w_obj, self.space.wrap(name))) == value
+ def assert_method(w_obj, name, value):
+ assert self.space.unwrap(self.space.call_method(w_obj, name)) == value
+ assert_attr(w_o1, "a", 1)
+ assert_attr(w_o1, "b", 3)
+ assert_method(w_o1, "c", True)
+ assert_method(w_o2, "c", False)
+
class AppTestTypeDef:
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -15,13 +15,19 @@
def __init__(self, __name, __base=None, **rawdict):
"NOT_RPYTHON: initialization-time only"
self.name = __name
- self.base = __base
+ if __base is None:
+ bases = []
+ elif isinstance(__base, tuple):
+ bases = list(__base)
+ else:
+ bases = [__base]
+ self.bases = bases
self.hasdict = '__dict__' in rawdict
self.weakrefable = '__weakref__' in rawdict
self.doc = rawdict.pop('__doc__', None)
- if __base is not None:
- self.hasdict |= __base.hasdict
- self.weakrefable |= __base.weakrefable
+ for base in bases:
+ self.hasdict |= base.hasdict
+ self.weakrefable |= base.weakrefable
self.rawdict = {}
self.acceptable_as_base_class = '__new__' in rawdict
self.applevel_subclasses_base = None
diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -20,6 +20,7 @@
from pypy.jit.backend.llgraph import symbolic
from pypy.jit.codewriter import longlong
+from pypy.rlib import libffi
from pypy.rlib.objectmodel import ComputedIntSymbolic, we_are_translated
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint
@@ -325,12 +326,12 @@
loop = _from_opaque(loop)
loop.operations.append(Operation(opnum))
-def compile_add_descr(loop, ofs, type, arg_types):
+def compile_add_descr(loop, ofs, type, arg_types, extrainfo, width):
from pypy.jit.backend.llgraph.runner import Descr
loop = _from_opaque(loop)
op = loop.operations[-1]
assert isinstance(type, str) and len(type) == 1
- op.descr = Descr(ofs, type, arg_types=arg_types)
+ op.descr = Descr(ofs, type, arg_types=arg_types, extrainfo=extrainfo, width=width)
def compile_add_descr_arg(loop, ofs, type, arg_types):
from pypy.jit.backend.llgraph.runner import Descr
@@ -825,6 +826,16 @@
else:
raise NotImplementedError
+ def op_getinteriorfield_raw(self, descr, array, index):
+ if descr.typeinfo == REF:
+ return do_getinteriorfield_raw_ptr(array, index, descr.width, descr.ofs)
+ elif descr.typeinfo == INT:
+ return do_getinteriorfield_raw_int(array, index, descr.width, descr.ofs)
+ elif descr.typeinfo == FLOAT:
+ return do_getinteriorfield_raw_float(array, index, descr.width, descr.ofs)
+ else:
+ raise NotImplementedError
+
def op_setinteriorfield_gc(self, descr, array, index, newvalue):
if descr.typeinfo == REF:
return do_setinteriorfield_gc_ptr(array, index, descr.ofs,
@@ -838,6 +849,16 @@
else:
raise NotImplementedError
+ def op_setinteriorfield_raw(self, descr, array, index, newvalue):
+ if descr.typeinfo == REF:
+ return do_setinteriorfield_raw_ptr(array, index, newvalue, descr.width, descr.ofs)
+ elif descr.typeinfo == INT:
+ return do_setinteriorfield_raw_int(array, index, newvalue, descr.width, descr.ofs)
+ elif descr.typeinfo == FLOAT:
+ return do_setinteriorfield_raw_float(array, index, newvalue, descr.width, descr.ofs)
+ else:
+ raise NotImplementedError
+
def op_setfield_gc(self, fielddescr, struct, newvalue):
if fielddescr.typeinfo == REF:
do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue)
@@ -1403,6 +1424,14 @@
struct = array._obj.container.getitem(index)
return cast_to_ptr(_getinteriorfield_gc(struct, fieldnum))
+def _getinteriorfield_raw(ffitype, array, index, width, ofs):
+ addr = rffi.cast(rffi.VOIDP, array)
+ return libffi.array_getitem(ffitype, width, addr, index, ofs)
+
+def do_getinteriorfield_raw_int(array, index, width, ofs):
+ res = _getinteriorfield_raw(libffi.types.slong, array, index, width, ofs)
+ return res
+
def _getfield_raw(struct, fieldnum):
STRUCT, fieldname = symbolic.TokenToField[fieldnum]
ptr = cast_from_int(lltype.Ptr(STRUCT), struct)
@@ -1479,7 +1508,14 @@
return do_setinteriorfield_gc
do_setinteriorfield_gc_int = new_setinteriorfield_gc(cast_from_int)
do_setinteriorfield_gc_float = new_setinteriorfield_gc(cast_from_floatstorage)
-do_setinteriorfield_gc_ptr = new_setinteriorfield_gc(cast_from_ptr)
+do_setinteriorfield_gc_ptr = new_setinteriorfield_gc(cast_from_ptr)
+
+def new_setinteriorfield_raw(ffitype):
+ def do_setinteriorfield_raw(array, index, newvalue, width, ofs):
+ addr = rffi.cast(rffi.VOIDP, array)
+ return libffi.array_setitem(ffitype, width, addr, index, ofs, newvalue)
+ return do_setinteriorfield_raw
+do_setinteriorfield_raw_int = new_setinteriorfield_raw(libffi.types.slong)
def do_setfield_raw_int(struct, fieldnum, newvalue):
STRUCT, fieldname = symbolic.TokenToField[fieldnum]
diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -23,8 +23,10 @@
class Descr(history.AbstractDescr):
def __init__(self, ofs, typeinfo, extrainfo=None, name=None,
- arg_types=None, count_fields_if_immut=-1, ffi_flags=0):
+ arg_types=None, count_fields_if_immut=-1, ffi_flags=0, width=-1):
+
self.ofs = ofs
+ self.width = width
self.typeinfo = typeinfo
self.extrainfo = extrainfo
self.name = name
@@ -119,14 +121,14 @@
return False
def getdescr(self, ofs, typeinfo='?', extrainfo=None, name=None,
- arg_types=None, count_fields_if_immut=-1, ffi_flags=0):
+ arg_types=None, count_fields_if_immut=-1, ffi_flags=0, width=-1):
key = (ofs, typeinfo, extrainfo, name, arg_types,
- count_fields_if_immut, ffi_flags)
+ count_fields_if_immut, ffi_flags, width)
try:
return self._descrs[key]
except KeyError:
descr = Descr(ofs, typeinfo, extrainfo, name, arg_types,
- count_fields_if_immut, ffi_flags)
+ count_fields_if_immut, ffi_flags, width)
self._descrs[key] = descr
return descr
@@ -179,7 +181,8 @@
descr = op.getdescr()
if isinstance(descr, Descr):
llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo,
- descr.arg_types)
+ descr.arg_types, descr.extrainfo,
+ descr.width)
if (isinstance(descr, history.LoopToken) and
op.getopnum() != rop.JUMP):
llimpl.compile_add_loop_token(c, descr)
@@ -324,10 +327,22 @@
def interiorfielddescrof(self, A, fieldname):
S = A.OF
- ofs2 = symbolic.get_size(A)
+ width = symbolic.get_size(A)
ofs, size = symbolic.get_field_token(S, fieldname)
token = history.getkind(getattr(S, fieldname))
- return self.getdescr(ofs, token[0], name=fieldname, extrainfo=ofs2)
+ return self.getdescr(ofs, token[0], name=fieldname, width=width)
+
+ def interiorfielddescrof_dynamic(self, offset, width, fieldsize,
+ is_pointer, is_float, is_signed):
+
+ if is_pointer:
+ typeinfo = REF
+ elif is_float:
+ typeinfo = FLOAT
+ else:
+ typeinfo = INT
+ # we abuse the arg_types field to distinguish dynamic and static descrs
+ return Descr(offset, typeinfo, arg_types='dynamic', name='<dynamic interior field>', width=width)
def calldescrof(self, FUNC, ARGS, RESULT, extrainfo):
arg_types = []
diff --git a/pypy/jit/backend/llsupport/descr.py b/pypy/jit/backend/llsupport/descr.py
--- a/pypy/jit/backend/llsupport/descr.py
+++ b/pypy/jit/backend/llsupport/descr.py
@@ -111,6 +111,16 @@
def repr_of_descr(self):
return '<%s %s %s>' % (self._clsname, self.name, self.offset)
+class DynamicFieldDescr(BaseFieldDescr):
+ def __init__(self, offset, fieldsize, is_pointer, is_float, is_signed):
+ self.offset = offset
+ self._fieldsize = fieldsize
+ self._is_pointer_field = is_pointer
+ self._is_float_field = is_float
+ self._is_field_signed = is_signed
+
+ def get_field_size(self, translate_support_code):
+ return self._fieldsize
class NonGcPtrFieldDescr(BaseFieldDescr):
_clsname = 'NonGcPtrFieldDescr'
@@ -182,6 +192,7 @@
def repr_of_descr(self):
return '<%s>' % self._clsname
+
class NonGcPtrArrayDescr(BaseArrayDescr):
_clsname = 'NonGcPtrArrayDescr'
def get_item_size(self, translate_support_code):
@@ -211,6 +222,13 @@
def get_ofs_length(self, translate_support_code):
return -1
+class DynamicArrayNoLengthDescr(BaseArrayNoLengthDescr):
+ def __init__(self, itemsize):
+ self.itemsize = itemsize
+
+ def get_item_size(self, translate_support_code):
+ return self.itemsize
+
class NonGcPtrArrayNoLengthDescr(BaseArrayNoLengthDescr):
_clsname = 'NonGcPtrArrayNoLengthDescr'
def get_item_size(self, translate_support_code):
@@ -305,12 +323,16 @@
_clsname = ''
loop_token = None
arg_classes = '' # <-- annotation hack
- ffi_flags = 0
+ ffi_flags = 1
- def __init__(self, arg_classes, extrainfo=None, ffi_flags=0):
+ def __init__(self, arg_classes, extrainfo=None, ffi_flags=1):
self.arg_classes = arg_classes # string of "r" and "i" (ref/int)
self.extrainfo = extrainfo
self.ffi_flags = ffi_flags
+ # NB. the default ffi_flags is 1, meaning FUNCFLAG_CDECL, which
+ # makes sense on Windows as it's the one for all the C functions
+ # we are compiling together with the JIT. On non-Windows platforms
+ # it is just ignored anyway.
def __repr__(self):
res = '%s(%s)' % (self.__class__.__name__, self.arg_classes)
@@ -351,6 +373,10 @@
return False # unless overridden
def create_call_stub(self, rtyper, RESULT):
+ from pypy.rlib.clibffi import FFI_DEFAULT_ABI
+ assert self.get_call_conv() == FFI_DEFAULT_ABI, (
+ "%r: create_call_stub() with a non-default call ABI" % (self,))
+
def process(c):
if c == 'L':
assert longlong.supports_longlong
@@ -445,7 +471,7 @@
"""
_clsname = 'DynamicIntCallDescr'
- def __init__(self, arg_classes, result_size, result_sign, extrainfo=None, ffi_flags=0):
+ def __init__(self, arg_classes, result_size, result_sign, extrainfo, ffi_flags):
BaseIntCallDescr.__init__(self, arg_classes, extrainfo, ffi_flags)
assert isinstance(result_sign, bool)
self._result_size = chr(result_size)
diff --git a/pypy/jit/backend/llsupport/ffisupport.py b/pypy/jit/backend/llsupport/ffisupport.py
--- a/pypy/jit/backend/llsupport/ffisupport.py
+++ b/pypy/jit/backend/llsupport/ffisupport.py
@@ -8,7 +8,7 @@
class UnsupportedKind(Exception):
pass
-def get_call_descr_dynamic(cpu, ffi_args, ffi_result, extrainfo=None, ffi_flags=0):
+def get_call_descr_dynamic(cpu, ffi_args, ffi_result, extrainfo, ffi_flags):
"""Get a call descr: the types of result and args are represented by
rlib.libffi.types.*"""
try:
diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -9,9 +9,10 @@
from pypy.jit.backend.llsupport import symbolic
from pypy.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes
from pypy.jit.backend.llsupport.descr import (get_size_descr,
- get_field_descr, BaseFieldDescr, get_array_descr, BaseArrayDescr,
- get_call_descr, BaseIntCallDescr, GcPtrCallDescr, FloatCallDescr,
- VoidCallDescr, InteriorFieldDescr, get_interiorfield_descr)
+ get_field_descr, BaseFieldDescr, DynamicFieldDescr, get_array_descr,
+ BaseArrayDescr, DynamicArrayNoLengthDescr, get_call_descr,
+ BaseIntCallDescr, GcPtrCallDescr, FloatCallDescr, VoidCallDescr,
+ InteriorFieldDescr, get_interiorfield_descr)
from pypy.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
@@ -238,6 +239,12 @@
def interiorfielddescrof(self, A, fieldname):
return get_interiorfield_descr(self.gc_ll_descr, A, A.OF, fieldname)
+ def interiorfielddescrof_dynamic(self, offset, width, fieldsize,
+ is_pointer, is_float, is_signed):
+ arraydescr = DynamicArrayNoLengthDescr(width)
+ fielddescr = DynamicFieldDescr(offset, fieldsize, is_pointer, is_float, is_signed)
+ return InteriorFieldDescr(arraydescr, fielddescr)
+
def unpack_arraydescr(self, arraydescr):
assert isinstance(arraydescr, BaseArrayDescr)
return arraydescr.get_base_size(self.translate_support_code)
diff --git a/pypy/jit/backend/llsupport/test/test_ffisupport.py b/pypy/jit/backend/llsupport/test/test_ffisupport.py
--- a/pypy/jit/backend/llsupport/test/test_ffisupport.py
+++ b/pypy/jit/backend/llsupport/test/test_ffisupport.py
@@ -13,44 +13,46 @@
def test_call_descr_dynamic():
args = [types.sint, types.pointer]
- descr = get_call_descr_dynamic(FakeCPU(), args, types.sint, ffi_flags=42)
+ descr = get_call_descr_dynamic(FakeCPU(), args, types.sint, None,
+ ffi_flags=42)
assert isinstance(descr, DynamicIntCallDescr)
assert descr.arg_classes == 'ii'
assert descr.get_ffi_flags() == 42
args = [types.sint, types.double, types.pointer]
- descr = get_call_descr_dynamic(FakeCPU(), args, types.void)
+ descr = get_call_descr_dynamic(FakeCPU(), args, types.void, None, 42)
assert descr is None # missing floats
descr = get_call_descr_dynamic(FakeCPU(supports_floats=True),
- args, types.void, ffi_flags=43)
+ args, types.void, None, ffi_flags=43)
assert isinstance(descr, VoidCallDescr)
assert descr.arg_classes == 'ifi'
assert descr.get_ffi_flags() == 43
- descr = get_call_descr_dynamic(FakeCPU(), [], types.sint8)
+ descr = get_call_descr_dynamic(FakeCPU(), [], types.sint8, None, 42)
assert isinstance(descr, DynamicIntCallDescr)
assert descr.get_result_size(False) == 1
assert descr.is_result_signed() == True
- descr = get_call_descr_dynamic(FakeCPU(), [], types.uint8)
+ descr = get_call_descr_dynamic(FakeCPU(), [], types.uint8, None, 42)
assert isinstance(descr, DynamicIntCallDescr)
assert descr.get_result_size(False) == 1
assert descr.is_result_signed() == False
if not is_64_bit:
- descr = get_call_descr_dynamic(FakeCPU(), [], types.slonglong)
+ descr = get_call_descr_dynamic(FakeCPU(), [], types.slonglong,
+ None, 42)
assert descr is None # missing longlongs
descr = get_call_descr_dynamic(FakeCPU(supports_longlong=True),
- [], types.slonglong, ffi_flags=43)
+ [], types.slonglong, None, ffi_flags=43)
assert isinstance(descr, LongLongCallDescr)
assert descr.get_ffi_flags() == 43
else:
assert types.slonglong is types.slong
- descr = get_call_descr_dynamic(FakeCPU(), [], types.float)
+ descr = get_call_descr_dynamic(FakeCPU(), [], types.float, None, 42)
assert descr is None # missing singlefloats
descr = get_call_descr_dynamic(FakeCPU(supports_singlefloats=True),
- [], types.float, ffi_flags=44)
+ [], types.float, None, ffi_flags=44)
SingleFloatCallDescr = getCallDescrClass(rffi.FLOAT)
assert isinstance(descr, SingleFloatCallDescr)
assert descr.get_ffi_flags() == 44
diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py
--- a/pypy/jit/backend/model.py
+++ b/pypy/jit/backend/model.py
@@ -183,38 +183,35 @@
lst[n] = None
self.fail_descr_free_list.extend(faildescr_indices)
- @staticmethod
- def sizeof(S):
+ def sizeof(self, S):
raise NotImplementedError
- @staticmethod
- def fielddescrof(S, fieldname):
+ def fielddescrof(self, S, fieldname):
"""Return the Descr corresponding to field 'fieldname' on the
structure 'S'. It is important that this function (at least)
caches the results."""
raise NotImplementedError
- @staticmethod
- def arraydescrof(A):
+ def interiorfielddescrof(self, A, fieldname):
raise NotImplementedError
- @staticmethod
- def calldescrof(FUNC, ARGS, RESULT):
+ def interiorfielddescrof_dynamic(self, offset, width, fieldsize, is_pointer,
+ is_float, is_signed):
+ raise NotImplementedError
+
+ def arraydescrof(self, A):
+ raise NotImplementedError
+
+ def calldescrof(self, FUNC, ARGS, RESULT):
# FUNC is the original function type, but ARGS is a list of types
# with Voids removed
raise NotImplementedError
- @staticmethod
- def methdescrof(SELFTYPE, methname):
+ def methdescrof(self, SELFTYPE, methname):
# must return a subclass of history.AbstractMethDescr
raise NotImplementedError
- @staticmethod
- def typedescrof(TYPE):
- raise NotImplementedError
-
- @staticmethod
- def interiorfielddescrof(A, fieldname):
+ def typedescrof(self, TYPE):
raise NotImplementedError
# ---------- the backend-dependent operations ----------
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -8,8 +8,8 @@
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.annlowlevel import llhelper
from pypy.jit.backend.model import CompiledLoopToken
-from pypy.jit.backend.x86.regalloc import (RegAlloc, get_ebp_ofs,
- _get_scale, gpr_reg_mgr_cls)
+from pypy.jit.backend.x86.regalloc import (RegAlloc, get_ebp_ofs, _get_scale,
+ gpr_reg_mgr_cls, _valid_addressing_size)
from pypy.jit.backend.x86.arch import (FRAME_FIXED_SIZE, FORCE_INDEX_OFS, WORD,
IS_X86_32, IS_X86_64)
@@ -1601,8 +1601,10 @@
assert isinstance(itemsize_loc, ImmedLoc)
if isinstance(index_loc, ImmedLoc):
temp_loc = imm(index_loc.value * itemsize_loc.value)
+ elif _valid_addressing_size(itemsize_loc.value):
+ return AddressLoc(base_loc, index_loc, _get_scale(itemsize_loc.value), ofs_loc.value)
else:
- # XXX should not use IMUL in most cases
+ # XXX should not use IMUL in more cases, it can use a clever LEA
assert isinstance(temp_loc, RegLoc)
assert isinstance(index_loc, RegLoc)
assert not temp_loc.is_xmm
@@ -1619,6 +1621,8 @@
ofs_loc)
self.load_from_mem(resloc, src_addr, fieldsize_loc, sign_loc)
+ genop_getinteriorfield_raw = genop_getinteriorfield_gc
+
def genop_discard_setfield_gc(self, op, arglocs):
base_loc, ofs_loc, size_loc, value_loc = arglocs
@@ -1634,6 +1638,8 @@
ofs_loc)
self.save_into_mem(dest_addr, value_loc, fieldsize_loc)
+ genop_discard_setinteriorfield_raw = genop_discard_setinteriorfield_gc
+
def genop_discard_setarrayitem_gc(self, op, arglocs):
base_loc, ofs_loc, value_loc, size_loc, baseofs = arglocs
assert isinstance(baseofs, ImmedLoc)
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -1067,6 +1067,8 @@
self.PerformDiscard(op, [base_loc, ofs, itemsize, fieldsize,
index_loc, temp_loc, value_loc])
+ consider_setinteriorfield_raw = consider_setinteriorfield_gc
+
def consider_strsetitem(self, op):
args = op.getarglist()
base_loc = self.rm.make_sure_var_in_reg(op.getarg(0), args)
@@ -1158,6 +1160,8 @@
self.Perform(op, [base_loc, ofs, itemsize, fieldsize,
index_loc, temp_loc, sign_loc], result_loc)
+ consider_getinteriorfield_raw = consider_getinteriorfield_gc
+
def consider_int_is_true(self, op, guard_op):
# doesn't need arg to be in a register
argloc = self.loc(op.getarg(0))
@@ -1430,8 +1434,11 @@
# i.e. the n'th word beyond the fixed frame size.
return -WORD * (FRAME_FIXED_SIZE + position)
+def _valid_addressing_size(size):
+ return size == 1 or size == 2 or size == 4 or size == 8
+
def _get_scale(size):
- assert size == 1 or size == 2 or size == 4 or size == 8
+ assert _valid_addressing_size(size)
if size < 4:
return size - 1 # 1, 2 => 0, 1
else:
diff --git a/pypy/jit/backend/x86/test/test_fficall.py b/pypy/jit/backend/x86/test/test_fficall.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/x86/test/test_fficall.py
@@ -0,0 +1,8 @@
+import py
+from pypy.jit.metainterp.test import test_fficall
+from pypy.jit.backend.x86.test.test_basic import Jit386Mixin
+
+class TestFfiLookups(Jit386Mixin, test_fficall.FfiLookupTests):
+ # for the individual tests see
+ # ====> ../../../metainterp/test/test_fficall.py
+ supports_all = True
diff --git a/pypy/jit/backend/x86/test/test_runner.py b/pypy/jit/backend/x86/test/test_runner.py
--- a/pypy/jit/backend/x86/test/test_runner.py
+++ b/pypy/jit/backend/x86/test/test_runner.py
@@ -455,6 +455,9 @@
EffectInfo.MOST_GENERAL,
ffi_flags=-1)
calldescr.get_call_conv = lambda: ffi # <==== hack
+ # ^^^ we patch get_call_conv() so that the test also makes sense
+ # on Linux, because clibffi.get_call_conv() would always
+ # return FFI_DEFAULT_ABI on non-Windows platforms.
funcbox = ConstInt(rawstart)
i1 = BoxInt()
i2 = BoxInt()
diff --git a/pypy/jit/codewriter/call.py b/pypy/jit/codewriter/call.py
--- a/pypy/jit/codewriter/call.py
+++ b/pypy/jit/codewriter/call.py
@@ -212,7 +212,10 @@
elidable = False
loopinvariant = False
if op.opname == "direct_call":
- func = getattr(get_funcobj(op.args[0].value), '_callable', None)
+ funcobj = get_funcobj(op.args[0].value)
+ assert getattr(funcobj, 'calling_conv', 'c') == 'c', (
+ "%r: getcalldescr() with a non-default call ABI" % (op,))
+ func = getattr(funcobj, '_callable', None)
elidable = getattr(func, "_elidable_function_", False)
loopinvariant = getattr(func, "_jit_loop_invariant_", False)
if loopinvariant:
diff --git a/pypy/jit/codewriter/effectinfo.py b/pypy/jit/codewriter/effectinfo.py
--- a/pypy/jit/codewriter/effectinfo.py
+++ b/pypy/jit/codewriter/effectinfo.py
@@ -48,6 +48,8 @@
OS_LIBFFI_PREPARE = 60
OS_LIBFFI_PUSH_ARG = 61
OS_LIBFFI_CALL = 62
+ OS_LIBFFI_GETARRAYITEM = 63
+ OS_LIBFFI_SETARRAYITEM = 64
#
OS_LLONG_INVERT = 69
OS_LLONG_ADD = 70
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -1615,6 +1615,12 @@
elif oopspec_name.startswith('libffi_call_'):
oopspecindex = EffectInfo.OS_LIBFFI_CALL
extraeffect = EffectInfo.EF_RANDOM_EFFECTS
+ elif oopspec_name == 'libffi_array_getitem':
+ oopspecindex = EffectInfo.OS_LIBFFI_GETARRAYITEM
+ extraeffect = EffectInfo.EF_CANNOT_RAISE
+ elif oopspec_name == 'libffi_array_setitem':
+ oopspecindex = EffectInfo.OS_LIBFFI_SETARRAYITEM
+ extraeffect = EffectInfo.EF_CANNOT_RAISE
else:
assert False, 'unsupported oopspec: %s' % oopspec_name
return self._handle_oopspec_call(op, args, oopspecindex, extraeffect)
diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py
--- a/pypy/jit/metainterp/executor.py
+++ b/pypy/jit/metainterp/executor.py
@@ -340,6 +340,8 @@
rop.DEBUG_MERGE_POINT,
rop.JIT_DEBUG,
rop.SETARRAYITEM_RAW,
+ rop.GETINTERIORFIELD_RAW,
+ rop.SETINTERIORFIELD_RAW,
rop.CALL_RELEASE_GIL,
rop.QUASIIMMUT_FIELD,
): # list of opcodes never executed by pyjitpl
diff --git a/pypy/jit/metainterp/optimizeopt/fficall.py b/pypy/jit/metainterp/optimizeopt/fficall.py
--- a/pypy/jit/metainterp/optimizeopt/fficall.py
+++ b/pypy/jit/metainterp/optimizeopt/fficall.py
@@ -1,11 +1,13 @@
+from pypy.jit.codewriter.effectinfo import EffectInfo
+from pypy.jit.metainterp.optimizeopt.optimizer import Optimization
+from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method
+from pypy.jit.metainterp.resoperation import rop, ResOperation
+from pypy.rlib import clibffi, libffi
+from pypy.rlib.debug import debug_print
+from pypy.rlib.libffi import Func
+from pypy.rlib.objectmodel import we_are_translated
from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
-from pypy.rlib.objectmodel import we_are_translated
-from pypy.rlib.libffi import Func
-from pypy.rlib.debug import debug_print
-from pypy.jit.codewriter.effectinfo import EffectInfo
-from pypy.jit.metainterp.resoperation import rop, ResOperation
-from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method
-from pypy.jit.metainterp.optimizeopt.optimizer import Optimization
+from pypy.rpython.lltypesystem import llmemory
class FuncInfo(object):
@@ -78,7 +80,7 @@
def new(self):
return OptFfiCall()
-
+
def begin_optimization(self, funcval, op):
self.rollback_maybe('begin_optimization', op)
self.funcinfo = FuncInfo(funcval, self.optimizer.cpu, op)
@@ -116,6 +118,9 @@
ops = self.do_push_arg(op)
elif oopspec == EffectInfo.OS_LIBFFI_CALL:
ops = self.do_call(op)
+ elif (oopspec == EffectInfo.OS_LIBFFI_GETARRAYITEM or
+ oopspec == EffectInfo.OS_LIBFFI_SETARRAYITEM):
+ ops = self.do_getsetarrayitem(op, oopspec)
#
for op in ops:
self.emit_operation(op)
@@ -190,6 +195,53 @@
ops.append(newop)
return ops
+ def do_getsetarrayitem(self, op, oopspec):
+ ffitypeval = self.getvalue(op.getarg(1))
+ widthval = self.getvalue(op.getarg(2))
+ offsetval = self.getvalue(op.getarg(5))
+ if not ffitypeval.is_constant() or not widthval.is_constant() or not offsetval.is_constant():
+ return [op]
+
+ ffitypeaddr = ffitypeval.box.getaddr()
+ ffitype = llmemory.cast_adr_to_ptr(ffitypeaddr, clibffi.FFI_TYPE_P)
+ offset = offsetval.box.getint()
+ width = widthval.box.getint()
+ descr = self._get_interior_descr(ffitype, width, offset)
+
+ arglist = [
+ self.getvalue(op.getarg(3)).force_box(self.optimizer),
+ self.getvalue(op.getarg(4)).force_box(self.optimizer),
+ ]
+ if oopspec == EffectInfo.OS_LIBFFI_GETARRAYITEM:
+ opnum = rop.GETINTERIORFIELD_RAW
+ elif oopspec == EffectInfo.OS_LIBFFI_SETARRAYITEM:
+ opnum = rop.SETINTERIORFIELD_RAW
+ arglist.append(self.getvalue(op.getarg(6)).force_box(self.optimizer))
+ else:
+ assert False
+ return [
+ ResOperation(opnum, arglist, op.result, descr=descr),
+ ]
+
+ def _get_interior_descr(self, ffitype, width, offset):
+ kind = libffi.types.getkind(ffitype)
+ is_pointer = is_float = is_signed = False
+ if ffitype is libffi.types.pointer:
+ is_pointer = True
+ elif kind == 'i':
+ is_signed = True
+ elif kind == 'f' or kind == 'I' or kind == 'U':
+ # longlongs are treated as floats, see
+ # e.g. llsupport/descr.py:getDescrClass
+ is_float = True
+ else:
+ assert False, "unsupported ffitype or kind"
+ #
+ fieldsize = ffitype.c_size
+ return self.optimizer.cpu.interiorfielddescrof_dynamic(
+ offset, width, fieldsize, is_pointer, is_float, is_signed
+ )
+
def propagate_forward(self, op):
if self.logops is not None:
debug_print(self.logops.repr_of_resop(op))
diff --git a/pypy/jit/metainterp/optimizeopt/intutils.py b/pypy/jit/metainterp/optimizeopt/intutils.py
--- a/pypy/jit/metainterp/optimizeopt/intutils.py
+++ b/pypy/jit/metainterp/optimizeopt/intutils.py
@@ -1,4 +1,4 @@
-from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift, LONG_BIT
+from pypy.rlib.rarithmetic import ovfcheck, LONG_BIT
from pypy.rlib.objectmodel import we_are_translated
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.metainterp.history import BoxInt, ConstInt
@@ -174,10 +174,10 @@
other.known_ge(IntBound(0, 0)) and \
other.known_lt(IntBound(LONG_BIT, LONG_BIT)):
try:
- vals = (ovfcheck_lshift(self.upper, other.upper),
- ovfcheck_lshift(self.upper, other.lower),
- ovfcheck_lshift(self.lower, other.upper),
- ovfcheck_lshift(self.lower, other.lower))
+ vals = (ovfcheck(self.upper << other.upper),
+ ovfcheck(self.upper << other.lower),
+ ovfcheck(self.lower << other.upper),
+ ovfcheck(self.lower << other.lower))
return IntBound(min4(vals), max4(vals))
except (OverflowError, ValueError):
return IntUnbounded()
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -4999,6 +4999,34 @@
"""
self.optimize_loop(ops, expected)
+ def test_known_equal_ints(self):
+ py.test.skip("in-progress")
+ ops = """
+ [i0, i1, i2, p0]
+ i3 = int_eq(i0, i1)
+ guard_true(i3) []
+
+ i4 = int_lt(i2, i0)
+ guard_true(i4) []
+ i5 = int_lt(i2, i1)
+ guard_true(i5) []
+
+ i6 = getarrayitem_gc(p0, i2)
+ finish(i6)
+ """
+ expected = """
+ [i0, i1, i2, p0]
+ i3 = int_eq(i0, i1)
+ guard_true(i3) []
+
+ i4 = int_lt(i2, i0)
+ guard_true(i4) []
+
+ i6 = getarrayitem_gc(p0, i3)
+ finish(i6)
+ """
+ self.optimize_loop(ops, expected)
+
class TestLLtype(BaseTestOptimizeBasic, LLtypeMixin):
pass
diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -461,6 +461,7 @@
'GETARRAYITEM_GC/2d',
'GETARRAYITEM_RAW/2d',
'GETINTERIORFIELD_GC/2d',
+ 'GETINTERIORFIELD_RAW/2d',
'GETFIELD_GC/1d',
'GETFIELD_RAW/1d',
'_MALLOC_FIRST',
@@ -479,6 +480,7 @@
'SETARRAYITEM_GC/3d',
'SETARRAYITEM_RAW/3d',
'SETINTERIORFIELD_GC/3d',
+ 'SETINTERIORFIELD_RAW/3d',
'SETFIELD_GC/2d',
'SETFIELD_RAW/2d',
'STRSETITEM/3',
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -14,7 +14,7 @@
from pypy.rlib.jit import (JitDriver, we_are_jitted, hint, dont_look_inside,
loop_invariant, elidable, promote, jit_debug, assert_green,
AssertGreenFailed, unroll_safe, current_trace_length, look_inside_iff,
- isconstant, isvirtual, promote_string)
+ isconstant, isvirtual, promote_string, set_param)
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
from pypy.rpython.ootypesystem import ootype
@@ -1256,15 +1256,18 @@
n -= 1
x += n
return x
- def f(n, threshold):
- myjitdriver.set_param('threshold', threshold)
+ def f(n, threshold, arg):
+ if arg:
+ set_param(myjitdriver, 'threshold', threshold)
+ else:
+ set_param(None, 'threshold', threshold)
return g(n)
- res = self.meta_interp(f, [10, 3])
+ res = self.meta_interp(f, [10, 3, 1])
assert res == 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0
self.check_tree_loop_count(2)
- res = self.meta_interp(f, [10, 13])
+ res = self.meta_interp(f, [10, 13, 0])
assert res == 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0
self.check_tree_loop_count(0)
@@ -2328,8 +2331,8 @@
get_printable_location=get_printable_location)
bytecode = "0j10jc20a3"
def f():
- myjitdriver.set_param('threshold', 7)
- myjitdriver.set_param('trace_eagerness', 1)
+ set_param(myjitdriver, 'threshold', 7)
+ set_param(myjitdriver, 'trace_eagerness', 1)
i = j = c = a = 1
while True:
myjitdriver.jit_merge_point(i=i, j=j, c=c, a=a)
@@ -2607,7 +2610,7 @@
myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a'])
def f(n, limit):
- myjitdriver.set_param('retrace_limit', limit)
+ set_param(myjitdriver, 'retrace_limit', limit)
sa = i = a = 0
while i < n:
myjitdriver.jit_merge_point(n=n, i=i, sa=sa, a=a)
@@ -2625,8 +2628,8 @@
myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a'])
def f(n, limit):
- myjitdriver.set_param('retrace_limit', 3)
- myjitdriver.set_param('max_retrace_guards', limit)
+ set_param(myjitdriver, 'retrace_limit', 3)
+ set_param(myjitdriver, 'max_retrace_guards', limit)
sa = i = a = 0
while i < n:
myjitdriver.jit_merge_point(n=n, i=i, sa=sa, a=a)
@@ -2645,7 +2648,7 @@
myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a',
'node'])
def f(n, limit):
- myjitdriver.set_param('retrace_limit', limit)
+ set_param(myjitdriver, 'retrace_limit', limit)
sa = i = a = 0
node = [1, 2, 3]
node[1] = n
@@ -2668,10 +2671,10 @@
myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'i', 'sa'])
bytecode = "0+sI0+SI"
def f(n):
- myjitdriver.set_param('threshold', 3)
- myjitdriver.set_param('trace_eagerness', 1)
- myjitdriver.set_param('retrace_limit', 5)
- myjitdriver.set_param('function_threshold', -1)
+ set_param(None, 'threshold', 3)
+ set_param(None, 'trace_eagerness', 1)
+ set_param(None, 'retrace_limit', 5)
+ set_param(None, 'function_threshold', -1)
pc = sa = i = 0
while pc < len(bytecode):
myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i)
@@ -2728,9 +2731,9 @@
myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'a', 'i', 'j', 'sa'])
bytecode = "ij+Jj+JI"
def f(n, a):
- myjitdriver.set_param('threshold', 5)
- myjitdriver.set_param('trace_eagerness', 1)
- myjitdriver.set_param('retrace_limit', 2)
+ set_param(None, 'threshold', 5)
+ set_param(None, 'trace_eagerness', 1)
+ set_param(None, 'retrace_limit', 2)
pc = sa = i = j = 0
while pc < len(bytecode):
myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j, a=a)
@@ -2793,8 +2796,8 @@
return B(self.val + 1)
myjitdriver = JitDriver(greens = [], reds = ['sa', 'a'])
def f():
- myjitdriver.set_param('threshold', 3)
- myjitdriver.set_param('trace_eagerness', 2)
+ set_param(None, 'threshold', 3)
+ set_param(None, 'trace_eagerness', 2)
a = A(0)
sa = 0
while a.val < 8:
@@ -2824,8 +2827,8 @@
return B(self.val + 1)
myjitdriver = JitDriver(greens = [], reds = ['sa', 'b', 'a'])
def f(b):
- myjitdriver.set_param('threshold', 6)
- myjitdriver.set_param('trace_eagerness', 4)
+ set_param(None, 'threshold', 6)
+ set_param(None, 'trace_eagerness', 4)
a = A(0)
sa = 0
while a.val < 15:
@@ -2862,10 +2865,10 @@
myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'i', 'sa'])
bytecode = "0+sI0+SI"
def f(n):
- myjitdriver.set_param('threshold', 3)
- myjitdriver.set_param('trace_eagerness', 1)
- myjitdriver.set_param('retrace_limit', 5)
- myjitdriver.set_param('function_threshold', -1)
+ set_param(None, 'threshold', 3)
+ set_param(None, 'trace_eagerness', 1)
+ set_param(None, 'retrace_limit', 5)
+ set_param(None, 'function_threshold', -1)
pc = sa = i = 0
while pc < len(bytecode):
myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i)
diff --git a/pypy/jit/metainterp/test/test_fficall.py b/pypy/jit/metainterp/test/test_fficall.py
--- a/pypy/jit/metainterp/test/test_fficall.py
+++ b/pypy/jit/metainterp/test/test_fficall.py
@@ -1,19 +1,18 @@
+import py
-import py
+from pypy.jit.metainterp.test.support import LLJitMixin
+from pypy.rlib.jit import JitDriver, promote, dont_look_inside
+from pypy.rlib.libffi import (ArgChain, IS_32_BIT, array_getitem, array_setitem,
+ types)
+from pypy.rlib.objectmodel import specialize
from pypy.rlib.rarithmetic import r_singlefloat, r_longlong, r_ulonglong
-from pypy.rlib.jit import JitDriver, promote, dont_look_inside
+from pypy.rlib.test.test_libffi import TestLibffiCall as _TestLibffiCall
from pypy.rlib.unroll import unrolling_iterable
-from pypy.rlib.libffi import ArgChain
-from pypy.rlib.libffi import IS_32_BIT
-from pypy.rlib.test.test_libffi import TestLibffiCall as _TestLibffiCall
from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.rlib.objectmodel import specialize
from pypy.tool.sourcetools import func_with_new_name
-from pypy.jit.metainterp.test.support import LLJitMixin
-class TestFfiCall(LLJitMixin, _TestLibffiCall):
- supports_all = False # supports_{floats,longlong,singlefloats}
+class FfiCallTests(_TestLibffiCall):
# ===> ../../../rlib/test/test_libffi.py
def call(self, funcspec, args, RESULT, is_struct=False, jitif=[]):
@@ -92,6 +91,69 @@
test_byval_result.__doc__ = _TestLibffiCall.test_byval_result.__doc__
test_byval_result.dont_track_allocations = True
+class FfiLookupTests(object):
+ def test_array_fields(self):
+ myjitdriver = JitDriver(
+ greens = [],
+ reds = ["n", "i", "points", "result_point"],
+ )
-class TestFfiCallSupportAll(TestFfiCall):
+ POINT = lltype.Struct("POINT",
+ ("x", lltype.Signed),
+ ("y", lltype.Signed),
+ )
+ def f(points, result_point, n):
+ i = 0
+ while i < n:
+ myjitdriver.jit_merge_point(i=i, points=points, n=n,
+ result_point=result_point)
+ x = array_getitem(
+ types.slong, rffi.sizeof(lltype.Signed) * 2, points, i, 0
+ )
+ y = array_getitem(
+ types.slong, rffi.sizeof(lltype.Signed) * 2, points, i, rffi.sizeof(lltype.Signed)
+ )
+
+ cur_x = array_getitem(
+ types.slong, rffi.sizeof(lltype.Signed) * 2, result_point, 0, 0
+ )
+ cur_y = array_getitem(
+ types.slong, rffi.sizeof(lltype.Signed) * 2, result_point, 0, rffi.sizeof(lltype.Signed)
+ )
+
+ array_setitem(
+ types.slong, rffi.sizeof(lltype.Signed) * 2, result_point, 0, 0, cur_x + x
+ )
+ array_setitem(
+ types.slong, rffi.sizeof(lltype.Signed) * 2, result_point, 0, rffi.sizeof(lltype.Signed), cur_y + y
+ )
+ i += 1
+
+ def main(n):
+ with lltype.scoped_alloc(rffi.CArray(POINT), n) as points:
+ with lltype.scoped_alloc(rffi.CArray(POINT), 1) as result_point:
+ for i in xrange(n):
+ points[i].x = i * 2
+ points[i].y = i * 2 + 1
+ points = rffi.cast(rffi.CArrayPtr(lltype.Char), points)
+ result_point[0].x = 0
+ result_point[0].y = 0
+ result_point = rffi.cast(rffi.CArrayPtr(lltype.Char), result_point)
+ f(points, result_point, n)
+ result_point = rffi.cast(rffi.CArrayPtr(POINT), result_point)
+ return result_point[0].x * result_point[0].y
+
+ assert self.meta_interp(main, [10]) == main(10) == 9000
+ self.check_loops({"int_add": 3, "jump": 1, "int_lt": 1, "guard_true": 1,
+ "getinteriorfield_raw": 4, "setinteriorfield_raw": 2
+ })
+
+
+class TestFfiCall(FfiCallTests, LLJitMixin):
+ supports_all = False
+
+class TestFfiCallSupportAll(FfiCallTests, LLJitMixin):
supports_all = True # supports_{floats,longlong,singlefloats}
+
+class TestFfiLookup(FfiLookupTests, LLJitMixin):
+ pass
\ No newline at end of file
diff --git a/pypy/jit/metainterp/test/test_jitdriver.py b/pypy/jit/metainterp/test/test_jitdriver.py
--- a/pypy/jit/metainterp/test/test_jitdriver.py
+++ b/pypy/jit/metainterp/test/test_jitdriver.py
@@ -1,5 +1,5 @@
"""Tests for multiple JitDrivers."""
-from pypy.rlib.jit import JitDriver, unroll_safe
+from pypy.rlib.jit import JitDriver, unroll_safe, set_param
from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.jit.metainterp.warmspot import get_stats
@@ -113,7 +113,7 @@
return n
#
def loop2(g, r):
- myjitdriver1.set_param('function_threshold', 0)
+ set_param(None, 'function_threshold', 0)
while r > 0:
myjitdriver2.can_enter_jit(g=g, r=r)
myjitdriver2.jit_merge_point(g=g, r=r)
diff --git a/pypy/jit/metainterp/test/test_loop.py b/pypy/jit/metainterp/test/test_loop.py
--- a/pypy/jit/metainterp/test/test_loop.py
+++ b/pypy/jit/metainterp/test/test_loop.py
@@ -1,5 +1,5 @@
import py
-from pypy.rlib.jit import JitDriver, hint
+from pypy.rlib.jit import JitDriver, hint, set_param
from pypy.rlib.objectmodel import compute_hash
from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats
from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
@@ -364,7 +364,7 @@
myjitdriver = JitDriver(greens = ['pos'], reds = ['i', 'j', 'n', 'x'])
bytecode = "IzJxji"
def f(n, threshold):
- myjitdriver.set_param('threshold', threshold)
+ set_param(myjitdriver, 'threshold', threshold)
i = j = x = 0
pos = 0
op = '-'
@@ -411,7 +411,7 @@
myjitdriver = JitDriver(greens = ['pos'], reds = ['i', 'j', 'n', 'x'])
bytecode = "IzJxji"
def f(nval, threshold):
- myjitdriver.set_param('threshold', threshold)
+ set_param(myjitdriver, 'threshold', threshold)
i, j, x = A(0), A(0), A(0)
n = A(nval)
pos = 0
diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py
--- a/pypy/jit/metainterp/test/test_recursive.py
+++ b/pypy/jit/metainterp/test/test_recursive.py
@@ -1,5 +1,5 @@
import py
-from pypy.rlib.jit import JitDriver, we_are_jitted, hint
+from pypy.rlib.jit import JitDriver, hint, set_param
from pypy.rlib.jit import unroll_safe, dont_look_inside, promote
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.debug import fatalerror
@@ -308,8 +308,8 @@
pc += 1
return n
def main(n):
- myjitdriver.set_param('threshold', 3)
- myjitdriver.set_param('trace_eagerness', 5)
+ set_param(None, 'threshold', 3)
+ set_param(None, 'trace_eagerness', 5)
return f("c-l", n)
expected = main(100)
res = self.meta_interp(main, [100], enable_opts='', inline=True)
@@ -329,7 +329,7 @@
return recursive(n - 1) + 1
return 0
def loop(n):
- myjitdriver.set_param("threshold", 10)
+ set_param(myjitdriver, "threshold", 10)
pc = 0
while n:
myjitdriver.can_enter_jit(n=n)
@@ -351,8 +351,8 @@
return 0
myjitdriver = JitDriver(greens=[], reds=['n'])
def loop(n):
- myjitdriver.set_param("threshold", 4)
- myjitdriver.set_param("trace_eagerness", 2)
+ set_param(None, "threshold", 4)
+ set_param(None, "trace_eagerness", 2)
while n:
myjitdriver.can_enter_jit(n=n)
myjitdriver.jit_merge_point(n=n)
@@ -482,12 +482,12 @@
TRACE_LIMIT = 66
def main(inline):
- myjitdriver.set_param("threshold", 10)
- myjitdriver.set_param('function_threshold', 60)
+ set_param(None, "threshold", 10)
+ set_param(None, 'function_threshold', 60)
if inline:
- myjitdriver.set_param('inlining', True)
+ set_param(None, 'inlining', True)
else:
- myjitdriver.set_param('inlining', False)
+ set_param(None, 'inlining', False)
return loop(100)
res = self.meta_interp(main, [0], enable_opts='', trace_limit=TRACE_LIMIT)
@@ -564,11 +564,11 @@
pc += 1
return n
def g(m):
- myjitdriver.set_param('inlining', True)
+ set_param(None, 'inlining', True)
# carefully chosen threshold to make sure that the inner function
# cannot be inlined, but the inner function on its own is small
# enough
- myjitdriver.set_param('trace_limit', 40)
+ set_param(None, 'trace_limit', 40)
if m > 1000000:
f('', 0)
result = 0
@@ -1207,9 +1207,9 @@
driver.can_enter_jit(c=c, i=i, v=v)
break
- def main(c, i, set_param, v):
- if set_param:
- driver.set_param('function_threshold', 0)
+ def main(c, i, _set_param, v):
+ if _set_param:
+ set_param(driver, 'function_threshold', 0)
portal(c, i, v)
self.meta_interp(main, [10, 10, False, False], inline=True)
diff --git a/pypy/jit/metainterp/test/test_warmspot.py b/pypy/jit/metainterp/test/test_warmspot.py
--- a/pypy/jit/metainterp/test/test_warmspot.py
+++ b/pypy/jit/metainterp/test/test_warmspot.py
@@ -1,10 +1,7 @@
import py
-from pypy.jit.metainterp.warmspot import ll_meta_interp
from pypy.jit.metainterp.warmspot import get_stats
-from pypy.rlib.jit import JitDriver
-from pypy.rlib.jit import unroll_safe
+from pypy.rlib.jit import JitDriver, set_param, unroll_safe
from pypy.jit.backend.llgraph import runner
-from pypy.jit.metainterp.history import BoxInt
from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.jit.metainterp.optimizeopt import ALL_OPTS_NAMES
@@ -97,7 +94,7 @@
n = A().m(n)
return n
def f(n, enable_opts):
- myjitdriver.set_param('enable_opts', hlstr(enable_opts))
+ set_param(None, 'enable_opts', hlstr(enable_opts))
return g(n)
# check that the set_param will override the default
diff --git a/pypy/jit/metainterp/test/test_ztranslation.py b/pypy/jit/metainterp/test/test_ztranslation.py
--- a/pypy/jit/metainterp/test/test_ztranslation.py
+++ b/pypy/jit/metainterp/test/test_ztranslation.py
@@ -1,7 +1,7 @@
import py
from pypy.jit.metainterp.warmspot import rpython_ll_meta_interp, ll_meta_interp
from pypy.jit.backend.llgraph import runner
-from pypy.rlib.jit import JitDriver, unroll_parameters
+from pypy.rlib.jit import JitDriver, unroll_parameters, set_param
from pypy.rlib.jit import PARAMETERS, dont_look_inside, hint
from pypy.jit.metainterp.jitprof import Profiler
from pypy.rpython.lltypesystem import lltype, llmemory
@@ -57,9 +57,9 @@
get_printable_location=get_printable_location)
def f(i):
for param, defl in unroll_parameters:
- jitdriver.set_param(param, defl)
- jitdriver.set_param("threshold", 3)
- jitdriver.set_param("trace_eagerness", 2)
+ set_param(jitdriver, param, defl)
+ set_param(jitdriver, "threshold", 3)
+ set_param(jitdriver, "trace_eagerness", 2)
total = 0
frame = Frame(i)
while frame.l[0] > 3:
@@ -117,8 +117,8 @@
raise ValueError
return 2
def main(i):
- jitdriver.set_param("threshold", 3)
- jitdriver.set_param("trace_eagerness", 2)
+ set_param(jitdriver, "threshold", 3)
+ set_param(jitdriver, "trace_eagerness", 2)
total = 0
n = i
while n > 3:
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -120,7 +120,8 @@
op = block.operations[i]
if (op.opname == 'jit_marker' and
op.args[0].value == marker_name and
- op.args[1].value.active): # the jitdriver
+ (op.args[1].value is None or
+ op.args[1].value.active)): # the jitdriver
results.append((graph, block, i))
return results
@@ -846,11 +847,18 @@
_, PTR_SET_PARAM_STR_FUNCTYPE = self.cpu.ts.get_FuncType(
[lltype.Ptr(STR)], lltype.Void)
def make_closure(jd, fullfuncname, is_string):
- state = jd.warmstate
- def closure(i):
- if is_string:
- i = hlstr(i)
- getattr(state, fullfuncname)(i)
+ if jd is None:
+ def closure(i):
+ if is_string:
+ i = hlstr(i)
+ for jd in self.jitdrivers_sd:
+ getattr(jd.warmstate, fullfuncname)(i)
+ else:
+ state = jd.warmstate
+ def closure(i):
+ if is_string:
+ i = hlstr(i)
+ getattr(state, fullfuncname)(i)
if is_string:
TP = PTR_SET_PARAM_STR_FUNCTYPE
else:
@@ -859,12 +867,16 @@
return Constant(funcptr, TP)
#
for graph, block, i in find_set_param(graphs):
+
op = block.operations[i]
- for jd in self.jitdrivers_sd:
- if jd.jitdriver is op.args[1].value:
- break
+ if op.args[1].value is not None:
+ for jd in self.jitdrivers_sd:
+ if jd.jitdriver is op.args[1].value:
+ break
+ else:
+ assert 0, "jitdriver of set_param() not found"
else:
- assert 0, "jitdriver of set_param() not found"
+ jd = None
funcname = op.args[2].value
key = jd, funcname
if key not in closures:
diff --git a/pypy/module/_rawffi/structure.py b/pypy/module/_rawffi/structure.py
--- a/pypy/module/_rawffi/structure.py
+++ b/pypy/module/_rawffi/structure.py
@@ -212,6 +212,8 @@
while count + basic_size <= total_size:
fieldtypes.append(basic_ffi_type)
count += basic_size
+ if basic_size == 0: # corner case. get out of this infinite
+ break # loop after 1 iteration ("why not")
self.ffi_struct = clibffi.make_struct_ffitype_e(self.size,
self.alignment,
fieldtypes)
diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -1022,6 +1022,12 @@
assert ret.y == 1234500, "ret.y == %d" % (ret.y,)
s.free()
+ def test_ffi_type(self):
+ import _rawffi
+ EMPTY = _rawffi.Structure([])
+ S2E = _rawffi.Structure([('bah', (EMPTY, 1))])
+ S2E.get_ffi_type() # does not hang
+
class AppTestAutoFree:
def setup_class(cls):
space = gettestobjspace(usemodules=('_rawffi', 'struct'))
diff --git a/pypy/module/cpyext/include/eval.h b/pypy/module/cpyext/include/eval.h
--- a/pypy/module/cpyext/include/eval.h
+++ b/pypy/module/cpyext/include/eval.h
@@ -14,8 +14,8 @@
PyObject * PyEval_CallFunction(PyObject *obj, const char *format, ...);
PyObject * PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...);
-PyObject * PyObject_CallFunction(PyObject *obj, char *format, ...);
-PyObject * PyObject_CallMethod(PyObject *obj, char *name, char *format, ...);
+PyObject * PyObject_CallFunction(PyObject *obj, const char *format, ...);
+PyObject * PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...);
PyObject * PyObject_CallFunctionObjArgs(PyObject *callable, ...);
PyObject * PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...);
diff --git a/pypy/module/cpyext/include/modsupport.h b/pypy/module/cpyext/include/modsupport.h
--- a/pypy/module/cpyext/include/modsupport.h
+++ b/pypy/module/cpyext/include/modsupport.h
@@ -48,7 +48,11 @@
/*
* This is from pyport.h. Perhaps it belongs elsewhere.
*/
+#ifdef __cplusplus
+#define PyMODINIT_FUNC extern "C" void
+#else
#define PyMODINIT_FUNC void
+#endif
#ifdef __cplusplus
diff --git a/pypy/module/cpyext/include/pycobject.h b/pypy/module/cpyext/include/pycobject.h
--- a/pypy/module/cpyext/include/pycobject.h
+++ b/pypy/module/cpyext/include/pycobject.h
@@ -33,7 +33,7 @@
PyAPI_FUNC(void *) PyCObject_GetDesc(PyObject *);
/* Import a pointer to a C object from a module using a PyCObject. */
-PyAPI_FUNC(void *) PyCObject_Import(char *module_name, char *cobject_name);
+PyAPI_FUNC(void *) PyCObject_Import(const char *module_name, const char *cobject_name);
/* Modify a C object. Fails (==0) if object has a destructor. */
PyAPI_FUNC(int) PyCObject_SetVoidPtr(PyObject *self, void *cobj);
diff --git a/pypy/module/cpyext/include/pyerrors.h b/pypy/module/cpyext/include/pyerrors.h
--- a/pypy/module/cpyext/include/pyerrors.h
+++ b/pypy/module/cpyext/include/pyerrors.h
@@ -11,8 +11,8 @@
(PyClass_Check((x)) || (PyType_Check((x)) && \
PyObject_IsSubclass((x), PyExc_BaseException)))
-PyObject *PyErr_NewException(char *name, PyObject *base, PyObject *dict);
-PyObject *PyErr_NewExceptionWithDoc(char *name, char *doc, PyObject *base, PyObject *dict);
+PyObject *PyErr_NewException(const char *name, PyObject *base, PyObject *dict);
+PyObject *PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict);
PyObject *PyErr_Format(PyObject *exception, const char *format, ...);
/* These APIs aren't really part of the error implementation, but
diff --git a/pypy/module/cpyext/modsupport.py b/pypy/module/cpyext/modsupport.py
--- a/pypy/module/cpyext/modsupport.py
+++ b/pypy/module/cpyext/modsupport.py
@@ -54,9 +54,15 @@
modname = rffi.charp2str(name)
state = space.fromcache(State)
f_name, f_path = state.package_context
- w_mod = PyImport_AddModule(space, f_name)
+ if f_name is not None:
+ modname = f_name
+ w_mod = PyImport_AddModule(space, modname)
+ state.package_context = None, None
- dict_w = {'__file__': space.wrap(f_path)}
+ if f_path is not None:
+ dict_w = {'__file__': space.wrap(f_path)}
+ else:
+ dict_w = {}
convert_method_defs(space, dict_w, methods, None, w_self, modname)
for key, w_value in dict_w.items():
space.setattr(w_mod, space.wrap(key), w_value)
diff --git a/pypy/module/cpyext/presetup.py b/pypy/module/cpyext/presetup.py
--- a/pypy/module/cpyext/presetup.py
+++ b/pypy/module/cpyext/presetup.py
@@ -42,4 +42,4 @@
patch_distutils()
del sys.argv[0]
-execfile(sys.argv[0], {'__file__': sys.argv[0]})
+execfile(sys.argv[0], {'__file__': sys.argv[0], '__name__': '__main__'})
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -116,8 +116,8 @@
try:
return typedescr_cache[typedef]
except KeyError:
- if typedef.base is not None:
- return _get_typedescr_1(typedef.base)
+ if typedef.bases:
+ return _get_typedescr_1(typedef.bases[0])
return typedescr_cache[None]
def get_typedescr(typedef):
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -9,7 +9,8 @@
unaryfunc, wrapperfunc, ternaryfunc, PyTypeObjectPtr, binaryfunc,
getattrfunc, getattrofunc, setattrofunc, lenfunc, ssizeargfunc,
ssizessizeargfunc, ssizeobjargproc, iternextfunc, initproc, richcmpfunc,
- cmpfunc, hashfunc, descrgetfunc, descrsetfunc, objobjproc, readbufferproc)
+ cmpfunc, hashfunc, descrgetfunc, descrsetfunc, objobjproc, objobjargproc,
+ readbufferproc)
from pypy.module.cpyext.pyobject import from_ref
from pypy.module.cpyext.pyerrors import PyErr_Occurred
from pypy.module.cpyext.state import State
@@ -175,6 +176,15 @@
space.fromcache(State).check_and_raise_exception(always=True)
return space.wrap(res)
+def wrap_objobjargproc(space, w_self, w_args, func):
+ func_target = rffi.cast(objobjargproc, func)
+ check_num_args(space, w_args, 2)
+ w_key, w_value = space.fixedview(w_args)
+ res = generic_cpy_call(space, func_target, w_self, w_key, w_value)
+ if rffi.cast(lltype.Signed, res) == -1:
+ space.fromcache(State).check_and_raise_exception(always=True)
+ return space.wrap(res)
+
def wrap_ssizessizeargfunc(space, w_self, w_args, func):
func_target = rffi.cast(ssizessizeargfunc, func)
check_num_args(space, w_args, 2)
diff --git a/pypy/module/cpyext/src/cobject.c b/pypy/module/cpyext/src/cobject.c
--- a/pypy/module/cpyext/src/cobject.c
+++ b/pypy/module/cpyext/src/cobject.c
@@ -77,7 +77,7 @@
}
void *
-PyCObject_Import(char *module_name, char *name)
+PyCObject_Import(const char *module_name, const char *name)
{
PyObject *m, *c;
void *r = NULL;
diff --git a/pypy/module/cpyext/src/modsupport.c b/pypy/module/cpyext/src/modsupport.c
--- a/pypy/module/cpyext/src/modsupport.c
+++ b/pypy/module/cpyext/src/modsupport.c
@@ -541,7 +541,7 @@
}
PyObject *
-PyObject_CallFunction(PyObject *callable, char *format, ...)
+PyObject_CallFunction(PyObject *callable, const char *format, ...)
{
va_list va;
PyObject *args;
@@ -558,7 +558,7 @@
}
PyObject *
-PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
+PyObject_CallMethod(PyObject *o, const char *name, const char *format, ...)
{
va_list va;
PyObject *args;
diff --git a/pypy/module/cpyext/src/pyerrors.c b/pypy/module/cpyext/src/pyerrors.c
--- a/pypy/module/cpyext/src/pyerrors.c
+++ b/pypy/module/cpyext/src/pyerrors.c
@@ -21,7 +21,7 @@
}
PyObject *
-PyErr_NewException(char *name, PyObject *base, PyObject *dict)
+PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
{
char *dot;
PyObject *modulename = NULL;
@@ -72,7 +72,7 @@
/* Create an exception with docstring */
PyObject *
-PyErr_NewExceptionWithDoc(char *name, char *doc, PyObject *base, PyObject *dict)
+PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict)
{
int result;
PyObject *ret = NULL;
diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -397,3 +397,31 @@
def __str__(self):
return "text"
assert module.tp_str(C()) == "text"
+
+ def test_mp_ass_subscript(self):
+ module = self.import_extension('foo', [
+ ("new_obj", "METH_NOARGS",
+ '''
+ PyObject *obj;
+ Foo_Type.tp_as_mapping = &tp_as_mapping;
+ tp_as_mapping.mp_ass_subscript = mp_ass_subscript;
+ if (PyType_Ready(&Foo_Type) < 0) return NULL;
+ obj = PyObject_New(PyObject, &Foo_Type);
+ return obj;
+ '''
+ )],
+ '''
+ static int
+ mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value)
+ {
+ PyErr_SetNone(PyExc_ZeroDivisionError);
+ return -1;
+ }
+ PyMappingMethods tp_as_mapping;
+ static PyTypeObject Foo_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "foo.foo",
+ };
+ ''')
+ obj = module.new_obj()
+ raises(ZeroDivisionError, obj.__setitem__, 5, None)
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -513,7 +513,7 @@
space.warn(msg, space.w_ImportWarning)
modtype, suffix, filemode = find_modtype(space, filepart)
try:
- if modtype in (PY_SOURCE, PY_COMPILED):
+ if modtype in (PY_SOURCE, PY_COMPILED, C_EXTENSION):
assert suffix is not None
filename = filepart + suffix
stream = streamio.open_file_as_stream(filename, filemode)
@@ -522,9 +522,6 @@
except:
stream.close()
raise
- if modtype == C_EXTENSION:
- filename = filepart + suffix
- return FindInfo(modtype, filename, None, suffix, filemode)
except StreamErrors:
pass # XXX! must not eat all exceptions, e.g.
# Out of file descriptors.
diff --git a/pypy/module/math/test/test_translated.py b/pypy/module/math/test/test_translated.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/math/test/test_translated.py
@@ -0,0 +1,10 @@
+import py
+from pypy.translator.c.test.test_genc import compile
+from pypy.module.math.interp_math import _gamma
+
+
+def test_gamma_overflow():
+ f = compile(_gamma, [float])
+ assert f(10.0) == 362880.0
+ py.test.raises(OverflowError, f, 1720.0)
+ py.test.raises(OverflowError, f, 172.0)
diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -2,7 +2,7 @@
class Module(MixedModule):
- applevel_name = 'numpy'
+ applevel_name = 'numpypy'
interpleveldefs = {
'array': 'interp_numarray.SingleDimArray',
diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py
--- a/pypy/module/micronumpy/app_numpy.py
+++ b/pypy/module/micronumpy/app_numpy.py
@@ -1,6 +1,6 @@
import math
-import numpy
+import numpypy
inf = float("inf")
@@ -13,5 +13,5 @@
def mean(a):
if not hasattr(a, "mean"):
- a = numpy.array(a)
+ a = numpypy.array(a)
return a.mean()
diff --git a/pypy/module/micronumpy/bench/add.py b/pypy/module/micronumpy/bench/add.py
--- a/pypy/module/micronumpy/bench/add.py
+++ b/pypy/module/micronumpy/bench/add.py
@@ -1,5 +1,8 @@
-import numpy
+try:
+ import numpypy as numpy
+except:
+ import numpy
def f():
a = numpy.zeros(10000000)
diff --git a/pypy/module/micronumpy/bench/iterate.py b/pypy/module/micronumpy/bench/iterate.py
--- a/pypy/module/micronumpy/bench/iterate.py
+++ b/pypy/module/micronumpy/bench/iterate.py
@@ -1,5 +1,8 @@
-import numpy
+try:
+ import numpypy as numpy
+except:
+ import numpy
def f():
sum = 0
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -3,7 +3,7 @@
class AppTestDtypes(BaseNumpyAppTest):
def test_dtype(self):
- from numpy import dtype
+ from numpypy import dtype
d = dtype('?')
assert d.num == 0
@@ -14,7 +14,7 @@
raises(TypeError, dtype, 1042)
def test_dtype_with_types(self):
- from numpy import dtype
+ from numpypy import dtype
assert dtype(bool).num == 0
assert dtype(int).num == 7
@@ -22,13 +22,13 @@
assert dtype(float).num == 12
def test_array_dtype_attr(self):
- from numpy import array, dtype
+ from numpypy import array, dtype
a = array(range(5), long)
assert a.dtype is dtype(long)
def test_repr_str(self):
- from numpy import dtype
+ from numpypy import dtype
assert repr(dtype) == "<type 'numpy.dtype'>"
d = dtype('?')
@@ -36,57 +36,57 @@
assert str(d) == "bool"
def test_bool_array(self):
- import numpy
+ from numpypy import array, False_, True_
- a = numpy.array([0, 1, 2, 2.5], dtype='?')
- assert a[0] is numpy.False_
+ a = array([0, 1, 2, 2.5], dtype='?')
+ assert a[0] is False_
for i in xrange(1, 4):
- assert a[i] is numpy.True_
+ assert a[i] is True_
def test_copy_array_with_dtype(self):
- import numpy
+ from numpypy import array, False_, True_
- a = numpy.array([0, 1, 2, 3], dtype=long)
+ a = array([0, 1, 2, 3], dtype=long)
# int on 64-bit, long in 32-bit
assert isinstance(a[0], (int, long))
b = a.copy()
assert isinstance(b[0], (int, long))
- a = numpy.array([0, 1, 2, 3], dtype=bool)
- assert a[0] is numpy.False_
+ a = array([0, 1, 2, 3], dtype=bool)
+ assert a[0] is False_
b = a.copy()
- assert b[0] is numpy.False_
+ assert b[0] is False_
def test_zeros_bool(self):
- import numpy
+ from numpypy import zeros, False_
- a = numpy.zeros(10, dtype=bool)
+ a = zeros(10, dtype=bool)
for i in range(10):
- assert a[i] is numpy.False_
+ assert a[i] is False_
def test_ones_bool(self):
- import numpy
+ from numpypy import ones, True_
- a = numpy.ones(10, dtype=bool)
+ a = ones(10, dtype=bool)
for i in range(10):
- assert a[i] is numpy.True_
+ assert a[i] is True_
def test_zeros_long(self):
- from numpy import zeros
+ from numpypy import zeros
a = zeros(10, dtype=long)
for i in range(10):
assert isinstance(a[i], (int, long))
assert a[1] == 0
def test_ones_long(self):
- from numpy import ones
+ from numpypy import ones
a = ones(10, dtype=long)
for i in range(10):
assert isinstance(a[i], (int, long))
assert a[1] == 1
def test_overflow(self):
- from numpy import array, dtype
+ from numpypy import array, dtype
assert array([128], 'b')[0] == -128
assert array([256], 'B')[0] == 0
assert array([32768], 'h')[0] == -32768
@@ -98,7 +98,7 @@
raises(OverflowError, "array([2**64], 'Q')")
def test_bool_binop_types(self):
- from numpy import array, dtype
+ from numpypy import array, dtype
types = [
'?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd'
]
@@ -107,7 +107,7 @@
assert (a + array([0], t)).dtype is dtype(t)
def test_binop_types(self):
- from numpy import array, dtype
+ from numpypy import array, dtype
tests = [('b','B','h'), ('b','h','h'), ('b','H','i'), ('b','i','i'),
('b','l','l'), ('b','q','q'), ('b','Q','d'), ('B','h','h'),
('B','H','H'), ('B','i','i'), ('B','I','I'), ('B','l','l'),
@@ -129,7 +129,7 @@
assert (array([1], d1) + array([1], d2)).dtype is dtype(dout)
def test_add_int8(self):
- from numpy import array, dtype
+ from numpypy import array, dtype
a = array(range(5), dtype="int8")
b = a + a
@@ -138,7 +138,7 @@
assert b[i] == i * 2
def test_add_int16(self):
- from numpy import array, dtype
+ from numpypy import array, dtype
a = array(range(5), dtype="int16")
b = a + a
@@ -147,7 +147,7 @@
assert b[i] == i * 2
def test_add_uint32(self):
- from numpy import array, dtype
+ from numpypy import array, dtype
a = array(range(5), dtype="I")
b = a + a
@@ -156,12 +156,12 @@
assert b[i] == i * 2
def test_shape(self):
- from numpy import dtype
+ from numpypy import dtype
assert dtype(long).shape == ()
def test_cant_subclass(self):
- from numpy import dtype
+ from numpypy import dtype
# You can't subclass dtype
raises(TypeError, type, "Foo", (dtype,), {})
diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py
--- a/pypy/module/micronumpy/test/test_module.py
+++ b/pypy/module/micronumpy/test/test_module.py
@@ -3,19 +3,19 @@
class AppTestNumPyModule(BaseNumpyAppTest):
def test_mean(self):
- from numpy import array, mean
+ from numpypy import array, mean
assert mean(array(range(5))) == 2.0
assert mean(range(5)) == 2.0
def test_average(self):
- from numpy import array, average
+ from numpypy import array, average
assert average(range(10)) == 4.5
assert average(array(range(10))) == 4.5
def test_constants(self):
import math
- from numpy import inf, e
+ from numpypy import inf, e
assert type(inf) is float
assert inf == float("inf")
assert e == math.e
- assert type(e) is float
\ No newline at end of file
+ assert type(e) is float
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -4,12 +4,12 @@
class AppTestNumArray(BaseNumpyAppTest):
def test_type(self):
- from numpy import array
+ from numpypy import array
ar = array(range(5))
assert type(ar) is type(ar + ar)
def test_init(self):
- from numpy import zeros
+ from numpypy import zeros
a = zeros(15)
# Check that storage was actually zero'd.
assert a[10] == 0.0
@@ -18,7 +18,7 @@
assert a[13] == 5.3
def test_size(self):
- from numpy import array
+ from numpypy import array
# XXX fixed on multidim branch
#assert array(3).size == 1
a = array([1, 2, 3])
@@ -30,13 +30,13 @@
Test that empty() works.
"""
- from numpy import empty
+ from numpypy import empty
a = empty(2)
a[1] = 1.0
assert a[1] == 1.0
def test_ones(self):
- from numpy import ones
+ from numpypy import ones
a = ones(3)
assert len(a) == 3
assert a[0] == 1
@@ -45,19 +45,19 @@
assert a[2] == 4
def test_copy(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = a.copy()
for i in xrange(5):
assert b[i] == a[i]
def test_iterator_init(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
assert a[3] == 3
def test_repr(self):
- from numpy import array, zeros
+ from numpypy import array, zeros
a = array(range(5), float)
assert repr(a) == "array([0.0, 1.0, 2.0, 3.0, 4.0])"
a = array([], float)
@@ -72,7 +72,7 @@
assert repr(a) == "array([True, False, True, False], dtype=bool)"
def test_repr_slice(self):
- from numpy import array, zeros
+ from numpypy import array, zeros
a = array(range(5), float)
b = a[1::2]
assert repr(b) == "array([1.0, 3.0])"
@@ -81,7 +81,7 @@
assert repr(b) == "array([0.0, 0.0, 0.0, ..., 0.0, 0.0, 0.0])"
def test_str(self):
- from numpy import array, zeros
+ from numpypy import array, zeros
a = array(range(5), float)
assert str(a) == "[0.0 1.0 2.0 3.0 4.0]"
assert str((2*a)[:]) == "[0.0 2.0 4.0 6.0 8.0]"
@@ -100,7 +100,7 @@
assert str(a) == "[0 1 2 3 4]"
def test_str_slice(self):
- from numpy import array, zeros
+ from numpypy import array, zeros
a = array(range(5), float)
b = a[1::2]
assert str(b) == "[1.0 3.0]"
@@ -109,7 +109,7 @@
assert str(b) == "[0.0 0.0 0.0 ..., 0.0 0.0 0.0]"
def test_getitem(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
raises(IndexError, "a[5]")
a = a + a
@@ -118,7 +118,7 @@
raises(IndexError, "a[-6]")
def test_getitem_tuple(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
raises(IndexError, "a[(1,2)]")
for i in xrange(5):
@@ -128,7 +128,7 @@
assert a[i] == b[i]
def test_setitem(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
a[-1] = 5.0
assert a[4] == 5.0
@@ -136,7 +136,7 @@
raises(IndexError, "a[-6] = 3.0")
def test_setitem_tuple(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
raises(IndexError, "a[(1,2)] = [0,1]")
for i in xrange(5):
@@ -147,7 +147,7 @@
assert a[i] == i
def test_setslice_array(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = array(range(2))
a[1:4:2] = b
@@ -158,7 +158,7 @@
assert b[1] == 0.
def test_setslice_of_slice_array(self):
- from numpy import array, zeros
+ from numpypy import array, zeros
a = zeros(5)
a[::2] = array([9., 10., 11.])
assert a[0] == 9.
@@ -177,7 +177,7 @@
assert a[0] == 3.
def test_setslice_list(self):
- from numpy import array
+ from numpypy import array
a = array(range(5), float)
b = [0., 1.]
a[1:4:2] = b
@@ -185,20 +185,20 @@
assert a[3] == 1.
def test_setslice_constant(self):
- from numpy import array
+ from numpypy import array
a = array(range(5), float)
a[1:4:2] = 0.
assert a[1] == 0.
assert a[3] == 0.
def test_len(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
assert len(a) == 5
assert len(a + a) == 5
def test_shape(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
assert a.shape == (5,)
b = a + a
@@ -207,7 +207,7 @@
assert c.shape == (3,)
def test_add(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = a + a
for i in range(5):
@@ -220,7 +220,7 @@
assert c[i] == bool(a[i] + b[i])
def test_add_other(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = array(range(4, -1, -1))
c = a + b
@@ -228,20 +228,20 @@
assert c[i] == 4
def test_add_constant(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = a + 5
for i in range(5):
assert b[i] == i + 5
def test_radd(self):
- from numpy import array
+ from numpypy import array
r = 3 + array(range(3))
for i in range(3):
assert r[i] == i + 3
def test_add_list(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = list(reversed(range(5)))
c = a + b
@@ -250,14 +250,14 @@
assert c[i] == 4
def test_subtract(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = a - a
for i in range(5):
assert b[i] == 0
def test_subtract_other(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = array([1, 1, 1, 1, 1])
c = a - b
@@ -265,29 +265,29 @@
assert c[i] == i - 1
def test_subtract_constant(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = a - 5
for i in range(5):
assert b[i] == i - 5
def test_mul(self):
- import numpy
+ import numpypy
- a = numpy.array(range(5))
+ a = numpypy.array(range(5))
b = a * a
for i in range(5):
assert b[i] == i * i
- a = numpy.array(range(5), dtype=bool)
+ a = numpypy.array(range(5), dtype=bool)
b = a * a
- assert b.dtype is numpy.dtype(bool)
- assert b[0] is numpy.False_
+ assert b.dtype is numpypy.dtype(bool)
+ assert b[0] is numpypy.False_
for i in range(1, 5):
- assert b[i] is numpy.True_
+ assert b[i] is numpypy.True_
def test_mul_constant(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = a * 5
for i in range(5):
@@ -295,7 +295,7 @@
def test_div(self):
from math import isnan
- from numpy import array, dtype, inf
+ from numpypy import array, dtype, inf
a = array(range(1, 6))
b = a / a
@@ -327,7 +327,7 @@
assert c[2] == -inf
def test_div_other(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = array([2, 2, 2, 2, 2], float)
c = a / b
@@ -335,14 +335,14 @@
assert c[i] == i / 2.0
def test_div_constant(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = a / 5.0
for i in range(5):
assert b[i] == i / 5.0
def test_pow(self):
- from numpy import array
+ from numpypy import array
a = array(range(5), float)
b = a ** a
for i in range(5):
@@ -350,7 +350,7 @@
assert b[i] == i**i
def test_pow_other(self):
- from numpy import array
+ from numpypy import array
a = array(range(5), float)
b = array([2, 2, 2, 2, 2])
c = a ** b
@@ -358,14 +358,14 @@
assert c[i] == i ** 2
def test_pow_constant(self):
- from numpy import array
+ from numpypy import array
a = array(range(5), float)
b = a ** 2
for i in range(5):
assert b[i] == i ** 2
def test_mod(self):
- from numpy import array
+ from numpypy import array
a = array(range(1,6))
b = a % a
for i in range(5):
@@ -378,7 +378,7 @@
assert b[i] == 1
def test_mod_other(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = array([2, 2, 2, 2, 2])
c = a % b
@@ -386,14 +386,14 @@
assert c[i] == i % 2
def test_mod_constant(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = a % 2
for i in range(5):
assert b[i] == i % 2
def test_pos(self):
- from numpy import array
+ from numpypy import array
a = array([1.,-2.,3.,-4.,-5.])
b = +a
for i in range(5):
@@ -404,7 +404,7 @@
assert a[i] == i
def test_neg(self):
- from numpy import array
+ from numpypy import array
a = array([1.,-2.,3.,-4.,-5.])
b = -a
for i in range(5):
@@ -415,7 +415,7 @@
assert a[i] == -i
def test_abs(self):
- from numpy import array
+ from numpypy import array
a = array([1.,-2.,3.,-4.,-5.])
b = abs(a)
for i in range(5):
@@ -426,7 +426,7 @@
assert a[i + 5] == abs(i)
def test_auto_force(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = a - 1
a[2] = 3
@@ -440,7 +440,7 @@
assert c[1] == 4
def test_getslice(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
s = a[1:5]
assert len(s) == 4
@@ -454,7 +454,7 @@
assert s[0] == 5
def test_getslice_step(self):
- from numpy import array
+ from numpypy import array
a = array(range(10))
s = a[1:9:2]
assert len(s) == 4
@@ -462,7 +462,7 @@
assert s[i] == a[2*i+1]
def test_slice_update(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
s = a[0:3]
s[1] = 10
@@ -473,7 +473,7 @@
def test_slice_invaidate(self):
# check that slice shares invalidation list with
- from numpy import array
+ from numpypy import array
a = array(range(5))
s = a[0:2]
b = array([10,11])
@@ -487,13 +487,13 @@
assert d[1] == 12
def test_mean(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
assert a.mean() == 2.0
assert a[:4].mean() == 1.5
def test_sum(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
assert a.sum() == 10.0
assert a[:4].sum() == 6.0
@@ -502,32 +502,32 @@
assert a.sum() == 5
def test_prod(self):
- from numpy import array
+ from numpypy import array
a = array(range(1,6))
assert a.prod() == 120.0
assert a[:4].prod() == 24.0
def test_max(self):
- from numpy import array
+ from numpypy import array
a = array([-1.2, 3.4, 5.7, -3.0, 2.7])
assert a.max() == 5.7
b = array([])
raises(ValueError, "b.max()")
def test_max_add(self):
- from numpy import array
+ from numpypy import array
a = array([-1.2, 3.4, 5.7, -3.0, 2.7])
assert (a+a).max() == 11.4
def test_min(self):
- from numpy import array
+ from numpypy import array
a = array([-1.2, 3.4, 5.7, -3.0, 2.7])
assert a.min() == -3.0
b = array([])
raises(ValueError, "b.min()")
def test_argmax(self):
- from numpy import array
+ from numpypy import array
a = array([-1.2, 3.4, 5.7, -3.0, 2.7])
assert a.argmax() == 2
b = array([])
@@ -537,14 +537,14 @@
assert a.argmax() == 9
def test_argmin(self):
- from numpy import array
+ from numpypy import array
a = array([-1.2, 3.4, 5.7, -3.0, 2.7])
assert a.argmin() == 3
b = array([])
raises(ValueError, "b.argmin()")
def test_all(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
assert a.all() == False
a[0] = 3.0
@@ -553,7 +553,7 @@
assert b.all() == True
def test_any(self):
- from numpy import array, zeros
+ from numpypy import array, zeros
a = array(range(5))
assert a.any() == True
b = zeros(5)
@@ -562,7 +562,7 @@
assert c.any() == False
def test_dot(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
assert a.dot(a) == 30.0
@@ -570,14 +570,14 @@
assert a.dot(range(5)) == 30
def test_dot_constant(self):
- from numpy import array
+ from numpypy import array
a = array(range(5))
b = a.dot(2.5)
for i in xrange(5):
assert b[i] == 2.5 * a[i]
def test_dtype_guessing(self):
- from numpy import array, dtype
+ from numpypy import array, dtype
assert array([True]).dtype is dtype(bool)
assert array([True, False]).dtype is dtype(bool)
@@ -590,7 +590,7 @@
def test_comparison(self):
import operator
- from numpy import array, dtype
+ from numpypy import array, dtype
a = array(range(5))
b = array(range(5), float)
@@ -616,7 +616,7 @@
cls.w_data = cls.space.wrap(struct.pack('dddd', 1, 2, 3, 4))
def test_fromstring(self):
- from numpy import fromstring
+ from numpypy import fromstring
a = fromstring(self.data)
for i in range(4):
assert a[i] == i + 1
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -4,14 +4,14 @@
class AppTestUfuncs(BaseNumpyAppTest):
def test_ufunc_instance(self):
- from numpy import add, ufunc
+ from numpypy import add, ufunc
assert isinstance(add, ufunc)
assert repr(add) == "<ufunc 'add'>"
assert repr(ufunc) == "<type 'numpy.ufunc'>"
def test_ufunc_attrs(self):
- from numpy import add, multiply, sin
+ from numpypy import add, multiply, sin
assert add.identity == 0
assert multiply.identity == 1
@@ -22,7 +22,7 @@
assert sin.nin == 1
def test_wrong_arguments(self):
- from numpy import add, sin
+ from numpypy import add, sin
raises(ValueError, add, 1)
raises(TypeError, add, 1, 2, 3)
@@ -30,14 +30,14 @@
raises(ValueError, sin)
def test_single_item(self):
- from numpy import negative, sign, minimum
+ from numpypy import negative, sign, minimum
assert negative(5.0) == -5.0
assert sign(-0.0) == 0.0
assert minimum(2.0, 3.0) == 2.0
def test_sequence(self):
- from numpy import array, negative, minimum
+ from numpypy import array, negative, minimum
a = array(range(3))
b = [2.0, 1.0, 0.0]
c = 1.0
@@ -71,7 +71,7 @@
assert min_c_b[i] == min(b[i], c)
def test_negative(self):
- from numpy import array, negative
+ from numpypy import array, negative
a = array([-5.0, 0.0, 1.0])
b = negative(a)
@@ -86,7 +86,7 @@
assert negative(a + a)[3] == -6
def test_abs(self):
- from numpy import array, absolute
+ from numpypy import array, absolute
a = array([-5.0, -0.0, 1.0])
b = absolute(a)
@@ -94,7 +94,7 @@
assert b[i] == abs(a[i])
def test_add(self):
- from numpy import array, add
+ from numpypy import array, add
a = array([-5.0, -0.0, 1.0])
b = array([ 3.0, -2.0,-3.0])
@@ -103,7 +103,7 @@
assert c[i] == a[i] + b[i]
def test_divide(self):
- from numpy import array, divide
+ from numpypy import array, divide
a = array([-5.0, -0.0, 1.0])
b = array([ 3.0, -2.0,-3.0])
@@ -112,7 +112,7 @@
assert c[i] == a[i] / b[i]
def test_fabs(self):
- from numpy import array, fabs
+ from numpypy import array, fabs
from math import fabs as math_fabs
a = array([-5.0, -0.0, 1.0])
@@ -121,7 +121,7 @@
assert b[i] == math_fabs(a[i])
def test_minimum(self):
- from numpy import array, minimum
+ from numpypy import array, minimum
a = array([-5.0, -0.0, 1.0])
b = array([ 3.0, -2.0,-3.0])
@@ -130,7 +130,7 @@
assert c[i] == min(a[i], b[i])
def test_maximum(self):
- from numpy import array, maximum
+ from numpypy import array, maximum
a = array([-5.0, -0.0, 1.0])
b = array([ 3.0, -2.0,-3.0])
@@ -143,7 +143,7 @@
assert isinstance(x, (int, long))
def test_multiply(self):
- from numpy import array, multiply
+ from numpypy import array, multiply
a = array([-5.0, -0.0, 1.0])
b = array([ 3.0, -2.0,-3.0])
@@ -152,7 +152,7 @@
assert c[i] == a[i] * b[i]
def test_sign(self):
- from numpy import array, sign, dtype
+ from numpypy import array, sign, dtype
reference = [-1.0, 0.0, 0.0, 1.0]
a = array([-5.0, -0.0, 0.0, 6.0])
@@ -171,7 +171,7 @@
assert a[1] == 0
def test_reciporocal(self):
- from numpy import array, reciprocal
+ from numpypy import array, reciprocal
reference = [-0.2, float("inf"), float("-inf"), 2.0]
a = array([-5.0, 0.0, -0.0, 0.5])
@@ -180,7 +180,7 @@
assert b[i] == reference[i]
def test_subtract(self):
- from numpy import array, subtract
+ from numpypy import array, subtract
a = array([-5.0, -0.0, 1.0])
b = array([ 3.0, -2.0,-3.0])
@@ -189,7 +189,7 @@
assert c[i] == a[i] - b[i]
def test_floor(self):
- from numpy import array, floor
+ from numpypy import array, floor
reference = [-2.0, -1.0, 0.0, 1.0, 1.0]
a = array([-1.4, -1.0, 0.0, 1.0, 1.4])
@@ -198,7 +198,7 @@
assert b[i] == reference[i]
def test_copysign(self):
- from numpy import array, copysign
+ from numpypy import array, copysign
reference = [5.0, -0.0, 0.0, -6.0]
a = array([-5.0, 0.0, 0.0, 6.0])
@@ -214,7 +214,7 @@
def test_exp(self):
import math
- from numpy import array, exp
+ from numpypy import array, exp
a = array([-5.0, -0.0, 0.0, 12345678.0, float("inf"),
-float('inf'), -12343424.0])
@@ -228,7 +228,7 @@
def test_sin(self):
import math
- from numpy import array, sin
+ from numpypy import array, sin
a = array([0, 1, 2, 3, math.pi, math.pi*1.5, math.pi*2])
b = sin(a)
@@ -241,7 +241,7 @@
def test_cos(self):
import math
- from numpy import array, cos
+ from numpypy import array, cos
a = array([0, 1, 2, 3, math.pi, math.pi*1.5, math.pi*2])
b = cos(a)
@@ -250,7 +250,7 @@
def test_tan(self):
import math
- from numpy import array, tan
+ from numpypy import array, tan
a = array([0, 1, 2, 3, math.pi, math.pi*1.5, math.pi*2])
b = tan(a)
@@ -260,7 +260,7 @@
def test_arcsin(self):
import math
- from numpy import array, arcsin
+ from numpypy import array, arcsin
a = array([-1, -0.5, -0.33, 0, 0.33, 0.5, 1])
b = arcsin(a)
@@ -274,7 +274,7 @@
def test_arccos(self):
import math
- from numpy import array, arccos
+ from numpypy import array, arccos
a = array([-1, -0.5, -0.33, 0, 0.33, 0.5, 1])
b = arccos(a)
@@ -289,7 +289,7 @@
def test_arctan(self):
import math
- from numpy import array, arctan
+ from numpypy import array, arctan
a = array([-3, -2, -1, 0, 1, 2, 3, float('inf'), float('-inf')])
b = arctan(a)
@@ -302,7 +302,7 @@
def test_arcsinh(self):
import math
- from numpy import arcsinh, inf
+ from numpypy import arcsinh, inf
for v in [inf, -inf, 1.0, math.e]:
assert math.asinh(v) == arcsinh(v)
@@ -310,7 +310,7 @@
def test_arctanh(self):
import math
- from numpy import arctanh
+ from numpypy import arctanh
for v in [.99, .5, 0, -.5, -.99]:
assert math.atanh(v) == arctanh(v)
@@ -320,13 +320,13 @@
assert arctanh(v) == math.copysign(float("inf"), v)
def test_reduce_errors(self):
- from numpy import sin, add
+ from numpypy import sin, add
raises(ValueError, sin.reduce, [1, 2, 3])
raises(TypeError, add.reduce, 1)
def test_reduce(self):
- from numpy import add, maximum
+ from numpypy import add, maximum
assert add.reduce([1, 2, 3]) == 6
assert maximum.reduce([1]) == 1
@@ -335,7 +335,7 @@
def test_comparisons(self):
import operator
- from numpy import equal, not_equal, less, less_equal, greater, greater_equal
+ from numpypy import equal, not_equal, less, less_equal, greater, greater_equal
for ufunc, func in [
(equal, operator.eq),
diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -137,6 +137,8 @@
interpleveldefs['execve'] = 'interp_posix.execve'
if hasattr(posix, 'spawnv'):
interpleveldefs['spawnv'] = 'interp_posix.spawnv'
+ if hasattr(posix, 'spawnve'):
+ interpleveldefs['spawnve'] = 'interp_posix.spawnve'
if hasattr(os, 'uname'):
interpleveldefs['uname'] = 'interp_posix.uname'
if hasattr(os, 'sysconf'):
diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -760,6 +760,14 @@
except OSError, e:
raise wrap_oserror(space, e)
+def _env2interp(space, w_env):
+ env = {}
+ w_keys = space.call_method(w_env, 'keys')
+ for w_key in space.unpackiterable(w_keys):
+ w_value = space.getitem(w_env, w_key)
+ env[space.str_w(w_key)] = space.str_w(w_value)
+ return env
+
def execve(space, w_command, w_args, w_env):
""" execve(path, args, env)
@@ -771,11 +779,7 @@
"""
command = fsencode_w(space, w_command)
args = [fsencode_w(space, w_arg) for w_arg in space.unpackiterable(w_args)]
- env = {}
- w_keys = space.call_method(w_env, 'keys')
- for w_key in space.unpackiterable(w_keys):
- w_value = space.getitem(w_env, w_key)
- env[space.str_w(w_key)] = space.str_w(w_value)
+ env = _env2interp(space, w_env)
try:
os.execve(command, args, env)
except OSError, e:
@@ -790,6 +794,16 @@
raise wrap_oserror(space, e)
return space.wrap(ret)
+ at unwrap_spec(mode=int, path=str)
+def spawnve(space, mode, path, w_args, w_env):
+ args = [space.str_w(w_arg) for w_arg in space.unpackiterable(w_args)]
+ env = _env2interp(space, w_env)
+ try:
+ ret = os.spawnve(mode, path, args, env)
+ except OSError, e:
+ raise wrap_oserror(space, e)
+ return space.wrap(ret)
+
def utime(space, w_path, w_tuple):
""" utime(path, (atime, mtime))
utime(path, None)
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -471,6 +471,17 @@
['python', '-c', 'raise(SystemExit(42))'])
assert ret == 42
+ if hasattr(__import__(os.name), "spawnve"):
+ def test_spawnve(self):
+ os = self.posix
+ import sys
+ print self.python
+ ret = os.spawnve(os.P_WAIT, self.python,
+ ['python', '-c',
+ "raise(SystemExit(int(__import__('os').environ['FOOBAR'])))"],
+ {'FOOBAR': '42'})
+ assert ret == 42
+
def test_popen(self):
os = self.posix
for i in range(5):
diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py
--- a/pypy/module/pypyjit/interp_jit.py
+++ b/pypy/module/pypyjit/interp_jit.py
@@ -6,6 +6,7 @@
from pypy.tool.pairtype import extendabletype
from pypy.rlib.rarithmetic import r_uint, intmask
from pypy.rlib.jit import JitDriver, hint, we_are_jitted, dont_look_inside
+from pypy.rlib import jit
from pypy.rlib.jit import current_trace_length, unroll_parameters
import pypy.interpreter.pyopcode # for side-effects
from pypy.interpreter.error import OperationError, operationerrfmt
@@ -200,18 +201,18 @@
if len(args_w) == 1:
text = space.str_w(args_w[0])
try:
- pypyjitdriver.set_user_param(text)
+ jit.set_user_param(None, text)
except ValueError:
raise OperationError(space.w_ValueError,
space.wrap("error in JIT parameters string"))
for key, w_value in kwds_w.items():
if key == 'enable_opts':
- pypyjitdriver.set_param('enable_opts', space.str_w(w_value))
+ jit.set_param(None, 'enable_opts', space.str_w(w_value))
else:
intval = space.int_w(w_value)
for name, _ in unroll_parameters:
if name == key and name != 'enable_opts':
- pypyjitdriver.set_param(name, intval)
+ jit.set_param(None, name, intval)
break
else:
raise operationerrfmt(space.w_TypeError,
diff --git a/pypy/module/pypyjit/test_pypy_c/model.py b/pypy/module/pypyjit/test_pypy_c/model.py
--- a/pypy/module/pypyjit/test_pypy_c/model.py
+++ b/pypy/module/pypyjit/test_pypy_c/model.py
@@ -285,6 +285,11 @@
guard_false(ticker_cond1, descr=...)
"""
src = src.replace('--EXC-TICK--', exc_ticker_check)
+ #
+ # ISINF is done as a macro; fix it here
+ r = re.compile('(\w+) = --ISINF--[(](\w+)[)]')
+ src = r.sub(r'\2\B999 = float_add(\2, ...)\n\1 = float_eq(\2\B999, \2)',
+ src)
return src
@classmethod
diff --git a/pypy/module/pypyjit/test_pypy_c/test_math.py b/pypy/module/pypyjit/test_pypy_c/test_math.py
--- a/pypy/module/pypyjit/test_pypy_c/test_math.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_math.py
@@ -1,3 +1,4 @@
+import py
from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
@@ -49,10 +50,7 @@
guard_true(i2, descr=...)
guard_not_invalidated(descr=...)
f1 = cast_int_to_float(i0)
- i3 = float_eq(f1, inf)
- i4 = float_eq(f1, -inf)
- i5 = int_or(i3, i4)
- i6 = int_is_true(i5)
+ i6 = --ISINF--(f1)
guard_false(i6, descr=...)
f2 = call(ConstClass(sin), f1, descr=<FloatCallDescr>)
f3 = call(ConstClass(cos), f1, descr=<FloatCallDescr>)
@@ -64,6 +62,7 @@
""")
def test_fmod(self):
+ py.test.skip("test relies on the old and broken ll_math_fmod")
def main(n):
import math
@@ -90,4 +89,4 @@
i6 = int_sub(i0, 1)
--TICK--
jump(..., descr=)
- """)
\ No newline at end of file
+ """)
diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py
--- a/pypy/module/select/test/test_select.py
+++ b/pypy/module/select/test/test_select.py
@@ -214,11 +214,15 @@
def test_poll(self):
import select
- class A(object):
- def __int__(self):
- return 3
-
- select.poll().poll(A()) # assert did not crash
+ readend, writeend = self.getpair()
+ try:
+ class A(object):
+ def __int__(self):
+ return readend.fileno()
+ select.poll().poll(A()) # assert did not crash
+ finally:
+ readend.close()
+ writeend.close()
class AppTestSelectWithPipes(_AppTestSelect):
"Use a pipe to get pairs of file descriptors"
diff --git a/pypy/module/signal/__init__.py b/pypy/module/signal/__init__.py
--- a/pypy/module/signal/__init__.py
+++ b/pypy/module/signal/__init__.py
@@ -20,7 +20,7 @@
interpleveldefs['pause'] = 'interp_signal.pause'
interpleveldefs['siginterrupt'] = 'interp_signal.siginterrupt'
- if hasattr(cpy_signal, 'setitimer'):
+ if os.name == 'posix':
interpleveldefs['setitimer'] = 'interp_signal.setitimer'
interpleveldefs['getitimer'] = 'interp_signal.getitimer'
for name in ['ITIMER_REAL', 'ITIMER_VIRTUAL', 'ITIMER_PROF']:
diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py
--- a/pypy/module/signal/test/test_signal.py
+++ b/pypy/module/signal/test/test_signal.py
@@ -1,4 +1,4 @@
-import os, py
+import os, py, sys
import signal as cpy_signal
from pypy.conftest import gettestobjspace
@@ -264,6 +264,10 @@
class AppTestItimer:
spaceconfig = dict(usemodules=['signal'])
+ def setup_class(cls):
+ if sys.platform == 'win32':
+ py.test.skip("Unix only")
+
def test_itimer_real(self):
import signal
diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py
--- a/pypy/module/sys/test/test_sysmodule.py
+++ b/pypy/module/sys/test/test_sysmodule.py
@@ -567,6 +567,11 @@
import time
import thread
+ # XXX workaround for now: to prevent deadlocks, call
+ # sys._current_frames() once before starting threads.
+ # This is an issue in non-translated versions only.
+ sys._current_frames()
+
thread_id = thread.get_ident()
def other_thread():
print "thread started"
diff --git a/pypy/module/test_lib_pypy/test_pwd.py b/pypy/module/test_lib_pypy/test_pwd.py
--- a/pypy/module/test_lib_pypy/test_pwd.py
+++ b/pypy/module/test_lib_pypy/test_pwd.py
@@ -1,7 +1,10 @@
+import py, sys
from pypy.conftest import gettestobjspace
class AppTestPwd:
def setup_class(cls):
+ if sys.platform == 'win32':
+ py.test.skip("Unix only")
cls.space = gettestobjspace(usemodules=('_ffi', '_rawffi'))
cls.space.appexec((), "(): import pwd")
diff --git a/pypy/objspace/flow/operation.py b/pypy/objspace/flow/operation.py
--- a/pypy/objspace/flow/operation.py
+++ b/pypy/objspace/flow/operation.py
@@ -11,7 +11,7 @@
from pypy.interpreter.baseobjspace import ObjSpace
from pypy.interpreter.error import OperationError
from pypy.tool.sourcetools import compile2
-from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift
+from pypy.rlib.rarithmetic import ovfcheck
from pypy.objspace.flow import model
@@ -144,7 +144,7 @@
return ovfcheck(x % y)
def lshift_ovf(x, y):
- return ovfcheck_lshift(x, y)
+ return ovfcheck(x << y)
# slicing: operator.{get,set,del}slice() don't support b=None or c=None
def do_getslice(a, b, c):
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -282,15 +282,12 @@
def str__Bytearray(space, w_bytearray):
return space.wrap(''.join(w_bytearray.data))
-def _convert_idx_params(space, w_self, w_start, w_stop):
- length = len(w_self.data)
+def str_count__Bytearray_Int_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
+ char = w_char.intval
+ bytearray = w_bytearray.data
+ length = len(bytearray)
start, stop = slicetype.unwrap_start_stop(
space, length, w_start, w_stop, False)
- return start, stop, length
-
-def str_count__Bytearray_Int_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
- char = w_char.intval
- start, stop, length = _convert_idx_params(space, w_bytearray, w_start, w_stop)
count = 0
for i in range(start, min(stop, length)):
c = w_bytearray.data[i]
diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py
--- a/pypy/objspace/std/bytearraytype.py
+++ b/pypy/objspace/std/bytearraytype.py
@@ -122,10 +122,11 @@
return -1
def descr_fromhex(space, w_type, w_hexstring):
- "bytearray.fromhex(string) -> bytearray\n\nCreate a bytearray object "
- "from a string of hexadecimal numbers.\nSpaces between two numbers are "
- "accepted.\nExample: bytearray.fromhex('B9 01EF') -> "
- "bytearray(b'\\xb9\\x01\\xef')."
+ "bytearray.fromhex(string) -> bytearray\n"
+ "\n"
+ "Create a bytearray object from a string of hexadecimal numbers.\n"
+ "Spaces between two numbers are accepted.\n"
+ "Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')."
hexstring = space.str_w(w_hexstring)
hexstring = hexstring.lower()
data = []
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -6,7 +6,7 @@
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.register_all import register_all
from pypy.rlib import jit
-from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift, LONG_BIT, r_uint
+from pypy.rlib.rarithmetic import ovfcheck, LONG_BIT, r_uint
from pypy.rlib.rbigint import rbigint
"""
@@ -16,7 +16,10 @@
something CPython does not do anymore.
"""
-class W_IntObject(W_Object):
+class W_AbstractIntObject(W_Object):
+ __slots__ = ()
+
+class W_IntObject(W_AbstractIntObject):
__slots__ = 'intval'
_immutable_fields_ = ['intval']
@@ -245,7 +248,7 @@
b = w_int2.intval
if r_uint(b) < LONG_BIT: # 0 <= b < LONG_BIT
try:
- c = ovfcheck_lshift(a, b)
+ c = ovfcheck(a << b)
except OverflowError:
raise FailedToImplementArgs(space.w_OverflowError,
space.wrap("integer left shift"))
diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py
--- a/pypy/objspace/std/iterobject.py
+++ b/pypy/objspace/std/iterobject.py
@@ -4,7 +4,10 @@
from pypy.objspace.std.register_all import register_all
-class W_AbstractSeqIterObject(W_Object):
+class W_AbstractIterObject(W_Object):
+ __slots__ = ()
+
+class W_AbstractSeqIterObject(W_AbstractIterObject):
from pypy.objspace.std.itertype import iter_typedef as typedef
def __init__(w_self, w_seq, index=0):
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -11,7 +11,10 @@
from pypy.rlib.listsort import make_timsort_class
from pypy.interpreter.argument import Signature
-class W_ListObject(W_Object):
+class W_AbstractListObject(W_Object):
+ __slots__ = ()
+
+class W_ListObject(W_AbstractListObject):
from pypy.objspace.std.listtype import list_typedef as typedef
def __init__(w_self, wrappeditems):
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -8,7 +8,10 @@
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.rlib.rbigint import rbigint, SHIFT
-class W_LongObject(W_Object):
+class W_AbstractLongObject(W_Object):
+ __slots__ = ()
+
+class W_LongObject(W_AbstractLongObject):
"""This is a wrapper of rbigint."""
from pypy.objspace.std.longtype import long_typedef as typedef
_immutable_fields_ = ['num']
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -83,12 +83,7 @@
if self.config.objspace.std.withtproxy:
transparent.setup(self)
- interplevel_classes = {}
- for type, classes in self.model.typeorder.iteritems():
- if len(classes) >= 3: # XXX what does this 3 mean??!
- # W_Root, AnyXxx and actual object
- interplevel_classes[self.gettypefor(type)] = classes[0][0]
- self._interplevel_classes = interplevel_classes
+ self.setup_isinstance_cache()
def get_builtin_types(self):
return self.builtin_types
@@ -592,6 +587,63 @@
def isinstance_w(space, w_inst, w_type):
return space._type_isinstance(w_inst, w_type)
+ def setup_isinstance_cache(self):
+ # This assumes that all classes in the stdobjspace implementing a
+ # particular app-level type are distinguished by a common base class.
+ # Alternatively, you can turn off the cache on specific classes,
+ # like e.g. proxyobject. It is just a bit less performant but
+ # should not have any bad effect.
+ from pypy.objspace.std.model import W_Root, W_Object
+ #
+ # Build a dict {class: w_typeobject-or-None}. The value None is used
+ # on classes that are known to be abstract base classes.
+ class2type = {}
+ class2type[W_Root] = None
+ class2type[W_Object] = None
+ for cls in self.model.typeorder.keys():
+ if getattr(cls, 'typedef', None) is None:
+ continue
+ if getattr(cls, 'ignore_for_isinstance_cache', False):
+ continue
+ w_type = self.gettypefor(cls)
+ w_oldtype = class2type.setdefault(cls, w_type)
+ assert w_oldtype is w_type
+ #
+ # Build the real dict {w_typeobject: class-or-base-class}. For every
+ # w_typeobject we look for the most precise common base class of all
+ # the registered classes. If no such class is found, we will find
+ # W_Object or W_Root, and complain. Then you must either add an
+ # artificial common base class, or disable caching on one of the
+ # two classes with ignore_for_isinstance_cache.
+ def getmro(cls):
+ while True:
+ yield cls
+ if cls is W_Root:
+ break
+ cls = cls.__bases__[0]
+ self._interplevel_classes = {}
+ for cls, w_type in class2type.items():
+ if w_type is None:
+ continue
+ if w_type not in self._interplevel_classes:
+ self._interplevel_classes[w_type] = cls
+ else:
+ cls1 = self._interplevel_classes[w_type]
+ mro1 = list(getmro(cls1))
+ for base in getmro(cls):
+ if base in mro1:
+ break
+ if base in class2type and class2type[base] is not w_type:
+ if class2type.get(base) is None:
+ msg = ("cannot find a common interp-level base class"
+ " between %r and %r" % (cls1, cls))
+ else:
+ msg = ("%s is a base class of both %r and %r" % (
+ class2type[base], cls1, cls))
+ raise AssertionError("%r: %s" % (w_type, msg))
+ class2type[base] = w_type
+ self._interplevel_classes[w_type] = base
+
@specialize.memo()
def _get_interplevel_cls(self, w_type):
if not hasattr(self, "_interplevel_classes"):
diff --git a/pypy/objspace/std/proxyobject.py b/pypy/objspace/std/proxyobject.py
--- a/pypy/objspace/std/proxyobject.py
+++ b/pypy/objspace/std/proxyobject.py
@@ -16,6 +16,8 @@
def transparent_class(name, BaseCls):
class W_Transparent(BaseCls):
+ ignore_for_isinstance_cache = True
+
def __init__(self, space, w_type, w_controller):
self.w_type = w_type
self.w_controller = w_controller
diff --git a/pypy/objspace/std/rangeobject.py b/pypy/objspace/std/rangeobject.py
--- a/pypy/objspace/std/rangeobject.py
+++ b/pypy/objspace/std/rangeobject.py
@@ -5,7 +5,7 @@
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.inttype import wrapint
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
-from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.listobject import W_AbstractListObject, W_ListObject
from pypy.objspace.std import listtype, iterobject, slicetype
from pypy.interpreter import gateway, baseobjspace
@@ -21,7 +21,7 @@
return (start - stop - step - 1)/-step
-class W_RangeListObject(W_Object):
+class W_RangeListObject(W_AbstractListObject):
typedef = listtype.list_typedef
def __init__(w_self, start, step, length):
diff --git a/pypy/objspace/std/ropeobject.py b/pypy/objspace/std/ropeobject.py
--- a/pypy/objspace/std/ropeobject.py
+++ b/pypy/objspace/std/ropeobject.py
@@ -6,7 +6,7 @@
from pypy.rlib.objectmodel import we_are_translated
from pypy.objspace.std.inttype import wrapint
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
-from pypy.objspace.std import slicetype
+from pypy.objspace.std import stringobject, slicetype, iterobject
from pypy.objspace.std.listobject import W_ListObject
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.tupleobject import W_TupleObject
@@ -19,7 +19,7 @@
str_format__String as str_format__Rope,
_upper, _lower, DEFAULT_NOOP_TABLE)
-class W_RopeObject(W_Object):
+class W_RopeObject(stringobject.W_AbstractStringObject):
from pypy.objspace.std.stringtype import str_typedef as typedef
_immutable_fields_ = ['_node']
@@ -59,7 +59,7 @@
registerimplementation(W_RopeObject)
-class W_RopeIterObject(W_Object):
+class W_RopeIterObject(iterobject.W_AbstractIterObject):
from pypy.objspace.std.itertype import iter_typedef as typedef
def __init__(w_self, w_rope, index=0):
diff --git a/pypy/objspace/std/ropeunicodeobject.py b/pypy/objspace/std/ropeunicodeobject.py
--- a/pypy/objspace/std/ropeunicodeobject.py
+++ b/pypy/objspace/std/ropeunicodeobject.py
@@ -9,7 +9,7 @@
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.rlib import rope
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
-from pypy.objspace.std import slicetype
+from pypy.objspace.std import unicodeobject, slicetype, iterobject
from pypy.objspace.std.tupleobject import W_TupleObject
from pypy.rlib.rarithmetic import intmask, ovfcheck
from pypy.module.unicodedata import unicodedb
@@ -76,7 +76,7 @@
return encode_object(space, w_unistr, encoding, errors)
-class W_RopeUnicodeObject(W_Object):
+class W_RopeUnicodeObject(unicodeobject.W_AbstractUnicodeObject):
from pypy.objspace.std.unicodetype import unicode_typedef as typedef
_immutable_fields_ = ['_node']
@@ -117,7 +117,7 @@
return rope.LiteralUnicodeNode(space.unicode_w(w_str))
-class W_RopeUnicodeIterObject(W_Object):
+class W_RopeUnicodeIterObject(iterobject.W_AbstractIterObject):
from pypy.objspace.std.itertype import iter_typedef as typedef
def __init__(w_self, w_rope, index=0):
diff --git a/pypy/objspace/std/smallintobject.py b/pypy/objspace/std/smallintobject.py
--- a/pypy/objspace/std/smallintobject.py
+++ b/pypy/objspace/std/smallintobject.py
@@ -6,7 +6,7 @@
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
from pypy.objspace.std.noneobject import W_NoneObject
-from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.intobject import W_AbstractIntObject, W_IntObject
from pypy.interpreter.error import OperationError
from pypy.rlib.objectmodel import UnboxedValue
from pypy.rlib.rbigint import rbigint
@@ -14,7 +14,7 @@
from pypy.tool.sourcetools import func_with_new_name
from pypy.objspace.std.inttype import wrapint
-class W_SmallIntObject(W_Object, UnboxedValue):
+class W_SmallIntObject(W_AbstractIntObject, UnboxedValue):
__slots__ = 'intval'
from pypy.objspace.std.inttype import int_typedef as typedef
diff --git a/pypy/objspace/std/smalllongobject.py b/pypy/objspace/std/smalllongobject.py
--- a/pypy/objspace/std/smalllongobject.py
+++ b/pypy/objspace/std/smalllongobject.py
@@ -9,7 +9,7 @@
from pypy.rlib.rarithmetic import r_longlong, r_int, r_uint
from pypy.rlib.rarithmetic import intmask, LONGLONG_BIT
from pypy.rlib.rbigint import rbigint
-from pypy.objspace.std.longobject import W_LongObject
+from pypy.objspace.std.longobject import W_AbstractLongObject, W_LongObject
from pypy.objspace.std.intobject import W_IntObject
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.interpreter.error import OperationError
@@ -17,7 +17,7 @@
LONGLONG_MIN = r_longlong((-1) << (LONGLONG_BIT-1))
-class W_SmallLongObject(W_Object):
+class W_SmallLongObject(W_AbstractLongObject):
from pypy.objspace.std.longtype import long_typedef as typedef
_immutable_fields_ = ['longlong']
diff --git a/pypy/objspace/std/smalltupleobject.py b/pypy/objspace/std/smalltupleobject.py
--- a/pypy/objspace/std/smalltupleobject.py
+++ b/pypy/objspace/std/smalltupleobject.py
@@ -9,9 +9,9 @@
from pypy.interpreter import gateway
from pypy.rlib.debug import make_sure_not_resized
from pypy.rlib.unroll import unrolling_iterable
-from pypy.objspace.std.tupleobject import W_TupleObject
+from pypy.objspace.std.tupleobject import W_AbstractTupleObject, W_TupleObject
-class W_SmallTupleObject(W_Object):
+class W_SmallTupleObject(W_AbstractTupleObject):
from pypy.objspace.std.tupletype import tuple_typedef as typedef
def tolist(self):
diff --git a/pypy/objspace/std/stdtypedef.py b/pypy/objspace/std/stdtypedef.py
--- a/pypy/objspace/std/stdtypedef.py
+++ b/pypy/objspace/std/stdtypedef.py
@@ -32,11 +32,14 @@
from pypy.objspace.std.objecttype import object_typedef
if b is object_typedef:
return True
- while a is not b:
- if a is None:
- return False
- a = a.base
- return True
+ if a is None:
+ return False
+ if a is b:
+ return True
+ for a1 in a.bases:
+ if issubtypedef(a1, b):
+ return True
+ return False
std_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict,
doc="dictionary for instance variables (if defined)")
@@ -75,8 +78,8 @@
if typedef is object_typedef:
bases_w = []
else:
- base = typedef.base or object_typedef
- bases_w = [space.gettypeobject(base)]
+ bases = typedef.bases or [object_typedef]
+ bases_w = [space.gettypeobject(base) for base in bases]
# wrap everything
dict_w = {}
diff --git a/pypy/objspace/std/strbufobject.py b/pypy/objspace/std/strbufobject.py
--- a/pypy/objspace/std/strbufobject.py
+++ b/pypy/objspace/std/strbufobject.py
@@ -1,11 +1,12 @@
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.stringobject import W_AbstractStringObject
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.unicodeobject import delegate_String2Unicode
from pypy.rlib.rstring import StringBuilder
from pypy.interpreter.buffer import Buffer
-class W_StringBufferObject(W_Object):
+class W_StringBufferObject(W_AbstractStringObject):
from pypy.objspace.std.stringtype import str_typedef as typedef
w_str = None
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -19,7 +19,10 @@
from pypy.objspace.std.formatting import mod_format
-class W_StringObject(W_Object):
+class W_AbstractStringObject(W_Object):
+ __slots__ = ()
+
+class W_StringObject(W_AbstractStringObject):
from pypy.objspace.std.stringtype import str_typedef as typedef
_immutable_fields_ = ['_value']
diff --git a/pypy/objspace/std/strjoinobject.py b/pypy/objspace/std/strjoinobject.py
--- a/pypy/objspace/std/strjoinobject.py
+++ b/pypy/objspace/std/strjoinobject.py
@@ -1,11 +1,12 @@
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.stringobject import W_AbstractStringObject
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.unicodeobject import delegate_String2Unicode
from pypy.objspace.std.stringtype import wrapstr
-class W_StringJoinObject(W_Object):
+class W_StringJoinObject(W_AbstractStringObject):
from pypy.objspace.std.stringtype import str_typedef as typedef
def __init__(w_self, joined_strs, until=-1):
diff --git a/pypy/objspace/std/strsliceobject.py b/pypy/objspace/std/strsliceobject.py
--- a/pypy/objspace/std/strsliceobject.py
+++ b/pypy/objspace/std/strsliceobject.py
@@ -1,6 +1,7 @@
from pypy.interpreter.error import OperationError
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.stringobject import W_AbstractStringObject
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.unicodeobject import delegate_String2Unicode
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
@@ -12,7 +13,7 @@
stringendswith, stringstartswith
-class W_StringSliceObject(W_Object):
+class W_StringSliceObject(W_AbstractStringObject):
from pypy.objspace.std.stringtype import str_typedef as typedef
def __init__(w_self, str, start, stop):
diff --git a/pypy/objspace/std/test/test_bytes.py b/pypy/objspace/std/test/test_bytearrayobject.py
rename from pypy/objspace/std/test/test_bytes.py
rename to pypy/objspace/std/test/test_bytearrayobject.py
diff --git a/pypy/objspace/std/test/test_sliceobject.py b/pypy/objspace/std/test/test_sliceobject.py
--- a/pypy/objspace/std/test/test_sliceobject.py
+++ b/pypy/objspace/std/test/test_sliceobject.py
@@ -1,3 +1,4 @@
+import sys
from pypy.objspace.std.sliceobject import normalize_simple_slice
@@ -56,8 +57,9 @@
sl = space.newslice(w(start), w(stop), w(step))
mystart, mystop, mystep, slicelength = sl.indices4(space, length)
assert len(range(length)[start:stop:step]) == slicelength
- assert slice(start, stop, step).indices(length) == (
- mystart, mystop, mystep)
+ if sys.version_info >= (2, 6): # doesn't work in 2.5
+ assert slice(start, stop, step).indices(length) == (
+ mystart, mystop, mystep)
class AppTest_SliceObject:
def test_new(self):
diff --git a/pypy/objspace/std/test/test_stdobjspace.py b/pypy/objspace/std/test/test_stdobjspace.py
--- a/pypy/objspace/std/test/test_stdobjspace.py
+++ b/pypy/objspace/std/test/test_stdobjspace.py
@@ -50,6 +50,8 @@
def test_fastpath_isinstance(self):
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.intobject import W_IntObject
+ from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
+ from pypy.objspace.std.iterobject import W_SeqIterObject
space = self.space
assert space._get_interplevel_cls(space.w_str) is W_StringObject
@@ -62,9 +64,13 @@
assert space.isinstance_w(X(), space.w_str)
+ w_sequenceiterator = space.gettypefor(W_SeqIterObject)
+ cls = space._get_interplevel_cls(w_sequenceiterator)
+ assert cls is W_AbstractSeqIterObject
+
def test_withstrbuf_fastpath_isinstance(self):
- from pypy.objspace.std.stringobject import W_StringObject
+ from pypy.objspace.std.stringobject import W_AbstractStringObject
- space = gettestobjspace(withstrbuf=True)
- assert space._get_interplevel_cls(space.w_str) is W_StringObject
-
+ space = gettestobjspace(withstrbuf=True)
+ cls = space._get_interplevel_cls(space.w_str)
+ assert cls is W_AbstractStringObject
diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -9,7 +9,10 @@
from pypy.interpreter import gateway
from pypy.rlib.debug import make_sure_not_resized
-class W_TupleObject(W_Object):
+class W_AbstractTupleObject(W_Object):
+ __slots__ = ()
+
+class W_TupleObject(W_AbstractTupleObject):
from pypy.objspace.std.tupletype import tuple_typedef as typedef
_immutable_fields_ = ['wrappeditems[*]']
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -19,7 +19,10 @@
from pypy.objspace.std.formatting import mod_format
from pypy.objspace.std.stringtype import stringstartswith, stringendswith
-class W_UnicodeObject(W_Object):
+class W_AbstractUnicodeObject(W_Object):
+ __slots__ = ()
+
+class W_UnicodeObject(W_AbstractUnicodeObject):
from pypy.objspace.std.unicodetype import unicode_typedef as typedef
_immutable_fields_ = ['_value']
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -210,26 +210,48 @@
elif sz == 8: return ffi_type_uint64
else: raise ValueError("unsupported type size for %r" % (TYPE,))
-TYPE_MAP = {
- rffi.DOUBLE : ffi_type_double,
- rffi.FLOAT : ffi_type_float,
- rffi.LONGDOUBLE : ffi_type_longdouble,
- rffi.UCHAR : ffi_type_uchar,
- rffi.CHAR : ffi_type_schar,
- rffi.SHORT : ffi_type_sshort,
- rffi.USHORT : ffi_type_ushort,
- rffi.UINT : ffi_type_uint,
- rffi.INT : ffi_type_sint,
+__int_type_map = [
+ (rffi.UCHAR, ffi_type_uchar),
+ (rffi.SIGNEDCHAR, ffi_type_schar),
+ (rffi.SHORT, ffi_type_sshort),
+ (rffi.USHORT, ffi_type_ushort),
+ (rffi.UINT, ffi_type_uint),
+ (rffi.INT, ffi_type_sint),
# xxx don't use ffi_type_slong and ffi_type_ulong - their meaning
# changes from a libffi version to another :-((
- rffi.ULONG : _unsigned_type_for(rffi.ULONG),
- rffi.LONG : _signed_type_for(rffi.LONG),
- rffi.ULONGLONG : _unsigned_type_for(rffi.ULONGLONG),
- rffi.LONGLONG : _signed_type_for(rffi.LONGLONG),
- lltype.Void : ffi_type_void,
- lltype.UniChar : _unsigned_type_for(lltype.UniChar),
- lltype.Bool : _unsigned_type_for(lltype.Bool),
- }
+ (rffi.ULONG, _unsigned_type_for(rffi.ULONG)),
+ (rffi.LONG, _signed_type_for(rffi.LONG)),
+ (rffi.ULONGLONG, _unsigned_type_for(rffi.ULONGLONG)),
+ (rffi.LONGLONG, _signed_type_for(rffi.LONGLONG)),
+ (lltype.UniChar, _unsigned_type_for(lltype.UniChar)),
+ (lltype.Bool, _unsigned_type_for(lltype.Bool)),
+ ]
+
+__float_type_map = [
+ (rffi.DOUBLE, ffi_type_double),
+ (rffi.FLOAT, ffi_type_float),
+ (rffi.LONGDOUBLE, ffi_type_longdouble),
+ ]
+
+__ptr_type_map = [
+ (rffi.VOIDP, ffi_type_pointer),
+ ]
+
+__type_map = __int_type_map + __float_type_map + [
+ (lltype.Void, ffi_type_void)
+ ]
+
+TYPE_MAP_INT = dict(__int_type_map)
+TYPE_MAP_FLOAT = dict(__float_type_map)
+TYPE_MAP = dict(__type_map)
+
+ffitype_map_int = unrolling_iterable(__int_type_map)
+ffitype_map_int_or_ptr = unrolling_iterable(__int_type_map + __ptr_type_map)
+ffitype_map_float = unrolling_iterable(__float_type_map)
+ffitype_map = unrolling_iterable(__type_map)
+
+del __int_type_map, __float_type_map, __ptr_type_map, __type_map
+
def external(name, args, result, **kwds):
return rffi.llexternal(name, args, result, compilation_info=eci, **kwds)
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -450,55 +450,6 @@
# special-cased by ExtRegistryEntry
pass
- def _set_param(self, name, value):
- # special-cased by ExtRegistryEntry
- # (internal, must receive a constant 'name')
- # if value is DEFAULT, sets the default value.
- assert name in PARAMETERS
-
- @specialize.arg(0, 1)
- def set_param(self, name, value):
- """Set one of the tunable JIT parameter."""
- self._set_param(name, value)
-
- @specialize.arg(0, 1)
- def set_param_to_default(self, name):
- """Reset one of the tunable JIT parameters to its default value."""
- self._set_param(name, DEFAULT)
-
- def set_user_param(self, text):
- """Set the tunable JIT parameters from a user-supplied string
- following the format 'param=value,param=value', or 'off' to
- disable the JIT. For programmatic setting of parameters, use
- directly JitDriver.set_param().
- """
- if text == 'off':
- self.set_param('threshold', -1)
- self.set_param('function_threshold', -1)
- return
- if text == 'default':
- for name1, _ in unroll_parameters:
- self.set_param_to_default(name1)
- return
- for s in text.split(','):
- s = s.strip(' ')
- parts = s.split('=')
- if len(parts) != 2:
- raise ValueError
- name = parts[0]
- value = parts[1]
- if name == 'enable_opts':
- self.set_param('enable_opts', value)
- else:
- for name1, _ in unroll_parameters:
- if name1 == name and name1 != 'enable_opts':
- try:
- self.set_param(name1, int(value))
- except ValueError:
- raise
- set_user_param._annspecialcase_ = 'specialize:arg(0)'
-
-
def on_compile(self, logger, looptoken, operations, type, *greenargs):
""" A hook called when loop is compiled. Overwrite
for your own jitdriver if you want to do something special, like
@@ -524,16 +475,61 @@
self.jit_merge_point = self.jit_merge_point
self.can_enter_jit = self.can_enter_jit
self.loop_header = self.loop_header
- self._set_param = self._set_param
-
class Entry(ExtEnterLeaveMarker):
_about_ = (self.jit_merge_point, self.can_enter_jit)
class Entry(ExtLoopHeader):
_about_ = self.loop_header
- class Entry(ExtSetParam):
- _about_ = self._set_param
+def _set_param(driver, name, value):
+ # special-cased by ExtRegistryEntry
+ # (internal, must receive a constant 'name')
+ # if value is DEFAULT, sets the default value.
+ assert name in PARAMETERS
+
+ at specialize.arg(0, 1)
+def set_param(driver, name, value):
+ """Set one of the tunable JIT parameter. Driver can be None, then all
+ drivers have this set """
+ _set_param(driver, name, value)
+
+ at specialize.arg(0, 1)
+def set_param_to_default(driver, name):
+ """Reset one of the tunable JIT parameters to its default value."""
+ _set_param(driver, name, DEFAULT)
+
+def set_user_param(driver, text):
+ """Set the tunable JIT parameters from a user-supplied string
+ following the format 'param=value,param=value', or 'off' to
+ disable the JIT. For programmatic setting of parameters, use
+ directly JitDriver.set_param().
+ """
+ if text == 'off':
+ set_param(driver, 'threshold', -1)
+ set_param(driver, 'function_threshold', -1)
+ return
+ if text == 'default':
+ for name1, _ in unroll_parameters:
+ set_param_to_default(driver, name1)
+ return
+ for s in text.split(','):
+ s = s.strip(' ')
+ parts = s.split('=')
+ if len(parts) != 2:
+ raise ValueError
+ name = parts[0]
+ value = parts[1]
+ if name == 'enable_opts':
+ set_param(driver, 'enable_opts', value)
+ else:
+ for name1, _ in unroll_parameters:
+ if name1 == name and name1 != 'enable_opts':
+ try:
+ set_param(driver, name1, int(value))
+ except ValueError:
+ raise
+set_user_param._annspecialcase_ = 'specialize:arg(0)'
+
# ____________________________________________________________
#
@@ -705,8 +701,9 @@
resulttype=lltype.Void)
class ExtSetParam(ExtRegistryEntry):
+ _about_ = _set_param
- def compute_result_annotation(self, s_name, s_value):
+ def compute_result_annotation(self, s_driver, s_name, s_value):
from pypy.annotation import model as annmodel
assert s_name.is_constant()
if not self.bookkeeper.immutablevalue(DEFAULT).contains(s_value):
@@ -722,21 +719,22 @@
from pypy.objspace.flow.model import Constant
hop.exception_cannot_occur()
- driver = self.instance.im_self
- name = hop.args_s[0].const
+ driver = hop.inputarg(lltype.Void, arg=0)
+ name = hop.args_s[1].const
if name == 'enable_opts':
repr = string_repr
else:
repr = lltype.Signed
- if (isinstance(hop.args_v[1], Constant) and
- hop.args_v[1].value is DEFAULT):
+ if (isinstance(hop.args_v[2], Constant) and
+ hop.args_v[2].value is DEFAULT):
value = PARAMETERS[name]
v_value = hop.inputconst(repr, value)
else:
- v_value = hop.inputarg(repr, arg=1)
+ v_value = hop.inputarg(repr, arg=2)
vlist = [hop.inputconst(lltype.Void, "set_param"),
- hop.inputconst(lltype.Void, driver),
+ driver,
hop.inputconst(lltype.Void, name),
v_value]
return hop.genop('jit_marker', vlist,
resulttype=lltype.Void)
+
diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -140,7 +140,7 @@
self.last.next = arg
self.last = arg
self.numargs += 1
-
+
class AbstractArg(object):
next = None
@@ -234,7 +234,7 @@
# It is important that there is no other operation in the middle, else
# the optimizer will fail to recognize the pattern and won't turn it
# into a fast CALL. Note that "arg = arg.next" is optimized away,
- # assuming that archain is completely virtual.
+ # assuming that argchain is completely virtual.
self = jit.promote(self)
if argchain.numargs != len(self.argtypes):
raise TypeError, 'Wrong number of arguments: %d expected, got %d' %\
@@ -410,3 +410,22 @@
def getaddressindll(self, name):
return dlsym(self.lib, name)
+
+ at jit.oopspec("libffi_array_getitem(ffitype, width, addr, index, offset)")
+def array_getitem(ffitype, width, addr, index, offset):
+ for TYPE, ffitype2 in clibffi.ffitype_map:
+ if ffitype is ffitype2:
+ addr = rffi.ptradd(addr, index * width)
+ addr = rffi.ptradd(addr, offset)
+ return rffi.cast(rffi.CArrayPtr(TYPE), addr)[0]
+ assert False
+
+ at jit.oopspec("libffi_array_setitem(ffitype, width, addr, index, offset, value)")
+def array_setitem(ffitype, width, addr, index, offset, value):
+ for TYPE, ffitype2 in clibffi.ffitype_map:
+ if ffitype is ffitype2:
+ addr = rffi.ptradd(addr, index * width)
+ addr = rffi.ptradd(addr, offset)
+ rffi.cast(rffi.CArrayPtr(TYPE), addr)[0] = value
+ return
+ assert False
\ No newline at end of file
diff --git a/pypy/rlib/listsort.py b/pypy/rlib/listsort.py
--- a/pypy/rlib/listsort.py
+++ b/pypy/rlib/listsort.py
@@ -1,4 +1,4 @@
-from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift
+from pypy.rlib.rarithmetic import ovfcheck
## ------------------------------------------------------------------------
@@ -136,7 +136,7 @@
if lower(a.list[p + ofs], key):
lastofs = ofs
try:
- ofs = ovfcheck_lshift(ofs, 1)
+ ofs = ovfcheck(ofs << 1)
except OverflowError:
ofs = maxofs
else:
@@ -161,7 +161,7 @@
# key <= a[hint - ofs]
lastofs = ofs
try:
- ofs = ovfcheck_lshift(ofs, 1)
+ ofs = ovfcheck(ofs << 1)
except OverflowError:
ofs = maxofs
else:
diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py
--- a/pypy/rlib/rarithmetic.py
+++ b/pypy/rlib/rarithmetic.py
@@ -12,9 +12,6 @@
back to a signed int value
ovfcheck check on CPython whether the result of a signed
integer operation did overflow
-ovfcheck_lshift
- << with oveflow checking
- catering to 2.3/2.4 differences about <<
ovfcheck_float_to_int
convert to an integer or raise OverflowError
r_longlong
@@ -111,18 +108,6 @@
raise OverflowError, "signed integer expression did overflow"
return r
-def _local_ovfcheck(r):
- # a copy of the above, because we cannot call ovfcheck
- # in a context where no primitiveoperator is involved.
- assert not isinstance(r, r_uint), "unexpected ovf check on unsigned"
- if isinstance(r, long):
- raise OverflowError, "signed integer expression did overflow"
- return r
-
-def ovfcheck_lshift(a, b):
- "NOT_RPYTHON"
- return _local_ovfcheck(int(long(a) << b))
-
# Strange things happening for float to int on 64 bit:
# int(float(i)) != i because of rounding issues.
# These are the minimum and maximum float value that can
diff --git a/pypy/rlib/rgc.py b/pypy/rlib/rgc.py
--- a/pypy/rlib/rgc.py
+++ b/pypy/rlib/rgc.py
@@ -216,8 +216,8 @@
func._gc_no_collect_ = True
return func
-def is_light_finalizer(func):
- func._is_light_finalizer_ = True
+def must_be_light_finalizer(func):
+ func._must_be_light_finalizer_ = True
return func
# ____________________________________________________________
diff --git a/pypy/rlib/test/test_libffi.py b/pypy/rlib/test/test_libffi.py
--- a/pypy/rlib/test/test_libffi.py
+++ b/pypy/rlib/test/test_libffi.py
@@ -1,11 +1,13 @@
+import sys
+
import py
-import sys
+
+from pypy.rlib.libffi import (CDLL, Func, get_libc_name, ArgChain, types,
+ IS_32_BIT, array_getitem, array_setitem)
+from pypy.rlib.rarithmetic import r_singlefloat, r_longlong, r_ulonglong
+from pypy.rlib.test.test_clibffi import BaseFfiTest, get_libm_name, make_struct_ffitype_e
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.rpython.lltypesystem.ll2ctypes import ALLOCATED
-from pypy.rlib.rarithmetic import r_singlefloat, r_longlong, r_ulonglong
-from pypy.rlib.test.test_clibffi import BaseFfiTest, get_libm_name, make_struct_ffitype_e
-from pypy.rlib.libffi import CDLL, Func, get_libc_name, ArgChain, types
-from pypy.rlib.libffi import IS_32_BIT
class TestLibffiMisc(BaseFfiTest):
@@ -52,6 +54,34 @@
del lib
assert not ALLOCATED
+ def test_array_fields(self):
+ POINT = lltype.Struct("POINT",
+ ("x", lltype.Float),
+ ("y", lltype.Float),
+ )
+ points = lltype.malloc(rffi.CArray(POINT), 2, flavor="raw")
+ points[0].x = 1.0
+ points[0].y = 2.0
+ points[1].x = 3.0
+ points[1].y = 4.0
+ points = rffi.cast(rffi.CArrayPtr(lltype.Char), points)
+ assert array_getitem(types.double, 16, points, 0, 0) == 1.0
+ assert array_getitem(types.double, 16, points, 0, 8) == 2.0
+ assert array_getitem(types.double, 16, points, 1, 0) == 3.0
+ assert array_getitem(types.double, 16, points, 1, 8) == 4.0
+
+ array_setitem(types.double, 16, points, 0, 0, 10.0)
+ array_setitem(types.double, 16, points, 0, 8, 20.0)
+ array_setitem(types.double, 16, points, 1, 0, 30.0)
+ array_setitem(types.double, 16, points, 1, 8, 40.0)
+
+ assert array_getitem(types.double, 16, points, 0, 0) == 10.0
+ assert array_getitem(types.double, 16, points, 0, 8) == 20.0
+ assert array_getitem(types.double, 16, points, 1, 0) == 30.0
+ assert array_getitem(types.double, 16, points, 1, 8) == 40.0
+
+ lltype.free(points, flavor="raw")
+
class TestLibffiCall(BaseFfiTest):
"""
Test various kind of calls through libffi.
@@ -109,7 +139,7 @@
This method is overridden by metainterp/test/test_fficall.py in
order to do the call in a loop and JIT it. The optional arguments are
used only by that overridden method.
-
+
"""
lib, name, argtypes, restype = funcspec
func = lib.getpointer(name, argtypes, restype)
@@ -132,7 +162,7 @@
return x - y;
}
"""
- libfoo = self.get_libfoo()
+ libfoo = self.get_libfoo()
func = (libfoo, 'diff_xy', [types.sint, types.slong], types.sint)
res = self.call(func, [50, 8], lltype.Signed)
assert res == 42
@@ -144,7 +174,7 @@
return (x + (int)y);
}
"""
- libfoo = self.get_libfoo()
+ libfoo = self.get_libfoo()
func = (libfoo, 'sum_xy', [types.sint, types.double], types.sint)
res = self.call(func, [38, 4.2], lltype.Signed, jitif=["floats"])
assert res == 42
@@ -179,6 +209,17 @@
res = self.call(func, [chr(20), 22], rffi.LONG)
assert res == 42
+ def test_char_args(self):
+ """
+ char sum_args(char a, char b) {
+ return a + b;
+ }
+ """
+ libfoo = self.get_libfoo()
+ func = (libfoo, 'sum_args', [types.schar, types.schar], types.schar)
+ res = self.call(func, [123, 43], rffi.CHAR)
+ assert res == chr(166)
+
def test_unsigned_short_args(self):
"""
unsigned short sum_xy_us(unsigned short x, unsigned short y)
@@ -238,7 +279,7 @@
};
struct pair my_static_pair = {10, 20};
-
+
long* get_pointer_to_b()
{
return &my_static_pair.b;
@@ -329,7 +370,7 @@
def test_wrong_number_of_arguments(self):
from pypy.rpython.llinterp import LLException
- libfoo = self.get_libfoo()
+ libfoo = self.get_libfoo()
func = (libfoo, 'sum_xy', [types.sint, types.double], types.sint)
glob = globals()
diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py
--- a/pypy/rpython/llinterp.py
+++ b/pypy/rpython/llinterp.py
@@ -1,6 +1,6 @@
from pypy.objspace.flow.model import FunctionGraph, Constant, Variable, c_last_exception
from pypy.rlib.rarithmetic import intmask, r_uint, ovfcheck, r_longlong
-from pypy.rlib.rarithmetic import r_ulonglong, ovfcheck_lshift
+from pypy.rlib.rarithmetic import r_ulonglong
from pypy.rpython.lltypesystem import lltype, llmemory, lloperation, llheap
from pypy.rpython.lltypesystem import rclass
from pypy.rpython.ootypesystem import ootype
@@ -1035,7 +1035,7 @@
assert isinstance(x, int)
assert isinstance(y, int)
try:
- return ovfcheck_lshift(x, y)
+ return ovfcheck(x << y)
except OverflowError:
self.make_llexception()
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
@@ -1163,10 +1163,14 @@
value = value.adr
if isinstance(value, llmemory.fakeaddress):
value = value.ptr or 0
+ if isinstance(value, r_singlefloat):
+ value = float(value)
TYPE1 = lltype.typeOf(value)
cvalue = lltype2ctypes(value)
cresulttype = get_ctypes_type(RESTYPE)
- if isinstance(TYPE1, lltype.Ptr):
+ if RESTYPE == TYPE1:
+ return value
+ elif isinstance(TYPE1, lltype.Ptr):
if isinstance(RESTYPE, lltype.Ptr):
# shortcut: ptr->ptr cast
cptr = ctypes.cast(cvalue, cresulttype)
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
@@ -1723,7 +1723,7 @@
class _subarray(_parentable): # only for direct_fieldptr()
# and direct_arrayitems()
_kind = "subarray"
- _cache = weakref.WeakKeyDictionary() # parentarray -> {subarrays}
+ _cache = {} # TYPE -> weak{ parentarray -> {subarrays} }
def __init__(self, TYPE, parent, baseoffset_or_fieldname):
_parentable.__init__(self, TYPE)
@@ -1781,10 +1781,15 @@
def _makeptr(parent, baseoffset_or_fieldname, solid=False):
try:
- cache = _subarray._cache.setdefault(parent, {})
+ d = _subarray._cache[parent._TYPE]
+ except KeyError:
+ d = _subarray._cache[parent._TYPE] = weakref.WeakKeyDictionary()
+ try:
+ cache = d.setdefault(parent, {})
except RuntimeError: # pointer comparison with a freed structure
_subarray._cleanup_cache()
- cache = _subarray._cache.setdefault(parent, {}) # try again
+ # try again
+ return _subarray._makeptr(parent, baseoffset_or_fieldname, solid)
try:
subarray = cache[baseoffset_or_fieldname]
except KeyError:
@@ -1805,14 +1810,18 @@
raise NotImplementedError('_subarray._getid()')
def _cleanup_cache():
- newcache = weakref.WeakKeyDictionary()
- for key, value in _subarray._cache.items():
- try:
- if not key._was_freed():
- newcache[key] = value
- except RuntimeError:
- pass # ignore "accessing subxxx, but already gc-ed parent"
- _subarray._cache = newcache
+ for T, d in _subarray._cache.items():
+ newcache = weakref.WeakKeyDictionary()
+ for key, value in d.items():
+ try:
+ if not key._was_freed():
+ newcache[key] = value
+ except RuntimeError:
+ pass # ignore "accessing subxxx, but already gc-ed parent"
+ if newcache:
+ _subarray._cache[T] = newcache
+ else:
+ del _subarray._cache[T]
_cleanup_cache = staticmethod(_cleanup_cache)
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
@@ -11,15 +11,17 @@
from pypy.translator.platform import platform
from pypy.rlib.rfloat import isfinite, isinf, isnan, INFINITY, NAN
+use_library_isinf_isnan = False
if sys.platform == "win32":
if platform.name == "msvc":
# When compiled with /O2 or /Oi (enable intrinsic functions)
# It's no more possible to take the address of some math functions.
# Ensure that the compiler chooses real functions instead.
eci = ExternalCompilationInfo(
- includes = ['math.h'],
+ includes = ['math.h', 'float.h'],
post_include_bits = ['#pragma function(floor)'],
)
+ use_library_isinf_isnan = True
else:
eci = ExternalCompilationInfo()
# Some math functions are C99 and not defined by the Microsoft compiler
@@ -108,18 +110,35 @@
#
# Custom implementations
+VERY_LARGE_FLOAT = 1.0
+while VERY_LARGE_FLOAT * 100.0 != INFINITY:
+ VERY_LARGE_FLOAT *= 64.0
+
+_lib_isnan = rffi.llexternal("_isnan", [lltype.Float], lltype.Signed,
+ compilation_info=eci)
+_lib_finite = rffi.llexternal("_finite", [lltype.Float], lltype.Signed,
+ compilation_info=eci)
+
def ll_math_isnan(y):
# By not calling into the external function the JIT can inline this.
# Floats are awesome.
+ if use_library_isinf_isnan and not jit.we_are_jitted():
+ return bool(_lib_isnan(y))
return y != y
def ll_math_isinf(y):
- # Use a bitwise OR so the JIT doesn't produce 2 different guards.
- return (y == INFINITY) | (y == -INFINITY)
+ if jit.we_are_jitted():
+ return (y + VERY_LARGE_FLOAT) == y
+ elif use_library_isinf_isnan:
+ return not _lib_finite(y) and not _lib_isnan(y)
+ else:
+ return y == INFINITY or y == -INFINITY
def ll_math_isfinite(y):
# Use a custom hack that is reasonably well-suited to the JIT.
# Floats are awesome (bis).
+ if use_library_isinf_isnan and not jit.we_are_jitted():
+ return bool(_lib_finite(y))
z = 0.0 * y
return z == z # i.e.: z is not a NaN
@@ -136,10 +155,12 @@
Windows, FreeBSD and alpha Tru64 are amongst platforms that don't
always follow C99.
"""
- if isnan(x) or isnan(y):
+ if isnan(x):
return NAN
- if isinf(y):
+ if not isfinite(y):
+ if isnan(y):
+ return NAN
if isinf(x):
if math_copysign(1.0, x) == 1.0:
# atan2(+-inf, +inf) == +-pi/4
@@ -168,7 +189,7 @@
def ll_math_frexp(x):
# deal with special cases directly, to sidestep platform differences
- if isnan(x) or isinf(x) or not x:
+ if not isfinite(x) or not x:
mantissa = x
exponent = 0
else:
@@ -185,7 +206,7 @@
INT_MIN = int(-2**31)
def ll_math_ldexp(x, exp):
- if x == 0.0 or isinf(x) or isnan(x):
+ if x == 0.0 or not isfinite(x):
return x # NaNs, zeros and infinities are returned unchanged
if exp > INT_MAX:
# overflow (64-bit platforms only)
@@ -209,10 +230,11 @@
def ll_math_modf(x):
# some platforms don't do the right thing for NaNs and
# infinities, so we take care of special cases directly.
- if isinf(x):
- return (math_copysign(0.0, x), x)
- elif isnan(x):
- return (x, x)
+ if not isfinite(x):
+ if isnan(x):
+ return (x, x)
+ else: # isinf(x)
+ return (math_copysign(0.0, x), x)
intpart_p = lltype.malloc(rffi.DOUBLEP.TO, 1, flavor='raw')
try:
fracpart = math_modf(x, intpart_p)
@@ -223,13 +245,21 @@
def ll_math_fmod(x, y):
- if isinf(x) and not isnan(y):
- raise ValueError("math domain error")
+ # fmod(x, +/-Inf) returns x for finite x.
+ if isinf(y) and isfinite(x):
+ return x
- if y == 0:
- raise ValueError("math domain error")
-
- return math_fmod(x, y)
+ _error_reset()
+ r = math_fmod(x, y)
+ errno = rposix.get_errno()
+ if isnan(r):
+ if isnan(x) or isnan(y):
+ errno = 0
+ else:
+ errno = EDOM
+ if errno:
+ _likely_raise(errno, r)
+ return r
def ll_math_hypot(x, y):
@@ -242,16 +272,17 @@
_error_reset()
r = math_hypot(x, y)
errno = rposix.get_errno()
- if isnan(r):
- if isnan(x) or isnan(y):
- errno = 0
- else:
- errno = EDOM
- elif isinf(r):
- if isinf(x) or isnan(x) or isinf(y) or isnan(y):
- errno = 0
- else:
- errno = ERANGE
+ if not isfinite(r):
+ if isnan(r):
+ if isnan(x) or isnan(y):
+ errno = 0
+ else:
+ errno = EDOM
+ else: # isinf(r)
+ if isfinite(x) and isfinite(y):
+ errno = ERANGE
+ else:
+ errno = 0
if errno:
_likely_raise(errno, r)
return r
@@ -261,30 +292,30 @@
# deal directly with IEEE specials, to cope with problems on various
# platforms whose semantics don't exactly match C99
- if isnan(x):
- if y == 0.0:
- return 1.0 # NaN**0 = 1
- return x
-
- elif isnan(y):
+ if isnan(y):
if x == 1.0:
return 1.0 # 1**Nan = 1
return y
- elif isinf(x):
- odd_y = not isinf(y) and math_fmod(math_fabs(y), 2.0) == 1.0
- if y > 0.0:
- if odd_y:
- return x
- return math_fabs(x)
- elif y == 0.0:
- return 1.0
- else: # y < 0.0
- if odd_y:
- return math_copysign(0.0, x)
- return 0.0
+ if not isfinite(x):
+ if isnan(x):
+ if y == 0.0:
+ return 1.0 # NaN**0 = 1
+ return x
+ else: # isinf(x)
+ odd_y = not isinf(y) and math_fmod(math_fabs(y), 2.0) == 1.0
+ if y > 0.0:
+ if odd_y:
+ return x
+ return math_fabs(x)
+ elif y == 0.0:
+ return 1.0
+ else: # y < 0.0
+ if odd_y:
+ return math_copysign(0.0, x)
+ return 0.0
- elif isinf(y):
+ if isinf(y):
if math_fabs(x) == 1.0:
return 1.0
elif y > 0.0 and math_fabs(x) > 1.0:
@@ -299,17 +330,18 @@
_error_reset()
r = math_pow(x, y)
errno = rposix.get_errno()
- if isnan(r):
- # a NaN result should arise only from (-ve)**(finite non-integer)
- errno = EDOM
- elif isinf(r):
- # an infinite result here arises either from:
- # (A) (+/-0.)**negative (-> divide-by-zero)
- # (B) overflow of x**y with x and y finite
- if x == 0.0:
+ if not isfinite(r):
+ if isnan(r):
+ # a NaN result should arise only from (-ve)**(finite non-integer)
errno = EDOM
- else:
- errno = ERANGE
+ else: # isinf(r)
+ # an infinite result here arises either from:
+ # (A) (+/-0.)**negative (-> divide-by-zero)
+ # (B) overflow of x**y with x and y finite
+ if x == 0.0:
+ errno = EDOM
+ else:
+ errno = ERANGE
if errno:
_likely_raise(errno, r)
return r
@@ -358,18 +390,19 @@
r = c_func(x)
# Error checking fun. Copied from CPython 2.6
errno = rposix.get_errno()
- if isnan(r):
- if isnan(x):
- errno = 0
- else:
- errno = EDOM
- elif isinf(r):
- if isinf(x) or isnan(x):
- errno = 0
- elif can_overflow:
- errno = ERANGE
- else:
- errno = EDOM
+ if not isfinite(r):
+ if isnan(r):
+ if isnan(x):
+ errno = 0
+ else:
+ errno = EDOM
+ else: # isinf(r)
+ if not isfinite(x):
+ errno = 0
+ elif can_overflow:
+ errno = ERANGE
+ else:
+ errno = EDOM
if errno:
_likely_raise(errno, r)
return r
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
@@ -125,6 +125,7 @@
canraise=False,
random_effects_on_gcobjs=
random_effects_on_gcobjs,
+ calling_conv=calling_conv,
**kwds)
if isinstance(_callable, ll2ctypes.LL2CtypesCallable):
_callable.funcptr = funcptr
@@ -245,8 +246,14 @@
wrapper._always_inline_ = True
# for debugging, stick ll func ptr to that
wrapper._ptr = funcptr
+ wrapper = func_with_new_name(wrapper, name)
- return func_with_new_name(wrapper, name)
+ if calling_conv != "c":
+ from pypy.rlib.jit import dont_look_inside
+ wrapper = dont_look_inside(wrapper)
+
+ return wrapper
+
class CallbackHolder:
def __init__(self):
@@ -855,11 +862,14 @@
try:
unsigned = not tp._type.SIGNED
except AttributeError:
- if tp in [lltype.Char, lltype.Float, lltype.Signed] or\
- isinstance(tp, lltype.Ptr):
+ if not isinstance(tp, lltype.Primitive):
unsigned = False
+ elif tp in (lltype.Signed, FLOAT, DOUBLE, llmemory.Address):
+ unsigned = False
+ elif tp in (lltype.Char, lltype.UniChar, lltype.Bool):
+ unsigned = True
else:
- unsigned = False
+ raise AssertionError("size_and_sign(%r)" % (tp,))
return size, unsigned
def sizeof(tp):
diff --git a/pypy/rpython/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py
--- a/pypy/rpython/lltypesystem/rstr.py
+++ b/pypy/rpython/lltypesystem/rstr.py
@@ -331,6 +331,8 @@
# unlike CPython, there is no reason to avoid to return -1
# but our malloc initializes the memory to zero, so we use zero as the
# special non-computed-yet value.
+ if not s:
+ return 0
x = s.hash
if x == 0:
x = _hash_string(s.chars)
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
@@ -18,6 +18,7 @@
from pypy.conftest import option
from pypy.objspace.flow.model import summary
from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.rlib.rarithmetic import r_singlefloat
class BaseTestRffi:
def test_basic(self):
@@ -704,6 +705,14 @@
res = cast(lltype.Signed, 42.5)
assert res == 42
+ res = cast(lltype.SingleFloat, 12.3)
+ assert res == r_singlefloat(12.3)
+ res = cast(lltype.SingleFloat, res)
+ assert res == r_singlefloat(12.3)
+
+ res = cast(lltype.Float, r_singlefloat(12.))
+ assert res == 12.
+
def test_rffi_sizeof(self):
try:
import ctypes
@@ -733,9 +742,10 @@
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]
+ assert size_and_sign(lltype.Char) == (1, True)
+ assert size_and_sign(lltype.UniChar)[1]
assert size_and_sign(UINT)[1]
+ assert not size_and_sign(INT)[1]
def test_rffi_offsetof(self):
import struct
diff --git a/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py
--- a/pypy/rpython/module/ll_os.py
+++ b/pypy/rpython/module/ll_os.py
@@ -356,6 +356,32 @@
return extdef([int, str, [str]], int, llimpl=spawnv_llimpl,
export_name="ll_os.ll_os_spawnv")
+ @registering_if(os, 'spawnve')
+ def register_os_spawnve(self):
+ os_spawnve = self.llexternal('spawnve',
+ [rffi.INT, rffi.CCHARP, rffi.CCHARPP,
+ rffi.CCHARPP],
+ rffi.INT)
+
+ def spawnve_llimpl(mode, path, args, env):
+ envstrs = []
+ for item in env.iteritems():
+ envstrs.append("%s=%s" % item)
+
+ mode = rffi.cast(rffi.INT, mode)
+ l_args = rffi.liststr2charpp(args)
+ l_env = rffi.liststr2charpp(envstrs)
+ childpid = os_spawnve(mode, path, l_args, l_env)
+ rffi.free_charpp(l_env)
+ rffi.free_charpp(l_args)
+ if childpid == -1:
+ raise OSError(rposix.get_errno(), "os_spawnve failed")
+ return rffi.cast(lltype.Signed, childpid)
+
+ return extdef([int, str, [str], {str: str}], int,
+ llimpl=spawnve_llimpl,
+ export_name="ll_os.ll_os_spawnve")
+
@registering(os.dup)
def register_os_dup(self):
os_dup = self.llexternal(underscore_on_windows+'dup', [rffi.INT], rffi.INT)
diff --git a/pypy/rpython/ootypesystem/rstr.py b/pypy/rpython/ootypesystem/rstr.py
--- a/pypy/rpython/ootypesystem/rstr.py
+++ b/pypy/rpython/ootypesystem/rstr.py
@@ -116,6 +116,8 @@
return ootype.oounicode(ch, -1)
def ll_strhash(s):
+ if not s:
+ return 0
return s.ll_hash()
def ll_strfasthash(s):
diff --git a/pypy/rpython/test/test_rtuple.py b/pypy/rpython/test/test_rtuple.py
--- a/pypy/rpython/test/test_rtuple.py
+++ b/pypy/rpython/test/test_rtuple.py
@@ -180,6 +180,19 @@
res2 = self.interpret(f, [27, 12])
assert res1 != res2
+ def test_constant_tuple_hash_str(self):
+ from pypy.rlib.objectmodel import compute_hash
+ def f(i):
+ if i:
+ t = (None, "abc")
+ else:
+ t = ("abc", None)
+ return compute_hash(t)
+
+ res1 = self.interpret(f, [0])
+ res2 = self.interpret(f, [1])
+ assert res1 != res2
+
def test_tuple_to_list(self):
def f(i, j):
return list((i, j))
diff --git a/pypy/translator/backendopt/finalizer.py b/pypy/translator/backendopt/finalizer.py
--- a/pypy/translator/backendopt/finalizer.py
+++ b/pypy/translator/backendopt/finalizer.py
@@ -4,7 +4,7 @@
class FinalizerError(Exception):
""" __del__ marked as lightweight finalizer, but the analyzer did
- not agreed
+ not agree
"""
class FinalizerAnalyzer(graphanalyze.BoolGraphAnalyzer):
@@ -23,7 +23,7 @@
def analyze_light_finalizer(self, graph):
result = self.analyze_direct_call(graph)
if (result is self.top_result() and
- getattr(graph.func, '_is_light_finalizer_', False)):
+ getattr(graph.func, '_must_be_light_finalizer_', False)):
raise FinalizerError(FinalizerError.__doc__, graph)
return result
diff --git a/pypy/translator/backendopt/test/test_finalizer.py b/pypy/translator/backendopt/test/test_finalizer.py
--- a/pypy/translator/backendopt/test/test_finalizer.py
+++ b/pypy/translator/backendopt/test/test_finalizer.py
@@ -126,13 +126,13 @@
r = self.analyze(f, [], A.__del__.im_func)
assert r
- def test_is_light_finalizer_decorator(self):
+ def test_must_be_light_finalizer_decorator(self):
S = lltype.GcStruct('S')
- @rgc.is_light_finalizer
+ @rgc.must_be_light_finalizer
def f():
lltype.malloc(S)
- @rgc.is_light_finalizer
+ @rgc.must_be_light_finalizer
def g():
pass
self.analyze(g, []) # did not explode
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -521,13 +521,13 @@
rules = [
('clean', '', 'rm -f $(OBJECTS) $(TARGET) $(GCMAPFILES) $(ASMFILES) *.gc?? ../module_cache/*.gc??'),
('clean_noprof', '', 'rm -f $(OBJECTS) $(TARGET) $(GCMAPFILES) $(ASMFILES)'),
- ('debug', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT" $(TARGET)'),
- ('debug_exc', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DDO_LOG_EXC" $(TARGET)'),
- ('debug_mem', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DTRIVIAL_MALLOC_DEBUG" $(TARGET)'),
+ ('debug', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT" debug_target'),
+ ('debug_exc', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DDO_LOG_EXC" debug_target'),
+ ('debug_mem', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DTRIVIAL_MALLOC_DEBUG" debug_target'),
('no_obmalloc', '', '$(MAKE) CFLAGS="-g -O2 -DRPY_ASSERT -DNO_OBMALLOC" $(TARGET)'),
- ('linuxmemchk', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DLINUXMEMCHK" $(TARGET)'),
+ ('linuxmemchk', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DLINUXMEMCHK" debug_target'),
('llsafer', '', '$(MAKE) CFLAGS="-O2 -DRPY_LL_ASSERT" $(TARGET)'),
- ('lldebug', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DRPY_LL_ASSERT" $(TARGET)'),
+ ('lldebug', '', '$(MAKE) CFLAGS="$(DEBUGFLAGS) -DRPY_ASSERT -DRPY_LL_ASSERT" debug_target'),
('profile', '', '$(MAKE) CFLAGS="-g -O1 -pg $(CFLAGS) -fno-omit-frame-pointer" LDFLAGS="-pg $(LDFLAGS)" $(TARGET)'),
]
if self.has_profopt():
@@ -554,7 +554,7 @@
mk.definition('ASMLBLFILES', lblsfiles)
mk.definition('GCMAPFILES', gcmapfiles)
if sys.platform == 'win32':
- mk.definition('DEBUGFLAGS', '/Zi')
+ mk.definition('DEBUGFLAGS', '/MD /Zi')
else:
mk.definition('DEBUGFLAGS', '-O2 -fomit-frame-pointer -g')
@@ -618,9 +618,13 @@
else:
if sys.platform == 'win32':
- mk.definition('DEBUGFLAGS', '/Zi')
+ mk.definition('DEBUGFLAGS', '/MD /Zi')
else:
mk.definition('DEBUGFLAGS', '-O1 -g')
+ if sys.platform == 'win32':
+ mk.rule('debug_target', 'debugmode_$(DEFAULT_TARGET)', 'rem')
+ else:
+ mk.rule('debug_target', '$(TARGET)', '#')
mk.write()
#self.translator.platform,
# ,
diff --git a/pypy/translator/c/test/test_extfunc.py b/pypy/translator/c/test/test_extfunc.py
--- a/pypy/translator/c/test/test_extfunc.py
+++ b/pypy/translator/c/test/test_extfunc.py
@@ -818,6 +818,24 @@
func()
assert open(filename).read() == "2"
+if hasattr(posix, 'spawnve'):
+ def test_spawnve():
+ filename = str(udir.join('test_spawnve.txt'))
+ progname = str(sys.executable)
+ scriptpath = udir.join('test_spawnve.py')
+ scriptpath.write('import os\n' +
+ 'f=open(%r,"w")\n' % filename +
+ 'f.write(os.environ["FOOBAR"])\n' +
+ 'f.close\n')
+ scriptname = str(scriptpath)
+ def does_stuff():
+ l = [progname, scriptname]
+ pid = os.spawnve(os.P_NOWAIT, progname, l, {'FOOBAR': '42'})
+ os.waitpid(pid, 0)
+ func = compile(does_stuff, [])
+ func()
+ assert open(filename).read() == "42"
+
def test_utime():
path = str(udir.ensure("test_utime.txt"))
from time import time, sleep
diff --git a/pypy/translator/cli/test/test_snippet.py b/pypy/translator/cli/test/test_snippet.py
--- a/pypy/translator/cli/test/test_snippet.py
+++ b/pypy/translator/cli/test/test_snippet.py
@@ -28,14 +28,14 @@
res = self.interpret(fn, [], backendopt=False)
def test_link_vars_overlapping(self):
- from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift
+ from pypy.rlib.rarithmetic import ovfcheck
def fn(maxofs):
lastofs = 0
ofs = 1
while ofs < maxofs:
lastofs = ofs
try:
- ofs = ovfcheck_lshift(ofs, 1)
+ ofs = ovfcheck(ofs << 1)
except OverflowError:
ofs = maxofs
else:
diff --git a/pypy/translator/platform/__init__.py b/pypy/translator/platform/__init__.py
--- a/pypy/translator/platform/__init__.py
+++ b/pypy/translator/platform/__init__.py
@@ -42,6 +42,8 @@
so_prefixes = ('',)
+ extra_libs = ()
+
def __init__(self, cc):
if self.__class__ is Platform:
raise TypeError("You should not instantiate Platform class directly")
@@ -102,6 +104,8 @@
bits = [self.__class__.__name__, 'cc=%r' % self.cc]
for varname in self.relevant_environ:
bits.append('%s=%r' % (varname, os.environ.get(varname)))
+ # adding sys.maxint to disambiguate windows
+ bits.append('%s=%r' % ('sys.maxint', sys.maxint))
return ' '.join(bits)
# some helpers which seem to be cross-platform enough
@@ -179,7 +183,8 @@
link_files = self._linkfiles(eci.link_files)
export_flags = self._exportsymbols_link_flags(eci)
return (library_dirs + list(self.link_flags) + export_flags +
- link_files + list(eci.link_extra) + libraries)
+ link_files + list(eci.link_extra) + libraries +
+ list(self.extra_libs))
def _exportsymbols_link_flags(self, eci, relto=None):
if eci.export_symbols:
@@ -238,10 +243,13 @@
else:
host_factory = Linux64
elif sys.platform == 'darwin':
- from pypy.translator.platform.darwin import Darwin_i386, Darwin_x86_64
+ from pypy.translator.platform.darwin import Darwin_i386, Darwin_x86_64, Darwin_PowerPC
import platform
- assert platform.machine() in ('i386', 'x86_64')
- if sys.maxint <= 2147483647:
+ assert platform.machine() in ('Power Macintosh', 'i386', 'x86_64')
+
+ if platform.machine() == 'Power Macintosh':
+ host_factory = Darwin_PowerPC
+ elif sys.maxint <= 2147483647:
host_factory = Darwin_i386
else:
host_factory = Darwin_x86_64
diff --git a/pypy/translator/platform/darwin.py b/pypy/translator/platform/darwin.py
--- a/pypy/translator/platform/darwin.py
+++ b/pypy/translator/platform/darwin.py
@@ -71,6 +71,11 @@
link_flags = ('-arch', 'i386')
cflags = ('-arch', 'i386', '-O3', '-fomit-frame-pointer')
+class Darwin_PowerPC(Darwin):#xxx fixme, mwp
+ name = "darwin_powerpc"
+ link_flags = ()
+ cflags = ('-O3', '-fomit-frame-pointer')
+
class Darwin_x86_64(Darwin):
name = "darwin_x86_64"
link_flags = ('-arch', 'x86_64')
diff --git a/pypy/translator/platform/linux.py b/pypy/translator/platform/linux.py
--- a/pypy/translator/platform/linux.py
+++ b/pypy/translator/platform/linux.py
@@ -6,7 +6,8 @@
class BaseLinux(BasePosix):
name = "linux"
- link_flags = ('-pthread', '-lrt')
+ link_flags = ('-pthread',)
+ extra_libs = ('-lrt',)
cflags = ('-O3', '-pthread', '-fomit-frame-pointer',
'-Wall', '-Wno-unused')
standalone_only = ()
diff --git a/pypy/translator/platform/posix.py b/pypy/translator/platform/posix.py
--- a/pypy/translator/platform/posix.py
+++ b/pypy/translator/platform/posix.py
@@ -140,7 +140,7 @@
('DEFAULT_TARGET', exe_name.basename),
('SOURCES', rel_cfiles),
('OBJECTS', rel_ofiles),
- ('LIBS', self._libs(eci.libraries)),
+ ('LIBS', self._libs(eci.libraries) + list(self.extra_libs)),
('LIBDIRS', self._libdirs(rel_libdirs)),
('INCLUDEDIRS', self._includedirs(rel_includedirs)),
('CFLAGS', cflags),
diff --git a/pypy/translator/platform/test/test_darwin.py b/pypy/translator/platform/test/test_darwin.py
--- a/pypy/translator/platform/test/test_darwin.py
+++ b/pypy/translator/platform/test/test_darwin.py
@@ -7,7 +7,7 @@
py.test.skip("Darwin only")
from pypy.tool.udir import udir
-from pypy.translator.platform.darwin import Darwin_i386, Darwin_x86_64
+from pypy.translator.platform.darwin import Darwin_i386, Darwin_x86_64, Darwin_PowerPC
from pypy.translator.platform.test.test_platform import TestPlatform as BasicTest
from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -17,7 +17,7 @@
else:
host_factory = Darwin_x86_64
else:
- host_factory = Darwin
+ host_factory = Darwin_PowerPC
class TestDarwin(BasicTest):
platform = host_factory()
diff --git a/pypy/translator/platform/test/test_posix.py b/pypy/translator/platform/test/test_posix.py
--- a/pypy/translator/platform/test/test_posix.py
+++ b/pypy/translator/platform/test/test_posix.py
@@ -41,6 +41,7 @@
if self.strict_on_stderr:
assert res.err == ''
assert res.returncode == 0
+ assert '-lrt' in tmpdir.join("Makefile").read()
def test_link_files(self):
tmpdir = udir.join('link_files' + self.__class__.__name__).ensure(dir=1)
diff --git a/pypy/translator/platform/windows.py b/pypy/translator/platform/windows.py
--- a/pypy/translator/platform/windows.py
+++ b/pypy/translator/platform/windows.py
@@ -294,6 +294,9 @@
['$(CC_LINK) /nologo $(LDFLAGS) $(LDFLAGSEXTRA) $(OBJECTS) $(LINKFILES) /out:$@ $(LIBDIRS) $(LIBS) /MANIFEST /MANIFESTFILE:$*.manifest',
'mt.exe -nologo -manifest $*.manifest -outputresource:$@;1',
])
+ m.rule('debugmode_$(TARGET)', '$(OBJECTS)',
+ ['$(CC_LINK) /nologo /DEBUG $(LDFLAGS) $(LDFLAGSEXTRA) $(OBJECTS) $(LINKFILES) /out:$@ $(LIBDIRS) $(LIBS)',
+ ])
if shared:
m.definition('SHARED_IMPORT_LIB', so_name.new(ext='lib').basename)
@@ -307,6 +310,9 @@
['$(CC_LINK) /nologo main.obj $(SHARED_IMPORT_LIB) /out:$@ /MANIFEST /MANIFESTFILE:$*.manifest',
'mt.exe -nologo -manifest $*.manifest -outputresource:$@;1',
])
+ m.rule('debugmode_$(DEFAULT_TARGET)', ['debugmode_$(TARGET)', 'main.obj'],
+ ['$(CC_LINK) /nologo /DEBUG main.obj $(SHARED_IMPORT_LIB) /out:$@'
+ ])
return m
diff --git a/pypy/translator/simplify.py b/pypy/translator/simplify.py
--- a/pypy/translator/simplify.py
+++ b/pypy/translator/simplify.py
@@ -111,16 +111,13 @@
# the while loop above will simplify recursively the new link
def transform_ovfcheck(graph):
- """The special function calls ovfcheck and ovfcheck_lshift need to
+ """The special function calls ovfcheck needs to
be translated into primitive operations. ovfcheck is called directly
after an operation that should be turned into an overflow-checked
version. It is considered a syntax error if the resulting <op>_ovf
is not defined in objspace/flow/objspace.py.
- ovfcheck_lshift is special because there is no preceding operation.
- Instead, it will be replaced by an OP_LSHIFT_OVF operation.
"""
covf = Constant(rarithmetic.ovfcheck)
- covfls = Constant(rarithmetic.ovfcheck_lshift)
def check_syntax(opname):
exlis = operation.implicit_exceptions.get("%s_ovf" % (opname,), [])
@@ -154,9 +151,6 @@
op1.opname += '_ovf'
del block.operations[i]
block.renamevariables({op.result: op1.result})
- elif op.args[0] == covfls:
- op.opname = 'lshift_ovf'
- del op.args[0]
def simplify_exceptions(graph):
"""The exception handling caused by non-implicit exceptions
diff --git a/pypy/translator/test/snippet.py b/pypy/translator/test/snippet.py
--- a/pypy/translator/test/snippet.py
+++ b/pypy/translator/test/snippet.py
@@ -1210,7 +1210,7 @@
return istk.top(), sstk.top()
-from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift
+from pypy.rlib.rarithmetic import ovfcheck
def add_func(i=numtype):
try:
@@ -1253,7 +1253,7 @@
def lshift_func(i=numtype):
try:
hugo(2, 3, 5)
- return ovfcheck_lshift((-maxint-1), i)
+ return ovfcheck((-maxint-1) << i)
except (hugelmugel, OverflowError, StandardError, ValueError):
raise
diff --git a/pypy/translator/test/test_simplify.py b/pypy/translator/test/test_simplify.py
--- a/pypy/translator/test/test_simplify.py
+++ b/pypy/translator/test/test_simplify.py
@@ -42,24 +42,6 @@
assert graph.startblock.operations[0].opname == 'int_mul_ovf'
assert graph.startblock.operations[1].opname == 'int_sub'
-def test_remove_ovfcheck_lshift():
- # check that ovfcheck_lshift() is handled
- from pypy.rlib.rarithmetic import ovfcheck_lshift
- def f(x):
- try:
- return ovfcheck_lshift(x, 2)
- except OverflowError:
- return -42
- graph, _ = translate(f, [int])
- assert len(graph.startblock.operations) == 1
- assert graph.startblock.operations[0].opname == 'int_lshift_ovf'
- assert len(graph.startblock.operations[0].args) == 2
- assert len(graph.startblock.exits) == 2
- assert [link.exitcase for link in graph.startblock.exits] == \
- [None, OverflowError]
- assert [link.target.operations for link in graph.startblock.exits] == \
- [(), ()]
-
def test_remove_ovfcheck_floordiv():
# check that ovfcheck() is handled even if the operation raises
# and catches another exception too, here ZeroDivisionError
More information about the pypy-commit
mailing list