Author: Matti Picus <[email protected]>
Branch: release-pypy2.7-v7.x
Changeset: r98328:c124c11a5921
Date: 2019-12-19 13:56 +0200
http://bitbucket.org/pypy/pypy/changeset/c124c11a5921/

Log:    merge default into release

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -59,3 +59,5 @@
 5da45ced70e515f94686be0df47c59abd1348ebc release-pypy3.6-v7.2.0
 e6471221abc16f4584a07fbfeece7ebcaeb7fc38 release-pypy2.7-v7.3.0rc1
 533398cfd64e5146a07c4824e90a1b629c8b6523 release-pypy3.6-v7.3.0rc1
+285307a0f5a77ffa46781b5c54c52eb1c385081d release-pypy2.7-v7.3.0rc2
+008914050baeedb6d3ca30fe26ef43b78bb63841 release-pypy3.6-v7.3.0rc2
diff --git a/lib-python/2.7/subprocess.py b/lib-python/2.7/subprocess.py
--- a/lib-python/2.7/subprocess.py
+++ b/lib-python/2.7/subprocess.py
@@ -1301,6 +1301,11 @@
             src_library = os.path.join(src_dir, libname)
             if os.path.exists(src_library):
                 caller.f_globals['copyfile'](src_library, dest_library)
+        src_lib = os.path.join(src_dir, '../lib')
+        if os.path.exists(src_lib):
+            # portable build
+            import shutil
+            shutil.copytree(src_lib, os.path.join(dest_dir, '../lib'))
 
 
 def _demo_posix():
diff --git a/lib_pypy/pyrepl/completing_reader.py 
b/lib_pypy/pyrepl/completing_reader.py
--- a/lib_pypy/pyrepl/completing_reader.py
+++ b/lib_pypy/pyrepl/completing_reader.py
@@ -266,7 +266,7 @@
     reader.ps1 = "c**> "
     reader.ps2 = "c/*> "
     reader.ps3 = "c|*> "
-    reader.ps4 = "c\*> "
+    reader.ps4 = r"c\*> "
     while reader.readline():
         pass
 
diff --git a/lib_pypy/pyrepl/reader.py b/lib_pypy/pyrepl/reader.py
--- a/lib_pypy/pyrepl/reader.py
+++ b/lib_pypy/pyrepl/reader.py
@@ -58,7 +58,7 @@
             return u[c]
         else:
             if unicodedata_.category(c).startswith('C'):
-                return '\u%04x'%(ord(c),)
+                return br'\u%04x'%(ord(c),)
             else:
                 return c
 
@@ -630,7 +630,7 @@
     reader.ps1 = "**> "
     reader.ps2 = "/*> "
     reader.ps3 = "|*> "
-    reader.ps4 = "\*> "
+    reader.ps4 = r"\*> "
     while reader.readline():
         pass
 
diff --git a/pypy/doc/release-v7.3.0.rst b/pypy/doc/release-v7.3.0.rst
--- a/pypy/doc/release-v7.3.0.rst
+++ b/pypy/doc/release-v7.3.0.rst
@@ -138,6 +138,10 @@
 * Overflow in RPython when converting ``2<<32`` into a ``Signed`` on 32-bit
   platforms rather than automatically using a ``SignedLongLong``, require an
   explicit ``r_int64()`` call instead
