[pypy-commit] pypy release-2.6.x: merge default into release

mattip noreply at buildbot.pypy.org
Tue May 26 14:32:05 CEST 2015


Author: mattip <matti.picus at gmail.com>
Branch: release-2.6.x
Changeset: r77576:fcdb94156515
Date: 2015-05-26 15:32 +0300
http://bitbucket.org/pypy/pypy/changeset/fcdb94156515/

Log:	merge default into release

diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -38,8 +38,8 @@
   Armin Rigo
   Maciej Fijalkowski
   Carl Friedrich Bolz
+  Amaury Forgeot d'Arc
   Antonio Cuni
-  Amaury Forgeot d'Arc
   Samuele Pedroni
   Alex Gaynor
   Brian Kearns
@@ -50,9 +50,9 @@
   Holger Krekel
   Christian Tismer
   Hakan Ardo
-  Benjamin Peterson
   Manuel Jacob
   Ronan Lamy
+  Benjamin Peterson
   Anders Chrigstrom
   Eric van Riet Paap
   Wim Lavrijsen
@@ -63,8 +63,8 @@
   Sven Hager
   Anders Lehmann
   Aurelien Campeas
+  Remi Meier
   Niklaus Haldimann
-  Remi Meier
   Camillo Bruni
   Laura Creighton
   Toon Verwaest
@@ -76,10 +76,10 @@
   David Edelsohn
   Anders Hammarquist
   Jakub Gustak
+  Gregor Wegberg
   Guido Wesdorp
   Lawrence Oluyede
   Bartosz Skowron
-  Gregor Wegberg
   Daniel Roberts
   Niko Matsakis
   Adrien Di Mascio
@@ -87,10 +87,11 @@
   Ludovic Aubry
   Jacob Hallen
   Jason Creighton
+  Richard Plangger
   Alex Martelli
   Michal Bendowski
+  stian
   Jan de Mooij
-  stian
   Tyler Wade
   Michael Foord
   Stephan Diehl
@@ -133,15 +134,15 @@
   Georg Brandl
   Bert Freudenberg
   Stian Andreassen
+  Edd Barrett
   Wanja Saatkamp
   Gerald Klix
   Mike Blume
+  Tobias Pape
   Oscar Nierstrasz
   Stefan H. Muller
-  Edd Barrett
   Jeremy Thurgood
   Rami Chowdhury
-  Tobias Pape
   Eugene Oden
   Henry Mason
   Vasily Kuznetsov
@@ -167,11 +168,13 @@
   Michael Twomey
   Lucian Branescu Mihaila
   Yichao Yu
+  Anton Gulenko
   Gabriel Lavoie
   Olivier Dormond
   Jared Grubb
   Karl Bartel
   Wouter van Heyst
+  Sebastian Pawluś
   Brian Dorsey
   Victor Stinner
   Andrews Medina
@@ -188,6 +191,7 @@
   Neil Shepperd
   Stanislaw Halik
   Mikael Schönenberg
+  Berkin Ilbeyi
   Elmo M?ntynen
   Jonathan David Riehl
   Anders Qvist
@@ -211,11 +215,11 @@
   Carl Meyer
   Karl Ramm
   Pieter Zieschang
-  Sebastian Pawluś
   Gabriel
   Lukas Vacek
   Andrew Dalke
   Sylvain Thenault
+  Jakub Stasiak
   Nathan Taylor
   Vladimir Kryachko
   Jacek Generowicz
@@ -242,6 +246,7 @@
   Tomo Cocoa
   Toni Mattis
   Lucas Stadler
+  Julian Berman
   roberto at goyle
   Yury V. Zaytsev
   Anna Katrina Dominguez
@@ -253,6 +258,8 @@
   Ben Darnell
   Roberto De Ioris
   Juan Francisco Cantero Hurtado
+  Ruochen Huang
+  Jeong YunWon
   Godefroid Chappelle
   Joshua Gilbert
   Dan Colish
@@ -271,6 +278,7 @@
   Christian Muirhead
   Berker Peksag
   James Lan
+  Volodymyr Vladymyrov
   shoma hosaka
   Daniel Neuhäuser
   Ben Mather
@@ -316,6 +324,7 @@
   yasirs
   Michael Chermside
   Anna Ravencroft
+  Andrey Churin
   Dan Crosta
   Julien Phalip
   Roman Podoliaka
diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO
--- a/lib_pypy/cffi.egg-info/PKG-INFO
+++ b/lib_pypy/cffi.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: cffi
-Version: 1.0.2
+Version: 1.0.3
 Summary: Foreign Function Interface for Python calling C code.
 Home-page: http://cffi.readthedocs.org
 Author: Armin Rigo, Maciej Fijalkowski
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -4,8 +4,8 @@
 from .api import FFI, CDefError, FFIError
 from .ffiplatform import VerificationError, VerificationMissing
 
-__version__ = "1.0.2"
-__version_info__ = (1, 0, 2)
+__version__ = "1.0.3"
+__version_info__ = (1, 0, 3)
 
 # The verifier module file names are based on the CRC32 of a string that
 # contains the following version number.  It may be older than __version__
diff --git a/lib_pypy/greenlet.egg-info b/lib_pypy/greenlet.egg-info
--- a/lib_pypy/greenlet.egg-info
+++ b/lib_pypy/greenlet.egg-info
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: greenlet
-Version: 0.4.6
+Version: 0.4.7
 Summary: Lightweight in-process concurrent programming
 Home-page: https://github.com/python-greenlet/greenlet
 Author: Ralf Schmitt (for CPython), PyPy team
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -1,7 +1,7 @@
 import sys
 import _continuation
 
-__version__ = "0.4.6"
+__version__ = "0.4.7"
 
 # ____________________________________________________________
 # Exceptions
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -39,7 +39,6 @@
 ])
 
 if sys.platform.startswith('linux') and sys.maxint > 2147483647:
-  if 0:     # XXX disabled until we fix the absurd .so mess
     working_modules.add('_vmprof')
 
 translation_modules = default_modules.copy()
diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst
--- a/pypy/doc/contributor.rst
+++ b/pypy/doc/contributor.rst
@@ -8,8 +8,8 @@
   Armin Rigo
   Maciej Fijalkowski
   Carl Friedrich Bolz
+  Amaury Forgeot d'Arc
   Antonio Cuni
-  Amaury Forgeot d'Arc
   Samuele Pedroni
   Alex Gaynor
   Brian Kearns
@@ -20,9 +20,9 @@
   Holger Krekel
   Christian Tismer
   Hakan Ardo
-  Benjamin Peterson
   Manuel Jacob
   Ronan Lamy
