Author: Armin Rigo <[email protected]>
Branch:
Changeset: r78990:20f74886a28e
Date: 2015-08-14 21:46 +0100
http://bitbucket.org/pypy/pypy/changeset/20f74886a28e/
Log: Issue #2114: get a new globals dictionary for every call to
pypy_execute_source_ptr. Expand the documentation to point out the
drawback of calling pypy_execute_source_ptr many times.
diff --git a/pypy/doc/embedding.rst b/pypy/doc/embedding.rst
--- a/pypy/doc/embedding.rst
+++ b/pypy/doc/embedding.rst
@@ -46,7 +46,11 @@
source. It'll acquire the GIL.
Note: this is meant to be called *only once* or a few times at most. See
- the `more complete example`_ below.
+ the `more complete example`_ below. In PyPy <= 2.6.0, the globals
+ dictionary is *reused* across multiple calls, giving potentially
+ strange results (e.g. objects dying too early). In PyPy >= 2.6.1,
+ you get a new globals dictionary for every call (but then, all globals
+ dictionaries are all kept alive forever, in ``sys._pypy_execute_source``).
.. function:: int pypy_execute_source_ptr(char* source, void* ptr);
diff --git a/pypy/goal/targetpypystandalone.py
b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -128,13 +128,7 @@
@entrypoint('main', [rffi.CCHARP], c_name='pypy_execute_source')
def pypy_execute_source(ll_source):
- after = rffi.aroundstate.after
- if after: after()
- source = rffi.charp2str(ll_source)
- res = _pypy_execute_source(source)
- before = rffi.aroundstate.before
- if before: before()
- return rffi.cast(rffi.INT, res)
+ return pypy_execute_source_ptr(ll_source, 0)
@entrypoint('main', [rffi.CCHARP, lltype.Signed],
c_name='pypy_execute_source_ptr')
@@ -142,9 +136,7 @@
after = rffi.aroundstate.after
if after: after()
source = rffi.charp2str(ll_source)
- space.setitem(w_globals, space.wrap('c_argument'),
- space.wrap(ll_ptr))
- res = _pypy_execute_source(source)
+ res = _pypy_execute_source(source, ll_ptr)
before = rffi.aroundstate.before
if before: before()
return rffi.cast(rffi.INT, res)
@@ -169,15 +161,21 @@
before = rffi.aroundstate.before
if before: before()
- w_globals = space.newdict()
- space.setitem(w_globals, space.wrap('__builtins__'),
- space.builtin_modules['__builtin__'])
-
- def _pypy_execute_source(source):
+ def _pypy_execute_source(source, c_argument):
try:
- compiler = space.createcompiler()
- stmt = compiler.compile(source, 'c callback', 'exec', 0)
- stmt.exec_code(space, w_globals, w_globals)
+ w_globals = space.newdict(module=True)
+ space.setitem(w_globals, space.wrap('__builtins__'),
+ space.builtin_modules['__builtin__'])
+ space.setitem(w_globals, space.wrap('c_argument'),
+ space.wrap(c_argument))
+ space.appexec([space.wrap(source), w_globals], """(src, glob):
+ import sys
+ stmt = compile(src, 'c callback', 'exec')
+ if not hasattr(sys, '_pypy_execute_source'):
+ sys._pypy_execute_source = []
+ sys._pypy_execute_source.append(glob)
+ exec stmt in glob
+ """)
except OperationError, e:
debug("OperationError:")
debug(" operror-type: " + e.w_type.getname(space))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit