[pypy-commit] pypy cpyext-gc-support: Add some keepalives when converting to 'PyObject *' to make sure the

arigo noreply at buildbot.pypy.org
Wed Oct 14 15:57:13 EDT 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-gc-support
Changeset: r80217:12bbded34910
Date: 2015-10-14 21:36 +0200
http://bitbucket.org/pypy/pypy/changeset/12bbded34910/

Log:	Add some keepalives when converting to 'PyObject *' to make sure the
	original W_Root objects stay alive for the whole duration of the
	call

diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -9,7 +9,7 @@
 from rpython.rtyper.tool import rffi_platform
 from rpython.rtyper.lltypesystem import ll2ctypes
 from rpython.rtyper.annlowlevel import llhelper
-from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.objectmodel import we_are_translated, keepalive_until_here
 from rpython.translator import cdir
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 from rpython.translator.gensupp import NameManager
@@ -293,16 +293,18 @@
                 from pypy.module.cpyext.pyobject import as_pyobj, is_pyobj
                 from pypy.module.cpyext.pyobject import Reference
                 newargs = ()
+                keepalives = ()
                 assert len(args) == len(api_function.argtypes)
                 for i, (ARG, is_wrapped) in types_names_enum_ui:
                     input_arg = args[i]
                     if is_PyObject(ARG) and not is_wrapped:
                         # build a 'PyObject *' (not holding a reference)
                         if not is_pyobj(input_arg):
+                            keepalives += (input_arg,)
                             input_arg = as_pyobj(input_arg)
                         arg = rffi.cast(ARG, input_arg)
                     elif is_PyObject(ARG) and is_wrapped:
-                        # convert to a wrapped object
+                        # build a W_Root, possibly from a 'PyObject *'
                         if is_pyobj(input_arg):
                             arg = from_ref(input_arg)
                         else:
@@ -329,7 +331,10 @@
                         arg = input_arg
                     newargs += (arg, )
                 try:
-                    res = func(space, *newargs)
+                    try:
+                        res = func(space, *newargs)
+                    finally:
+                        keepalive_until_here(*keepalives)
                 except OperationError, e:
                     if not catch_exception:
                         raise


More information about the pypy-commit mailing list