+  Benjamin Peterson
   Anders Chrigstrom
   Eric van Riet Paap
   Wim Lavrijsen
@@ -33,8 +33,8 @@
   Sven Hager
   Anders Lehmann
   Aurelien Campeas
+  Remi Meier
   Niklaus Haldimann
-  Remi Meier
   Camillo Bruni
   Laura Creighton
   Toon Verwaest
@@ -46,10 +46,10 @@
   David Edelsohn
   Anders Hammarquist
   Jakub Gustak
+  Gregor Wegberg
   Guido Wesdorp
   Lawrence Oluyede
   Bartosz Skowron
-  Gregor Wegberg
   Daniel Roberts
   Niko Matsakis
   Adrien Di Mascio
@@ -57,10 +57,11 @@
   Ludovic Aubry
   Jacob Hallen
   Jason Creighton
+  Richard Plangger
   Alex Martelli
   Michal Bendowski
+  stian
   Jan de Mooij
-  stian
   Tyler Wade
   Michael Foord
   Stephan Diehl
@@ -103,15 +104,15 @@
   Georg Brandl
   Bert Freudenberg
   Stian Andreassen
+  Edd Barrett
   Wanja Saatkamp
   Gerald Klix
   Mike Blume
+  Tobias Pape
   Oscar Nierstrasz
   Stefan H. Muller
-  Edd Barrett
   Jeremy Thurgood
   Rami Chowdhury
-  Tobias Pape
   Eugene Oden
   Henry Mason
   Vasily Kuznetsov
@@ -137,11 +138,13 @@
   Michael Twomey
   Lucian Branescu Mihaila
   Yichao Yu
+  Anton Gulenko
   Gabriel Lavoie
   Olivier Dormond
   Jared Grubb
   Karl Bartel
   Wouter van Heyst
+  Sebastian Pawluś
   Brian Dorsey
   Victor Stinner
   Andrews Medina
@@ -158,6 +161,7 @@
   Neil Shepperd
   Stanislaw Halik
   Mikael Schönenberg
+  Berkin Ilbeyi
   Elmo M?ntynen
   Jonathan David Riehl
   Anders Qvist
@@ -181,11 +185,11 @@
   Carl Meyer
   Karl Ramm
   Pieter Zieschang
-  Sebastian Pawluś
   Gabriel
   Lukas Vacek
   Andrew Dalke
   Sylvain Thenault
+  Jakub Stasiak
   Nathan Taylor
   Vladimir Kryachko
   Jacek Generowicz
@@ -212,6 +216,7 @@
   Tomo Cocoa
   Toni Mattis
   Lucas Stadler
+  Julian Berman
   roberto at goyle
   Yury V. Zaytsev
   Anna Katrina Dominguez
@@ -223,6 +228,8 @@
   Ben Darnell
   Roberto De Ioris
   Juan Francisco Cantero Hurtado
+  Ruochen Huang
+  Jeong YunWon
   Godefroid Chappelle
   Joshua Gilbert
   Dan Colish
@@ -241,6 +248,7 @@
   Christian Muirhead
   Berker Peksag
   James Lan
+  Volodymyr Vladymyrov
   shoma hosaka
   Daniel Neuhäuser
   Ben Mather
@@ -286,6 +294,7 @@
   yasirs
   Michael Chermside
   Anna Ravencroft
+  Andrey Churin
   Dan Crosta
   Julien Phalip
   Roman Podoliaka
diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py
--- a/pypy/doc/tool/makecontributor.py
+++ b/pypy/doc/tool/makecontributor.py
@@ -69,6 +69,7 @@
     'Rami Chowdhury': ['necaris'],
     'Stanislaw Halik':['w31rd0'],
     'Wenzhu Man':['wenzhu man', 'wenzhuman'],
+    'Anton Gulenko':['anton gulenko'],
     }
 
 alias_map = {}
diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py
--- a/pypy/module/_cffi_backend/__init__.py
+++ b/pypy/module/_cffi_backend/__init__.py
@@ -2,7 +2,7 @@
 from pypy.interpreter.mixedmodule import MixedModule
 from rpython.rlib import rdynload
 
-VERSION = "1.0.2"
+VERSION = "1.0.3"
 
 
 class Module(MixedModule):
diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py
--- a/pypy/module/_cffi_backend/ctypeprim.py
+++ b/pypy/module/_cffi_backend/ctypeprim.py
@@ -188,16 +188,7 @@
         if self.value_fits_long:
             value = misc.as_long(self.space, w_ob)
             if self.value_smaller_than_long:
-                size = self.size
-                if size == 1:
-                    signextended = misc.signext(value, 1)
-                elif size == 2:
-                    signextended = misc.signext(value, 2)
-                elif size == 4:
-                    signextended = misc.signext(value, 4)
-                else:
-                    raise AssertionError("unsupported size")
-                if value != signextended:
+                if value != misc.signext(value, self.size):
                     self._overflow(w_ob)
             misc.write_raw_signed_data(cdata, value, self.size)
         else:
diff --git a/pypy/module/_cffi_backend/ffi_obj.py b/pypy/module/_cffi_backend/ffi_obj.py
--- a/pypy/module/_cffi_backend/ffi_obj.py
+++ b/pypy/module/_cffi_backend/ffi_obj.py
@@ -10,7 +10,7 @@
 from pypy.module._cffi_backend import parse_c_type, realize_c_type
 from pypy.module._cffi_backend import newtype, cerrno, ccallback, ctypearray
 from pypy.module._cffi_backend import ctypestruct, ctypeptr, handle
-from pypy.module._cffi_backend import cbuffer, func, cgc, structwrapper
+from pypy.module._cffi_backend import cbuffer, func, cgc, wrapper
 from pypy.module._cffi_backend import cffi_opcode
 from pypy.module._cffi_backend.ctypeobj import W_CType
 from pypy.module._cffi_backend.cdataobj import W_CData
