[pypy-commit] pypy cpyext-gc-support: Tweak tweak but no correct object lifetime management here
arigo
noreply at buildbot.pypy.org
Fri Oct 16 17:57:58 EDT 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-gc-support
Changeset: r80300:e01fa1dab750
Date: 2015-10-16 23:58 +0200
http://bitbucket.org/pypy/pypy/changeset/e01fa1dab750/
Log: Tweak tweak but no correct object lifetime management here
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
@@ -192,7 +192,7 @@
class ApiFunction:
def __init__(self, argtypes, restype, callable, error=_NOT_SPECIFIED,
- c_name=None, gil=None):
+ c_name=None, gil=None, return_borrowed=False):
self.argtypes = argtypes
self.restype = restype
self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype))
@@ -209,6 +209,7 @@
self.argnames = argnames[1:]
assert len(self.argnames) == len(self.argtypes)
self.gil = gil
+ self.return_borrowed = return_borrowed
def _freeze_(self):
return True
@@ -245,6 +246,10 @@
- set `gil` to "acquire", "release" or "around" to acquire the GIL,
release the GIL, or both
"""
+ return_borrowed = restype is BORROW
+ if return_borrowed:
+ restype = PyObject
+
if isinstance(restype, lltype.Typedef):
real_restype = restype.OF
else:
@@ -267,7 +272,8 @@
else:
c_name = func_name
api_function = ApiFunction(argtypes, restype, func, error,
- c_name=c_name, gil=gil)
+ c_name=c_name, gil=gil,
+ return_borrowed=return_borrowed)
func.api_func = api_function
if external:
@@ -541,7 +547,7 @@
return False
return hasattr(TYPE.TO, 'c_ob_refcnt') and hasattr(TYPE.TO, 'c_ob_type')
-class BORROWED: pass
+class BORROW: pass
@specialize.memo()
def is_BORROWED(TYPE):
@@ -611,11 +617,12 @@
gil_acquire = (gil == "acquire" or gil == "around")
gil_release = (gil == "release" or gil == "around")
assert gil is None or gil_acquire or gil_release
+ return_borrowed = callable.api_func.return_borrowed
@specialize.ll()
def wrapper(*args):
from pypy.module.cpyext.pyobject import make_ref, from_ref
- from pypy.module.cpyext.pyobject import Reference
+ from pypy.module.cpyext.pyobject import Reference, as_pyobj, is_pyobj
# we hope that malloc removal removes the newtuple() that is
# inserted exactly here by the varargs specializer
if gil_acquire:
@@ -669,16 +676,12 @@
retval = error_value
elif is_PyObject(callable.api_func.restype):
- if result is None:
- retval = rffi.cast(callable.api_func.restype,
- make_ref(space, None))
- elif isinstance(result, Reference):
- retval = result.get_ref(space)
- elif not rffi._isllptr(result):
- retval = rffi.cast(callable.api_func.restype,
- make_ref(space, result))
+ if is_pyobj(result):
+ retval = result
else:
- retval = result
+ retval = as_pyobj(result)
+ if not return_borrowed and retval:
+ retval.c_ob_refcnt += 1
elif callable.api_func.restype is not lltype.Void:
retval = rffi.cast(callable.api_func.restype, result)
except Exception, e:
@@ -1211,7 +1214,7 @@
@specialize.memo()
def make_generic_cpy_call(FT, decref_args, expect_null):
from pypy.module.cpyext.pyobject import make_ref, from_ref, Py_DecRef
- from pypy.module.cpyext.pyobject import RefcountState
+ from pypy.module.cpyext.pyobject import RefcountState, is_pyobj, as_pyobj
from pypy.module.cpyext.pyerrors import PyErr_Occurred
unrolling_arg_types = unrolling_iterable(enumerate(FT.ARGS))
RESULT_TYPE = FT.RESULT
@@ -1261,7 +1264,7 @@
if not is_pyobj(result):
ret = result
else:
- ret = from_ref(space, result)
+ ret = from_ref(result)
# The object reference returned from a C function
# that is called from Python must be an owned reference
# - ownership is transferred from the function to its caller.
diff --git a/pypy/module/cpyext/modsupport.py b/pypy/module/cpyext/modsupport.py
--- a/pypy/module/cpyext/modsupport.py
+++ b/pypy/module/cpyext/modsupport.py
@@ -1,7 +1,7 @@
from rpython.rtyper.lltypesystem import rffi, lltype
from pypy.module.cpyext.api import cpython_api, cpython_struct, \
METH_STATIC, METH_CLASS, METH_COEXIST, CANNOT_FAIL, CONST_STRING
-from pypy.module.cpyext.pyobject import PyObject, borrow_from
+from pypy.module.cpyext.pyobject import PyObject, BORROW
from pypy.interpreter.module import Module
from pypy.module.cpyext.methodobject import (
W_PyCFunctionObject, PyCFunction_NewEx, PyDescr_NewMethod,
@@ -34,7 +34,7 @@
# This is actually the Py_InitModule4 function,
# renamed to refuse modules built against CPython headers.
@cpython_api([CONST_STRING, lltype.Ptr(PyMethodDef), CONST_STRING,
- PyObject, rffi.INT_real], PyObject)
+ PyObject, rffi.INT_real], BORROW)
def _Py_InitPyPyModule(space, name, methods, doc, w_self, apiver):
"""
Create a new module object based on a name and table of functions, returning
@@ -69,7 +69,7 @@
if doc:
space.setattr(w_mod, space.wrap("__doc__"),
space.wrap(rffi.charp2str(doc)))
- return borrow_from(None, w_mod)
+ return w_mod
def convert_method_defs(space, dict_w, methods, w_type, w_self=None, name=None):
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -3,7 +3,7 @@
from pypy.interpreter.baseobjspace import W_Root, SpaceCache
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from pypy.module.cpyext.api import (
- cpython_api, bootstrap_function, PyObject, PyObjectP, ADDR,
+ cpython_api, bootstrap_function, PyObject, PyObjectP, ADDR, BORROW,
CANNOT_FAIL, Py_TPFLAGS_HEAPTYPE, PyTypeObjectPtr, is_PyObject)
from pypy.module.cpyext.state import State
from pypy.objspace.std.typeobject import W_TypeObject
More information about the pypy-commit
mailing list