Commits

Philip Jenvey committed e1951a6 Merge

merge default

Comments (0)

Files changed (33)

lib-python/2.7/test/test_genericpath.py

         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):

pypy/doc/whatsnew-head.rst

 
 .. 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

pypy/module/_codecs/test/test_codecs.py

+import sys
+
 class AppTestCodecs:
     spaceconfig = {
         "usemodules": ['unicodedata', 'struct', 'binascii'],
 
 
 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
         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')

pypy/module/cpyext/pyerrors.py

     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),

pypy/module/cpyext/test/test_eval.py

             ("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);
              """),
             ])

pypy/module/cpyext/test/test_pyerrors.py

         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', [

pypy/module/micronumpy/ndarray.py

             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,
             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)
 
             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)

pypy/module/micronumpy/test/test_ndarray.py

         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"])

pypy/module/pypyjit/test_pypy_c/test_containers.py

             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)

pypy/module/pypyjit/test_pypy_c/test_instance.py

             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, _)
         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():

pypy/sandbox/test/test_pypy_interact.py

-import os, sys, stat, errno
+import os, stat, errno, py
 from pypy.sandbox.pypy_interact import PyPySandboxedProc
 from rpython.translator.interactive import Translation
 
 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

rpython/jit/backend/arm/opassembler.py

     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):

rpython/jit/backend/arm/regalloc.py

     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())

rpython/jit/backend/detect_cpu.py

 
 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():

rpython/jit/backend/llgraph/runner.py

 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
 
         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):
         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
 
             # 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

rpython/jit/backend/llsupport/test/test_rewrite.py

             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, \

rpython/jit/backend/x86/arch.py

 #
 #        +--------------------+    <== 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.
 # 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

rpython/jit/codewriter/effectinfo.py

                 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)
             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)

rpython/jit/codewriter/jtransform.py

     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])
 

rpython/jit/codewriter/test/test_flatten.py

     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_'):

rpython/jit/codewriter/test/test_longlong.py

 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):

rpython/jit/metainterp/history.py

         raise NotImplementedError
 
     def getaddr(self):
+        "Only for raw addresses (BoxInt & ConstInt), not for GC addresses"
         raise NotImplementedError
 
     def sort_key(self):
         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
         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)

rpython/jit/metainterp/logger.py

     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):
     """

rpython/jit/metainterp/optimizeopt/heap.py

         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 = []
             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:

rpython/jit/metainterp/optimizeopt/rewrite.py

             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)
         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)
 
         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)
 
                 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
         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.
     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):

rpython/jit/metainterp/optimizeopt/test/test_util.py

         def log_loop(*args):
             pass
 
+    class logger_ops:
+        repr_of_resop = repr
+
     class warmrunnerdesc:
         class memory_manager:
             retrace_limit = 5

rpython/jit/metainterp/optimizeopt/util.py

         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

rpython/jit/metainterp/test/test_ajit.py

 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:
         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):
         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

rpython/jit/metainterp/test/test_dict.py

         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

rpython/rlib/test/test_clibffi.py

     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

rpython/rlib/test/test_rposix.py

     def as_unicode(self):
         return self.unistr
 
-class BasePosixUnicode:
+class BasePosixUnicodeOrAscii:
     def setup_method(self, method):
         self.ufilename = self._get_filename()
         try:
             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():
     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():
 
         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:
         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"

rpython/rtyper/lltypesystem/ll2ctypes.py

 
     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:
                 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:

rpython/rtyper/lltypesystem/lltype.py

 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
         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))