@@ -478,7 +478,7 @@
 corresponding <ctype> object.
 It can also be used on 'cdata' instance to get its C type."""
         #
-        if isinstance(w_arg, structwrapper.W_StructWrapper):
+        if isinstance(w_arg, wrapper.W_FunctionWrapper):
             return w_arg.typeof(self)
         return self.ffi_type(w_arg, ACCEPT_STRING | ACCEPT_CDATA)
 
diff --git a/pypy/module/_cffi_backend/lib_obj.py b/pypy/module/_cffi_backend/lib_obj.py
--- a/pypy/module/_cffi_backend/lib_obj.py
+++ b/pypy/module/_cffi_backend/lib_obj.py
@@ -12,7 +12,7 @@
 from pypy.module._cffi_backend.realize_c_type import getop, getarg
 from pypy.module._cffi_backend.cdataobj import W_CData
 from pypy.module._cffi_backend.ctypefunc import W_CTypeFunc
-from pypy.module._cffi_backend.structwrapper import W_StructWrapper
+from pypy.module._cffi_backend.wrapper import W_FunctionWrapper
 
 
 class W_LibObject(W_Root):
@@ -49,7 +49,7 @@
             num += 1
         self.ffi.included_ffis_libs = includes[:]
 
-    def _build_cpython_func(self, g):
+    def _build_cpython_func(self, g, fnname):
         # Build a function: in the PyPy version, these are all equivalent
         # and 'g->address' is a pointer to a function of exactly the
         # C type specified --- almost: arguments that are structs or
@@ -64,10 +64,8 @@
         #
         ptr = rffi.cast(rffi.CCHARP, g.c_address)
         assert ptr
-        w_cdata = W_CData(self.space, ptr, w_ct)
-        if locs is not None:
-            w_cdata = W_StructWrapper(w_cdata, locs, rawfunctype)
-        return w_cdata
+        return W_FunctionWrapper(self.space, ptr, w_ct,
+                                 locs, rawfunctype, fnname)
 
     @jit.elidable_promote()
     def _get_attr_elidable(self, attr):
@@ -100,7 +98,7 @@
                 op == cffi_opcode.OP_CPYTHON_BLTN_N or
                 op == cffi_opcode.OP_CPYTHON_BLTN_O):
                 # A function
-                w_result = self._build_cpython_func(g)
+                w_result = self._build_cpython_func(g, attr)
                 #
             elif op == cffi_opcode.OP_GLOBAL_VAR:
                 # A global variable of the exact type specified here
@@ -210,7 +208,7 @@
         #
         if ((isinstance(w_value, W_CData) and
                 isinstance(w_value.ctype, W_CTypeFunc))
-            or isinstance(w_value, W_StructWrapper)):
+            or isinstance(w_value, W_FunctionWrapper)):
             # '&func' is 'func' in C, for a constant function 'func'
             return w_value
         #
diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -216,10 +216,9 @@
 neg_msg = "can't convert negative number to unsigned"
 ovf_msg = "long too big to convert"
 
- at specialize.arg(1)
 def signext(value, size):
     # 'value' is sign-extended from 'size' bytes to a full integer.
-    # 'size' should be a constant smaller than a full integer size.
+    # 'size' should be smaller than a full integer size.
     if size == rffi.sizeof(rffi.SIGNEDCHAR):
         return rffi.cast(lltype.Signed, rffi.cast(rffi.SIGNEDCHAR, value))
     elif size == rffi.sizeof(rffi.SHORT):
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -3335,4 +3335,4 @@
 
 def test_version():
     # this test is here mostly for PyPy
-    assert __version__ == "1.0.2"
+    assert __version__ == "1.0.3"
diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py b/pypy/module/_cffi_backend/test/test_recompiler.py
--- a/pypy/module/_cffi_backend/test/test_recompiler.py
+++ b/pypy/module/_cffi_backend/test/test_recompiler.py
@@ -740,3 +740,45 @@
         raises(AttributeError, ffi.addressof, lib, 'unknown_var')
         raises(AttributeError, ffi.addressof, lib, "FOOBAR")
         assert ffi.addressof(lib, 'FetchRectBottom') == lib.FetchRectBottom
+
+    def test_defines__CFFI_(self):
+        # Check that we define the macro _CFFI_ automatically.
+        # It should be done before including Python.h, so that PyPy's Python.h
+        # can check for it.
+        ffi, lib = self.prepare("""
+            #define CORRECT 1
+        """, "test_defines__CFFI_", """
+            #ifdef _CFFI_
+            #    define CORRECT 1
+            #endif
+        """)
+        assert lib.CORRECT == 1
+
+    def test_unpack_args(self):
+        ffi, lib = self.prepare(
+            "void foo0(void); void foo1(int); void foo2(int, int);",
+            "test_unpack_args", """
+                void foo0(void) { }
+                void foo1(int x) { }
+                void foo2(int x, int y) { }
+            """)
+        assert 'foo0' in repr(lib.foo0)
+        assert 'foo1' in repr(lib.foo1)
+        assert 'foo2' in repr(lib.foo2)
+        lib.foo0()
+        lib.foo1(42)
+        lib.foo2(43, 44)
+        e1 = raises(TypeError, lib.foo0, 42)
+        e2 = raises(TypeError, lib.foo0, 43, 44)
+        e3 = raises(TypeError, lib.foo1)
+        e4 = raises(TypeError, lib.foo1, 43, 44)
+        e5 = raises(TypeError, lib.foo2)
+        e6 = raises(TypeError, lib.foo2, 42)
+        e7 = raises(TypeError, lib.foo2, 45, 46, 47)
+        assert str(e1.value) == "foo0() takes no arguments (1 given)"
+        assert str(e2.value) == "foo0() takes no arguments (2 given)"
+        assert str(e3.value) == "foo1() takes exactly one argument (0 given)"
+        assert str(e4.value) == "foo1() takes exactly one argument (2 given)"
+        assert str(e5.value) == "foo2() takes exactly 2 arguments (0 given)"
+        assert str(e6.value) == "foo2() takes exactly 2 arguments (1 given)"
+        assert str(e7.value) == "foo2() takes exactly 2 arguments (3 given)"
diff --git a/pypy/module/_cffi_backend/structwrapper.py b/pypy/module/_cffi_backend/wrapper.py
rename from pypy/module/_cffi_backend/structwrapper.py
rename to pypy/module/_cffi_backend/wrapper.py
--- a/pypy/module/_cffi_backend/structwrapper.py
+++ b/pypy/module/_cffi_backend/wrapper.py
@@ -1,3 +1,4 @@
+from pypy.interpreter.error import oefmt
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app
@@ -10,7 +11,7 @@
 from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion
 
 
-class W_StructWrapper(W_Root):
+class W_FunctionWrapper(W_Root):
     """A wrapper around a real W_CData which points to a function
     generated in the C code.  The real W_CData has got no struct/union
     argument (only pointers to it), and no struct/union return type
