Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r70292:e1951a6821db
Date: 2014-03-25 16:53 -0700
http://bitbucket.org/pypy/pypy/changeset/e1951a6821db/
Log: merge default
diff --git a/lib-python/2.7/test/test_genericpath.py
b/lib-python/2.7/test/test_genericpath.py
--- a/lib-python/2.7/test/test_genericpath.py
+++ b/lib-python/2.7/test/test_genericpath.py
@@ -231,9 +231,14 @@
unicwd = u'\xe7w\xf0'
try:
fsencoding = test_support.TESTFN_ENCODING or "ascii"
- unicwd.encode(fsencoding)
+ asciival = unicwd.encode(fsencoding)
+ if fsencoding == "mbcs":
+ # http://bugs.python.org/issue850997
+ v = asciival.find('?')
+ if v >= 0:
+ raise UnicodeEncodeError(fsencoding, unicwd, v, v,
asciival)
except (AttributeError, UnicodeEncodeError):
- # FS encoding is probably ASCII
+ # FS encoding is probably ASCII or windows and codepage is
non-Latin1
pass
else:
with test_support.temp_cwd(unicwd):
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -117,3 +117,13 @@
.. branch: improve-consecutive-dict-lookups
Improve the situation when dict lookups of the same key are performed in a
chain
+
+.. branch: add_PyErr_SetFromErrnoWithFilenameObject_try_2
+.. branch: test_SetFromErrnoWithFilename_NULL
+.. branch: test_SetFromErrnoWithFilename__tweaks
+
+.. branch: refactor_PyErr_SetFromErrnoWithFilename
+Add support for PyErr_SetFromErrnoWithFilenameObject to cpyext
+
+.. branch: win32-fixes4
+fix more tests for win32
diff --git a/pypy/module/_codecs/test/test_codecs.py
b/pypy/module/_codecs/test/test_codecs.py
--- a/pypy/module/_codecs/test/test_codecs.py
+++ b/pypy/module/_codecs/test/test_codecs.py
@@ -1,3 +1,5 @@
+import sys
+
class AppTestCodecs:
spaceconfig = {
"usemodules": ['unicodedata', 'struct', 'binascii'],
@@ -138,7 +140,9 @@
class AppTestPartialEvaluation:
- spaceconfig = dict(usemodules=('array',))
+ spaceconfig = dict(usemodules=['array',])
+ if sys.platform == 'win32':
+ spaceconfig['usemodules'].append('_winreg')
def test_partial_utf8(self):
import _codecs
@@ -753,9 +757,25 @@
import sys
if sys.platform != 'win32':
return
- assert 'test'.encode('mbcs') == b'test'
- assert 'caf\xe9'.encode('mbcs') == b'caf\xe9'
- raises(UnicodeEncodeError, '\u040a'.encode, 'mbcs')
- raises(UnicodeEncodeError,
- "-\u5171\u0141\u2661\u0363\uDC80".encode, 'mbcs')
- assert b'cafx\e9'.decode('mbcs') == 'cafx\e9'
+ toencode = u'caf\xe9', b'caf\xe9'
+ try:
+ # test for non-latin1 codepage, more general test needed
+ import _winreg
+ key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
+ r'System\CurrentControlSet\Control\Nls\CodePage')
+ if _winreg.QueryValueEx(key, 'ACP')[0] == u'1255': # non-latin1
+ toencode = u'caf\xbf',b'caf\xbf'
+ except:
+ assert False, 'cannot test mbcs on this windows system, check code
page'
+ assert u'test'.encode('mbcs') == b'test'
+ assert toencode[0].encode('mbcs') == toencode[1]
+ assert u'\u040a'.encode('mbcs') == b'?' # some cyrillic letter
+ assert b'cafx\e9'.decode('mbcs') == u'cafx\e9'
+
+ def test_bad_handler_string_result(self):
+ import _codecs
+ def f(exc):
+ return (b'foo', exc.end)
+ _codecs.register_error("test.test_codecs_not_a_string", f)
+ raises(TypeError, u'\u1234'.encode, 'ascii',
+ 'test.test_codecs_not_a_string')
diff --git a/pypy/module/cpyext/pyerrors.py b/pypy/module/cpyext/pyerrors.py
--- a/pypy/module/cpyext/pyerrors.py
+++ b/pypy/module/cpyext/pyerrors.py
@@ -146,14 +146,29 @@
this is used to define the filename attribute of the exception instance.
Return value: always NULL."""
# XXX Doesn't actually do anything with PyErr_CheckSignals.
+ if llfilename:
+ w_filename = rffi.charp2str(llfilename)
+ filename = space.wrap(w_filename)
+ else:
+ filename = space.w_None
+
+ PyErr_SetFromErrnoWithFilenameObject(space, w_type, filename)
+
+@cpython_api([PyObject, PyObject], PyObject)
+def PyErr_SetFromErrnoWithFilenameObject(space, w_type, w_value):
+ """Similar to PyErr_SetFromErrno(), with the additional behavior that if
+ w_value is not NULL, it is passed to the constructor of type as a
+ third parameter. In the case of exceptions such as IOError and OSError,
+ this is used to define the filename attribute of the exception instance.
+ Return value: always NULL."""
+ # XXX Doesn't actually do anything with PyErr_CheckSignals.
errno = get_errno()
msg = os.strerror(errno)
- if llfilename:
- w_filename = rffi.charp2str(llfilename)
+ if w_value:
w_error = space.call_function(w_type,
space.wrap(errno),
space.wrap(msg),
- space.wrap(w_filename))
+ w_value)
else:
w_error = space.call_function(w_type,
space.wrap(errno),
diff --git a/pypy/module/cpyext/test/test_eval.py
b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -312,8 +312,9 @@
("get_flags", "METH_NOARGS",
"""
PyCompilerFlags flags;
+ int result;
flags.cf_flags = 0;
- int result = PyEval_MergeCompilerFlags(&flags);
+ result = PyEval_MergeCompilerFlags(&flags);
return Py_BuildValue("ii", result, flags.cf_flags);
"""),
])
diff --git a/pypy/module/cpyext/test/test_pyerrors.py
b/pypy/module/cpyext/test/test_pyerrors.py
--- a/pypy/module/cpyext/test/test_pyerrors.py
+++ b/pypy/module/cpyext/test/test_pyerrors.py
@@ -186,29 +186,136 @@
except OSError as e:
assert e.errno == errno.EBADF
assert e.strerror == os.strerror(errno.EBADF)
- assert e.filename == None
+ assert e.filename is None
def test_SetFromErrnoWithFilename(self):
- import sys
- if sys.platform != 'win32':
- skip("callbacks through ll2ctypes modify errno")
import errno, os
module = self.import_extension('foo', [
("set_from_errno", "METH_NOARGS",
'''
errno = EBADF;
- PyErr_SetFromErrnoWithFilename(PyExc_OSError, "blyf");
+ PyErr_SetFromErrnoWithFilename(PyExc_OSError,
"/path/to/file");
return NULL;
'''),
],
prologue="#include <errno.h>")
- try:
- module.set_from_errno()
- except OSError as e:
- assert e.filename == "blyf"
- assert e.errno == errno.EBADF
- assert e.strerror == os.strerror(errno.EBADF)
+ exc_info = raises(OSError, module.set_from_errno)
+ assert exc_info.value.filename == "/path/to/file"
+ assert exc_info.value.errno == errno.EBADF
+ assert exc_info.value.strerror == os.strerror(errno.EBADF)
+
+ def test_SetFromErrnoWithFilename_NULL(self):
+ import errno, os
+
+ module = self.import_extension('foo', [
+ ("set_from_errno", "METH_NOARGS",
+ '''
+ errno = EBADF;
+ PyErr_SetFromErrnoWithFilename(PyExc_OSError, NULL);
+ return NULL;
+ '''),
+ ],
+ prologue="#include <errno.h>")
+ exc_info = raises(OSError, module.set_from_errno)
+ assert exc_info.value.filename is None
+ assert exc_info.value.errno == errno.EBADF
+ assert exc_info.value.strerror == os.strerror(errno.EBADF)
+
+ def test_SetFromErrnoWithFilenameObject__PyString(self):
+ import errno, os
+
+ module = self.import_extension('foo', [
+ ("set_from_errno", "METH_NOARGS",
+ '''
+ errno = EBADF;
+ PyObject *filenameObject =
PyString_FromString("/path/to/file");
+ PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
filenameObject);
+ Py_DECREF(filenameObject);
+ return NULL;
+ '''),
+ ],
+ prologue="#include <errno.h>")
+ exc_info = raises(OSError, module.set_from_errno)
+ assert exc_info.value.filename == "/path/to/file"
+ assert exc_info.value.errno == errno.EBADF
+ assert exc_info.value.strerror == os.strerror(errno.EBADF)
+
+ def test_SetFromErrnoWithFilenameObject__PyInt(self):
+ import errno, os
+
+ module = self.import_extension('foo', [
+ ("set_from_errno", "METH_NOARGS",
+ '''
+ errno = EBADF;
+ PyObject *intObject = PyInt_FromLong(3);
+ PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
intObject);
+ Py_DECREF(intObject);
+ return NULL;
+ '''),
+ ],
+ prologue="#include <errno.h>")
+ exc_info = raises(OSError, module.set_from_errno)
+ assert exc_info.value.filename == 3
+ assert exc_info.value.errno == errno.EBADF
+ assert exc_info.value.strerror == os.strerror(errno.EBADF)
+
+ def test_SetFromErrnoWithFilenameObject__PyList(self):
+ import errno, os
+
+ module = self.import_extension('foo', [
+ ("set_from_errno", "METH_NOARGS",
+ '''
+ errno = EBADF;
+ PyObject *lst = Py_BuildValue("[iis]", 1, 2, "three");
+ PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, lst);
+ Py_DECREF(lst);
+ return NULL;
+ '''),
+ ],
+ prologue="#include <errno.h>")
+ exc_info = raises(OSError, module.set_from_errno)
+ assert exc_info.value.filename == [1, 2, "three"]
+ assert exc_info.value.errno == errno.EBADF
+ assert exc_info.value.strerror == os.strerror(errno.EBADF)
+
+ def test_SetFromErrnoWithFilenameObject__PyTuple(self):
+ import errno, os
+
+ module = self.import_extension('foo', [
+ ("set_from_errno", "METH_NOARGS",
+ '''
+ errno = EBADF;
+ PyObject *tuple = Py_BuildValue("(iis)", 1, 2, "three");
+ PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, tuple);
+ Py_DECREF(tuple);
+ return NULL;
+ '''),
+ ],
+ prologue="#include <errno.h>")
+ exc_info = raises(OSError, module.set_from_errno)
+ assert exc_info.value.filename == (1, 2, "three")
+ assert exc_info.value.errno == errno.EBADF
+ assert exc_info.value.strerror == os.strerror(errno.EBADF)
+
+ def test_SetFromErrnoWithFilenameObject__Py_None(self):
+ import errno, os
+
+ module = self.import_extension('foo', [
+ ("set_from_errno", "METH_NOARGS",
+ '''
+ errno = EBADF;
+ PyObject *none = Py_BuildValue("");
+ PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, none);
+ Py_DECREF(none);
+ return NULL;
+ '''),
+ ],
+ prologue="#include <errno.h>")
+ exc_info = raises(OSError, module.set_from_errno)
+ assert exc_info.value.filename is None
+ assert exc_info.value.errno == errno.EBADF
+ assert exc_info.value.strerror == os.strerror(errno.EBADF)
def test_PyErr_Display(self):
module = self.import_extension('foo', [
diff --git a/pypy/module/micronumpy/ndarray.py
b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -185,7 +185,7 @@
return chunks.apply(space, self)
shape = res_shape + self.get_shape()[len(indexes):]
w_res = W_NDimArray.from_shape(space, shape, self.get_dtype(),
- self.get_order(), w_instance=self)
+ self.get_order(), w_instance=self)
if not w_res.get_size():
return w_res
return loop.getitem_array_int(space, self, w_res, iter_shape, indexes,
@@ -201,6 +201,8 @@
view = chunks.apply(space, self)
view.implementation.setslice(space, val_arr)
return
+ if support.product(iter_shape) == 0:
+ return
loop.setitem_array_int(space, self, iter_shape, indexes, val_arr,
prefix)
@@ -1159,7 +1161,7 @@
raise OperationError(space.w_TypeError, space.wrap(
"numpy scalars from buffers not supported yet"))
totalsize = support.product(shape) * dtype.elsize
- if totalsize+offset > buf.getlength():
+ if totalsize + offset > buf.getlength():
raise OperationError(space.w_TypeError, space.wrap(
"buffer is too small for requested array"))
storage = rffi.cast(RAW_STORAGE_PTR, raw_ptr)
diff --git a/pypy/module/micronumpy/test/test_ndarray.py
b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -2360,6 +2360,19 @@
assert b.shape == b[...].shape
assert (b == b[...]).all()
+ def test_empty_indexing(self):
+ import numpy as np
+ r = np.ones(3)
+ ind = np.array([], np.int32)
+ tmp = np.array([], np.float64)
+ assert r[ind].shape == (0,)
+ r[ind] = 0
+ assert (r == np.ones(3)).all()
+ r[ind] = tmp
+ assert (r == np.ones(3)).all()
+ r[[]] = 0
+ assert (r == np.ones(3)).all()
+
class AppTestNumArrayFromBuffer(BaseNumpyAppTest):
spaceconfig = dict(usemodules=["micronumpy", "array", "mmap"])
diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py
b/pypy/module/pypyjit/test_pypy_c/test_containers.py
--- a/pypy/module/pypyjit/test_pypy_c/test_containers.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py
@@ -70,14 +70,14 @@
p13 = new(descr=...)
p15 = new_array(8, descr=<ArrayX .*>)
setfield_gc(p13, p15, descr=<FieldP dicttable.entries .*>)
- i17 = call(ConstClass(ll_dict_lookup_trampoline), p13, p10, i12,
descr=<Calli . rri EF=4>)
+ i17 = call(ConstClass(ll_dict_lookup_trampoline), p13, p10, i12,
descr=<Calli . rri EF=4 OS=4>)
setfield_gc(p13, 16, descr=<FieldS dicttable.resize_counter .*>)
guard_no_exception(descr=...)
p20 = new_with_vtable(ConstClass(W_IntObject))
call(ConstClass(_ll_dict_setitem_lookup_done_trampoline), p13,
p10, p20, i12, i17, descr=<Callv 0 rrrii EF=4>)
setfield_gc(p20, i5, descr=<FieldS .*W_IntObject.inst_intval .*>)
guard_no_exception(descr=...)
- i23 = call(ConstClass(ll_dict_lookup_trampoline), p13, p10, i12,
descr=<Calli . rri EF=4>)
+ i23 = call(ConstClass(ll_dict_lookup_trampoline), p13, p10, i12,
descr=<Calli . rri EF=4 OS=4>)
guard_no_exception(descr=...)
i26 = int_and(i23, .*)
i27 = int_is_true(i26)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_instance.py
b/pypy/module/pypyjit/test_pypy_c/test_instance.py
--- a/pypy/module/pypyjit/test_pypy_c/test_instance.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_instance.py
@@ -141,15 +141,16 @@
i = 0
b = B(1)
while i < 100:
- b.x
- v = b.x # ID: loadattr
+ v = b.x # ID: loadattr1
+ v = b.x # ID: loadattr2
i += v
return i
log = self.run(main, [], threshold=80)
loop, = log.loops_by_filename(self.filepath)
- assert loop.match_by_id('loadattr',
+ assert loop.match_by_id('loadattr1',
'''
+ guard_not_invalidated(descr=...)
i19 = call(ConstClass(ll_dict_lookup), _, _, _, descr=...)
guard_no_exception(descr=...)
i21 = int_and(i19, _)
@@ -161,6 +162,7 @@
i29 = int_is_true(i28)
guard_true(i29, descr=...)
''')
+ assert loop.match_by_id('loadattr2', "") # completely folded away
def test_python_contains(self):
def main():
diff --git a/pypy/sandbox/test/test_pypy_interact.py
b/pypy/sandbox/test/test_pypy_interact.py
--- a/pypy/sandbox/test/test_pypy_interact.py
+++ b/pypy/sandbox/test/test_pypy_interact.py
@@ -1,4 +1,4 @@
-import os, sys, stat, errno
+import os, stat, errno, py
from pypy.sandbox.pypy_interact import PyPySandboxedProc
from rpython.translator.interactive import Translation
@@ -9,6 +9,9 @@
SITE_PY_CONTENT = LIB_PYTHON.join('site.py').read()
ERROR_TEXT = os.strerror(errno.ENOENT)
+if os.name == 'nt':
+ py.test.skip('sandbox not supported on windows')
+
def assert_(cond, text):
if not cond:
print "assert failed:", text
diff --git a/rpython/jit/backend/arm/opassembler.py
b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -584,7 +584,10 @@
emit_op_getfield_gc_pure = emit_op_getfield_gc
def emit_op_increment_debug_counter(self, op, arglocs, regalloc, fcond):
- # XXX implement me
+ base_loc, value_loc = arglocs
+ self.mc.LDR_ri(value_loc.value, base_loc.value, 0, cond=fcond)
+ self.mc.ADD_ri(value_loc.value, value_loc.value, 1, cond=fcond)
+ self.mc.STR_ri(value_loc.value, base_loc.value, 0, cond=fcond)
return fcond
def emit_op_getinteriorfield_gc(self, op, arglocs, regalloc, fcond):
diff --git a/rpython/jit/backend/arm/regalloc.py
b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -850,8 +850,12 @@
prepare_op_getfield_gc_pure = prepare_op_getfield_gc
def prepare_op_increment_debug_counter(self, op, fcond):
- # XXX implement me
- return []
+ boxes = op.getarglist()
+ a0, = boxes
+ base_loc = self.make_sure_var_in_reg(a0, boxes)
+ value_loc = self.get_scratch_reg(INT, boxes)
+ self.free_temp_vars()
+ return [base_loc, value_loc]
def prepare_op_getinteriorfield_gc(self, op, fcond):
t = unpack_interiorfielddescr(op.getdescr())
diff --git a/rpython/jit/backend/detect_cpu.py
b/rpython/jit/backend/detect_cpu.py
--- a/rpython/jit/backend/detect_cpu.py
+++ b/rpython/jit/backend/detect_cpu.py
@@ -20,10 +20,11 @@
def detect_model_from_c_compiler():
# based on http://sourceforge.net/p/predef/wiki/Architectures/
+ # and http://msdn.microsoft.com/en-us/library/b0084kay.aspx
mapping = {
- MODEL_X86_64: ['__amd64__', '__amd64', '__x86_64__', '__x86_64'],
- MODEL_ARM: ['__arm__', '__thumb__'],
- MODEL_X86: ['i386', '__i386', '__i386__', '__i686__'],
+ MODEL_X86_64: ['__amd64__', '__amd64', '__x86_64__', '__x86_64',
'_M_X64', '_M_AMD64'],
+ MODEL_ARM: ['__arm__', '__thumb__','_M_ARM_EP'],
+ MODEL_X86: ['i386', '__i386', '__i386__', '__i686__','_M_IX86'],
MODEL_PPC_64: ['__powerpc64__'],
}
for k, v in mapping.iteritems():
diff --git a/rpython/jit/backend/llgraph/runner.py
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -13,6 +13,7 @@
from rpython.rtyper.llinterp import LLInterpreter, LLException
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rclass, rstr
+from rpython.rlib.clibffi import FFI_DEFAULT_ABI
from rpython.rlib.rarithmetic import ovfcheck, r_uint, r_ulonglong
from rpython.rlib.rtimer import read_timestamp
@@ -66,9 +67,10 @@
self.args = args
class CallDescr(AbstractDescr):
- def __init__(self, RESULT, ARGS, extrainfo):
+ def __init__(self, RESULT, ARGS, extrainfo, ABI=FFI_DEFAULT_ABI):
self.RESULT = RESULT
self.ARGS = ARGS
+ self.ABI = ABI
self.extrainfo = extrainfo
def __repr__(self):
@@ -428,7 +430,7 @@
try:
return self.descrs[key]
except KeyError:
- descr = CallDescr(RESULT, ARGS, extrainfo)
+ descr = CallDescr(RESULT, ARGS, extrainfo, ABI=cif_description.abi)
self.descrs[key] = descr
return descr
@@ -949,7 +951,7 @@
# graph, not to directly execute the python function
result = self.cpu.maybe_on_top_of_llinterp(func, call_args,
descr.RESULT)
else:
- FUNC = lltype.FuncType(descr.ARGS, descr.RESULT)
+ FUNC = lltype.FuncType(descr.ARGS, descr.RESULT, descr.ABI)
func_to_call = rffi.cast(lltype.Ptr(FUNC), func)
result = func_to_call(*call_args)
del self.force_guard_op
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py
b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -545,7 +545,7 @@
p1 = int_add(p0, %(strdescr.basesize + 16 * strdescr.itemsize)d)
setfield_gc(p1, %(unicodedescr.tid)d, descr=tiddescr)
setfield_gc(p1, 10, descr=unicodelendescr)
- p2 = call_malloc_nursery_varsize(2, 4, i2, \
+ p2 = call_malloc_nursery_varsize(2, %(unicodedescr.itemsize)d, i2,\
descr=unicodedescr)
setfield_gc(p2, i2, descr=unicodelendescr)
p3 = call_malloc_nursery_varsize(1, 1, i2, \
diff --git a/rpython/jit/backend/x86/arch.py b/rpython/jit/backend/x86/arch.py
--- a/rpython/jit/backend/x86/arch.py
+++ b/rpython/jit/backend/x86/arch.py
@@ -15,12 +15,12 @@
#
# +--------------------+ <== aligned to 16 bytes
# | return address |
-# +--------------------+
-# | saved regs |
-# +--------------------+
-# | scratch |
-# | space |
-# +--------------------+ <== aligned to 16 bytes
+# +--------------------+ ----------------------.
+# | saved regs | FRAME_FIXED_SIZE |
+# +--------------------+ --------------------. |
+# | scratch | PASS_ON_MY_FRAME | |
+# | space | | |
+# +--------------------+ <== aligned to 16 -----' ----'
# All the rest of the data is in a GC-managed variable-size "frame".
# This frame object's address is always stored in the register EBP/RBP.
@@ -30,14 +30,14 @@
# start of every frame: the saved value of some registers
if WORD == 4:
- # ebp + ebx + esi + edi + 14 extra words + return address = 19 words
+ # ebp + ebx + esi + edi + 15 extra words = 19 words
FRAME_FIXED_SIZE = 19
- PASS_ON_MY_FRAME = 14
+ PASS_ON_MY_FRAME = 15
JITFRAME_FIXED_SIZE = 6 + 8 * 2 # 6 GPR + 8 XMM * 2 WORDS/float
else:
- # rbp + rbx + r12 + r13 + r14 + r15 + 12 extra words + return address = 19
+ # rbp + rbx + r12 + r13 + r14 + r15 + 13 extra words = 19
FRAME_FIXED_SIZE = 19
- PASS_ON_MY_FRAME = 12
+ PASS_ON_MY_FRAME = 13
JITFRAME_FIXED_SIZE = 28 # 13 GPR + 15 XMM
assert PASS_ON_MY_FRAME >= 12 # asmgcc needs at least JIT_USE_WORDS + 3
diff --git a/rpython/jit/codewriter/effectinfo.py
b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -103,8 +103,10 @@
extradescrs=None):
key = (frozenset_or_none(readonly_descrs_fields),
frozenset_or_none(readonly_descrs_arrays),
+ frozenset_or_none(readonly_descrs_interiorfields),
frozenset_or_none(write_descrs_fields),
frozenset_or_none(write_descrs_arrays),
+ frozenset_or_none(write_descrs_interiorfields),
extraeffect,
oopspecindex,
can_invalidate)
@@ -222,6 +224,18 @@
descr = cpu.interiorfielddescrof(T, fieldname)
descrs_interiorfields.append(descr)
+ # a read or a write to an interiorfield, inside an array of
+ # structs, is additionally recorded as a read or write of
+ # the array itself
+ extraef = set()
+ for tup in effects:
+ if tup[0] == "interiorfield" or tup[0] == "readinteriorfield":
+ T = deref(tup[1])
+ if isinstance(T, lltype.Array) and consider_array(T):
+ extraef.add((tup[0].replace("interiorfield", "array"),
+ tup[1]))
+ effects |= extraef
+
for tup in effects:
if tup[0] == "struct":
add_struct(write_descrs_fields, tup)
diff --git a/rpython/jit/codewriter/jtransform.py
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -1854,8 +1854,7 @@
def _handle_dict_lookup_call(self, op, oopspec_name, args):
extradescr1 = self.cpu.fielddescrof(op.args[1].concretetype.TO,
'entries')
- extradescr2 = self.cpu.interiorfielddescrof(
- op.args[1].concretetype.TO.entries.TO, 'key')
+ extradescr2 =
self.cpu.arraydescrof(op.args[1].concretetype.TO.entries.TO)
return self._handle_oopspec_call(op, args, EffectInfo.OS_DICT_LOOKUP,
extradescr=[extradescr1, extradescr2])
diff --git a/rpython/jit/codewriter/test/test_flatten.py
b/rpython/jit/codewriter/test/test_flatten.py
--- a/rpython/jit/codewriter/test/test_flatten.py
+++ b/rpython/jit/codewriter/test/test_flatten.py
@@ -73,7 +73,7 @@
def guess_call_kind(self, op):
return 'residual'
def getcalldescr(self, op, oopspecindex=EffectInfo.OS_NONE,
- extraeffect=None):
+ extraeffect=None, extradescr=None):
try:
name = op.args[0].value._obj._name
if 'cannot_raise' in name or name.startswith('cast_'):
diff --git a/rpython/jit/codewriter/test/test_longlong.py
b/rpython/jit/codewriter/test/test_longlong.py
--- a/rpython/jit/codewriter/test/test_longlong.py
+++ b/rpython/jit/codewriter/test/test_longlong.py
@@ -17,7 +17,7 @@
class FakeBuiltinCallControl:
def guess_call_kind(self, op):
return 'builtin'
- def getcalldescr(self, op, oopspecindex=None, extraeffect=None):
+ def getcalldescr(self, op, oopspecindex=None, extraeffect=None,
extradescr=None):
assert oopspecindex is not None # in this test
return 'calldescr-%d' % oopspecindex
def calldescr_canraise(self, calldescr):
diff --git a/rpython/jit/metainterp/history.py
b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -108,6 +108,7 @@
raise NotImplementedError
def getaddr(self):
+ "Only for raw addresses (BoxInt & ConstInt), not for GC addresses"
raise NotImplementedError
def sort_key(self):
@@ -321,9 +322,6 @@
else:
return 0
- def getaddr(self):
- return llmemory.cast_ptr_to_adr(self.value)
-
def same_constant(self, other):
if isinstance(other, ConstPtr):
return self.value == other.value
@@ -494,9 +492,6 @@
return lltype.cast_opaque_ptr(PTR, self.getref_base())
getref._annspecialcase_ = 'specialize:arg(1)'
- def getaddr(self):
- return llmemory.cast_ptr_to_adr(self.value)
-
def _get_hash_(self):
if self.value:
return lltype.identityhash(self.value)
diff --git a/rpython/jit/metainterp/logger.py b/rpython/jit/metainterp/logger.py
--- a/rpython/jit/metainterp/logger.py
+++ b/rpython/jit/metainterp/logger.py
@@ -72,6 +72,9 @@
def _make_log_operations(self):
return LogOperations(self.metainterp_sd, self.guard_number)
+ def repr_of_resop(self, op):
+ return LogOperations(self.metainterp_sd,
self.guard_number).repr_of_resop(op)
+
class LogOperations(object):
"""
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py
b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -177,7 +177,7 @@
self.cached_arrayitems = {}
# cached dict items: {dict descr: {(optval, index): box-or-const}}
self.cached_dict_reads = {}
- # cache of corresponding array descrs
+ # cache of corresponding {array descrs: dict 'entries' field descr}
self.corresponding_array_descrs = {}
#
self._lazy_setfields_and_arrayitems = []
@@ -346,9 +346,8 @@
self.force_lazy_setfield(fielddescr, can_cache=False)
for arraydescr in effectinfo.write_descrs_arrays:
self.force_lazy_setarrayitem(arraydescr, can_cache=False)
- for descr in effectinfo.write_descrs_interiorfields:
- if descr in self.corresponding_array_descrs:
- dictdescr = self.corresponding_array_descrs.pop(descr)
+ if arraydescr in self.corresponding_array_descrs:
+ dictdescr = self.corresponding_array_descrs.pop(arraydescr)
try:
del self.cached_dict_reads[dictdescr]
except KeyError:
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py
b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -242,8 +242,9 @@
box = value.box
assert isinstance(box, Const)
if not box.same_constant(constbox):
- raise InvalidLoop('A GUARD_{VALUE,TRUE,FALSE} was proven to' +
- 'always fail')
+ r = self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
+ raise InvalidLoop('A GUARD_{VALUE,TRUE,FALSE} (%s) was proven '
+ 'to always fail' % r)
return
if emit_operation:
self.emit_operation(op)
@@ -255,7 +256,9 @@
if value.is_null():
return
elif value.is_nonnull():
- raise InvalidLoop('A GUARD_ISNULL was proven to always fail')
+ r = self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
+ raise InvalidLoop('A GUARD_ISNULL (%s) was proven to always fail'
+ % r)
self.emit_operation(op)
value.make_constant(self.optimizer.cpu.ts.CONST_NULL)
@@ -264,7 +267,9 @@
if value.is_nonnull():
return
elif value.is_null():
- raise InvalidLoop('A GUARD_NONNULL was proven to always fail')
+ r = self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
+ raise InvalidLoop('A GUARD_NONNULL (%s) was proven to always fail'
+ % r)
self.emit_operation(op)
value.make_nonnull(op)
@@ -292,7 +297,8 @@
assert previous_classbox is not None
assert expected_classbox is not None
if not previous_classbox.same_constant(expected_classbox):
- raise InvalidLoop('A GUARD_VALUE was proven to always
fail')
+ r =
self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
+ raise InvalidLoop('A GUARD_VALUE (%s) was proven to always
fail' % r)
op = old_guard_op.copy_and_change(rop.GUARD_VALUE,
args = [old_guard_op.getarg(0),
op.getarg(1)])
self.optimizer.replaces_guard[op] = old_guard_op
@@ -333,7 +339,9 @@
if realclassbox is not None:
if realclassbox.same_constant(expectedclassbox):
return
- raise InvalidLoop('A GUARD_CLASS was proven to always fail')
+ r = self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
+ raise InvalidLoop('A GUARD_CLASS (%s) was proven to always fail'
+ % r)
if value.last_guard:
# there already has been a guard_nonnull or guard_class or
# guard_nonnull_class on this value.
@@ -356,8 +364,9 @@
def optimize_GUARD_NONNULL_CLASS(self, op):
value = self.getvalue(op.getarg(0))
if value.is_null():
- raise InvalidLoop('A GUARD_NONNULL_CLASS was proven to always ' +
- 'fail')
+ r = self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
+ raise InvalidLoop('A GUARD_NONNULL_CLASS (%s) was proven to '
+ 'always fail' % r)
self.optimize_GUARD_CLASS(op)
def optimize_CALL_LOOPINVARIANT(self, op):
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py
b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -319,6 +319,9 @@
def log_loop(*args):
pass
+ class logger_ops:
+ repr_of_resop = repr
+
class warmrunnerdesc:
class memory_manager:
retrace_limit = 5
diff --git a/rpython/jit/metainterp/optimizeopt/util.py
b/rpython/jit/metainterp/optimizeopt/util.py
--- a/rpython/jit/metainterp/optimizeopt/util.py
+++ b/rpython/jit/metainterp/optimizeopt/util.py
@@ -139,7 +139,13 @@
txt1 = str(op1)
txt2 = str(op2)
while txt1 or txt2:
- print '%s| %s' % (txt1[:width].ljust(width), txt2[:width])
+ part1 = txt1[:width]
+ part2 = txt2[:width]
+ if part1 == part2:
+ sep = '| '
+ else:
+ sep = '<>'
+ print '%s%s%s' % (part1.ljust(width), sep, part2)
txt1 = txt1[width:]
txt2 = txt2[width:]
print '-' * totwidth
diff --git a/rpython/jit/metainterp/test/test_ajit.py
b/rpython/jit/metainterp/test/test_ajit.py
--- a/rpython/jit/metainterp/test/test_ajit.py
+++ b/rpython/jit/metainterp/test/test_ajit.py
@@ -14,6 +14,7 @@
from rpython.rlib.longlong2float import float2longlong, longlong2float
from rpython.rlib.rarithmetic import ovfcheck, is_valid_int
from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
class BasicTests:
@@ -3228,11 +3229,12 @@
self.check_resops(arraylen_gc=2)
def test_release_gil_flush_heap_cache(self):
+ eci = ExternalCompilationInfo()
if sys.platform == "win32":
- py.test.skip("needs 'time'")
+ eci = ExternalCompilationInfo(libraries=["msvcrt"])
T = rffi.CArrayPtr(rffi.TIME_T)
- external = rffi.llexternal("time", [T], rffi.TIME_T, releasegil=True)
+ external = rffi.llexternal("time", [T], rffi.TIME_T, releasegil=True,
compilation_info=eci)
# Not a real lock, has all the same properties with respect to GIL
# release though, so good for this test.
class Lock(object):
@@ -3920,10 +3922,13 @@
self.interp_operations(f, [])
def test_external_call(self):
+ eci = ExternalCompilationInfo()
+ if sys.platform == "win32":
+ eci = ExternalCompilationInfo(libraries=["msvcrt"])
from rpython.rlib.objectmodel import invoke_around_extcall
T = rffi.CArrayPtr(rffi.TIME_T)
- external = rffi.llexternal("time", [T], rffi.TIME_T)
+ external = rffi.llexternal("time", [T], rffi.TIME_T,
compilation_info=eci)
class Oups(Exception):
pass
diff --git a/rpython/jit/metainterp/test/test_dict.py
b/rpython/jit/metainterp/test/test_dict.py
--- a/rpython/jit/metainterp/test/test_dict.py
+++ b/rpython/jit/metainterp/test/test_dict.py
@@ -294,6 +294,54 @@
assert res == f(10)
self.check_simple_loop(call=3)
+ def test_dict_eq_can_release_gil(self):
+ from rpython.rtyper.lltypesystem import lltype, rffi
+ if type(self.newdict()) is not dict:
+ py.test.skip("this is an r_dict test")
+ T = rffi.CArrayPtr(rffi.TIME_T)
+ external = rffi.llexternal("time", [T], rffi.TIME_T, releasegil=True)
+ myjitdriver = JitDriver(greens = [], reds = ['total', 'dct'])
+ def key(x):
+ return x % 2
+ def eq(x, y):
+ external(lltype.nullptr(T.TO))
+ return (x % 2) == (y % 2)
+
+ def f(n):
+ dct = objectmodel.r_dict(eq, key)
+ total = n
+ x = 44444
+ y = 55555
+ z = 66666
+ while total:
+ myjitdriver.jit_merge_point(total=total, dct=dct)
+ dct[total] = total
+ x = dct[total]
+ y = dct[total]
+ z = dct[total]
+ total -= 1
+ return len(dct) + x + y + z
+
+ res = self.meta_interp(f, [10], listops=True)
+ assert res == 2 + 1 + 1 + 1
+ self.check_simple_loop(call_may_force=4, # ll_dict_lookup_trampoline
+ call=1) # ll_dict_setitem_lookup_done_trampoline
+
+ def test_bug42(self):
+ myjitdriver = JitDriver(greens = [], reds = 'auto')
+ def f(n):
+ mdict = {0: None, 1: None, 2: None, 3: None, 4: None,
+ 5: None, 6: None, 7: None, 8: None, 9: None}
+ while n > 0:
+ myjitdriver.jit_merge_point()
+ n -= 1
+ if n in mdict:
+ del mdict[n]
+ if n in mdict:
+ raise Exception
+ self.meta_interp(f, [10])
+ self.check_simple_loop(call_may_force=0, call=3)
+
class TestLLtype(DictTests, LLJitMixin):
pass
diff --git a/rpython/rlib/test/test_clibffi.py
b/rpython/rlib/test/test_clibffi.py
--- a/rpython/rlib/test/test_clibffi.py
+++ b/rpython/rlib/test/test_clibffi.py
@@ -423,11 +423,12 @@
def setup_class(cls):
if sys.platform != 'win32':
py.test.skip("Handle to libc library, Win-only test")
- BaseFfiTest.setup_class(cls)
+ BaseFfiTest.setup_class()
def test_get_libc_handle(self):
handle = get_libc_handle()
print get_libc_name()
- print hex(handle)
- assert handle != 0
- assert handle % 0x1000 == 0
+ print dir(handle)
+ addr = rffi.cast(rffi.INT, handle)
+ assert addr != 0
+ assert addr % 0x1000 == 0
diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -25,7 +25,7 @@
def as_unicode(self):
return self.unistr
-class BasePosixUnicode:
+class BasePosixUnicodeOrAscii:
def setup_method(self, method):
self.ufilename = self._get_filename()
try:
@@ -34,9 +34,12 @@
py.test.skip("encoding not good enough")
f.write("test")
f.close()
-
- self.path = UnicodeWithEncoding(self.ufilename)
- self.path2 = UnicodeWithEncoding(self.ufilename + ".new")
+ if sys.platform == 'win32' and isinstance(self.ufilename, str):
+ self.path = self.ufilename
+ self.path2 = self.ufilename + ".new"
+ else:
+ self.path = UnicodeWithEncoding(self.ufilename)
+ self.path2 = UnicodeWithEncoding(self.ufilename + ".new")
def test_open(self):
def f():
@@ -55,8 +58,11 @@
def test_stat(self):
def f():
return rposix.stat(self.path).st_mtime
-
- assert interpret(f, []) == os.stat(self.ufilename).st_mtime
+ if sys.platform == 'win32':
+ # double vs. float, be satisfied with sub-millisec resolution
+ assert abs(interpret(f, []) - os.stat(self.ufilename).st_mtime) <
1e-4
+ else:
+ assert interpret(f, []) == os.stat(self.ufilename).st_mtime
def test_access(self):
def f():
@@ -96,7 +102,11 @@
if sys.platform == 'win32':
def f():
- return u', '.join(rposix.listdir(udir))
+ if isinstance(udir.as_unicode(), str):
+ _udir = udir.as_unicode()
+ else:
+ _udir = udir
+ return u', '.join(rposix.listdir(_udir))
result = interpret(f, [])
assert os.path.basename(self.ufilename) in ll_to_string(result)
else:
@@ -149,11 +159,11 @@
interpret(f, []) # does not crash
-class TestPosixAscii(BasePosixUnicode):
+class TestPosixAscii(BasePosixUnicodeOrAscii):
def _get_filename(self):
return str(udir.join('test_open_ascii'))
-class TestPosixUnicode(BasePosixUnicode):
+class TestPosixUnicode(BasePosixUnicodeOrAscii):
def _get_filename(self):
return (unicode(udir.join('test_open')) +
u'\u65e5\u672c.txt') # "Japan"
diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py
b/rpython/rtyper/lltypesystem/ll2ctypes.py
--- a/rpython/rtyper/lltypesystem/ll2ctypes.py
+++ b/rpython/rtyper/lltypesystem/ll2ctypes.py
@@ -358,6 +358,12 @@
if isinstance(T, lltype.Ptr):
if isinstance(T.TO, lltype.FuncType):
+ functype = ctypes.CFUNCTYPE
+ if sys.platform == 'win32':
+ from rpython.rlib.clibffi import FFI_STDCALL, FFI_DEFAULT_ABI
+ if getattr(T.TO, 'ABI', FFI_DEFAULT_ABI) == FFI_STDCALL:
+ # for win32 system call
+ functype = ctypes.WINFUNCTYPE
argtypes = [get_ctypes_type(ARG) for ARG in T.TO.ARGS
if ARG is not lltype.Void]
if T.TO.RESULT is lltype.Void:
@@ -366,10 +372,10 @@
restype = get_ctypes_type(T.TO.RESULT)
try:
kwds = {'use_errno': True}
- return ctypes.CFUNCTYPE(restype, *argtypes, **kwds)
+ return functype(restype, *argtypes, **kwds)
except TypeError:
# unexpected 'use_errno' argument, old ctypes version
- return ctypes.CFUNCTYPE(restype, *argtypes)
+ return functype(restype, *argtypes)
elif isinstance(T.TO, lltype.OpaqueType):
return ctypes.c_void_p
else:
diff --git a/rpython/rtyper/lltypesystem/lltype.py
b/rpython/rtyper/lltypesystem/lltype.py
--- a/rpython/rtyper/lltypesystem/lltype.py
+++ b/rpython/rtyper/lltypesystem/lltype.py
@@ -537,7 +537,7 @@
class FuncType(ContainerType):
_gckind = 'raw'
__name__ = 'func'
- def __init__(self, args, result):
+ def __init__(self, args, result, abi='FFI_DEFAULT_ABI'):
for arg in args:
assert isinstance(arg, LowLevelType)
# There are external C functions eating raw structures, not
@@ -547,6 +547,7 @@
if isinstance(result, ContainerType):
raise TypeError, "function result can only be primitive or pointer"
self.RESULT = result
+ self.ABI = abi
def __str__(self):
args = ', '.join(map(str, self.ARGS))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit