[pypy-commit] pypy stm-gc: hg merge default

arigo noreply at buildbot.pypy.org
Sat Apr 28 11:27:47 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r54783:cfdeabad2c3e
Date: 2012-04-28 10:08 +0200
http://bitbucket.org/pypy/pypy/changeset/cfdeabad2c3e/

Log:	hg merge default

diff --git a/lib-python/modified-2.7/test/test_peepholer.py b/lib-python/modified-2.7/test/test_peepholer.py
--- a/lib-python/modified-2.7/test/test_peepholer.py
+++ b/lib-python/modified-2.7/test/test_peepholer.py
@@ -145,12 +145,15 @@
 
     def test_binary_subscr_on_unicode(self):
         # valid code get optimized
-        asm = dis_single('u"foo"[0]')
-        self.assertIn("(u'f')", asm)
-        self.assertNotIn('BINARY_SUBSCR', asm)
-        asm = dis_single('u"\u0061\uffff"[1]')
-        self.assertIn("(u'\\uffff')", asm)
-        self.assertNotIn('BINARY_SUBSCR', asm)
+        # XXX for now we always disable this optimization
+        # XXX see CPython's issue5057
+        if 0:
+            asm = dis_single('u"foo"[0]')
+            self.assertIn("(u'f')", asm)
+            self.assertNotIn('BINARY_SUBSCR', asm)
+            asm = dis_single('u"\u0061\uffff"[1]')
+            self.assertIn("(u'\\uffff')", asm)
+            self.assertNotIn('BINARY_SUBSCR', asm)
 
         # invalid code doesn't get optimized
         # out of range
diff --git a/pypy/jit/backend/llsupport/asmmemmgr.py b/pypy/jit/backend/llsupport/asmmemmgr.py
--- a/pypy/jit/backend/llsupport/asmmemmgr.py
+++ b/pypy/jit/backend/llsupport/asmmemmgr.py
@@ -277,6 +277,8 @@
             from pypy.jit.backend.hlinfo import highleveljitinfo
             if highleveljitinfo.sys_executable:
                 debug_print('SYS_EXECUTABLE', highleveljitinfo.sys_executable)
+            else:
+                debug_print('SYS_EXECUTABLE', '??')
             #
             HEX = '0123456789ABCDEF'
             dump = []
diff --git a/pypy/rlib/rposix.py b/pypy/rlib/rposix.py
--- a/pypy/rlib/rposix.py
+++ b/pypy/rlib/rposix.py
@@ -1,9 +1,11 @@
 import os
-from pypy.rpython.lltypesystem.rffi import CConstant, CExternVariable, INT
+from pypy.rpython.lltypesystem.rffi import (CConstant, CExternVariable,
+        INT, CCHARPP)
 from pypy.rpython.lltypesystem import lltype, ll2ctypes, rffi
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.rlib.rarithmetic import intmask
 from pypy.rlib.objectmodel import specialize
+from pypy.rlib import jit
 
 class CConstantErrno(CConstant):
     # these accessors are used when calling get_errno() or set_errno()
@@ -18,9 +20,69 @@
     def __setitem__(self, index, value):
         assert index == 0
         ll2ctypes.TLS.errno = value