@@ -21,17 +22,19 @@
     """
     _immutable_ = True
 
-    def __init__(self, w_cdata, locs, rawfunctype):
-        space = w_cdata.space
-        ctype = w_cdata.ctype
+    def __init__(self, space, fnptr, ctype, locs, rawfunctype, fnname):
         assert isinstance(ctype, W_CTypeFunc)
-        assert len(ctype.fargs) == len(locs)
+        assert ctype.cif_descr is not None     # not for '...' functions
+        assert locs is None or len(ctype.fargs) == len(locs)
         #
         self.space = space
-        self.w_cdata = w_cdata
+        self.fnptr = fnptr
+        self.ctype = ctype
         self.locs = locs
-        self.fargs = ctype.fargs
         self.rawfunctype = rawfunctype
+        self.fnname = fnname
+        self.nargs_expected = len(ctype.fargs) - (locs is not None and
+                                                  locs[0] == 'R')
 
     def typeof(self, ffi):
         return self.rawfunctype.unwrap_as_fnptr(ffi)
@@ -41,12 +44,12 @@
         # replaces struct/union arguments with ptr-to-struct/union arguments
         space = self.space
         locs = self.locs
-        result_w = args_w[:]
-        for i in range(start_index, min(len(args_w), len(locs))):
+        fargs = self.ctype.fargs
+        for i in range(start_index, len(locs)):
             if locs[i] != 'A':
                 continue
             w_arg = args_w[i]
-            farg = self.fargs[i]      # <ptr to struct/union>
+            farg = fargs[i]      # <ptr to struct/union>
             assert isinstance(farg, W_CTypePtrOrArray)
             if isinstance(w_arg, W_CData) and w_arg.ctype is farg.ctitem:
                 # fast way: we are given a W_CData "struct", so just make
@@ -62,25 +65,49 @@
                 if space.is_w(w_arg, space.w_None):
                     continue
                 w_arg = farg.newp(w_arg)
-            result_w[i] = w_arg
-        return result_w
+            args_w[i] = w_arg
 
     def descr_call(self, args_w):
-        # If the result we want to present to the user is "returns struct",
-        # then internally allocate the struct and pass a pointer to it as
-        # a first argument.
-        if self.locs[0] == 'R':
-            w_result_cdata = self.fargs[0].newp(self.space.w_None)
-            args_w = [w_result_cdata] + args_w
-            self.w_cdata.call(self._prepare(args_w, 1))
-            assert isinstance(w_result_cdata, W_CDataPtrToStructOrUnion)
-            return w_result_cdata.structobj
-        else:
-            return self.w_cdata.call(self._prepare(args_w, 0))
+        if len(args_w) != self.nargs_expected:
+            space = self.space
+            if self.nargs_expected == 0:
+                raise oefmt(space.w_TypeError,
+                            "%s() takes no arguments (%d given)",
+                            self.fnname, len(args_w))
+            elif self.nargs_expected == 1:
+                raise oefmt(space.w_TypeError,
+                            "%s() takes exactly one argument (%d given)",
+                            self.fnname, len(args_w))
+            else:
+                raise oefmt(space.w_TypeError,
+                            "%s() takes exactly %d arguments (%d given)",
+                            self.fnname, self.nargs_expected, len(args_w))
+        #
+        if self.locs is not None:
+            # This case is if there are structs as arguments or return values.
+            # If the result we want to present to the user is "returns struct",
+            # then internally allocate the struct and pass a pointer to it as
+            # a first argument.
+            if self.locs[0] == 'R':
+                w_result_cdata = self.ctype.fargs[0].newp(self.space.w_None)
+                args_w = [w_result_cdata] + args_w
+                self._prepare(args_w, 1)
+                self.ctype._call(self.fnptr, args_w)    # returns w_None
+                assert isinstance(w_result_cdata, W_CDataPtrToStructOrUnion)
+                return w_result_cdata.structobj
+            else:
+                args_w = args_w[:]
+                self._prepare(args_w, 0)
+        #
+        return self.ctype._call(self.fnptr, args_w)
 
+    def descr_repr(self, space):
+        return space.wrap("<FFIFunctionWrapper for %s()>" % (self.fnname,))
 
-W_StructWrapper.typedef = TypeDef(
-        'FFIFuncStructWrapper',
-        __call__ = interp2app(W_StructWrapper.descr_call),
+
+W_FunctionWrapper.typedef = TypeDef(
+        'FFIFunctionWrapper',
+        __repr__ = interp2app(W_FunctionWrapper.descr_repr),
+        __call__ = interp2app(W_FunctionWrapper.descr_call),
         )
-W_StructWrapper.typedef.acceptable_as_base_class = False
+W_FunctionWrapper.typedef.acceptable_as_base_class = False
diff --git a/pypy/module/_vmprof/interp_vmprof.py b/pypy/module/_vmprof/interp_vmprof.py
--- a/pypy/module/_vmprof/interp_vmprof.py
+++ b/pypy/module/_vmprof/interp_vmprof.py
@@ -27,15 +27,15 @@
     include_dirs = [SRC],
     includes = ['vmprof.h', 'trampoline.h'],
     separate_module_files = [SRC.join('trampoline.asmgcc.s')],
-    libraries = ['unwind'],
+    libraries = ['dl'],
     
     post_include_bits=["""
-        void pypy_vmprof_init(void);
+        int pypy_vmprof_init(void);
     """],
     
     separate_module_sources=["""