+* Fix multithread contention when creating an object in cffi (PyPy only)
+* Copy lib/* shared objects in portable builds when creating virtual
+  environments with virtualenv and venv
+* Potential fix in rare-case JIT optimizer (`issue 3128`_)
 
 C-API (cpyext) and c-extensions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -226,6 +230,7 @@
 .. _`issue 3117`: https://bitbucket.com/pypy/pypy/issues/3117
 .. _`issue 3119`: https://bitbucket.com/pypy/pypy/issues/3119
 .. _`issue 3120`: https://bitbucket.com/pypy/pypy/issues/3120
+.. _`issue 3128`: https://bitbucket.com/pypy/pypy/issues/3120
 
 .. _13312: https://bugs.python.org/issue13312
 .. _13617: https://bugs.python.org/issue13617
diff --git a/pypy/module/_cffi_backend/realize_c_type.py 
b/pypy/module/_cffi_backend/realize_c_type.py
--- a/pypy/module/_cffi_backend/realize_c_type.py
+++ b/pypy/module/_cffi_backend/realize_c_type.py
@@ -83,6 +83,8 @@
         self.space = space
         self.all_primitives = [None] * cffi_opcode._NUM_PRIM
         self.file_struct = None
+        self.lock = None
+        self.lock_owner = 0
         self.rec_level = 0
 
     def get_file_struct(self):
@@ -90,6 +92,33 @@
             self.file_struct = ctypestruct.W_CTypeStruct(self.space, "FILE")
         return self.file_struct
 
+    def __enter__(self):
+        # This is a simple recursive lock implementation
+        if self.space.config.objspace.usemodules.thread:
+            from rpython.rlib import rthread
+            #
+            tid = rthread.get_ident()
+            if tid != self.lock_owner:
+                if self.lock is None:
+                    self.lock = self.space.allocate_lock()
+                self.lock.acquire(True)
+                assert self.lock_owner == 0
+                assert self.rec_level == 0
+                self.lock_owner = tid
+        self.rec_level += 1
+
+    def __exit__(self, *args):
+        assert self.rec_level > 0
+        self.rec_level -= 1
+        if self.space.config.objspace.usemodules.thread:
+            from rpython.rlib import rthread
+            #
+            tid = rthread.get_ident()
+            assert tid == self.lock_owner
+            if self.rec_level == 0:
+                self.lock_owner = 0
+                self.lock.release()
+
 
 def get_primitive_type(ffi, num):
     space = ffi.space
@@ -408,21 +437,25 @@
         return ffi.cached_types[index]
 
     realize_cache = ffi.space.fromcache(RealizeCache)
-    if realize_cache.rec_level >= 1000:
-        raise oefmt(ffi.space.w_RuntimeError,
-            "type-building recursion too deep or infinite.  "
-            "This is known to occur e.g. in ``struct s { void(*callable)"
-            "(struct s); }''.  Please report if you get this error and "
-            "really need support for your case.")
-    realize_cache.rec_level += 1
-    try:
+    with realize_cache:
+        #
+        # check again cached_types, which might have been filled while
+        # we were waiting for the recursive lock
+        if from_ffi and ffi.cached_types[index] is not None:
+            return ffi.cached_types[index]
+
+        if realize_cache.rec_level > 1000:
+            raise oefmt(ffi.space.w_RuntimeError,
+                "type-building recursion too deep or infinite.  "
+                "This is known to occur e.g. in ``struct s { void(*callable)"
+                "(struct s); }''.  Please report if you get this error and "
+                "really need support for your case.")
         x = realize_c_type_or_func_now(ffi, op, opcodes, index)
-    finally:
-        realize_cache.rec_level -= 1
 
-    if from_ffi:
-        assert ffi.cached_types[index] is None or ffi.cached_types[index] is x
-        ffi.cached_types[index] = x
+        if from_ffi:
+            old = ffi.cached_types[index]
+            assert old is None or old is x
+            ffi.cached_types[index] = x
 
     return x
 
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py 
b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -683,7 +683,14 @@
                 elif constvalue == 1:
                     opnum = rop.GUARD_TRUE
                 else:
-                    raise AssertionError("uh?")
+                    # Issue #3128: there might be rare cases where strange
+                    # code is produced.  That issue hits the assert from
+                    # OptUnroll.inline_short_preamble's send_extra_operation().
+                    # Better just disable this optimization than crash with
+                    # an AssertionError here.  Note also that such code might
+                    # trigger an InvalidLoop to be raised later---so we must
+                    # not crash here.
+                    return op
                 newop = self.replace_op_with(op, opnum, [op.getarg(0)], descr)
                 return newop
         return op
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py 
b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -698,6 +698,15 @@
         """
         self.optimize_loop(ops, expected, preamble)
 
+    def test_guard_value_on_boolean_but_not_zero_or_one(self):
+        ops = """
+        [i]
+        i1 = int_lt(i, 3)
+        guard_value(i1, -1) [i]
+        jump(i)
+        """
+        py.test.raises(InvalidLoop, self.optimize_loop, ops, ops, ops)
+
     def test_int_is_true_of_bool(self):
         ops = """
         [i0, i1]
diff --git a/rpython/translator/c/test/test_standalone.py 
b/rpython/translator/c/test/test_standalone.py
--- a/rpython/translator/c/test/test_standalone.py
+++ b/rpython/translator/c/test/test_standalone.py
@@ -1146,6 +1146,33 @@
         out = cbuilder.cmdexec('')
         assert out.strip() == 'ok'
 
+    def test_int_manipulation(self):
+        # Distilled from micronumpy.descriptor._compute_hash
+        # which, for some version of gcc8 compiler produced
+        # out1 == out2
+        from rpython.rlib.rarithmetic import intmask
+        
+        def entry_point(argv):
+            if len(argv) < 4:
+                print 'need 3 arguments, not %s' % str(argv)
+                return -1
+            flags = 0
+            x = 0x345678
+            y = 0x345678
+            s = str(argv[1])[0]
+            y = intmask((1000003 * y) ^ ord(s))
+            y = intmask((1000003 * y) ^ ord(str(argv[2])[0]))
+            y = (1000003 * y)
+            y = intmask(y ^ flags)
+            y = intmask((1000003 * y) ^ int(argv[3]))
+            print y
+            return 0
+
+        t, cbuilder = self.compile(entry_point)
+        out1 = cbuilder.cmdexec(args=['i', '>', '64'])
+        out2 = cbuilder.cmdexec(args=['f', '>', '64'])
+        assert out1 != out2
+
 
 class TestThread(object):
     gcrootfinder = 'shadowstack'
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to