+if os.name == 'nt':
+    separate_module_sources =['''
+        /* Lifted completely from CPython 3.3 Modules/posix_module.c */
+        #include <malloc.h> /* for _msize */
+        typedef struct {
+            intptr_t osfhnd;
+            char osfile;
+        } my_ioinfo;
+        extern __declspec(dllimport) char * __pioinfo[];
+        #define IOINFO_L2E 5
+        #define IOINFO_ARRAY_ELTS   (1 << IOINFO_L2E)
+        #define IOINFO_ARRAYS 64
+        #define _NHANDLE_           (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
+        #define FOPEN 0x01
+        #define _NO_CONSOLE_FILENO (intptr_t)-2
 
+        /* This function emulates what the windows CRT
+            does to validate file handles */
+        int
+        _PyVerify_fd(int fd)
+        {
+            const int i1 = fd >> IOINFO_L2E;
+            const int i2 = fd & ((1 << IOINFO_L2E) - 1);
+
+            static size_t sizeof_ioinfo = 0;
+
+            /* Determine the actual size of the ioinfo structure,
+             * as used by the CRT loaded in memory
+             */
+            if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
+                sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
+            }
+            if (sizeof_ioinfo == 0) {
+                /* This should not happen... */
+                goto fail;
+            }
+
+            /* See that it isn't a special CLEAR fileno */
+                if (fd != _NO_CONSOLE_FILENO) {
+                /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that.  Instead
+                 * we check pointer validity and other info
+                 */
+                if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
+                    /* finally, check that the file is open */
+                    my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
+                    if (info->osfile & FOPEN) {
+                        return 1;
+                    }
+                }
+            }
+          fail:
+            errno = EBADF;
+            return 0;
+        }
+    ''',]
+    export_symbols = ['_PyVerify_fd']
+else:
+    separate_module_sources = []
+    export_symbols = []
 errno_eci = ExternalCompilationInfo(
-    includes=['errno.h']
+    includes=['errno.h','stdio.h'],
+    separate_module_sources = separate_module_sources,
+    export_symbols = export_symbols,
 )
 
 _get_errno, _set_errno = CExternVariable(INT, 'errno', errno_eci,
@@ -35,6 +97,21 @@
 def set_errno(errno):
     _set_errno(rffi.cast(INT, errno))
 
+if os.name == 'nt':
+    _validate_fd = rffi.llexternal(
+        "_PyVerify_fd", [rffi.INT], rffi.INT,
+        compilation_info=errno_eci,
+        )
+    @jit.dont_look_inside
+    def validate_fd(fd):
+        if not _validate_fd(fd):
+            raise OSError(get_errno(), 'Bad file descriptor')
+else:
+    def _validate_fd(fd):
+        return 1
+
+    def validate_fd(fd):
+        return 1
 
 def closerange(fd_low, fd_high):
     # this behaves like os.closerange() from Python 2.6.
diff --git a/pypy/rlib/test/test_rposix.py b/pypy/rlib/test/test_rposix.py
--- a/pypy/rlib/test/test_rposix.py
+++ b/pypy/rlib/test/test_rposix.py
@@ -131,3 +131,13 @@
                 os.rmdir(self.ufilename)
             except Exception:
                 pass
+
+    def test_validate_fd(self):
+        assert rposix._validate_fd(0) == 1
+        fid = open(str(udir.join('validate_test.txt')), 'w')
+        fd = fid.fileno()
+        assert rposix._validate_fd(fd) == 1
+        fid.close()
+        assert rposix._validate_fd(fd) == 0
+
+
diff --git a/pypy/rpython/annlowlevel.py b/pypy/rpython/annlowlevel.py
--- a/pypy/rpython/annlowlevel.py
+++ b/pypy/rpython/annlowlevel.py
@@ -488,6 +488,8 @@
     else:
         TO = PTR
     if not hasattr(object, '_carry_around_for_tests'):
+        if object is None:
+            return lltype.nullptr(PTR.TO)
         assert not hasattr(object, '_TYPE')
         object._carry_around_for_tests = True
         object._TYPE = TO
@@ -557,6 +559,8 @@
     """NOT_RPYTHON: hack. Reverse the hacking done in cast_object_to_ptr()."""
     if isinstance(lltype.typeOf(ptr), lltype.Ptr):
         ptr = ptr._as_obj()
+        if ptr is None:
+            return None
     if not isinstance(ptr, Class):
         raise NotImplementedError("cast_base_ptr_to_instance: casting %r to %r"
                                   % (ptr, Class))
diff --git a/pypy/rpython/test/test_llann.py b/pypy/rpython/test/test_llann.py
--- a/pypy/rpython/test/test_llann.py
+++ b/pypy/rpython/test/test_llann.py
@@ -9,6 +9,7 @@
 from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
 from pypy.rpython.annlowlevel import PseudoHighLevelCallable
 from pypy.rpython.annlowlevel import llhelper, cast_instance_to_base_ptr
+from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
 from pypy.rpython.annlowlevel import base_ptr_lltype
 from pypy.rpython.llinterp import LLInterpreter
 from pypy.rpython.test.test_llinterp import interpret
@@ -502,7 +503,10 @@
             self.y = y
 
     def f(x, y):
-        a = A(x, y)
+        if x > 20:
+            a = None
+        else:
+            a = A(x, y)
         a1 = cast_instance_to_base_ptr(a)
         return a1
 
@@ -510,3 +514,30 @@
     assert typeOf(res) == base_ptr_lltype()
     assert fishllattr(res, 'x') == 5
     assert fishllattr(res, 'y') == 10
+
+    res = interpret(f, [25, 10])
+    assert res == nullptr(base_ptr_lltype().TO)
+
+
+def test_cast_base_ptr_to_instance():
+    class A:
+        def __init__(self, x, y):
+            self.x = x
+            self.y = y
+
+    def f(x, y):
+        if x > 20:
+            a = None
+        else:
+            a = A(x, y)
+        a1 = cast_instance_to_base_ptr(a)
+        b = cast_base_ptr_to_instance(A, a1)
+        return a is b
+
+    assert f(5, 10) is True
+    assert f(25, 10) is True
+
+    res = interpret(f, [5, 10])
+    assert res is True
+    res = interpret(f, [25, 10])
+    assert res is True


More information about the pypy-commit mailing list