-        void pypy_vmprof_init(void) {
-            vmprof_set_mainloop(pypy_execute_frame_trampoline, 0,
+        int pypy_vmprof_init(void) {
+            return vmprof_set_mainloop(pypy_execute_frame_trampoline, 0,
                                 NULL);
         }
     """],
@@ -63,7 +63,7 @@
     _nowrapper=True, sandboxsafe=True,
     random_effects_on_gcobjs=True)
 
-pypy_vmprof_init = rffi.llexternal("pypy_vmprof_init", [], lltype.Void,
+pypy_vmprof_init = rffi.llexternal("pypy_vmprof_init", [], rffi.INT,
                                    compilation_info=eci)
 vmprof_enable = rffi.llexternal("vmprof_enable",
                                 [rffi.INT, rffi.LONG, rffi.INT,
@@ -73,6 +73,9 @@
 vmprof_disable = rffi.llexternal("vmprof_disable", [], rffi.INT,
                                  compilation_info=eci,
                                 save_err=rffi.RFFI_SAVE_ERRNO)
+vmprof_get_error = rffi.llexternal("vmprof_get_error", [], rffi.CCHARP,
+                                   compilation_info=eci,
+                                   save_err=rffi.RFFI_SAVE_ERRNO)
 
 vmprof_register_virtual_function = rffi.llexternal(
     "vmprof_register_virtual_function",
@@ -142,7 +145,11 @@
         self.write_header(fileno, period_usec)
         if not self.ever_enabled:
             if we_are_translated():
-                pypy_vmprof_init()
+                res = pypy_vmprof_init()
+                if res:
+                    raise OperationError(
+                        space.w_IOError,
+                        space.wrap(rffi.charp2str(vmprof_get_error())))
             self.ever_enabled = True
         self.gather_all_code_objs(space)
         space.register_code_callback(vmprof_register_code)
diff --git a/pypy/module/_vmprof/src/vmprof.c b/pypy/module/_vmprof/src/vmprof.c
--- a/pypy/module/_vmprof/src/vmprof.c
+++ b/pypy/module/_vmprof/src/vmprof.c
@@ -27,9 +27,10 @@
 #include <sys/types.h>
 #include <errno.h>
 #include <pthread.h>
+#include <dlfcn.h>
 
-#define UNW_LOCAL_ONLY
-#include <libunwind.h>
+//#define UNW_LOCAL_ONLY
+//#include <libunwind.h>
 
 #include "vmprof.h"
 
@@ -44,6 +45,7 @@
 static char profile_write_buffer[BUFFER_SIZE];
 static int profile_buffer_position = 0;
 void* vmprof_mainloop_func;
+char* vmprof_error = NULL;
 static ptrdiff_t mainloop_sp_offset;
 static vmprof_get_virtual_ip_t mainloop_get_virtual_ip;
 static long last_period_usec = 0;
@@ -59,6 +61,11 @@
 #define MARKER_VIRTUAL_IP '\x02'
 #define MARKER_TRAILER '\x03'
 
+int (*unw_get_reg)(unw_cursor_t*, int, unw_word_t*) = NULL;
+int (*unw_step)(unw_cursor_t*) = NULL;
+int (*unw_init_local)(unw_cursor_t *, unw_context_t *) = NULL;
+int (*unw_get_proc_info)(unw_cursor_t *, unw_proc_info_t *) = NULL;
+
 static void prof_word(long x) {
 	((long*)(profile_write_buffer + profile_buffer_position))[0] = x;
 	profile_buffer_position += sizeof(long);
@@ -342,11 +349,44 @@
  * *************************************************************
  */
 
-void vmprof_set_mainloop(void* func, ptrdiff_t sp_offset, 
+int vmprof_set_mainloop(void* func, ptrdiff_t sp_offset, 
                          vmprof_get_virtual_ip_t get_virtual_ip) {
+    void *libhandle;
+
     mainloop_sp_offset = sp_offset;
     mainloop_get_virtual_ip = get_virtual_ip;
     vmprof_mainloop_func = func;
+    if (!unw_get_reg) {
+        if (!(libhandle = dlopen("libunwind.so", RTLD_LAZY | RTLD_LOCAL))) {
+            vmprof_error = dlerror();
+            return -1;
+        }
+        if (!(unw_get_reg = dlsym(libhandle, "_ULx86_64_get_reg"))) {
+            vmprof_error = dlerror();
+            return -1;
+        }
+        if (!(unw_get_proc_info = dlsym(libhandle, "_ULx86_64_get_proc_info"))){
+            vmprof_error = dlerror();
+            return -1;
+        }
+        if (!(unw_init_local = dlsym(libhandle, "_ULx86_64_init_local"))) {
+            vmprof_error = dlerror();
+            return -1;
+        }
+        if (!(unw_step = dlsym(libhandle, "_ULx86_64_step"))) {
+            vmprof_error = dlerror();
+            return -1;
+        }
+    }
+    return 0;
+}
+
+char* vmprof_get_error()
+{
+    char* res;
+    res = vmprof_error;
+    vmprof_error = NULL;
+    return res;
 }
 
 int vmprof_enable(int fd, long period_usec, int write_header, char *s,
diff --git a/pypy/module/_vmprof/src/vmprof.h b/pypy/module/_vmprof/src/vmprof.h
--- a/pypy/module/_vmprof/src/vmprof.h
+++ b/pypy/module/_vmprof/src/vmprof.h
@@ -2,11 +2,110 @@
 #define VMPROF_VMPROF_H_
 
 #include <stddef.h>
+#include <stdint.h>
+#include <ucontext.h>
+
+// copied from libunwind.h
+
+typedef enum
+  {
+    UNW_X86_64_RAX,
+    UNW_X86_64_RDX,
+    UNW_X86_64_RCX,
+    UNW_X86_64_RBX,
+    UNW_X86_64_RSI,
+    UNW_X86_64_RDI,
+    UNW_X86_64_RBP,
+    UNW_X86_64_RSP,
+    UNW_X86_64_R8,
+    UNW_X86_64_R9,
+    UNW_X86_64_R10,
+    UNW_X86_64_R11,
+    UNW_X86_64_R12,
+    UNW_X86_64_R13,
+    UNW_X86_64_R14,
+    UNW_X86_64_R15,
+    UNW_X86_64_RIP,
+#ifdef CONFIG_MSABI_SUPPORT
+    UNW_X86_64_XMM0,
+    UNW_X86_64_XMM1,
+    UNW_X86_64_XMM2,
+    UNW_X86_64_XMM3,
+    UNW_X86_64_XMM4,
+    UNW_X86_64_XMM5,
+    UNW_X86_64_XMM6,
+    UNW_X86_64_XMM7,
+    UNW_X86_64_XMM8,
+    UNW_X86_64_XMM9,
+    UNW_X86_64_XMM10,
+    UNW_X86_64_XMM11,
+    UNW_X86_64_XMM12,
+    UNW_X86_64_XMM13,
+    UNW_X86_64_XMM14,
+    UNW_X86_64_XMM15,
+    UNW_TDEP_LAST_REG = UNW_X86_64_XMM15,
+#else
+    UNW_TDEP_LAST_REG = UNW_X86_64_RIP,
+#endif
+
+    /* XXX Add other regs here */
+
+    /* frame info (read-only) */
+    UNW_X86_64_CFA,
+
+    UNW_TDEP_IP = UNW_X86_64_RIP,
+    UNW_TDEP_SP = UNW_X86_64_RSP,
+    UNW_TDEP_BP = UNW_X86_64_RBP,
+    UNW_TDEP_EH = UNW_X86_64_RAX
+  }
+x86_64_regnum_t;
+
+typedef uint64_t unw_word_t;
+
+#define UNW_TDEP_CURSOR_LEN 127
+
+typedef struct unw_cursor
+  {
+    unw_word_t opaque[UNW_TDEP_CURSOR_LEN];
+  }
+unw_cursor_t;
+
+#define UNW_REG_IP UNW_X86_64_RIP
+#define UNW_REG_SP UNW_X86_64_RSP
+
+typedef ucontext_t unw_context_t;
+
+typedef struct unw_proc_info
+  {
+    unw_word_t start_ip;	/* first IP covered by this procedure */
+    unw_word_t end_ip;		/* first IP NOT covered by this procedure */
+    unw_word_t lsda;		/* address of lang.-spec. data area (if any) */
+    unw_word_t handler;		/* optional personality routine */
+    unw_word_t gp;		/* global-pointer value for this procedure */
+    unw_word_t flags;		/* misc. flags */
+
+    int format;			/* unwind-info format (arch-specific) */
+    int unwind_info_size;	/* size of the information (if applicable) */
+    void *unwind_info;		/* unwind-info (arch-specific) */
+  }
+unw_proc_info_t;
+
+// functions copied from libunwind using dlopen
+
+extern int (*unw_get_reg)(unw_cursor_t*, int, unw_word_t*);
+extern int (*unw_step)(unw_cursor_t*);
+extern int (*unw_init_local)(unw_cursor_t *, unw_context_t *);
+extern int (*unw_get_proc_info)(unw_cursor_t *, unw_proc_info_t *);
+
+// end of copy
+
+extern char* vmprof_error;
 
 typedef void* (*vmprof_get_virtual_ip_t)(void*);
+char* vmprof_get_error();
 
 extern void* vmprof_mainloop_func;
-void vmprof_set_mainloop(void* func, ptrdiff_t sp_offset, 
+int vmprof_set_mainloop(void* func, ptrdiff_t sp_offset, 
                          vmprof_get_virtual_ip_t get_virtual_ip);
 
 void vmprof_register_virtual_function(const char* name, void* start, void* end);
diff --git a/pypy/module/pypyjit/test_pypy_c/test_ffi.py b/pypy/module/pypyjit/test_pypy_c/test_ffi.py
--- a/pypy/module/pypyjit/test_pypy_c/test_ffi.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_ffi.py
@@ -208,6 +208,9 @@
         """, ignore_ops=['guard_not_invalidated'])
 
     def test__cffi_call_c_int(self):
+        if sys.platform == 'win32':
+            py.test.skip("not tested on Windows (this test must pass on "
+                         "other platforms, and it should work the same way)")
         def main():
             import os
             try:
@@ -248,6 +251,9 @@
         """ % extra, ignore_ops=['guard_not_invalidated'])
 
     def test__cffi_call_size_t(self):
+        if sys.platform == 'win32':
+            py.test.skip("not tested on Windows (this test must pass on "
+                         "other platforms, and it should work the same way)")
         def main():
             import os
             try:
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py
@@ -26,8 +26,11 @@
     tmpdir.ensure(dir=1)
     c_file = tmpdir.join('_test_re_python.c')
     c_file.write(SRC)
-    ext = ffiplatform.get_extension(str(c_file), '_test_re_python',
-                                    export_symbols=['add42', 'globalvar42'])
+    ext = ffiplatform.get_extension(
+        str(c_file),
+        '_test_re_python',
+        export_symbols=['add42', 'add43', 'globalvar42']
+    )
     outputfilename = ffiplatform.compile(str(tmpdir), ext)
     mod.extmod = outputfilename
     mod.tmpdir = tmpdir
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py
@@ -1,5 +1,5 @@
 # Generated by pypy/tool/import_cffi.py
-import sys, math, py
+import os, sys, math, py
 from cffi import FFI, VerificationError, VerificationMissing, model
 from cffi import recompiler
 from pypy.module.test_lib_pypy.cffi_tests.support import *
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -78,8 +78,9 @@
             subprocess.check_call(args, cwd=cwd)
         except subprocess.CalledProcessError:
             print >>sys.stderr, """!!!!!!!!!!\nBuilding {0} bindings failed.
-You can either install development headers package or
-add --without-{0} option to skip packaging this binary CFFI extension.""".format(key)
+You can either install development headers package,
+add the --without-{0} option to skip packaging this
+binary CFFI extension, or say --without-cffi.""".format(key)
             raise MissingDependenciesError(module)
 
 def pypy_runs(pypy_c, quiet=False):
@@ -88,7 +89,7 @@
         kwds['stderr'] = subprocess.PIPE
     return subprocess.call([str(pypy_c), '-c', 'pass'], **kwds) == 0
 
-def create_package(basedir, options):
+def create_package(basedir, options, _fake=False):
     retval = 0
     name = options.name
     if not name:
@@ -104,13 +105,13 @@
         pypy_c = basedir.join('pypy', 'goal', basename)
     else:
         pypy_c = py.path.local(override_pypy_c)
-    if not pypy_c.check():
+    if not _fake and not pypy_c.check():
         raise PyPyCNotFound(
             'Expected but did not find %s.'
             ' Please compile pypy first, using translate.py,'
             ' or check that you gave the correct path'
             ' with --override_pypy_c' % pypy_c)
-    if not pypy_runs(pypy_c):
+    if not _fake and not pypy_runs(pypy_c):
         raise OSError("Running %r failed!" % (str(pypy_c),))
     if not options.no_cffi:
         try:
@@ -121,18 +122,17 @@
     if sys.platform == 'win32' and not rename_pypy_c.lower().endswith('.exe'):
         rename_pypy_c += '.exe'
     binaries = [(pypy_c, rename_pypy_c)]
-    libpypy_name = 'libpypy-c.so' if not sys.platform.startswith('darwin') else 'libpypy-c.dylib'
-    libpypy_c = pypy_c.new(basename=libpypy_name)
-    if libpypy_c.check():
-        # check that this libpypy_c is really needed
-        os.rename(str(libpypy_c), str(libpypy_c) + '~')
-        try:
-            if pypy_runs(pypy_c, quiet=True):
-                raise Exception("It seems that %r runs without needing %r.  "
-                                "Please check and remove the latter" %
-                                (str(pypy_c), str(libpypy_c)))
-        finally:
-            os.rename(str(libpypy_c) + '~', str(libpypy_c))
+
+    if (sys.platform != 'win32' and    # handled below
+        not _fake and os.path.getsize(str(pypy_c)) < 500000):
+        # This pypy-c is very small, so it means it relies on libpypy_c.so.
+        # If it would be bigger, it wouldn't.  That's a hack.
+        libpypy_name = ('libpypy-c.so' if not sys.platform.startswith('darwin')
+                                       else 'libpypy-c.dylib')
+        libpypy_c = pypy_c.new(basename=libpypy_name)
+        if not libpypy_c.check():
+            raise PyPyCNotFound('Expected pypy to be mostly in %r, but did '
+                                'not find it' % (str(libpypy_c),))
         binaries.append((libpypy_c, libpypy_name))
     #
     builddir = options.builddir
@@ -192,7 +192,9 @@
 directory next to the dlls, as per build instructions."""
                 import traceback;traceback.print_exc()
                 raise MissingDependenciesError('Tk runtime')
-        
+
+    print '* Binaries:', [source.relto(str(basedir))
+                          for source, target in binaries]
 
     # Careful: to copy lib_pypy, copying just the hg-tracked files
     # would not be enough: there are also ctypes_config_cache/_*_cache.py.
@@ -225,7 +227,11 @@
         bindir.ensure(dir=True)
     for source, target in binaries:
         archive = bindir.join(target)
-        shutil.copy(str(source), str(archive))
+        if not _fake:
+            shutil.copy(str(source), str(archive))
+        else:
+            open(str(archive), 'wb').close()
+        os.chmod(str(archive), 0755)
     fix_permissions(pypydir)
 
     old_dir = os.getcwd()
@@ -274,7 +280,7 @@
         print "Ready in %s" % (builddir,)
     return retval, builddir # for tests
 
-def package(*args):
+def package(*args, **kwds):
     try:
         import argparse
     except ImportError:
@@ -335,7 +341,7 @@
         from rpython.tool.udir import udir
         options.builddir = udir.ensure("build", dir=True)
     assert '/' not in options.pypy_c
-    return create_package(basedir, options)
+    return create_package(basedir, options, **kwds)
 
 
 if __name__ == '__main__':
diff --git a/pypy/tool/release/test/test_package.py b/pypy/tool/release/test/test_package.py
--- a/pypy/tool/release/test/test_package.py
+++ b/pypy/tool/release/test/test_package.py
@@ -16,25 +16,10 @@
         rename_pypy_c = 'pypy'
         exe_name_in_archive = 'bin/pypy'
     pypy_c = py.path.local(pypydir).join('goal', basename)
-    if not pypy_c.check():
-        if sys.platform == 'win32':
-            import os, shutil
-            for d in os.environ['PATH'].split(';'):
-                if os.path.exists(os.path.join(d, 'cmd.exe')):
-                    shutil.copy(os.path.join(d, 'cmd.exe'), str(pypy_c))
-                    break
-            else:
-                assert False, 'could not find cmd.exe'
-        else:
-            pypy_c.write("#!/bin/sh")
-            pypy_c.chmod(0755)
-        fake_pypy_c = True
-    else:
-        fake_pypy_c = False
     try:
         retval, builddir = package.package(
             '--without-cffi', str(py.path.local(pypydir).dirpath()),
-            test, rename_pypy_c)
+            test, rename_pypy_c, _fake=True)
         assert retval == 0
         prefix = builddir.join(test)
         cpyver = '%d.%d' % CPYTHON_VERSION[:2]
@@ -79,8 +64,7 @@
         check_include('pypy_decl.h')
         check_include('numpy/arrayobject.h')
     finally:
-        if fake_pypy_c:
-            pypy_c.remove()
+        pass    # to keep the indentation
 
 def test_with_zipfile_module():
     prev = package.USE_ZIPFILE_MODULE
diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -6,7 +6,7 @@
     ConstInt, BoxInt, AbstractFailDescr)
 from rpython.jit.metainterp.resoperation import ResOperation, rop
 from rpython.rlib import rgc
-from rpython.rlib.debug import (debug_start, debug_stop, have_debug_prints,
+from rpython.rlib.debug import (debug_start, debug_stop, have_debug_prints_for,
                                 debug_print)
 from rpython.rlib.rarithmetic import r_uint
 from rpython.rlib.objectmodel import specialize, compute_unique_id
@@ -120,9 +120,7 @@
             # if self._debug is already set it means that someone called
             # set_debug by hand before initializing the assembler. Leave it
             # as it is
-            debug_start('jit-backend-counts')
-            self.set_debug(have_debug_prints())
-            debug_stop('jit-backend-counts')
+            self.set_debug(have_debug_prints_for('jit-backend-counts'))
         # when finishing, we only have one value at [0], the rest dies
         self.gcmap_for_finish = lltype.malloc(jitframe.GCMAP, 1,
                                               flavor='raw',
diff --git a/rpython/jit/metainterp/warmstate.py b/rpython/jit/metainterp/warmstate.py
--- a/rpython/jit/metainterp/warmstate.py
+++ b/rpython/jit/metainterp/warmstate.py
@@ -4,7 +4,7 @@
 from rpython.jit.codewriter import support, heaptracker, longlong
 from rpython.jit.metainterp import history
 from rpython.rlib.debug import debug_start, debug_stop, debug_print
-from rpython.rlib.debug import have_debug_prints
+from rpython.rlib.debug import have_debug_prints_for
 from rpython.rlib.jit import PARAMETERS
 from rpython.rlib.nonconst import NonConstant
 from rpython.rlib.objectmodel import specialize, we_are_translated, r_dict
@@ -639,7 +639,7 @@
                        'disabled, no debug_print)' % drivername)
             #
             def get_location_str(greenkey):
-                if not have_debug_prints():
+                if not have_debug_prints_for("jit-"):
                     return missing
                 greenargs = unwrap_greenkey(greenkey)
                 fn = support.maybe_on_top_of_llinterp(rtyper, get_location_ptr)
diff --git a/rpython/rlib/debug.py b/rpython/rlib/debug.py
--- a/rpython/rlib/debug.py
+++ b/rpython/rlib/debug.py
@@ -141,10 +141,16 @@
     # and False if they would not have any effect.
     return True
 
+def have_debug_prints_for(category_prefix):
+    # returns True if debug prints are enabled for at least some
+    # category strings starting with "prefix" (must be a constant).
+    assert len(category_prefix) > 0
+    return True
+
 class Entry(ExtRegistryEntry):
-    _about_ = have_debug_prints
+    _about_ = have_debug_prints, have_debug_prints_for
 
-    def compute_result_annotation(self):
+    def compute_result_annotation(self, s_prefix=None):
         from rpython.annotator import model as annmodel
         t = self.bookkeeper.annotator.translator
         if t.config.translation.log:
@@ -157,6 +163,12 @@
         t = hop.rtyper.annotator.translator
         hop.exception_cannot_occur()
         if t.config.translation.log:
+            if hop.args_v:
+                [c_prefix] = hop.args_v
+                assert len(c_prefix.value) > 0
+                args = [hop.inputconst(lltype.Void, c_prefix.value)]
+                return hop.genop('have_debug_prints_for', args,
+                                 resulttype=lltype.Bool)
             return hop.genop('have_debug_prints', [], resulttype=lltype.Bool)
         else:
             return hop.inputconst(lltype.Bool, False)
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -796,6 +796,13 @@
     def OP_DEBUG_STOP(self, op):
         return self._op_debug('PYPY_DEBUG_STOP', op.args[0])
 
+    def OP_HAVE_DEBUG_PRINTS_FOR(self, op):
+        arg = op.args[0]
+        assert isinstance(arg, Constant) and isinstance(arg.value, str)
+        string_literal = c_string_constant(arg.value)
+        return '%s = pypy_have_debug_prints_for(%s);' % (
+            self.expr(op.result), string_literal)
+
     def OP_DEBUG_ASSERT(self, op):
         return 'RPyAssert(%s, %s);' % (self.expr(op.args[0]),
                                        c_string_constant(op.args[1].value))
diff --git a/rpython/translator/c/src/debug_print.c b/rpython/translator/c/src/debug_print.c
--- a/rpython/translator/c/src/debug_print.c
+++ b/rpython/translator/c/src/debug_print.c
@@ -138,6 +138,7 @@
 
 static unsigned char startswithoneof(const char *str, const char *substr)
 {
+    /* any([str.startswith(x) for x in substr.split(',')]) */
   const char *p = str;
   for (; *substr; substr++)
     {
@@ -154,6 +155,23 @@
   return p != NULL;
 }
 
+static long oneofstartswith(const char *str, const char *substr)
+{
+    /* any([x.startswith(substr) for x in str.split(',')]) */
+    const char *p = substr;
+    for (; *str; str++) {
+        if (p) {
+            if (*p++ != *str)
+                p = NULL;   /* mismatch */
+            else if (*p == '\0')
+                return 1;   /* full substring match */
+        }
+        if (*str == ',')
+            p = substr;     /* restart looking */
+    }
+    return 0;
+}
+
 #if defined(_MSC_VER) || defined(__MINGW32__)
 #define PYPY_LONG_LONG_PRINTF_FORMAT "I64"
 #else
@@ -199,3 +217,13 @@
     display_startstop("", "}", category, debug_start_colors_2);
   pypy_have_debug_prints >>= 1;
 }
+
+long pypy_have_debug_prints_for(const char *category_prefix)
+{
+  pypy_debug_ensure_opened();
+  return (!debug_profile && debug_prefix &&
+          /* if 'PYPYLOG=abc,xyz:-' and prefix=="ab", then return 1 */
+          (oneofstartswith(debug_prefix, category_prefix) ||
+           /* if prefix=="abcdef" and 'PYPYLOG=abc,xyz:-' then return 1 */
+           startswithoneof(category_prefix, debug_prefix)));
+}
diff --git a/rpython/translator/c/src/debug_print.h b/rpython/translator/c/src/debug_print.h
--- a/rpython/translator/c/src/debug_print.h
+++ b/rpython/translator/c/src/debug_print.h
@@ -42,6 +42,7 @@
 RPY_EXTERN void pypy_debug_stop(const char *category);
 RPY_EXTERN long pypy_debug_offset(void);
 RPY_EXTERN void pypy_debug_forked(long original_offset);
+RPY_EXTERN long pypy_have_debug_prints_for(const char *category_prefix);
 
 RPY_EXTERN long pypy_have_debug_prints;
 RPY_EXPORTED FILE *pypy_debug_file;
diff --git a/rpython/translator/c/test/red.ico b/rpython/translator/c/test/red.ico
new file mode 100644
index 0000000000000000000000000000000000000000..6b93272462ebf1acbae64f6247ce64a68858f337
GIT binary patch

[cut]

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
@@ -6,7 +6,8 @@
 from rpython.rlib.objectmodel import keepalive_until_here
 from rpython.rlib.rarithmetic import r_longlong
 from rpython.rlib.debug import ll_assert, have_debug_prints, debug_flush
-from rpython.rlib.debug import debug_print, debug_start, debug_stop, debug_offset
+from rpython.rlib.debug import debug_print, debug_start, debug_stop
+from rpython.rlib.debug import debug_offset, have_debug_prints_for
 from rpython.rlib.entrypoint import entrypoint, secondary_entrypoints
 from rpython.rtyper.lltypesystem import lltype
 from rpython.translator.translator import TranslationContext
@@ -350,6 +351,8 @@
             tell = -1
         def entry_point(argv):
             x = "got:"
+            if have_debug_prints_for("my"): x += "M"
+            if have_debug_prints_for("myc"): x += "m"
             debug_start  ("mycat")
             if have_debug_prints(): x += "b"
             debug_print    ("foo", r_longlong(2), "bar", 3)
@@ -387,7 +390,7 @@
         assert 'bok' not in err
         # check with PYPYLOG=:- (means print to stderr)
         out, err = cbuilder.cmdexec("", err=True, env={'PYPYLOG': ':-'})
-        assert out.strip() == 'got:bcda.%d.' % tell
+        assert out.strip() == 'got:Mmbcda.%d.' % tell
         assert 'toplevel' in err
         assert '{mycat' in err
         assert 'mycat}' in err
@@ -402,7 +405,7 @@
         out, err = cbuilder.cmdexec("", err=True,
                                     env={'PYPYLOG': ':%s' % path})
         size = os.stat(str(path)).st_size
-        assert out.strip() == 'got:bcda.' + str(size) + '.'
+        assert out.strip() == 'got:Mmbcda.' + str(size) + '.'
         assert not err
         assert path.check(file=1)
         data = path.read()
@@ -455,7 +458,7 @@
         out, err = cbuilder.cmdexec("", err=True,
                                     env={'PYPYLOG': 'myc:%s' % path})
         size = os.stat(str(path)).st_size
-        assert out.strip() == 'got:bda.' + str(size) + '.'
+        assert out.strip() == 'got:Mmbda.' + str(size) + '.'
         assert not err
         assert path.check(file=1)
         data = path.read()
@@ -486,7 +489,7 @@
         out, err = cbuilder.cmdexec("", err=True,
                                     env={'PYPYLOG': 'myc,cat2:%s' % path})
         size = os.stat(str(path)).st_size
-        assert out.strip() == 'got:bcda.' + str(size) + '.'
+        assert out.strip() == 'got:Mmbcda.' + str(size) + '.'
         assert not err
         assert path.check(file=1)
         data = path.read()
diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py
--- a/rpython/translator/platform/windows.py
+++ b/rpython/translator/platform/windows.py
@@ -417,6 +417,7 @@
             deps = ['main.obj']
             m.rule('wmain.c', '',
                    ['echo #define WIN32_LEAN_AND_MEAN > $@',
+                   'echo #include "stdlib.h" >> $@',
                    'echo #include "windows.h" >> $@',
                    'echo int $(PYPY_MAIN_FUNCTION)(int, char*[]); >> $@',
                    'echo int WINAPI WinMain( >> $@',


More information about the pypy-commit mailing list