Author: Carl Friedrich Bolz <[email protected]>
Branch: typed-cells
Changeset: r75650:2ac6556197f9
Date: 2015-02-02 16:30 +0100
http://bitbucket.org/pypy/pypy/changeset/2ac6556197f9/

Log:    merge default

diff --git a/lib-python/2.7/ctypes/test/test_frombuffer.py 
b/lib-python/2.7/ctypes/test/test_frombuffer.py
--- a/lib-python/2.7/ctypes/test/test_frombuffer.py
+++ b/lib-python/2.7/ctypes/test/test_frombuffer.py
@@ -2,7 +2,6 @@
 import array
 import gc
 import unittest
-from ctypes.test import xfail
 
 class X(Structure):
     _fields_ = [("c_int", c_int)]
@@ -11,7 +10,6 @@
         self._init_called = True
 
 class Test(unittest.TestCase):
-    @xfail
     def test_fom_buffer(self):
         a = array.array("i", range(16))
         x = (c_int * 16).from_buffer(a)
@@ -34,10 +32,9 @@
         del a; gc.collect(); gc.collect(); gc.collect()
         self.assertEqual(x[:], expected)
 
-        self.assertRaises(TypeError,
+        self.assertRaises((TypeError, ValueError),
                           (c_char * 16).from_buffer, "a" * 16)
 
-    @xfail
     def test_fom_buffer_with_offset(self):
         a = array.array("i", range(16))
         x = (c_int * 15).from_buffer(a, sizeof(c_int))
@@ -46,7 +43,6 @@
         self.assertRaises(ValueError, lambda: (c_int * 16).from_buffer(a, 
sizeof(c_int)))
         self.assertRaises(ValueError, lambda: (c_int * 1).from_buffer(a, 16 * 
sizeof(c_int)))
 
-    @xfail
     def test_from_buffer_copy(self):
         a = array.array("i", range(16))
         x = (c_int * 16).from_buffer_copy(a)
@@ -71,7 +67,6 @@
         x = (c_char * 16).from_buffer_copy("a" * 16)
         self.assertEqual(x[:], "a" * 16)
 
-    @xfail
     def test_fom_buffer_copy_with_offset(self):
         a = array.array("i", range(16))
         x = (c_int * 15).from_buffer_copy(a, sizeof(c_int))
diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -83,6 +83,37 @@
     def in_dll(self, dll, name):
         return self.from_address(dll._handle.getaddressindll(name))
 
+    def from_buffer(self, obj, offset=0):
+        size = self._sizeofinstances()
+        buf = buffer(obj, offset, size)
+        if len(buf) < size:
+            raise ValueError(
+                "Buffer size too small (%d instead of at least %d bytes)"
+                % (len(buf) + offset, size + offset))
+        raw_addr = buf._pypy_raw_address()
+        result = self.from_address(raw_addr)
+        result._ensure_objects()['ffffffff'] = obj
+        return result
+
+    def from_buffer_copy(self, obj, offset=0):
+        size = self._sizeofinstances()
+        buf = buffer(obj, offset, size)
+        if len(buf) < size:
+            raise ValueError(
+                "Buffer size too small (%d instead of at least %d bytes)"
+                % (len(buf) + offset, size + offset))
+        result = self()
+        dest = result._buffer.buffer
+        try:
+            raw_addr = buf._pypy_raw_address()
+        except ValueError:
+            _rawffi.rawstring2charp(dest, buf)
+        else:
+            from ctypes import memmove
+            memmove(dest, raw_addr, size)
+        return result
+
+
 class CArgObject(object):
     """ simple wrapper around buffer, just for the case of freeing
     it afterwards
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -1,3 +1,4 @@
+import sys
 import _rawffi
 from _ctypes.basics import _CData, _CDataMeta, keepalive_key,\
      store_reference, ensure_objects, CArgObject
@@ -178,6 +179,8 @@
         instance = StructOrUnion.__new__(self)
         if isinstance(address, _rawffi.StructureInstance):
             address = address.buffer
+        # fix the address: turn it into as unsigned, in case it is negative
+        address = address & (sys.maxint * 2 + 1)
         instance.__dict__['_buffer'] = self._ffistruct.fromaddress(address)
         return instance
 
diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst
--- a/pypy/doc/faq.rst
+++ b/pypy/doc/faq.rst
@@ -3,6 +3,13 @@
 
 .. contents::
 
+See also: `Frequently ask questions about RPython.`__
+
+.. __: http://rpython.readthedocs.org/en/latest/faq.html
+
+---------------------------
+
+
 What is PyPy?
 -------------
 
diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst
--- a/pypy/doc/project-ideas.rst
+++ b/pypy/doc/project-ideas.rst
@@ -1,14 +1,23 @@
 Potential project list
 ======================
 
-===========================
-Simple tasks for newcomers:
-===========================
+==========================
+Simple tasks for newcomers
+==========================
 
-Optimize random
----------------
+* Tkinter module missing support for threads:
+  
https://bitbucket.org/pypy/pypy/issue/1929/tkinter-broken-for-threaded-python-on-both
 
-https://bitbucket.org/pypy/pypy/issue/1901/try-using-a-different-implementation-of
+* Optimize random:
+  
https://bitbucket.org/pypy/pypy/issue/1901/try-using-a-different-implementation-of
+
+* Implement AF_XXX packet types of sockets:
+  https://bitbucket.org/pypy/pypy/issue/1942/support-for-af_xxx-sockets
+
+
+==================
+Mid-to-large tasks
+==================
 
 Below is a list of projects that are interesting for potential contributors
 who are seriously interested in the PyPy project. They mostly share common
@@ -33,15 +42,8 @@
 ------------------------
 
 PyPy's bytearray type is very inefficient. It would be an interesting
-task to look into possible optimizations on this.
-
-Implement AF_XXX packet types for PyPy
---------------------------------------
-
-PyPy is missing AF_XXX types of sockets. Implementing it is easy-to-medium
-task. `bug report`_
-
-.. _`bug report`: 
https://bitbucket.org/pypy/pypy/issue/1942/support-for-af_xxx-sockets#more
+task to look into possible optimizations on this.  (XXX current status
+unknown; ask on #pypy for updates on this.)
 
 Implement copy-on-write list slicing
 ------------------------------------
@@ -106,6 +108,8 @@
 Translation Toolchain
 ---------------------
 
+(XXX this is unlikely to be feasible.)
+
 * Incremental or distributed translation.
 * Allow separate compilation of extension modules.
 
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -439,7 +439,10 @@
         f_back = space.interp_w(PyFrame, w_f_back, can_be_None=True)
         new_frame.f_backref = jit.non_virtual_ref(f_back)
 
-        new_frame.builtin = space.interp_w(Module, w_builtin)
+        if space.config.objspace.honor__builtins__:
+            new_frame.builtin = space.interp_w(Module, w_builtin)
+        else:
+            assert space.interp_w(Module, w_builtin) is space.builtin
         new_frame.set_blocklist([unpickle_block(space, w_blk)
                                  for w_blk in 
space.unpackiterable(w_blockstack)])
         values_w = maker.slp_from_tuple_with_nulls(space, w_valuestack)
@@ -524,9 +527,10 @@
 
         # cellvars are values exported to inner scopes
         # freevars are values coming from outer scopes
-        freevarnames = list(self.pycode.co_cellvars)
+        # (see locals2fast for why CO_OPTIMIZED)
+        freevarnames = self.pycode.co_cellvars
         if self.pycode.co_flags & consts.CO_OPTIMIZED:
-            freevarnames.extend(self.pycode.co_freevars)
+            freevarnames = freevarnames + self.pycode.co_freevars
         for i in range(len(freevarnames)):
             name = freevarnames[i]
             cell = self.cells[i]
@@ -555,7 +559,16 @@
 
         self.setfastscope(new_fastlocals_w)
 
-        freevarnames = self.pycode.co_cellvars + self.pycode.co_freevars
+        freevarnames = self.pycode.co_cellvars
+        if self.pycode.co_flags & consts.CO_OPTIMIZED:
+            freevarnames = freevarnames + self.pycode.co_freevars
+            # If the namespace is unoptimized, then one of the
+            # following cases applies:
+            # 1. It does not contain free variables, because it
+            #    uses import * or is a top-level namespace.
+            # 2. It is a class namespace.
+            # We don't want to accidentally copy free variables
+            # into the locals dict used by the class.
         for i in range(len(freevarnames)):
             name = freevarnames[i]
             cell = self.cells[i]
diff --git a/pypy/interpreter/test/test_pyframe.py 
b/pypy/interpreter/test/test_pyframe.py
--- a/pypy/interpreter/test/test_pyframe.py
+++ b/pypy/interpreter/test/test_pyframe.py
@@ -516,3 +516,21 @@
         assert seen == [(1, f, firstline + 6, 'line', None),
                         (1, f, firstline + 7, 'line', None),
                         (1, f, firstline + 8, 'line', None)]
+
+    def test_locals2fast_freevar_bug(self):
+        import sys
+        def f(n):
+            class A(object):
+                def g(self):
+                    return n
+                n = 42
+            return A()
+        res = f(10).g()
+        assert res == 10
+        #
+        def trace(*args):
+            return trace
+        sys.settrace(trace)
+        res = f(10).g()
+        sys.settrace(None)
+        assert res == 10
diff --git a/rpython/doc/faq.rst b/rpython/doc/faq.rst
--- a/rpython/doc/faq.rst
+++ b/rpython/doc/faq.rst
@@ -3,6 +3,12 @@
 
 .. contents::
 
+See also: `Frequently ask questions about PyPy.`__
+
+.. __: http://pypy.readthedocs.org/en/latest/faq.html
+
+--------------------------
+
 What is RPython?
 ----------------
 
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
@@ -1298,5 +1298,6 @@
         self.load_reg(self.mc, res_loc, r.sp, ofs)
         scale = get_scale(size_loc.value)
         signed = (sign_loc.value != 0)
-        self._load_from_mem(res_loc, res_loc, ofs_loc, scale, signed, fcond)
+        self._load_from_mem(res_loc, res_loc, ofs_loc, imm(scale), signed,
+                            fcond)
         return fcond
diff --git a/rpython/jit/backend/x86/valgrind.py 
b/rpython/jit/backend/x86/valgrind.py
--- a/rpython/jit/backend/x86/valgrind.py
+++ b/rpython/jit/backend/x86/valgrind.py
@@ -6,6 +6,7 @@
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 from rpython.rlib.objectmodel import we_are_translated
+from rpython.jit.backend.x86.arch import WORD
 
 
 eci = ExternalCompilationInfo(includes = ['valgrind/valgrind.h'])
@@ -13,9 +14,91 @@
 try:
     rffi_platform.verify_eci(eci)
 except rffi_platform.CompilationError:
-    VALGRIND_DISCARD_TRANSLATIONS = None
-else:
-    VALGRIND_DISCARD_TRANSLATIONS = rffi.llexternal(
+    # Can't open 'valgrind/valgrind.h'.  It is a bad idea to just go
+    # ahead and not compile the valgrind-specific hacks.  Instead,
+    # we'll include manually the few needed macros from a hopefully
+    # standard valgrind.h file.
+    eci = ExternalCompilationInfo(post_include_bits = [r"""
+/************ Valgrind support: only with GCC/clang for now ***********/
+/**  This code is inserted only if valgrind/valgrind.h is not found  **/
+/**********************************************************************/
+#ifdef __GNUC__
+
+#if ${WORD} == 4     /* if 32-bit x86 */
+
+#define VG__SPECIAL_INSTRUCTION_PREAMBLE                          \
+                     "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
+                     "roll $29, %%edi ; roll $19, %%edi\n\t"
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
+        _zzq_default, _zzq_request,                               \
+        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
+  __extension__                                                   \
+  ({volatile unsigned int _zzq_args[6];                           \
+    volatile unsigned int _zzq_result;                            \
+    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
+    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
+    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
+    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
+    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
+    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
+    __asm__ volatile(VG__SPECIAL_INSTRUCTION_PREAMBLE             \
+                     /* %EDX = client_request ( %EAX ) */         \
+                     "xchgl %%ebx,%%ebx"                          \
+                     : "=d" (_zzq_result)                         \
+                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
+                     : "cc", "memory"                             \
+                    );                                            \
+    _zzq_result;                                                  \
+  })
+
+#else          /* 64-bit x86-64 */
+
+#define VG__SPECIAL_INSTRUCTION_PREAMBLE                          \
+                     "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
+                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
+        _zzq_default, _zzq_request,                               \
+        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
+    __extension__                                                 \
+    ({ volatile unsigned long long int _zzq_args[6];              \
+    volatile unsigned long long int _zzq_result;                  \
+    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
+    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
+    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
+    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
+    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
+    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
+    __asm__ volatile(VG__SPECIAL_INSTRUCTION_PREAMBLE             \
+                     /* %RDX = client_request ( %RAX ) */         \
+                     "xchgq %%rbx,%%rbx"                          \
+                     : "=d" (_zzq_result)                         \
+                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
+                     : "cc", "memory"                             \
+                    );                                            \
+    _zzq_result;                                                  \
+    })
+#endif
+
+#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1,        \
+                           _zzq_arg2,  _zzq_arg3, _zzq_arg4, _zzq_arg5) \
+  do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                        \
+                    (_zzq_request), (_zzq_arg1), (_zzq_arg2),           \
+                    (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
+
+#define VG_USERREQ__DISCARD_TRANSLATIONS   0x1002
+#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)              \
+    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS,  \
+                                    _qzz_addr, _qzz_len, 0, 0, 0)
+
+/**********************************************************************/
+#else    /* if !__GNUC__ */
+#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)  do { } while(0)
+#endif
+/**********************************************************************/
+""".replace("${WORD}", str(WORD))])
+
+
+VALGRIND_DISCARD_TRANSLATIONS = rffi.llexternal(
         "VALGRIND_DISCARD_TRANSLATIONS",
         [llmemory.Address, lltype.Signed],
         lltype.Void,
@@ -26,5 +109,5 @@
 # ____________________________________________________________
 
 def discard_translations(data, size):
-    if we_are_translated() and VALGRIND_DISCARD_TRANSLATIONS is not None:
+    if we_are_translated():
         VALGRIND_DISCARD_TRANSLATIONS(llmemory.cast_int_to_adr(data), size)
diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -477,8 +477,7 @@
     @enforceargs(None, str)
     def write(self, value):
         self._check_closed()
-        ll_value, is_pinned, is_raw = rffi.get_nonmovingbuffer(value)
-        try:
+        with rffi.scoped_nonmovingbuffer(value) as ll_value:
             # note that since we got a nonmoving buffer, it is either raw
             # or already cannot move, so the arithmetics below are fine
             length = len(value)
@@ -487,8 +486,6 @@
                 errno = rposix.get_saved_errno()
                 c_clearerr(self._ll_file)
                 raise IOError(errno, os.strerror(errno))
-        finally:
-            rffi.free_nonmovingbuffer(value, ll_value, is_pinned, is_raw)
 
     def flush(self):
         self._check_closed()
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -684,7 +684,7 @@
 class RegisterGcTraceEntry(ExtRegistryEntry):
     _about_ = register_custom_trace_hook
 
-    def compute_result_annotation(self, *args_s):
+    def compute_result_annotation(self, s_tp, s_lambda_func):
         pass
 
     def specialize_call(self, hop):
@@ -692,3 +692,26 @@
         lambda_func = hop.args_s[1].const
         hop.exception_cannot_occur()
         hop.rtyper.custom_trace_funcs.append((TP, lambda_func()))
+
+def register_custom_light_finalizer(TP, lambda_func):
+    """ This function does not do anything, but called from any annotated
+    place, will tell that "func" is used as a lightweight finalizer for TP.
+    The func must be specified as "lambda: func" in this call, for internal
+    reasons.
+    """
+
+class RegisterCustomLightFinalizer(ExtRegistryEntry):
+    _about_ = register_custom_light_finalizer
+
+    def compute_result_annotation(self, s_tp, s_lambda_func):
+        pass
+
+    def specialize_call(self, hop):
+        from rpython.rtyper.llannotation import SomePtr
+        TP = hop.args_s[0].const
+        lambda_func = hop.args_s[1].const
+        ll_func = lambda_func()
+        args_s = [SomePtr(lltype.Ptr(TP))]
+        funcptr = hop.rtyper.annotate_helper_fn(ll_func, args_s)
+        hop.exception_cannot_occur()
+        lltype.attachRuntimeTypeInfo(TP, destrptr=funcptr)
diff --git a/rpython/translator/c/src/asm_msvc.h 
b/rpython/translator/c/src/asm_msvc.h
--- a/rpython/translator/c/src/asm_msvc.h
+++ b/rpython/translator/c/src/asm_msvc.h
@@ -2,3 +2,14 @@
 #define PYPY_X86_CHECK_SSE2_DEFINED
 RPY_EXTERN void pypy_x86_check_sse2(void);
 #endif
+
+
+/* Provides the same access to RDTSC as used by the JIT backend.  This
+   is needed (at least if the JIT is enabled) because otherwise the
+   JIT-produced assembler would use RDTSC while the non-jitted code
+   would use QueryPerformanceCounter(), giving different incompatible
+   results.  See issue #900.
+*/
+#include <intrin.h>
+#pragma intrinsic(__rdtsc)
+#define READ_TIMESTAMP(val)   do { val = (long long)__rdtsc(); } while (0)
diff --git a/rpython/translator/c/test/test_newgc.py 
b/rpython/translator/c/test/test_newgc.py
--- a/rpython/translator/c/test/test_newgc.py
+++ b/rpython/translator/c/test/test_newgc.py
@@ -473,6 +473,31 @@
         res = self.run('custom_trace', 0)
         assert res == 10000
 
+    def define_custom_light_finalizer(cls):
+        from rpython.rtyper.annlowlevel import llhelper
+        #
+        T = lltype.Struct('T', ('count', lltype.Signed))
+        t = lltype.malloc(T, zero=True, immortal=True, flavor='raw')
+        #
+        S = lltype.GcStruct('S', rtti=True)
+        def customlightfinlz(addr):
+            t.count += 1
+        lambda_customlightfinlz = lambda: customlightfinlz
+        #
+        def setup():
+            rgc.register_custom_light_finalizer(S, lambda_customlightfinlz)
+            for i in range(10000):
+                lltype.malloc(S)
+        def f(n):
+            setup()
+            llop.gc__collect(lltype.Void)
+            return t.count
+        return f
+
+    def test_custom_light_finalizer(self):
+        res = self.run('custom_light_finalizer', 0)
+        assert res == 10000
+
     def define_weakref(cls):
         import weakref
 
diff --git a/rpython/translator/tool/cbuild.py 
b/rpython/translator/tool/cbuild.py
--- a/rpython/translator/tool/cbuild.py
+++ b/rpython/translator/tool/cbuild.py
@@ -59,7 +59,11 @@
         separately and linked later on.  (If an .h file is needed for
         other .c files to access this, it can be put in includes.)
 
-        (export_symbols: killed, replaced by @rlib.entrypoint.export_symbol)
+        (export_symbols: killed; you need, depending on the case, to
+        add the RPY_EXTERN or RPY_EXPORTED macro just before the
+        declaration of each function in the C header file, as explained
+        in translator/c/src/precommondefs.h; or you need the decorator
+        @rlib.entrypoint.export_symbol)
 
         compile_extra: list of parameters which will be directly passed to
         the compiler
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to