[pypy-commit] pypy py3k-fix-strategies: merge py3k
pjenvey
noreply at buildbot.pypy.org
Thu Apr 24 01:42:56 CEST 2014
Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k-fix-strategies
Changeset: r70903:f3443cbe086e
Date: 2014-04-23 16:41 -0700
http://bitbucket.org/pypy/pypy/changeset/f3443cbe086e/
Log: merge py3k
diff too long, truncating to 2000 out of 9793 lines
diff --git a/lib-python/2.7/ctypes/util.py b/lib-python/2.7/ctypes/util.py
--- a/lib-python/2.7/ctypes/util.py
+++ b/lib-python/2.7/ctypes/util.py
@@ -86,9 +86,10 @@
elif os.name == "posix":
# Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
- import re, tempfile, errno
+ import re, errno
def _findLib_gcc(name):
+ import tempfile
expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
fdout, ccout = tempfile.mkstemp()
os.close(fdout)
diff --git a/lib-python/2.7/test/test_argparse.py b/lib-python/2.7/test/test_argparse.py
--- a/lib-python/2.7/test/test_argparse.py
+++ b/lib-python/2.7/test/test_argparse.py
@@ -51,7 +51,7 @@
for root, dirs, files in os.walk(self.temp_dir, topdown=False):
for name in files:
os.chmod(os.path.join(self.temp_dir, name), stat.S_IWRITE)
- shutil.rmtree(self.temp_dir, True)
+ shutil.rmtree(self.temp_dir, True)
def create_readonly_file(self, filename):
file_path = os.path.join(self.temp_dir, filename)
diff --git a/lib-python/2.7/test/test_httpservers.py b/lib-python/2.7/test/test_httpservers.py
--- a/lib-python/2.7/test/test_httpservers.py
+++ b/lib-python/2.7/test/test_httpservers.py
@@ -335,7 +335,7 @@
response = self.request(self.tempdir_name + '/')
self.check_status_and_reason(response, 404)
os.chmod(self.tempdir, 0755)
- f.close()
+ f.close()
def test_head(self):
response = self.request(
diff --git a/lib_pypy/_pypy_testcapi.py b/lib_pypy/_pypy_testcapi.py
--- a/lib_pypy/_pypy_testcapi.py
+++ b/lib_pypy/_pypy_testcapi.py
@@ -1,6 +1,7 @@
import os, sys, imp
import tempfile, binascii
+
def get_hashed_dir(cfile):
with open(cfile,'r') as fid:
content = fid.read()
@@ -15,7 +16,7 @@
output_dir = tempfile.gettempdir() + os.path.sep + 'tmp_%s%s' %(k1, k2)
if not os.path.exists(output_dir):
os.mkdir(output_dir)
- return output_dir
+ return output_dir
def _get_c_extension_suffix():
diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py
--- a/lib_pypy/ctypes_support.py
+++ b/lib_pypy/ctypes_support.py
@@ -1,4 +1,3 @@
-
""" This file provides some support for things like standard_c_lib and
errno access, as portable as possible
"""
@@ -22,7 +21,7 @@
standard_c_lib._errno.argtypes = None
def _where_is_errno():
return standard_c_lib._errno()
-
+
elif sys.platform in ('linux2', 'freebsd6'):
standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int)
standard_c_lib.__errno_location.argtypes = None
@@ -42,5 +41,3 @@
def set_errno(value):
errno_p = _where_is_errno()
errno_p.contents.value = value
-
-
diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst
--- a/pypy/doc/contributor.rst
+++ b/pypy/doc/contributor.rst
@@ -15,21 +15,21 @@
Alex Gaynor
Michael Hudson
David Schneider
+ Matti Picus
+ Brian Kearns
+ Philip Jenvey
Holger Krekel
Christian Tismer
- Matti Picus
Hakan Ardo
Benjamin Peterson
- Philip Jenvey
+ Manuel Jacob
Anders Chrigstrom
- Brian Kearns
- Manuel Jacob
Eric van Riet Paap
Wim Lavrijsen
+ Ronan Lamy
Richard Emslie
Alexander Schremmer
Dan Villiom Podlaski Christiansen
- Ronan Lamy
Lukas Diekmann
Sven Hager
Anders Lehmann
@@ -38,23 +38,23 @@
Camillo Bruni
Laura Creighton
Toon Verwaest
+ Remi Meier
Leonardo Santagada
Seo Sanghyeon
+ Romain Guillebert
Justin Peel
Ronny Pfannschmidt
David Edelsohn
Anders Hammarquist
Jakub Gustak
- Romain Guillebert
Guido Wesdorp
Lawrence Oluyede
- Remi Meier
Bartosz Skowron
Daniel Roberts
Niko Matsakis
Adrien Di Mascio
+ Alexander Hesse
Ludovic Aubry
- Alexander Hesse
Jacob Hallen
Jason Creighton
Alex Martelli
@@ -71,6 +71,7 @@
Bruno Gola
Jean-Paul Calderone
Timo Paulssen
+ Squeaky
Alexandre Fayolle
Simon Burton
Marius Gedminas
@@ -87,6 +88,7 @@
Paweł Piotr Przeradowski
Paul deGrandis
Ilya Osadchiy
+ Tobias Oberstein
Adrian Kuhn
Boris Feigin
Stefano Rivera
@@ -95,13 +97,17 @@
Georg Brandl
Bert Freudenberg
Stian Andreassen
+ Laurence Tratt
Wanja Saatkamp
Gerald Klix
Mike Blume
Oscar Nierstrasz
Stefan H. Muller
- Laurence Tratt
+ Jeremy Thurgood
+ Gregor Wegberg
Rami Chowdhury
+ Tobias Pape
+ Edd Barrett
David Malcolm
Eugene Oden
Henry Mason
@@ -110,9 +116,7 @@
David Ripton
Dusty Phillips
Lukas Renggli
- Edd Barrett
Guenter Jantzen
- Tobias Oberstein
Ned Batchelder
Amit Regmi
Ben Young
@@ -123,7 +127,6 @@
Nicholas Riley
Jason Chu
Igor Trindade Oliveira
- Jeremy Thurgood
Rocco Moretti
Gintautas Miliauskas
Michael Twomey
@@ -134,7 +137,6 @@
Olivier Dormond
Jared Grubb
Karl Bartel
- Tobias Pape
Brian Dorsey
Victor Stinner
Andrews Medina
@@ -146,9 +148,9 @@
Aaron Iles
Michael Cheng
Justas Sadzevicius
+ Mikael Schönenberg
Gasper Zejn
Neil Shepperd
- Mikael Schönenberg
Elmo Mäntynen
Jonathan David Riehl
Stanislaw Halik
@@ -161,7 +163,9 @@
Alexander Sedov
Corbin Simpson
Christopher Pope
+ wenzhuman
Christian Tismer
+ Marc Abramowitz
Dan Stromberg
Stefano Parmesan
Alexis Daboville
@@ -170,6 +174,7 @@
Karl Ramm
Pieter Zieschang
Gabriel
+ Lukas Vacek
Andrew Dalke
Sylvain Thenault
Nathan Taylor
@@ -180,6 +185,7 @@
Travis Francis Athougies
Kristjan Valur Jonsson
Neil Blakey-Milner
+ anatoly techtonik
Lutz Paelike
Lucio Torre
Lars Wassermann
@@ -200,7 +206,6 @@
Bobby Impollonia
timo at eistee.fritz.box
Andrew Thompson
- Yusei Tahara
Ben Darnell
Roberto De Ioris
Juan Francisco Cantero Hurtado
@@ -212,28 +217,35 @@
Anders Sigfridsson
Yasir Suhail
Floris Bruynooghe
+ Laurens Van Houtven
Akira Li
Gustavo Niemeyer
Stephan Busemann
Rafał Gałczyński
+ Yusei Tahara
Christian Muirhead
James Lan
shoma hosaka
- Daniel Neuhäuser
+ Daniel Neuh?user
+ Matthew Miller
Buck Golemon
Konrad Delong
Dinu Gherman
Chris Lambacher
coolbutuseless at gmail.com
+ Rodrigo Araújo
w31rd0
Jim Baker
- Rodrigo Araújo
+ James Robert
Armin Ronacher
Brett Cannon
yrttyr
+ aliceinwire
+ OlivierBlanvillain
Zooko Wilcox-O Hearn
Tomer Chachamu
Christopher Groskopf
+ jiaaro
opassembler.py
Antony Lee
Jim Hunziker
@@ -241,6 +253,7 @@
Even Wiik Thomassen
jbs
soareschen
+ Kurt Griffiths
Mike Bayer
Flavio Percoco
Kristoffer Kleine
diff --git a/pypy/doc/release-2.3.0.rst b/pypy/doc/release-2.3.0.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-2.3.0.rst
@@ -0,0 +1,88 @@
+=======================================
+PyPy 2.3 - XXXX TODO
+=======================================
+
+We're pleased to announce PyPy 2.3, which targets version 2.7.6 of the Python
+language. This release updates the stdlib from 2.7.3, jumping directly to 2.7.6.
+
+This release also contains several bugfixes and performance improvements.
+
+You can download the PyPy 2.3 release here:
+
+ http://pypy.org/download.html
+
+We would like to thank our donors for the continued support of the PyPy
+project. We showed quite a bit of progress on all three projects (see below)
+and we're slowly running out of funds.
+Please consider donating more so we can finish those projects! The three
+projects are:
+
+* Py3k (supporting Python 3.x): the release PyPy3 2.2 is imminent.
+
+* STM (software transactional memory): a preview will be released very soon,
+ as soon as we fix a few bugs
+
+* NumPy: the work done is included in the PyPy 2.2 release. More details below.
+
+.. _`Raspberry Pi Foundation`: http://www.raspberrypi.org
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`pypy 2.2 and cpython 2.7.2`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+This release supports x86 machines running Linux 32/64, Mac OS X 64, Windows
+32, or ARM (ARMv6 or ARMv7, with VFPv3).
+
+Work on the native Windows 64 is still stalling, we would welcome a volunteer
+to handle that.
+
+.. _`pypy 2.2 and cpython 2.7.2`: http://speed.pypy.org
+
+Highlights
+==========
+
+* Our Garbage Collector is now "incremental". It should avoid almost
+ all pauses due to a major collection taking place. Previously, it
+ would pause the program (rarely) to walk all live objects, which
+ could take arbitrarily long if your process is using a whole lot of
+ RAM. Now the same work is done in steps. This should make PyPy
+ more responsive, e.g. in games. There are still other pauses, from
+ the GC and the JIT, but they should be on the order of 5
+ milliseconds each.
+
+* The JIT counters for hot code were never reset, which meant that a
+ process running for long enough would eventually JIT-compile more
+ and more rarely executed code. Not only is it useless to compile
+ such code, but as more compiled code means more memory used, this
+ gives the impression of a memory leak. This has been tentatively
+ fixed by decreasing the counters from time to time.
+
+* NumPy has been split: now PyPy only contains the core module, called
+ ``_numpypy``. The ``numpy`` module itself has been moved to
+ ``https://bitbucket.org/pypy/numpy`` and ``numpypy`` disappeared.
+ You need to install NumPy separately with a virtualenv:
+ ``pip install git+https://bitbucket.org/pypy/numpy.git``;
+ or directly:
+ ``git clone https://bitbucket.org/pypy/numpy.git``;
+ ``cd numpy``; ``pypy setup.py install``.
+
+* non-inlined calls have less overhead
+
+* Things that use ``sys.set_trace`` are now JITted (like coverage)
+
+* JSON decoding is now very fast (JSON encoding was already very fast)
+
+* various buffer copying methods experience speedups (like list-of-ints to
+ ``int[]`` buffer from cffi)
+
+* We finally wrote (hopefully) all the missing ``os.xxx()`` functions,
+ including ``os.startfile()`` on Windows and a handful of rare ones
+ on Posix.
+
+* numpy has a rudimentary C API that cooperates with ``cpyext``
+
+Cheers,
+Armin Rigo and Maciej Fijalkowski
diff --git a/pypy/doc/whatsnew-2.3.0.rst b/pypy/doc/whatsnew-2.3.0.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/whatsnew-2.3.0.rst
@@ -0,0 +1,154 @@
+=======================
+What's new in PyPy 2.2+
+=======================
+
+.. this is a revision shortly after release-2.2.x
+.. startrev: 4cd1bc8b3111
+
+.. branch: release-2.2.x
+
+.. branch: numpy-newbyteorder
+Clean up numpy types, add newbyteorder functionality
+
+.. branch: windows-packaging
+Package tk/tcl runtime with win32
+
+.. branch: armhf-singlefloat
+JIT support for singlefloats on ARM using the hardfloat ABI
+
+.. branch: voidtype_strformat
+Better support for record numpy arrays
+
+.. branch: osx-eci-frameworks-makefile
+OSX: Ensure frameworks end up in Makefile when specified in External compilation info
+
+.. branch: less-stringly-ops
+Use subclasses of SpaceOperation instead of SpaceOperator objects.
+Random cleanups in flowspace and annotator.
+
+.. branch: ndarray-buffer
+adds support for the buffer= argument to the ndarray ctor
+
+.. branch: better_ftime_detect2
+On OpenBSD do not pull in libcompat.a as it is about to be removed.
+And more generally, if you have gettimeofday(2) you will not need ftime(3).
+
+.. branch: timeb_h
+Remove dependency upon <sys/timeb.h> on OpenBSD. This will be disappearing
+along with libcompat.a.
+
+.. branch: OlivierBlanvillain/fix-3-broken-links-on-pypy-published-pap-1386250839215
+Fix 3 broken links on PyPy published papers in docs.
+
+.. branch: jit-ordereddict
+
+.. branch: refactor-str-types
+Remove multimethods on str/unicode/bytearray and make the implementations share code.
+
+.. branch: remove-del-from-generatoriterator
+Speed up generators that don't yield inside try or wait blocks by skipping
+unnecessary cleanup.
+
+.. branch: annotator
+Remove FlowObjSpace.
+Improve cohesion between rpython.flowspace and rpython.annotator.
+
+.. branch: detect-immutable-fields
+mapdicts keep track of whether or not an attribute is every assigned to
+multiple times. If it's only assigned once then an elidable lookup is used when
+possible.
+
+.. branch: precompiled-headers
+Create a Makefile using precompiled headers for MSVC platforms.
+The downside is a messy nmake-compatible Makefile. Since gcc shows minimal
+speedup, it was not implemented.
+
+.. branch: camelot
+With a properly configured 256-color terminal (TERM=...-256color), the
+Mandelbrot set shown during translation now uses a range of 50 colours.
+Essential!
+
+.. branch: NonConstant
+Simplify implementation of NonConstant.
+
+.. branch: array-propagate-len
+Kill some guards and operations in JIT traces by adding integer bounds
+propagation for getfield_(raw|gc) and getarrayitem_(raw|gc).
+
+.. branch: optimize-int-and
+Optimize away INT_AND with constant mask of 1s that fully cover the bitrange
+of other operand.
+
+.. branch: bounds-int-add-or
+Propagate appropriate bounds through INT_(OR|XOR|AND) operations if the
+operands are positive to kill some guards
+
+.. branch: remove-intlong-smm
+kills int/long/smalllong/bool multimethods
+
+.. branch: numpy-refactor
+Cleanup micronumpy module
+
+.. branch: int_w-refactor
+In a lot of places CPython allows objects with __int__ and __float__ instead of actual ints and floats, while until now pypy disallowed them. We fix it by making space.{int_w,float_w,etc.} accepting those objects by default, and disallowing conversions only when explicitly needed.
+
+.. branch: test-58c3d8552833
+Fix for getarrayitem_gc_pure optimization
+
+.. branch: simple-range-strategy
+Implements SimpleRangeListStrategy for case range(n) where n is a positive number.
+Makes some traces nicer by getting rid of multiplication for calculating loop counter
+and propagates that n > 0 further to get rid of guards.
+
+.. branch: popen-pclose
+Provide an exit status for popen'ed RFiles via pclose
+
+.. branch: stdlib-2.7.6
+Update stdlib to v2.7.6
+
+.. branch: virtual-raw-store-load
+Support for virtualizing raw_store/raw_load operations
+
+.. branch: refactor-buffer-api
+Separate the interp-level buffer API from the buffer type exposed to
+app-level. The `Buffer` class is now used by `W_MemoryView` and
+`W_Buffer`, which is not present in Python 3. Previously `W_Buffer` was
+an alias to `Buffer`, which was wrappable itself.
+
+.. 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
+
+.. branch: latest-improve-doc
+Fix broken links in documentation
+
+.. branch: ast-issue1673
+fix ast classes __dict__ are always empty problem and fix the ast deepcopy issue when
+there is missing field
+
+.. branch: issue1514
+Fix issues with reimporting builtin modules
+
+.. branch: numpypy-nditer
+Implement the core of nditer, without many of the fancy flags (external_loop, buffered)
+
+.. branch: numpy-speed
+Separate iterator from its state so jit can optimize better
+
+.. branch: numpy-searchsorted
+Implement searchsorted without sorter kwarg
+
+.. branch: openbsd-lib-prefix
+add 'lib' prefix to link libraries on OpenBSD
+
+.. branch: small-unroll-improvements
+Improve optimization of small allocation-heavy loops in the JIT
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -1,145 +1,11 @@
=======================
-What's new in PyPy 2.2+
+What's new in PyPy 2.3+
=======================
-.. this is a revision shortly after release-2.2.x
-.. startrev: 4cd1bc8b3111
+.. this is a revision shortly after release-2.3.x
+.. startrev: ba569fe1efdb
-.. branch: release-2.2.x
+.. branch: small-unroll-improvements
+Improve optimiziation of small allocation-heavy loops in the JIT
-.. branch: numpy-newbyteorder
-Clean up numpy types, add newbyteorder functionality
-
-.. branch: windows-packaging
-Package tk/tcl runtime with win32
-
-.. branch: armhf-singlefloat
-JIT support for singlefloats on ARM using the hardfloat ABI
-
-.. branch: voidtype_strformat
-Better support for record numpy arrays
-
-.. branch: osx-eci-frameworks-makefile
-OSX: Ensure frameworks end up in Makefile when specified in External compilation info
-
-.. branch: less-stringly-ops
-Use subclasses of SpaceOperation instead of SpaceOperator objects.
-Random cleanups in flowspace and annotator.
-
-.. branch: ndarray-buffer
-adds support for the buffer= argument to the ndarray ctor
-
-.. branch: better_ftime_detect2
-On OpenBSD do not pull in libcompat.a as it is about to be removed.
-And more generally, if you have gettimeofday(2) you will not need ftime(3).
-
-.. branch: timeb_h
-Remove dependency upon <sys/timeb.h> on OpenBSD. This will be disappearing
-along with libcompat.a.
-
-.. branch: OlivierBlanvillain/fix-3-broken-links-on-pypy-published-pap-1386250839215
-Fix 3 broken links on PyPy published papers in docs.
-
-.. branch: jit-ordereddict
-
-.. branch: refactor-str-types
-Remove multimethods on str/unicode/bytearray and make the implementations share code.
-
-.. branch: remove-del-from-generatoriterator
-Speed up generators that don't yield inside try or wait blocks by skipping
-unnecessary cleanup.
-
-.. branch: annotator
-Remove FlowObjSpace.
-Improve cohesion between rpython.flowspace and rpython.annotator.
-
-.. branch: detect-immutable-fields
-mapdicts keep track of whether or not an attribute is every assigned to
-multiple times. If it's only assigned once then an elidable lookup is used when
-possible.
-
-.. branch: precompiled-headers
-Create a Makefile using precompiled headers for MSVC platforms.
-The downside is a messy nmake-compatible Makefile. Since gcc shows minimal
-speedup, it was not implemented.
-
-.. branch: camelot
-With a properly configured 256-color terminal (TERM=...-256color), the
-Mandelbrot set shown during translation now uses a range of 50 colours.
-Essential!
-
-.. branch: NonConstant
-Simplify implementation of NonConstant.
-
-.. branch: array-propagate-len
-Kill some guards and operations in JIT traces by adding integer bounds
-propagation for getfield_(raw|gc) and getarrayitem_(raw|gc).
-
-.. branch: optimize-int-and
-Optimize away INT_AND with constant mask of 1s that fully cover the bitrange
-of other operand.
-
-.. branch: bounds-int-add-or
-Propagate appropriate bounds through INT_(OR|XOR|AND) operations if the
-operands are positive to kill some guards
-
-.. branch: remove-intlong-smm
-kills int/long/smalllong/bool multimethods
-
-.. branch: numpy-refactor
-Cleanup micronumpy module
-
-.. branch: int_w-refactor
-In a lot of places CPython allows objects with __int__ and __float__ instead of actual ints and floats, while until now pypy disallowed them. We fix it by making space.{int_w,float_w,etc.} accepting those objects by default, and disallowing conversions only when explicitly needed.
-
-.. branch: test-58c3d8552833
-Fix for getarrayitem_gc_pure optimization
-
-.. branch: simple-range-strategy
-Implements SimpleRangeListStrategy for case range(n) where n is a positive number.
-Makes some traces nicer by getting rid of multiplication for calculating loop counter
-and propagates that n > 0 further to get rid of guards.
-
-.. branch: popen-pclose
-Provide an exit status for popen'ed RFiles via pclose
-
-.. branch: stdlib-2.7.6
-Update stdlib to v2.7.6
-
-.. branch: virtual-raw-store-load
-Support for virtualizing raw_store/raw_load operations
-
-.. branch: refactor-buffer-api
-Separate the interp-level buffer API from the buffer type exposed to
-app-level. The `Buffer` class is now used by `W_MemoryView` and
-`W_Buffer`, which is not present in Python 3. Previously `W_Buffer` was
-an alias to `Buffer`, which was wrappable itself.
-
-.. 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
-
-.. branch: latest-improve-doc
-Fix broken links in documentation
-
-.. branch: ast-issue1673
-fix ast classes __dict__ are always empty problem and fix the ast deepcopy issue when
-there is missing field
-
-.. branch: issue1514
-Fix issues with reimporting builtin modules
-
-.. branch: numpypy-nditer
-Implement the core of nditer, without many of the fancy flags (external_loop, buffered)
-
-.. branch: numpy-speed
-Separate iterator from its state so jit can optimize better
+.. branch: reflex-support
diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst
--- a/pypy/doc/windows.rst
+++ b/pypy/doc/windows.rst
@@ -89,8 +89,23 @@
http://hboehm.info/gc/gc_source/gc-7.1.tar.gz
Versions 7.0 and 7.1 are known to work; the 6.x series won't work with
-pypy. Unpack this folder in the base directory. Then open a command
-prompt::
+pypy. Unpack this folder in the base directory.
+The default GC_abort(...) function in misc.c will try to open a MessageBox.
+You may want to disable this with the following patch::
+
+ --- a/misc.c Sun Apr 20 14:08:27 2014 +0300
+ +++ b/misc.c Sun Apr 20 14:08:37 2014 +0300
+ @@ -1058,7 +1058,7 @@
+ #ifndef PCR
+ void GC_abort(const char *msg)
+ {
+ -# if defined(MSWIN32)
+ +# if 0 && defined(MSWIN32)
+ (void) MessageBoxA(NULL, msg, "Fatal error in gc", MB_ICONERROR|MB_OK);
+ # else
+ GC_err_printf("%s\n", msg);
+
+Then open a command prompt::
cd gc-7.1
nmake -f NT_THREADS_MAKEFILE
diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py
--- a/pypy/module/_sre/interp_sre.py
+++ b/pypy/module/_sre/interp_sre.py
@@ -34,8 +34,9 @@
def slice_w(space, ctx, start, end, w_default):
if 0 <= start <= end:
- if isinstance(ctx, rsre_core.StrMatchContext):
- return space.wrapbytes(ctx._string[start:end])
+ if isinstance(ctx, rsre_core.BufMatchContext):
+ return space.wrapbytes(ctx._buffer.getslice(start, end, 1,
+ end-start))
elif isinstance(ctx, rsre_core.UnicodeMatchContext):
return space.wrap(ctx._unicodestr[start:end])
else:
@@ -97,7 +98,7 @@
space.wrap("cannot copy this pattern object"))
def make_ctx(self, w_string, pos=0, endpos=sys.maxint):
- """Make a StrMatchContext or a UnicodeMatchContext for searching
+ """Make a BufMatchContext or a UnicodeMatchContext for searching
in the given w_string object."""
space = self.space
if pos < 0:
@@ -117,16 +118,18 @@
return rsre_core.UnicodeMatchContext(self.code, unicodestr,
pos, endpos, self.flags)
else:
- str = space.bufferstr_w(w_string)
+ buf = space.buffer_w(w_string)
if (not space.is_none(self.w_pattern) and
space.isinstance_w(self.w_pattern, space.w_unicode)):
raise OperationError(space.w_TypeError, space.wrap(
"can't use a bytes pattern on a string-like object"))
- if pos > len(str):
- pos = len(str)
- if endpos > len(str):
- endpos = len(str)
- return rsre_core.StrMatchContext(self.code, str,
+ size = buf.getlength()
+ assert size >= 0
+ if pos > size:
+ pos = size
+ if endpos > size:
+ endpos = size
+ return rsre_core.BufMatchContext(self.code, buf,
pos, endpos, self.flags)
def getmatch(self, ctx, found):
@@ -488,8 +491,8 @@
def fget_string(self, space):
ctx = self.ctx
- if isinstance(ctx, rsre_core.StrMatchContext):
- return space.wrapbytes(ctx._string)
+ if isinstance(ctx, rsre_core.BufMatchContext):
+ return space.wrapbytes(ctx._buffer.as_str())
elif isinstance(ctx, rsre_core.UnicodeMatchContext):
return space.wrap(ctx._unicodestr)
else:
diff --git a/pypy/module/cppyy/__init__.py b/pypy/module/cppyy/__init__.py
--- a/pypy/module/cppyy/__init__.py
+++ b/pypy/module/cppyy/__init__.py
@@ -12,8 +12,10 @@
'_template_byname' : 'interp_cppyy.template_byname',
'_std_string_name' : 'interp_cppyy.std_string_name',
'_set_class_generator' : 'interp_cppyy.set_class_generator',
+ '_set_function_generator': 'interp_cppyy.set_function_generator',
'_register_class' : 'interp_cppyy.register_class',
'_is_static' : 'interp_cppyy.is_static',
+ '_get_nullptr' : 'interp_cppyy.get_nullptr',
'CPPInstance' : 'interp_cppyy.W_CPPInstance',
'addressof' : 'interp_cppyy.addressof',
'bind_object' : 'interp_cppyy.bind_object',
diff --git a/pypy/module/cppyy/capi/builtin_capi.py b/pypy/module/cppyy/capi/builtin_capi.py
--- a/pypy/module/cppyy/capi/builtin_capi.py
+++ b/pypy/module/cppyy/capi/builtin_capi.py
@@ -190,7 +190,8 @@
[C_SCOPE, C_INDEX], C_METHPTRGETTER_PTR,
releasegil=ts_reflect,
compilation_info=backend.eci,
- elidable_function=True)
+ elidable_function=True,
+ random_effects_on_gcobjs=False)
def c_get_methptr_getter(space, cppscope, index):
return _c_get_methptr_getter(cppscope.handle, index)
@@ -214,7 +215,8 @@
[], rffi.SIZE_T,
releasegil=ts_memory,
compilation_info=backend.eci,
- elidable_function=True)
+ elidable_function=True,
+ random_effects_on_gcobjs=False)
def c_function_arg_sizeof(space):
return _c_function_arg_sizeof()
_c_function_arg_typeoffset = rffi.llexternal(
@@ -222,7 +224,8 @@
[], rffi.SIZE_T,
releasegil=ts_memory,
compilation_info=backend.eci,
- elidable_function=True)
+ elidable_function=True,
+ random_effects_on_gcobjs=False)
def c_function_arg_typeoffset(space):
return _c_function_arg_typeoffset()
@@ -283,7 +286,8 @@
[C_TYPE, C_TYPE], rffi.INT,
releasegil=ts_reflect,
compilation_info=backend.eci,
- elidable_function=True)
+ elidable_function=True,
+ random_effects_on_gcobjs=False)
@jit.elidable_promote('2')
def c_is_subtype(space, derived, base):
if derived == base:
@@ -295,7 +299,8 @@
[C_TYPE, C_TYPE, C_OBJECT, rffi.INT], rffi.SIZE_T,
releasegil=ts_reflect,
compilation_info=backend.eci,
- elidable_function=True)
+ elidable_function=True,
+ random_effects_on_gcobjs=False)
@jit.elidable_promote('1,2,4')
def c_base_offset(space, derived, base, address, direction):
if derived == base:
@@ -543,19 +548,3 @@
compilation_info=backend.eci)
def c_stdstring2stdstring(space, cppobject):
return _c_stdstring2stdstring(cppobject)
-_c_assign2stdstring = rffi.llexternal(
- "cppyy_assign2stdstring",
- [C_OBJECT, rffi.CCHARP], lltype.Void,
- releasegil=ts_helper,
- compilation_info=backend.eci)
-def c_assign2stdstring(space, cppobject, svalue):
- charp = rffi.str2charp(svalue)
- _c_assign2stdstring(cppobject, charp)
- rffi.free_charp(charp)
-_c_free_stdstring = rffi.llexternal(
- "cppyy_free_stdstring",
- [C_OBJECT], lltype.Void,
- releasegil=ts_helper,
- compilation_info=backend.eci)
-def c_free_stdstring(space, cppobject):
- _c_free_stdstring(cppobject)
diff --git a/pypy/module/cppyy/capi/cint_capi.py b/pypy/module/cppyy/capi/cint_capi.py
--- a/pypy/module/cppyy/capi/cint_capi.py
+++ b/pypy/module/cppyy/capi/cint_capi.py
@@ -6,8 +6,11 @@
from pypy.interpreter.baseobjspace import W_Root
from rpython.translator.tool.cbuild import ExternalCompilationInfo
-from rpython.rtyper.lltypesystem import rffi
+from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib import libffi, rdynload
+from rpython.tool.udir import udir
+
+from pypy.module.cppyy.capi.capi_types import C_OBJECT
__all__ = ['identify', 'std_string_name', 'eci', 'c_load_dictionary']
@@ -19,21 +22,21 @@
if os.environ.get("ROOTSYS"):
import commands
(stat, incdir) = commands.getstatusoutput("root-config --incdir")
- if stat != 0: # presumably Reflex-only
- rootincpath = [os.path.join(os.environ["ROOTSYS"], "include")]
+ if stat != 0:
+ rootincpath = [os.path.join(os.environ["ROOTSYS"], "include"), py.path.local(udir)]
rootlibpath = [os.path.join(os.environ["ROOTSYS"], "lib64"), os.path.join(os.environ["ROOTSYS"], "lib")]
else:
- rootincpath = [incdir]
+ rootincpath = [incdir, py.path.local(udir)]
rootlibpath = commands.getoutput("root-config --libdir").split()
else:
- rootincpath = []
+ rootincpath = [py.path.local(udir)]
rootlibpath = []
def identify():
return 'CINT'
-ts_reflect = False
-ts_call = False
+ts_reflect = True
+ts_call = True
ts_memory = False
ts_helper = False
@@ -47,13 +50,15 @@
_cintdll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW)
with rffi.scoped_str2charp('libCore.so') as ll_libname:
_coredll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW)
+with rffi.scoped_str2charp('libHist.so') as ll_libname:
+ _coredll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW)
eci = ExternalCompilationInfo(
separate_module_files=[srcpath.join("cintcwrapper.cxx")],
include_dirs=[incpath] + rootincpath,
includes=["cintcwrapper.h"],
library_dirs=rootlibpath,
- libraries=["Core", "Cint"],
+ libraries=["Hist", "Core", "Cint"],
use_cpp_linker=True,
)
@@ -71,6 +76,23 @@
# CINT-specific pythonizations ===============================================
+_c_charp2TString = rffi.llexternal(
+ "cppyy_charp2TString",
+ [rffi.CCHARP], C_OBJECT,
+ releasegil=ts_helper,
+ compilation_info=eci)
+def c_charp2TString(space, svalue):
+ charp = rffi.str2charp(svalue)
+ result = _c_charp2TString(charp)
+ rffi.free_charp(charp)
+ return result
+_c_TString2TString = rffi.llexternal(
+ "cppyy_TString2TString",
+ [C_OBJECT], C_OBJECT,
+ releasegil=ts_helper,
+ compilation_info=eci)
+def c_TString2TString(space, cppobject):
+ return _c_TString2TString(cppobject)
def _get_string_data(space, w_obj, m1, m2 = None):
from pypy.module.cppyy import interp_cppyy
@@ -80,10 +102,85 @@
return w_1
return obj.space.call_method(w_1, m2)
+### TF1 ----------------------------------------------------------------------
+class State(object):
+ def __init__(self, space):
+ self.tfn_pyfuncs = []
+ self.tfn_callbacks = []
+
+_create_tf1 = rffi.llexternal(
+ "cppyy_create_tf1",
+ [rffi.CCHARP, rffi.ULONG, rffi.DOUBLE, rffi.DOUBLE, rffi.INT], C_OBJECT,
+ releasegil=False,
+ compilation_info=eci)
+
+ at unwrap_spec(args_w='args_w')
+def tf1_tf1(space, w_self, args_w):
+ """Pythonized version of TF1 constructor:
+ takes functions and callable objects, and allows a callback into them."""
+
+ from pypy.module.cppyy import interp_cppyy
+ tf1_class = interp_cppyy.scope_byname(space, "TF1")
+
+ # expected signature:
+ # 1. (char* name, pyfunc, double xmin, double xmax, int npar = 0)
+ argc = len(args_w)
+
+ try:
+ # Note: argcount is +1 for the class (== w_self)
+ if argc < 5 or 6 < argc:
+ raise TypeError("wrong number of arguments")
+
+ # second argument must be a name
+ funcname = space.str_w(args_w[1])
+
+ # last (optional) argument is number of parameters
+ npar = 0
+ if argc == 6: npar = space.int_w(args_w[5])
+
+ # third argument must be a callable python object
+ w_callable = args_w[2]
+ if not space.is_true(space.callable(w_callable)):
+ raise TypeError("2nd argument is not a valid python callable")
+
+ # generate a pointer to function
+ from pypy.module._cffi_backend import newtype, ctypefunc, func
+
+ c_double = newtype.new_primitive_type(space, 'double')
+ c_doublep = newtype.new_pointer_type(space, c_double)
+
+ # wrap the callable as the signature needs modifying
+ w_ifunc = interp_cppyy.get_interface_func(space, w_callable, npar)
+
+ w_cfunc = ctypefunc.W_CTypeFunc(space, [c_doublep, c_doublep], c_double, False)
+ w_callback = func.callback(space, w_cfunc, w_ifunc, None)
+ funcaddr = rffi.cast(rffi.ULONG, w_callback.get_closure())
+
+ # so far, so good; leaves on issue: CINT is expecting a wrapper, but
+ # we need the overload that takes a function pointer, which is not in
+ # the dictionary, hence this helper:
+ newinst = _create_tf1(space.str_w(args_w[1]), funcaddr,
+ space.float_w(args_w[3]), space.float_w(args_w[4]), npar)
+
+ from pypy.module.cppyy import interp_cppyy
+ w_instance = interp_cppyy.wrap_cppobject(space, newinst, tf1_class,
+ do_cast=False, python_owns=True, fresh=True)
+
+ # tie all the life times to the TF1 instance
+ space.setattr(w_instance, space.wrap('_callback'), w_callback)
+
+ return w_instance
+ except (OperationError, TypeError, IndexError), e:
+ newargs_w = args_w[1:] # drop class
+
+ # return control back to the original, unpythonized overload
+ ol = tf1_class.get_overload("TF1")
+ return ol.call(None, newargs_w)
+
### TTree --------------------------------------------------------------------
_ttree_Branch = rffi.llexternal(
"cppyy_ttree_Branch",
- [rffi.VOIDP, rffi.CCHARP, rffi.CCHARP, rffi.VOIDP, rffi.INT, rffi.INT], rffi.LONG,
+ [rffi.VOIDP, rffi.CCHARP, rffi.CCHARP, rffi.VOIDP, rffi.INT, rffi.INT], C_OBJECT,
releasegil=False,
compilation_info=eci)
@@ -202,6 +299,8 @@
# some instance
klass = interp_cppyy.scope_byname(space, space.str_w(w_klassname))
w_obj = klass.construct()
+ # 0x10000 = kDeleteObject; reset because we own the object
+ space.call_method(w_branch, "ResetBit", space.wrap(0x10000))
space.call_method(w_branch, "SetObject", w_obj)
space.call_method(w_branch, "GetEntry", space.wrap(entry))
space.setattr(w_self, args_w[0], w_obj)
@@ -274,6 +373,9 @@
allfuncs = [
+ ### TF1
+ tf1_tf1,
+
### TTree
ttree_Branch, ttree_iter, ttree_getattr,
]
@@ -288,7 +390,14 @@
# callback coming in when app-level bound classes have been created
def pythonize(space, name, w_pycppclass):
- if name == "TFile":
+ if name == "TCollection":
+ _method_alias(space, w_pycppclass, "append", "Add")
+ _method_alias(space, w_pycppclass, "__len__", "GetSize")
+
+ elif name == "TF1":
+ space.setattr(w_pycppclass, space.wrap("__new__"), _pythonizations["tf1_tf1"])
+
+ elif name == "TFile":
_method_alias(space, w_pycppclass, "__getattr__", "Get")
elif name == "TObjString":
@@ -310,3 +419,17 @@
elif name[0:8] == "TVectorT": # TVectorT<> template
_method_alias(space, w_pycppclass, "__len__", "GetNoElements")
+
+# destruction callback (needs better solution, but this is for CINT
+# only and should not appear outside of ROOT-specific uses)
+from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL
+
+ at cpython_api([rffi.VOIDP], lltype.Void, error=CANNOT_FAIL)
+def _Py_cppyy_recursive_remove(space, cppobject):
+ from pypy.module.cppyy.interp_cppyy import memory_regulator
+ from pypy.module.cppyy.capi import C_OBJECT, C_NULL_OBJECT
+
+ obj = memory_regulator.retrieve(rffi.cast(C_OBJECT, cppobject))
+ if obj is not None:
+ memory_regulator.unregister(obj)
+ obj._rawobject = C_NULL_OBJECT
diff --git a/pypy/module/cppyy/capi/cling_capi.py b/pypy/module/cppyy/capi/cling_capi.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cppyy/capi/cling_capi.py
@@ -0,0 +1,69 @@
+import py, os
+
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from rpython.rtyper.lltypesystem import rffi
+from rpython.rlib import libffi, rdynload
+
+__all__ = ['identify', 'std_string_name', 'eci', 'c_load_dictionary']
+
+pkgpath = py.path.local(__file__).dirpath().join(os.pardir)
+srcpath = pkgpath.join("src")
+incpath = pkgpath.join("include")
+
+import commands
+(config_stat, incdir) = commands.getstatusoutput("root-config --incdir")
+
+if os.environ.get("ROOTSYS"):
+ if config_stat != 0: # presumably Reflex-only
+ rootincpath = [os.path.join(os.environ["ROOTSYS"], "interpreter/cling/include"),
+ os.path.join(os.environ["ROOTSYS"], "interpreter/llvm/inst/include")]
+ rootlibpath = [os.path.join(os.environ["ROOTSYS"], "lib64"), os.path.join(os.environ["ROOTSYS"], "lib")]
+ else:
+ rootincpath = [incdir]
+ rootlibpath = commands.getoutput("root-config --libdir").split()
+else:
+ if config_stat == 0:
+ rootincpath = [incdir]
+ rootlibpath = commands.getoutput("root-config --libdir").split()
+ else:
+ rootincpath = []
+ rootlibpath = []
+
+def identify():
+ return 'Cling'
+
+ts_reflect = False
+ts_call = 'auto'
+ts_memory = 'auto'
+ts_helper = 'auto'
+
+std_string_name = 'std::basic_string<char>'
+
+eci = ExternalCompilationInfo(
+ separate_module_files=[srcpath.join("clingcwrapper.cxx")],
+ include_dirs=[incpath] + rootincpath,
+ includes=["clingcwrapper.h"],
+ library_dirs=rootlibpath,
+ libraries=["Cling"],
+ compile_extra=["-fno-strict-aliasing"],
+ use_cpp_linker=True,
+)
+
+_c_load_dictionary = rffi.llexternal(
+ "cppyy_load_dictionary",
+ [rffi.CCHARP], rdynload.DLLHANDLE,
+ releasegil=False,
+ compilation_info=eci)
+
+def c_load_dictionary(name):
+ pch = _c_load_dictionary(name)
+ return pch
+
+
+# Cling-specific pythonizations
+def register_pythonizations(space):
+ "NOT_RPYTHON"
+ pass
+
+def pythonize(space, name, w_pycppclass):
+ pass
diff --git a/pypy/module/cppyy/capi/loadable_capi.py b/pypy/module/cppyy/capi/loadable_capi.py
--- a/pypy/module/cppyy/capi/loadable_capi.py
+++ b/pypy/module/cppyy/capi/loadable_capi.py
@@ -214,15 +214,22 @@
'charp2stdstring' : ([c_ccharp], c_object),
'stdstring2stdstring' : ([c_object], c_object),
- 'assign2stdstring' : ([c_object, c_ccharp], c_void),
- 'free_stdstring' : ([c_object], c_void),
}
+ # size/offset are backend-specific but fixed after load
+ self.c_sizeof_farg = 0
+ self.c_offset_farg = 0
+
+
def load_reflection_library(space):
state = space.fromcache(State)
if state.library is None:
from pypy.module._cffi_backend.libraryobj import W_Library
state.library = W_Library(space, reflection_library, rdynload.RTLD_LOCAL | rdynload.RTLD_LAZY)
+ if state.library:
+ # fix constants
+ state.c_sizeof_farg = _cdata_to_size_t(space, call_capi(space, 'function_arg_sizeof', []))
+ state.c_offset_farg = _cdata_to_size_t(space, call_capi(space, 'function_arg_typeoffset', []))
return state.library
def verify_backend(space):
@@ -342,12 +349,12 @@
return _cdata_to_ptr(space, call_capi(space, 'allocate_function_args', [_Arg(l=size)]))
def c_deallocate_function_args(space, cargs):
call_capi(space, 'deallocate_function_args', [_Arg(vp=cargs)])
- at jit.elidable
def c_function_arg_sizeof(space):
- return _cdata_to_size_t(space, call_capi(space, 'function_arg_sizeof', []))
- at jit.elidable
+ state = space.fromcache(State)
+ return state.c_sizeof_farg
def c_function_arg_typeoffset(space):
- return _cdata_to_size_t(space, call_capi(space, 'function_arg_typeoffset', []))
+ state = space.fromcache(State)
+ return state.c_offset_farg
# scope reflection information -----------------------------------------------
def c_is_namespace(space, scope):
@@ -367,13 +374,12 @@
def c_base_name(space, cppclass, base_index):
args = [_Arg(l=cppclass.handle), _Arg(l=base_index)]
return charp2str_free(space, call_capi(space, 'base_name', args))
- at jit.elidable_promote('2')
def c_is_subtype(space, derived, base):
+ jit.promote(base)
if derived == base:
return bool(1)
return space.bool_w(call_capi(space, 'is_subtype', [_Arg(l=derived.handle), _Arg(l=base.handle)]))
- at jit.elidable_promote('1,2,4')
def _c_base_offset(space, derived_h, base_h, address, direction):
args = [_Arg(l=derived_h), _Arg(l=base_h), _Arg(l=address), _Arg(l=direction)]
return _cdata_to_size_t(space, call_capi(space, 'base_offset', args))
@@ -504,11 +510,6 @@
return _cdata_to_cobject(space, call_capi(space, 'charp2stdstring', [_Arg(s=svalue)]))
def c_stdstring2stdstring(space, cppobject):
return _cdata_to_cobject(space, call_capi(space, 'stdstring2stdstring', [_Arg(l=cppobject)]))
-def c_assign2stdstring(space, cppobject, svalue):
- args = [_Arg(l=cppobject), _Arg(s=svalue)]
- call_capi(space, 'assign2stdstring', args)
-def c_free_stdstring(space, cppobject):
- call_capi(space, 'free_stdstring', [_Arg(l=cppobject)])
# loadable-capi-specific pythonizations (none, as the capi isn't known until runtime)
def register_pythonizations(space):
diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py
--- a/pypy/module/cppyy/converter.py
+++ b/pypy/module/cppyy/converter.py
@@ -6,8 +6,8 @@
from rpython.rlib.rarithmetic import r_singlefloat
from rpython.rlib import jit_libffi, rfloat
-from pypy.module._rawffi.interp_rawffi import unpack_simple_shape
-from pypy.module._rawffi.array import W_Array
+from pypy.module._rawffi.interp_rawffi import letter2tp
+from pypy.module._rawffi.array import W_Array, W_ArrayInstance
from pypy.module.cppyy import helper, capi, ffitypes
@@ -47,21 +47,35 @@
return rawobject
return capi.C_NULL_OBJECT
+def is_nullpointer_specialcase(space, w_obj):
+ # 0, None, and nullptr may serve as "NULL", check for any of them
+
+ # integer 0
+ try:
+ return space.int_w(w_obj) == 0
+ except Exception:
+ pass
+ # None or nullptr
+ from pypy.module.cppyy import interp_cppyy
+ return space.is_true(space.is_(w_obj, space.w_None)) or \
+ space.is_true(space.is_(w_obj, interp_cppyy.get_nullptr(space)))
+
def get_rawbuffer(space, w_obj):
+ # raw buffer
try:
buf = space.buffer_w(w_obj)
return rffi.cast(rffi.VOIDP, buf.get_raw_address())
except Exception:
pass
- # special case: allow integer 0 as NULL
+ # array type
try:
- buf = space.int_w(w_obj)
- if buf == 0:
- return rffi.cast(rffi.VOIDP, 0)
+ arr = space.interp_w(W_ArrayInstance, w_obj, can_be_None=True)
+ if arr:
+ return rffi.cast(rffi.VOIDP, space.uint_w(arr.getbuffer(space)))
except Exception:
pass
- # special case: allow None as NULL
- if space.is_true(space.is_(w_obj, space.w_None)):
+ # pre-defined NULL
+ if is_nullpointer_specialcase(space, w_obj):
return rffi.cast(rffi.VOIDP, 0)
raise TypeError("not an addressable buffer")
@@ -118,7 +132,7 @@
def __getattr__(self, name):
if name.startswith('array_'):
typecode = name[len('array_'):]
- arr = self.space.interp_w(W_Array, unpack_simple_shape(self.space, self.space.wrap(typecode)))
+ arr = self.space.interp_w(W_Array, letter2tp(self.space, typecode))
setattr(self, name, arr)
return arr
raise AttributeError(name)
@@ -139,8 +153,6 @@
self.size = array_size
def from_memory(self, space, w_obj, w_pycppclass, offset):
- if hasattr(space, "fake"):
- raise NotImplementedError
# read access, so no copy needed
address_value = self._get_raw_address(space, w_obj, offset)
address = rffi.cast(rffi.ULONG, address_value)
@@ -261,8 +273,7 @@
self.name = name
def convert_argument(self, space, w_obj, address, call_local):
- raise OperationError(space.w_TypeError,
- space.wrap('no converter available for type "%s"' % self.name))
+ self._is_abstract(space)
class BoolConverter(ffitypes.typeid(bool), TypeConverter):
@@ -372,7 +383,12 @@
try:
obj = get_rawbuffer(space, w_obj)
except TypeError:
- obj = rffi.cast(rffi.VOIDP, get_rawobject(space, w_obj))
+ try:
+ # TODO: accept a 'capsule' rather than naked int
+ # (do accept int(0), though)
+ obj = rffi.cast(rffi.VOIDP, space.int_w(w_obj))
+ except Exception:
+ obj = rffi.cast(rffi.VOIDP, get_rawobject(space, w_obj))
return obj
def convert_argument(self, space, w_obj, address, call_local):
@@ -385,6 +401,24 @@
x = rffi.cast(rffi.VOIDPP, address)
x[0] = self._unwrap_object(space, w_obj)
+ def from_memory(self, space, w_obj, w_pycppclass, offset):
+ # returned as a long value for the address (INTPTR_T is not proper
+ # per se, but rffi does not come with a PTRDIFF_T)
+ address = self._get_raw_address(space, w_obj, offset)
+ ptrval = rffi.cast(rffi.ULONG, rffi.cast(rffi.VOIDPP, address)[0])
+ if ptrval == 0:
+ from pypy.module.cppyy import interp_cppyy
+ return interp_cppyy.get_nullptr(space)
+ arr = space.interp_w(W_Array, letter2tp(space, 'P'))
+ return arr.fromaddress(space, ptrval, sys.maxint)
+
+ def to_memory(self, space, w_obj, w_value, offset):
+ address = rffi.cast(rffi.VOIDPP, self._get_raw_address(space, w_obj, offset))
+ if is_nullpointer_specialcase(space, w_value):
+ address[0] = rffi.cast(rffi.VOIDP, 0)
+ else:
+ address[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_value))
+
class VoidPtrPtrConverter(TypeConverter):
_immutable_fields_ = ['uses_local']
@@ -412,7 +446,7 @@
_immutable_fields_ = ['uses_local']
uses_local = True
-class InstancePtrConverter(TypeConverter):
+class InstanceRefConverter(TypeConverter):
_immutable_fields_ = ['libffitype', 'cppclass']
libffitype = jit_libffi.types.pointer
@@ -444,17 +478,7 @@
x = rffi.cast(rffi.VOIDPP, address)
x[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_obj))
- def from_memory(self, space, w_obj, w_pycppclass, offset):
- address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj, offset))
- from pypy.module.cppyy import interp_cppyy
- return interp_cppyy.wrap_cppobject(space, address, self.cppclass,
- do_cast=False, is_ref=True)
-
- def to_memory(self, space, w_obj, w_value, offset):
- address = rffi.cast(rffi.VOIDPP, self._get_raw_address(space, w_obj, offset))
- address[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_value))
-
-class InstanceConverter(InstancePtrConverter):
+class InstanceConverter(InstanceRefConverter):
def convert_argument_libffi(self, space, w_obj, address, call_local):
from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
@@ -468,6 +492,28 @@
def to_memory(self, space, w_obj, w_value, offset):
self._is_abstract(space)
+
+class InstancePtrConverter(InstanceRefConverter):
+
+ def _unwrap_object(self, space, w_obj):
+ try:
+ return InstanceRefConverter._unwrap_object(self, space, w_obj)
+ except OperationError, e:
+ # if not instance, allow certain special cases
+ if is_nullpointer_specialcase(space, w_obj):
+ return capi.C_NULL_OBJECT
+ raise e
+
+ def from_memory(self, space, w_obj, w_pycppclass, offset):
+ address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj, offset))
+ from pypy.module.cppyy import interp_cppyy
+ return interp_cppyy.wrap_cppobject(space, address, self.cppclass,
+ do_cast=False, is_ref=True)
+
+ def to_memory(self, space, w_obj, w_value, offset):
+ address = rffi.cast(rffi.VOIDPP, self._get_raw_address(space, w_obj, offset))
+ address[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_value))
+
class InstancePtrPtrConverter(InstancePtrConverter):
_immutable_fields_ = ['uses_local']
@@ -487,12 +533,6 @@
from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
raise FastCallNotPossible
- def from_memory(self, space, w_obj, w_pycppclass, offset):
- self._is_abstract(space)
-
- def to_memory(self, space, w_obj, w_value, offset):
- self._is_abstract(space)
-
def finalize_call(self, space, w_obj, call_local):
from pypy.module.cppyy.interp_cppyy import W_CPPInstance
assert isinstance(w_obj, W_CPPInstance)
@@ -501,7 +541,6 @@
class StdStringConverter(InstanceConverter):
- _immutable_fields_ = ['cppclass']
def __init__(self, space, extra):
from pypy.module.cppyy import interp_cppyy
@@ -509,24 +548,25 @@
InstanceConverter.__init__(self, space, cppclass)
def _unwrap_object(self, space, w_obj):
- try:
+ from pypy.module.cppyy.interp_cppyy import W_CPPInstance
+ if isinstance(w_obj, W_CPPInstance):
+ arg = InstanceConverter._unwrap_object(self, space, w_obj)
+ return capi.c_stdstring2stdstring(space, arg)
+ else:
return capi.c_charp2stdstring(space, space.str_w(w_obj))
- except Exception, e:
- arg = InstanceConverter._unwrap_object(self, space, w_obj)
- result = capi.c_stdstring2stdstring(space, arg)
- return result
def to_memory(self, space, w_obj, w_value, offset):
try:
address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj, offset))
- capi.c_assign2stdstring(space, address, space.str_w(w_value))
- return
+ assign = self.cppclass.get_overload("__assign__")
+ from pypy.module.cppyy import interp_cppyy
+ assign.call(
+ interp_cppyy.wrap_cppobject(space, address, self.cppclass, do_cast=False), [w_value])
except Exception:
- pass
- return InstanceConverter.to_memory(self, space, w_obj, w_value, offset)
+ InstanceConverter.to_memory(self, space, w_obj, w_value, offset)
def free_argument(self, space, arg, call_local):
- capi.c_free_stdstring(space, rffi.cast(capi.C_OBJECT, rffi.cast(rffi.VOIDPP, arg)[0]))
+ capi.c_destruct(space, self.cppclass, rffi.cast(capi.C_OBJECT, rffi.cast(rffi.VOIDPP, arg)[0]))
class StdStringRefConverter(InstancePtrConverter):
_immutable_fields_ = ['cppclass']
@@ -570,6 +610,7 @@
def free_argument(self, space, arg, call_local):
if hasattr(space, "fake"):
raise NotImplementedError
+ space.getbuiltinmodule("cpyext")
from pypy.module.cpyext.pyobject import Py_DecRef, PyObject
Py_DecRef(space, rffi.cast(PyObject, rffi.cast(rffi.VOIDPP, arg)[0]))
@@ -627,8 +668,10 @@
# type check for the benefit of the annotator
from pypy.module.cppyy.interp_cppyy import W_CPPClass
cppclass = space.interp_w(W_CPPClass, cppclass, can_be_None=False)
- if compound == "*" or compound == "&":
+ if compound == "*":
return InstancePtrConverter(space, cppclass)
+ elif compound == "&":
+ return InstanceRefConverter(space, cppclass)
elif compound == "**":
return InstancePtrPtrConverter(space, cppclass)
elif compound == "":
@@ -654,7 +697,7 @@
_converters["void**"] = VoidPtrPtrConverter
_converters["void*&"] = VoidPtrRefConverter
-# special cases (note: CINT backend requires the simple name 'string')
+# special cases (note: 'string' aliases added below)
_converters["std::basic_string<char>"] = StdStringConverter
_converters["const std::basic_string<char>&"] = StdStringConverter # TODO: shouldn't copy
_converters["std::basic_string<char>&"] = StdStringRefConverter
@@ -776,3 +819,27 @@
for c_type, alias in aliases:
_converters[alias] = _converters[c_type]
_add_aliased_converters()
+
+# ROOT-specific converters (TODO: this is a general use case and should grow
+# an API; putting it here is done only to circumvent circular imports)
+if capi.identify() == "CINT":
+
+ class TStringConverter(InstanceConverter):
+ def __init__(self, space, extra):
+ from pypy.module.cppyy import interp_cppyy
+ cppclass = interp_cppyy.scope_byname(space, "TString")
+ InstanceConverter.__init__(self, space, cppclass)
+
+ def _unwrap_object(self, space, w_obj):
+ from pypy.module.cppyy import interp_cppyy
+ if isinstance(w_obj, interp_cppyy.W_CPPInstance):
+ arg = InstanceConverter._unwrap_object(self, space, w_obj)
+ return capi.backend.c_TString2TString(space, arg)
+ else:
+ return capi.backend.c_charp2TString(space, space.str_w(w_obj))
+
+ def free_argument(self, space, arg, call_local):
+ capi.c_destruct(space, self.cppclass, rffi.cast(capi.C_OBJECT, rffi.cast(rffi.VOIDPP, arg)[0]))
+
+ _converters["TString"] = TStringConverter
+ _converters["const TString&"] = TStringConverter
diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py
--- a/pypy/module/cppyy/executor.py
+++ b/pypy/module/cppyy/executor.py
@@ -53,17 +53,12 @@
if hasattr(space, "fake"):
raise NotImplementedError
lresult = capi.c_call_l(space, cppmethod, cppthis, num_args, args)
- address = rffi.cast(rffi.ULONG, lresult)
+ ptrval = rffi.cast(rffi.ULONG, lresult)
arr = space.interp_w(W_Array, unpack_simple_shape(space, space.wrap(self.typecode)))
- if address == 0:
- # TODO: fix this hack; fromaddress() will allocate memory if address
- # is null and there seems to be no way around it (ll_buffer can not
- # be touched directly)
- nullarr = arr.fromaddress(space, address, 0)
- assert isinstance(nullarr, W_ArrayInstance)
- nullarr.free(space)
- return nullarr
- return arr.fromaddress(space, address, sys.maxint)
+ if ptrval == 0:
+ from pypy.module.cppyy import interp_cppyy
+ return interp_cppyy.get_nullptr(space)
+ return arr.fromaddress(space, ptrval, sys.maxint)
class VoidExecutor(FunctionExecutor):
@@ -144,7 +139,7 @@
from pypy.module.cppyy import interp_cppyy
newthis = capi.c_constructor(space, cppmethod, cpptype, num_args, args)
assert lltype.typeOf(newthis) == capi.C_OBJECT
- return space.wrap(newthis)
+ return space.wrap(rffi.cast(rffi.LONG, newthis)) # really want ptrdiff_t here
class InstancePtrExecutor(FunctionExecutor):
@@ -160,7 +155,8 @@
from pypy.module.cppyy import interp_cppyy
long_result = capi.c_call_l(space, cppmethod, cppthis, num_args, args)
ptr_result = rffi.cast(capi.C_OBJECT, long_result)
- return interp_cppyy.wrap_cppobject(space, ptr_result, self.cppclass)
+ pyres = interp_cppyy.wrap_cppobject(space, ptr_result, self.cppclass)
+ return pyres
def execute_libffi(self, space, cif_descr, funcaddr, buffer):
jit_libffi.jit_ffi_call(cif_descr, funcaddr, buffer)
@@ -189,7 +185,7 @@
long_result = capi.c_call_o(space, cppmethod, cppthis, num_args, args, self.cppclass)
ptr_result = rffi.cast(capi.C_OBJECT, long_result)
return interp_cppyy.wrap_cppobject(space, ptr_result, self.cppclass,
- do_cast=False, python_owns=True)
+ do_cast=False, python_owns=True, fresh=True)
def execute_libffi(self, space, cif_descr, funcaddr, buffer):
from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
@@ -206,6 +202,13 @@
from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
raise FastCallNotPossible
+class StdStringRefExecutor(InstancePtrExecutor):
+
+ def __init__(self, space, cppclass):
+ from pypy.module.cppyy import interp_cppyy
+ cppclass = interp_cppyy.scope_byname(space, capi.std_string_name)
+ InstancePtrExecutor.__init__(self, space, cppclass)
+
class PyObjectExecutor(PtrTypeExecutor):
@@ -295,12 +298,12 @@
_executors["void*"] = PtrTypeExecutor
_executors["const char*"] = CStringExecutor
-# special cases
+# special cases (note: 'string' aliases added below)
_executors["constructor"] = ConstructorExecutor
_executors["std::basic_string<char>"] = StdStringExecutor
-_executors["const std::basic_string<char>&"] = StdStringExecutor
-_executors["std::basic_string<char>&"] = StdStringExecutor # TODO: shouldn't copy
+_executors["const std::basic_string<char>&"] = StdStringRefExecutor
+_executors["std::basic_string<char>&"] = StdStringRefExecutor
_executors["PyObject*"] = PyObjectExecutor
@@ -363,7 +366,11 @@
"NOT_RPYTHON"
aliases = (
("const char*", "char*"),
+
("std::basic_string<char>", "string"),
+ ("const std::basic_string<char>&", "const string&"),
+ ("std::basic_string<char>&", "string&"),
+
("PyObject*", "_object*"),
)
diff --git a/pypy/module/cppyy/include/capi.h b/pypy/module/cppyy/include/capi.h
--- a/pypy/module/cppyy/include/capi.h
+++ b/pypy/module/cppyy/include/capi.h
@@ -89,11 +89,11 @@
cppyy_index_t cppyy_get_global_operator(
cppyy_scope_t scope, cppyy_scope_t lc, cppyy_scope_t rc, const char* op);
- /* method properties ----------------------------------------------------- */
+ /* method properties ------------------------------------------------------ */
int cppyy_is_constructor(cppyy_type_t type, cppyy_index_t idx);
int cppyy_is_staticmethod(cppyy_type_t type, cppyy_index_t idx);
- /* data member reflection information ------------------------------------ */
+ /* data member reflection information ------------------------------------- */
int cppyy_num_datamembers(cppyy_scope_t scope);
char* cppyy_datamember_name(cppyy_scope_t scope, int datamember_index);
char* cppyy_datamember_type(cppyy_scope_t scope, int datamember_index);
@@ -101,7 +101,7 @@
int cppyy_datamember_index(cppyy_scope_t scope, const char* name);
- /* data member properties ------------------------------------------------ */
+ /* data member properties ------------------------------------------------- */
int cppyy_is_publicdata(cppyy_type_t type, int datamember_index);
int cppyy_is_staticdata(cppyy_type_t type, int datamember_index);
@@ -112,8 +112,6 @@
cppyy_object_t cppyy_charp2stdstring(const char* str);
cppyy_object_t cppyy_stdstring2stdstring(cppyy_object_t ptr);
- void cppyy_assign2stdstring(cppyy_object_t ptr, const char* str);
- void cppyy_free_stdstring(cppyy_object_t ptr);
#ifdef __cplusplus
}
diff --git a/pypy/module/cppyy/include/cintcwrapper.h b/pypy/module/cppyy/include/cintcwrapper.h
--- a/pypy/module/cppyy/include/cintcwrapper.h
+++ b/pypy/module/cppyy/include/cintcwrapper.h
@@ -11,12 +11,18 @@
void* cppyy_load_dictionary(const char* lib_name);
/* pythonization helpers */
+ cppyy_object_t cppyy_create_tf1(const char* funcname, unsigned long address,
+ double xmin, double xmax, int npar);
+
cppyy_object_t cppyy_ttree_Branch(
void* vtree, const char* branchname, const char* classname,
void* addobj, int bufsize, int splitlevel);
long long cppyy_ttree_GetEntry(void* vtree, long long entry);
+ cppyy_object_t cppyy_charp2TString(const char* str);
+ cppyy_object_t cppyy_TString2TString(cppyy_object_t ptr);
+
#ifdef __cplusplus
}
#endif // ifdef __cplusplus
diff --git a/pypy/module/cppyy/include/clingcwrapper.h b/pypy/module/cppyy/include/clingcwrapper.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cppyy/include/clingcwrapper.h
@@ -0,0 +1,37 @@
+#ifndef CPPYY_CLINGCWRAPPER
+#define CPPYY_CLINGCWRAPPER
+
+#include "capi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // ifdef __cplusplus
+
+ /* misc helpers */
+ void* cppyy_load_dictionary(const char* lib_name);
+
+#ifdef __cplusplus
+}
+#endif // ifdef __cplusplus
+
+// TODO: pick up from llvm-config --cxxflags
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS
+#endif
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+
+// Wrapper callback: except this to become available from Cling directly
+typedef void (*CPPYY_Cling_Wrapper_t)(void*, int, void**, void*);
+
+#endif // ifndef CPPYY_CLINGCWRAPPER
diff --git a/pypy/module/cppyy/include/cppyy.h b/pypy/module/cppyy/include/cppyy.h
--- a/pypy/module/cppyy/include/cppyy.h
+++ b/pypy/module/cppyy/include/cppyy.h
@@ -17,7 +17,7 @@
#ifdef __cplusplus
struct CPPYY_G__p2p {
#else
-#typedef struct
+typedef struct {
#endif
long i;
int reftype;
diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -40,9 +40,28 @@
def __init__(self, space):
self.cppscope_cache = {
"void" : W_CPPClass(space, "void", capi.C_NULL_TYPE) }
+ self.w_nullptr = None
self.cpptemplate_cache = {}
self.cppclass_registry = {}
self.w_clgen_callback = None
+ self.w_fngen_callback = None
+
+def get_nullptr(space):
+ if hasattr(space, "fake"):
+ raise NotImplementedError
+ state = space.fromcache(State)
+ if state.w_nullptr is None:
+ from pypy.module._rawffi.interp_rawffi import unpack_simple_shape
+ from pypy.module._rawffi.array import W_Array, W_ArrayInstance
+ arr = space.interp_w(W_Array, unpack_simple_shape(space, space.wrap('P')))
+ # TODO: fix this hack; fromaddress() will allocate memory if address
+ # is null and there seems to be no way around it (ll_buffer can not
+ # be touched directly)
+ nullarr = arr.fromaddress(space, rffi.cast(rffi.ULONG, 0), 0)
+ assert isinstance(nullarr, W_ArrayInstance)
+ nullarr.free(space)
+ state.w_nullptr = space.wrap(nullarr)
+ return state.w_nullptr
@unwrap_spec(name=str)
def resolve_name(space, name):
@@ -101,6 +120,11 @@
state = space.fromcache(State)
state.w_clgen_callback = w_callback
+ at unwrap_spec(w_callback=W_Root)
+def set_function_generator(space, w_callback):
+ state = space.fromcache(State)
+ state.w_fngen_callback = w_callback
+
def register_class(space, w_pycppclass):
w_cppclass = space.findattr(w_pycppclass, space.wrap("_cpp_proxy"))
cppclass = space.interp_w(W_CPPClass, w_cppclass, can_be_None=False)
@@ -108,7 +132,7 @@
# class allows simple aliasing of methods)
capi.pythonize(space, cppclass.name, w_pycppclass)
state = space.fromcache(State)
- state.cppclass_registry[cppclass.handle] = w_pycppclass
+ state.cppclass_registry[rffi.cast(rffi.LONG, cppclass.handle)] = w_pycppclass
class W_CPPLibrary(W_Root):
@@ -580,12 +604,10 @@
def get_returntype(self):
return self.space.wrap(self.converter.name)
- @jit.elidable_promote()
def _get_offset(self, cppinstance):
if cppinstance:
assert lltype.typeOf(cppinstance.cppclass.handle) == lltype.typeOf(self.scope.handle)
- offset = self.offset + capi.c_base_offset(self.space,
- cppinstance.cppclass, self.scope, cppinstance.get_rawobject(), 1)
+ offset = self.offset + cppinstance.cppclass.get_base_offset(cppinstance, self.scope)
else:
offset = self.offset
return offset
@@ -694,7 +716,6 @@
def get_method_names(self):
return self.space.newlist([self.space.wrap(name) for name in self.methods])
- @jit.elidable_promote('0')
def get_overload(self, name):
try:
return self.methods[name]
@@ -707,7 +728,6 @@
def get_datamember_names(self):
return self.space.newlist([self.space.wrap(name) for name in self.datamembers])
- @jit.elidable_promote('0')
def get_datamember(self, name):
try:
return self.datamembers[name]
@@ -717,7 +737,6 @@
self.datamembers[name] = new_dm
return new_dm
- @jit.elidable_promote('0')
def dispatch(self, name, signature):
overload = self.get_overload(name)
sig = '(%s)' % signature
@@ -886,6 +905,10 @@
def find_datamember(self, name):
raise self.missing_attribute_error(name)
+ def get_base_offset(self, cppinstance, calling_scope):
+ assert self == cppinstance.cppclass
+ return 0
+
def get_cppthis(self, cppinstance, calling_scope):
assert self == cppinstance.cppclass
return cppinstance.get_rawobject()
@@ -917,10 +940,15 @@
class W_ComplexCPPClass(W_CPPClass):
- def get_cppthis(self, cppinstance, calling_scope):
+ def get_base_offset(self, cppinstance, calling_scope):
assert self == cppinstance.cppclass
offset = capi.c_base_offset(self.space,
self, calling_scope, cppinstance.get_rawobject(), 1)
+ return offset
+
+ def get_cppthis(self, cppinstance, calling_scope):
+ assert self == cppinstance.cppclass
+ offset = self.get_base_offset(cppinstance, calling_scope)
return capi.direct_ptradd(cppinstance.get_rawobject(), offset)
W_ComplexCPPClass.typedef = TypeDef(
@@ -1130,19 +1158,23 @@
def get_pythonized_cppclass(space, handle):
state = space.fromcache(State)
try:
- w_pycppclass = state.cppclass_registry[handle]
+ w_pycppclass = state.cppclass_registry[rffi.cast(rffi.LONG, handle)]
except KeyError:
final_name = capi.c_scoped_final_name(space, handle)
# the callback will cache the class by calling register_class
w_pycppclass = space.call_function(state.w_clgen_callback, space.wrap(final_name))
return w_pycppclass
+def get_interface_func(space, w_callable, npar):
+ state = space.fromcache(State)
+ return space.call_function(state.w_fngen_callback, w_callable, space.wrap(npar))
+
def wrap_cppobject(space, rawobject, cppclass,
do_cast=True, python_owns=False, is_ref=False, fresh=False):
rawobject = rffi.cast(capi.C_OBJECT, rawobject)
- # cast to actual cast if requested and possible
- w_pycppclass = space.w_None
+ # cast to actual if requested and possible
+ w_pycppclass = None
if do_cast and rawobject:
actual = capi.c_actual_class(space, cppclass, rawobject)
if actual != cppclass.handle:
@@ -1158,7 +1190,7 @@
# the variables are re-assigned yet)
pass
- if space.is_w(w_pycppclass, space.w_None):
+ if w_pycppclass is None:
w_pycppclass = get_pythonized_cppclass(space, cppclass.handle)
# try to recycle existing object if this one is not newly created
@@ -1174,16 +1206,30 @@
memory_regulator.register(cppinstance)
return w_cppinstance
- at unwrap_spec(w_cppinstance=W_CPPInstance)
-def addressof(space, w_cppinstance):
- """Takes a bound C++ instance, returns the raw address."""
- address = rffi.cast(rffi.LONG, w_cppinstance.get_rawobject())
+def _addressof(space, w_obj):
+ try:
+ # attempt to extract address from array
+ return rffi.cast(rffi.INTPTR_T, converter.get_rawbuffer(space, w_obj))
+ except TypeError:
+ pass
+ # attempt to get address of C++ instance
+ return rffi.cast(rffi.INTPTR_T, converter.get_rawobject(space, w_obj))
+
+ at unwrap_spec(w_obj=W_Root)
+def addressof(space, w_obj):
+ """Takes a bound C++ instance or array, returns the raw address."""
+ address = _addressof(space, w_obj)
return space.wrap(address)
- at unwrap_spec(address=int, owns=bool)
-def bind_object(space, address, w_pycppclass, owns=False):
+ at unwrap_spec(owns=bool, cast=bool)
+def bind_object(space, w_obj, w_pycppclass, owns=False, cast=False):
"""Takes an address and a bound C++ class proxy, returns a bound instance."""
- rawobject = rffi.cast(capi.C_OBJECT, address)
+ try:
+ # attempt address from array or C++ instance
+ rawobject = rffi.cast(capi.C_OBJECT, _addressof(space, w_obj))
+ except Exception:
+ # accept integer value as address
+ rawobject = rffi.cast(capi.C_OBJECT, space.uint_w(w_obj))
w_cppclass = space.findattr(w_pycppclass, space.wrap("_cpp_proxy"))
if not w_cppclass:
w_cppclass = scope_byname(space, space.str_w(w_pycppclass))
@@ -1191,4 +1237,4 @@
raise OperationError(space.w_TypeError,
space.wrap("no such class: %s" % space.str_w(w_pycppclass)))
cppclass = space.interp_w(W_CPPClass, w_cppclass, can_be_None=False)
- return wrap_cppobject(space, rawobject, cppclass, do_cast=False, python_owns=owns)
+ return wrap_cppobject(space, rawobject, cppclass, do_cast=cast, python_owns=owns)
diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py
--- a/pypy/module/cppyy/pythonify.py
+++ b/pypy/module/cppyy/pythonify.py
@@ -55,6 +55,19 @@
def clgen_callback(name):
return get_pycppclass(name)
+def fngen_callback(func, npar): # todo, some kind of arg transform spec
+ if npar == 0:
+ def wrapper(a0, a1):
+ la0 = [a0[0], a0[1], a0[2], a0[3]]
+ return func(la0)
+ return wrapper
+ else:
+ def wrapper(a0, a1):
+ la0 = [a0[0], a0[1], a0[2], a0[3]]
+ la1 = [a1[i] for i in range(npar)]
+ return func(la0, la1)
+ return wrapper
+
def make_static_function(func_name, cppol):
def function(*args):
@@ -416,6 +429,9 @@
# class generator callback
cppyy._set_class_generator(clgen_callback)
+ # function generator callback
+ cppyy._set_function_generator(fngen_callback)
+
# user interface objects (note the two-step of not calling scope_byname here:
# creation of global functions may cause the creation of classes in the global
# namespace, so gbl must exist at that point to cache them)
@@ -431,6 +447,9 @@
# be the same issue for all typedef'd builtin types
setattr(gbl, 'unsigned int', int)
+ # install nullptr as a unique reference
+ setattr(gbl, 'nullptr', cppyy._get_nullptr())
+
# install for user access
cppyy.gbl = gbl
diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx b/pypy/module/cppyy/src/cintcwrapper.cxx
--- a/pypy/module/cppyy/src/cintcwrapper.cxx
+++ b/pypy/module/cppyy/src/cintcwrapper.cxx
@@ -8,6 +8,7 @@
#include "TApplication.h"
#include "TInterpreter.h"
+#include "TVirtualMutex.h"
#include "Getline.h"
#include "TBaseClass.h"
@@ -24,6 +25,8 @@
More information about the pypy-commit
mailing list