[pypy-svn] r73208 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test
afa at codespeak.net
afa at codespeak.net
Wed Mar 31 14:33:28 CEST 2010
Author: afa
Date: Wed Mar 31 14:33:26 2010
New Revision: 73208
Added:
pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py
- copied, changed from r73205, pypy/branch/cpython-extension/pypy/module/cpyext/macros.py
Removed:
pypy/branch/cpython-extension/pypy/module/cpyext/macros.py
Modified:
pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py
pypy/branch/cpython-extension/pypy/module/cpyext/api.py
pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py
pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h
pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py
pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py
pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py
pypy/branch/cpython-extension/pypy/module/cpyext/object.py
pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py
pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py
pypy/branch/cpython-extension/pypy/module/cpyext/state.py
pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py
pypy/branch/cpython-extension/pypy/module/cpyext/test/test_borrow.py
pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py
pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py
pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py
pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py
Log:
- Move object&memory management into a new file pyobject.py
- rename Py_INCREF to Py_IncRef (the old name is still available from C)
--Cette ligne, et les suivantes ci-dessous, seront ignorées--
M cpyext/test/test_borrow.py
M cpyext/test/test_cpyext.py
M cpyext/include/object.h
M cpyext/stringobject.py
M cpyext/__init__.py
M cpyext/listobject.py
M cpyext/object.py
M cpyext/methodobject.py
M cpyext/sequence.py
M cpyext/typeobject.py
M cpyext/api.py
M cpyext/dictobject.py
M cpyext/typeobjectdefs.py
M cpyext/modsupport.py
A + cpyext/pyobject.py
M cpyext/state.py
M cpyext/tupleobject.py
D cpyext/macros.py
M cpyext/pyerrors.py
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Wed Mar 31 14:33:26 2010
@@ -28,11 +28,11 @@
space.wrap(state.api_lib))
# import these modules to register api functions by side-effect
+import pypy.module.cpyext.pyobject
import pypy.module.cpyext.boolobject
import pypy.module.cpyext.floatobject
import pypy.module.cpyext.modsupport
import pypy.module.cpyext.pythonrun
-import pypy.module.cpyext.macros
import pypy.module.cpyext.pyerrors
import pypy.module.cpyext.typeobject
import pypy.module.cpyext.object
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 14:33:26 2010
@@ -25,7 +25,6 @@
# CPython 2.4 compatibility
from py.builtin import BaseException
-DEBUG_REFCOUNT = False
DEBUG_WRAPPER = False
Py_ssize_t = lltype.Signed
@@ -139,6 +138,8 @@
@specialize.ll()
def unwrapper(space, *args):
+ from pypy.module.cpyext.pyobject import Py_DecRef
+ from pypy.module.cpyext.pyobject import make_ref, from_ref
newargs = ()
to_decref = []
for i, (ARG, is_wrapped) in types_names_enum_ui:
@@ -177,9 +178,8 @@
if api_function.borrowed:
state = space.fromcache(State)
state.last_container = 0
- from pypy.module.cpyext.macros import Py_DECREF
for arg in to_decref:
- Py_DECREF(space, arg)
+ Py_DecRef(space, arg)
unwrapper.func = func
unwrapper.api_func = api_function
unwrapper._always_inline_ = True
@@ -241,136 +241,6 @@
TYPES[name].become(TYPE)
-class NullPointerException(Exception):
- pass
-
-class InvalidPointerException(Exception):
- pass
-
-def debug_refcount(*args, **kwargs):
- frame_stackdepth = kwargs.pop("frame_stackdepth", 2)
- assert not kwargs
- frame = sys._getframe(frame_stackdepth)
- print >>sys.stderr, "%25s" % (frame.f_code.co_name, ),
- for arg in args:
- print >>sys.stderr, arg,
- print >>sys.stderr
-
-
-def make_ref(space, w_obj, borrowed=False, steal=False):
- from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF
- if w_obj is None:
- return lltype.nullptr(PyObject.TO)
- assert isinstance(w_obj, W_Root)
- state = space.fromcache(State)
- py_obj = state.py_objects_w2r.get(w_obj, lltype.nullptr(PyObject.TO))
- if not py_obj:
- from pypy.module.cpyext.typeobject import allocate_type_obj,\
- W_PyCTypeObject, W_PyCObject
- w_type = space.type(w_obj)
- if space.is_w(w_type, space.w_type):
- pto = allocate_type_obj(space, w_obj)
- py_obj = rffi.cast(PyObject, pto)
- # c_ob_type and c_ob_refcnt are set by allocate_type_obj
- elif isinstance(w_obj, W_PyCObject):
- w_type = space.type(w_obj)
- assert isinstance(w_type, W_PyCTypeObject)
- pto = w_type.pto
- # Don't increase refcount for non-heaptypes
- # Py_INCREF(space, pto)
- basicsize = pto.c_tp_basicsize
- py_obj_pad = lltype.malloc(rffi.VOIDP.TO, basicsize,
- flavor="raw", zero=True)
- py_obj = rffi.cast(PyObject, py_obj_pad)
- py_obj.c_ob_refcnt = 1
- py_obj.c_ob_type = rffi.cast(PyObject, pto)
- elif isinstance(w_obj, W_StringObject):
- py_obj_str = lltype.malloc(PyStringObject.TO, flavor='raw', zero=True)
- py_obj_str.c_size = len(space.str_w(w_obj))
- py_obj_str.c_buffer = lltype.nullptr(rffi.CCHARP.TO)
- pto = make_ref(space, space.w_str)
- py_obj = rffi.cast(PyObject, py_obj_str)
- py_obj.c_ob_refcnt = 1
- py_obj.c_ob_type = rffi.cast(PyObject, pto)
- else:
- py_obj = lltype.malloc(PyObject.TO, flavor="raw", zero=True)
- py_obj.c_ob_refcnt = 1
- pto = make_ref(space, space.type(w_obj))
- py_obj.c_ob_type = rffi.cast(PyObject, pto)
- ptr = rffi.cast(ADDR, py_obj)
- if DEBUG_REFCOUNT:
- debug_refcount("MAKREF", py_obj, w_obj)
- state.py_objects_w2r[w_obj] = py_obj
- state.py_objects_r2w[ptr] = w_obj
- if borrowed and ptr not in state.borrowed_objects:
- state.borrowed_objects[ptr] = None
- elif not steal:
- if borrowed:
- py_obj_addr = rffi.cast(ADDR, py_obj)
- if py_obj_addr not in state.borrowed_objects:
- Py_INCREF(space, py_obj)
- state.borrowed_objects[py_obj_addr] = None
- else:
- Py_INCREF(space, py_obj)
- return py_obj
-
-def force_string(space, ref):
- state = space.fromcache(State)
- ref = rffi.cast(PyStringObject, ref)
- s = rffi.charpsize2str(ref.c_buffer, ref.c_size)
- ref = rffi.cast(PyObject, ref)
- w_str = space.wrap(s)
- state.py_objects_w2r[w_str] = ref
- ptr = rffi.cast(ADDR, ref)
- state.py_objects_r2w[ptr] = w_str
- return w_str
-
-
-def from_ref(space, ref):
- assert lltype.typeOf(ref) == PyObject
- if not ref:
- return None
- state = space.fromcache(State)
- ptr = rffi.cast(ADDR, ref)
- try:
- obj = state.py_objects_r2w[ptr]
- except KeyError:
- ref_type = ref.c_ob_type
- if ref != ref_type and space.is_w(from_ref(space, ref_type), space.w_str):
- return force_string(space, ref)
- else:
- msg = ""
- if not we_are_translated():
- msg = "Got invalid reference to a PyObject: %r" % (ref, )
- raise InvalidPointerException(msg)
- return obj
-
-
- at cpython_api([PyObject], lltype.Void, external=False)
-def register_container(space, container):
- state = space.fromcache(State)
- if not container: # self-managed
- container_ptr = -1
- else:
- container_ptr = rffi.cast(ADDR, container)
- assert not state.last_container, "Last container was not fetched"
- state.last_container = container_ptr
-
-def add_borrowed_object(space, obj):
- state = space.fromcache(State)
- container_ptr = state.last_container
- state.last_container = 0
- if not container_ptr:
- raise NullPointerException
- if container_ptr == -1:
- return
- borrowees = state.borrow_mapping.get(container_ptr, None)
- if borrowees is None:
- state.borrow_mapping[container_ptr] = borrowees = {}
- obj_ptr = rffi.cast(ADDR, obj)
- borrowees[obj_ptr] = None
-
-
def general_check(space, w_obj, w_type):
w_obj_type = space.type(w_obj)
return int(space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type)))
@@ -387,6 +257,9 @@
@specialize.ll()
def wrapper(*args):
+ from pypy.module.cpyext.pyobject import make_ref, from_ref
+ from pypy.module.cpyext.pyobject import add_borrowed_object
+ from pypy.module.cpyext.pyobject import NullPointerException
boxed_args = ()
if DEBUG_WRAPPER:
print >>sys.stderr, callable,
@@ -445,6 +318,7 @@
return wrapper
def bootstrap_types(space):
+ from pypy.module.cpyext.pyobject import make_ref
from pypy.module.cpyext.typeobject import PyTypeObjectPtr, PyPyType_Ready
# bootstrap this damn cycle
type_pto = make_ref(space, space.w_type)
@@ -464,6 +338,8 @@
# back into Pypy space functions
# Do not call this more than once per process
def build_bridge(space, rename=True):
+ from pypy.module.cpyext.pyobject import make_ref
+
export_symbols = list(FUNCTIONS) + list(FUNCTIONS_C) + list(GLOBALS)
db = LowLevelDatabase()
@@ -607,6 +483,8 @@
def setup_library(space, rename=False):
+ from pypy.module.cpyext.pyobject import make_ref
+
export_symbols = list(FUNCTIONS) + list(FUNCTIONS_C) + list(GLOBALS)
db = LowLevelDatabase()
@@ -665,7 +543,7 @@
@specialize.memo()
def make_generic_cpy_call(FT, decref_args):
- from pypy.module.cpyext.macros import Py_DECREF
+ from pypy.module.cpyext.pyobject import make_ref, from_ref, Py_DecRef
from pypy.module.cpyext.pyerrors import PyErr_Occurred
unrolling_arg_types = unrolling_iterable(enumerate(FT.ARGS))
RESULT_TYPE = FT.RESULT
@@ -701,7 +579,7 @@
# that is called from Python must be an owned reference
# - ownership is transferred from the function to its caller.
if result:
- Py_DECREF(space, result)
+ Py_DecRef(space, result)
# Check for exception consistency
has_error = PyErr_Occurred(space) is not None
@@ -721,6 +599,6 @@
finally:
if decref_args:
for ref in to_decref:
- Py_DECREF(space, ref)
+ Py_DecRef(space, ref)
return generic_cpy_call
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py Wed Mar 31 14:33:26 2010
@@ -1,6 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL, \
- general_check, general_check_exact, register_container
+from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import general_check, general_check_exact
+from pypy.module.cpyext.pyobject import PyObject, register_container
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
from pypy.interpreter.error import OperationError
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Wed Mar 31 14:33:26 2010
@@ -37,6 +37,9 @@
PyObject_VAR_HEAD
} PyVarObject;
+#define Py_INCREF(ob) (Py_IncRef(ob))
+#define Py_DECREF(ob) (Py_DecRef(ob))
+
#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py Wed Mar 31 14:33:26 2010
@@ -1,10 +1,9 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL,\
- Py_ssize_t
+from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, Py_ssize_t
from pypy.module.cpyext.api import general_check, general_check_exact
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
-from pypy.module.cpyext.macros import Py_XDECREF
+from pypy.module.cpyext.pyobject import Py_DecRef, PyObject
from pypy.objspace.std.listobject import W_ListObject
from pypy.interpreter.error import OperationError
@@ -44,7 +43,7 @@
This function "steals" a reference to item and discards a reference to
an item already in the list at the affected position.
"""
- Py_XDECREF(space, w_item)
+ Py_DecRef(space, w_item)
if not isinstance(w_list, W_ListObject):
PyErr_BadInternalCall(space)
wrappeditems = w_list.wrappeditems
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Wed Mar 31 14:33:26 2010
@@ -7,8 +7,8 @@
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.function import BuiltinFunction, Method
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import PyObject, from_ref, \
- make_ref, generic_cpy_call
+from pypy.module.cpyext.pyobject import PyObject, from_ref, make_ref
+from pypy.module.cpyext.api import generic_cpy_call
from pypy.module.cpyext.state import State
from pypy.module.cpyext.pyerrors import PyErr_Occurred
from pypy.rlib.objectmodel import we_are_translated
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Wed Mar 31 14:33:26 2010
@@ -1,7 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, \
- METH_STATIC, METH_CLASS, METH_COEXIST, general_check, CANNOT_FAIL, \
- register_container
+from pypy.module.cpyext.api import cpython_api, cpython_struct, \
+ METH_STATIC, METH_CLASS, METH_COEXIST, general_check, CANNOT_FAIL
+from pypy.module.cpyext.pyobject import PyObject, register_container
from pypy.interpreter.module import Module
from pypy.module.cpyext.methodobject import PyCFunction_NewEx, PyDescr_NewMethod
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Wed Mar 31 14:33:26 2010
@@ -1,8 +1,8 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref, \
- generic_cpy_call, CANNOT_FAIL
+from pypy.module.cpyext.api import cpython_api, generic_cpy_call, CANNOT_FAIL
+from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref
+from pypy.module.cpyext.pyobject import Py_IncRef, Py_DecRef
from pypy.module.cpyext.state import State
-from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF
from pypy.module.cpyext.typeobject import PyTypeObjectPtr, W_PyCTypeObject, W_PyCObject
from pypy.objspace.std.objectobject import W_ObjectObject
import pypy.module.__builtin__.operation as operation
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Wed Mar 31 14:33:26 2010
@@ -1,7 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.interpreter.error import OperationError
-from pypy.module.cpyext.api import cpython_api, PyObject, make_ref,\
- register_container, CANNOT_FAIL
+from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.pyobject import PyObject, make_ref, register_container
from pypy.module.cpyext.state import State
@cpython_api([PyObject, PyObject], lltype.Void)
Copied: pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py (from r73205, pypy/branch/cpython-extension/pypy/module/cpyext/macros.py)
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py Wed Mar 31 14:33:26 2010
@@ -1,14 +1,127 @@
import sys
+from pypy.interpreter.baseobjspace import W_Root
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref, \
- ADDR, debug_refcount, DEBUG_REFCOUNT
+from pypy.module.cpyext.api import cpython_api, PyObject, PyStringObject, ADDR
from pypy.module.cpyext.state import State
+from pypy.objspace.std.stringobject import W_StringObject
+from pypy.rlib.objectmodel import we_are_translated
+
+#________________________________________________________
+# refcounted object support
+
+class NullPointerException(Exception):
+ pass
+
+class InvalidPointerException(Exception):
+ pass
+
+DEBUG_REFCOUNT = False
+
+def debug_refcount(*args, **kwargs):
+ frame_stackdepth = kwargs.pop("frame_stackdepth", 2)
+ assert not kwargs
+ frame = sys._getframe(frame_stackdepth)
+ print >>sys.stderr, "%25s" % (frame.f_code.co_name, ),
+ for arg in args:
+ print >>sys.stderr, arg,
+ print >>sys.stderr
+
+
+def make_ref(space, w_obj, borrowed=False, steal=False):
+ if w_obj is None:
+ return lltype.nullptr(PyObject.TO)
+ assert isinstance(w_obj, W_Root)
+ state = space.fromcache(State)
+ py_obj = state.py_objects_w2r.get(w_obj, lltype.nullptr(PyObject.TO))
+ if not py_obj:
+ from pypy.module.cpyext.typeobject import allocate_type_obj,\
+ W_PyCTypeObject, W_PyCObject
+ w_type = space.type(w_obj)
+ if space.is_w(w_type, space.w_type):
+ pto = allocate_type_obj(space, w_obj)
+ py_obj = rffi.cast(PyObject, pto)
+ # c_ob_type and c_ob_refcnt are set by allocate_type_obj
+ elif isinstance(w_obj, W_PyCObject):
+ w_type = space.type(w_obj)
+ assert isinstance(w_type, W_PyCTypeObject)
+ pto = w_type.pto
+ # Don't increase refcount for non-heaptypes
+ # Py_IncRef(space, pto)
+ basicsize = pto.c_tp_basicsize
+ py_obj_pad = lltype.malloc(rffi.VOIDP.TO, basicsize,
+ flavor="raw", zero=True)
+ py_obj = rffi.cast(PyObject, py_obj_pad)
+ py_obj.c_ob_refcnt = 1
+ py_obj.c_ob_type = rffi.cast(PyObject, pto)
+ elif isinstance(w_obj, W_StringObject):
+ py_obj_str = lltype.malloc(PyStringObject.TO, flavor='raw', zero=True)
+ py_obj_str.c_size = len(space.str_w(w_obj))
+ py_obj_str.c_buffer = lltype.nullptr(rffi.CCHARP.TO)
+ pto = make_ref(space, space.w_str)
+ py_obj = rffi.cast(PyObject, py_obj_str)
+ py_obj.c_ob_refcnt = 1
+ py_obj.c_ob_type = rffi.cast(PyObject, pto)
+ else:
+ py_obj = lltype.malloc(PyObject.TO, flavor="raw", zero=True)
+ py_obj.c_ob_refcnt = 1
+ pto = make_ref(space, space.type(w_obj))
+ py_obj.c_ob_type = rffi.cast(PyObject, pto)
+ ptr = rffi.cast(ADDR, py_obj)
+ if DEBUG_REFCOUNT:
+ debug_refcount("MAKREF", py_obj, w_obj)
+ state.py_objects_w2r[w_obj] = py_obj
+ state.py_objects_r2w[ptr] = w_obj
+ if borrowed and ptr not in state.borrowed_objects:
+ state.borrowed_objects[ptr] = None
+ elif not steal:
+ if borrowed:
+ py_obj_addr = rffi.cast(ADDR, py_obj)
+ if py_obj_addr not in state.borrowed_objects:
+ Py_IncRef(space, py_obj)
+ state.borrowed_objects[py_obj_addr] = None
+ else:
+ Py_IncRef(space, py_obj)
+ return py_obj
+
+def force_string(space, ref):
+ state = space.fromcache(State)
+ ref = rffi.cast(PyStringObject, ref)
+ s = rffi.charpsize2str(ref.c_buffer, ref.c_size)
+ ref = rffi.cast(PyObject, ref)
+ w_str = space.wrap(s)
+ state.py_objects_w2r[w_str] = ref
+ ptr = rffi.cast(ADDR, ref)
+ state.py_objects_r2w[ptr] = w_str
+ return w_str
+
+
+def from_ref(space, ref):
+ assert lltype.typeOf(ref) == PyObject
+ if not ref:
+ return None
+ state = space.fromcache(State)
+ ptr = rffi.cast(ADDR, ref)
+ try:
+ obj = state.py_objects_r2w[ptr]
+ except KeyError:
+ ref_type = ref.c_ob_type
+ if ref != ref_type and space.is_w(from_ref(space, ref_type), space.w_str):
+ return force_string(space, ref)
+ else:
+ msg = ""
+ if not we_are_translated():
+ msg = "Got invalid reference to a PyObject: %r" % (ref, )
+ raise InvalidPointerException(msg)
+ return obj
# XXX Optimize these functions and put them into macro definitions
@cpython_api([PyObject], lltype.Void)
-def Py_DECREF(space, obj):
+def Py_DecRef(space, obj):
+ if not obj:
+ return
+
from pypy.module.cpyext.typeobject import string_dealloc
obj.c_ob_refcnt -= 1
if DEBUG_REFCOUNT:
@@ -31,7 +144,7 @@
w_containee = state.py_objects_r2w.get(containee, None)
if w_containee is not None:
containee = state.py_objects_w2r[w_containee]
- Py_DECREF(space, w_containee)
+ Py_DecRef(space, w_containee)
containee_ptr = rffi.cast(ADDR, containee)
try:
del state.borrowed_objects[containee_ptr]
@@ -46,22 +159,14 @@
assert obj.c_ob_refcnt > 0
@cpython_api([PyObject], lltype.Void)
-def Py_INCREF(space, obj):
+def Py_IncRef(space, obj):
+ if not obj:
+ return
obj.c_ob_refcnt += 1
assert obj.c_ob_refcnt > 0
if DEBUG_REFCOUNT:
debug_refcount("INCREF", obj, obj.c_ob_refcnt, frame_stackdepth=3)
- at cpython_api([PyObject], lltype.Void)
-def Py_XINCREF(space, obj):
- if obj:
- Py_INCREF(space, obj)
-
- at cpython_api([PyObject], lltype.Void)
-def Py_XDECREF(space, obj):
- if obj:
- Py_DECREF(space, obj)
-
def _Py_Dealloc(space, obj):
from pypy.module.cpyext.typeobject import PyTypeObjectPtr
from pypy.module.cpyext.api import generic_cpy_call_dont_decref
@@ -71,3 +176,31 @@
# "'s type which is", rffi.charp2str(pto.c_tp_name)
generic_cpy_call_dont_decref(space, pto.c_tp_dealloc, obj)
+#___________________________________________________________
+# Support for borrowed references
+
+ at cpython_api([PyObject], lltype.Void, external=False)
+def register_container(space, container):
+ state = space.fromcache(State)
+ if not container: # self-managed
+ container_ptr = -1
+ else:
+ container_ptr = rffi.cast(ADDR, container)
+ assert not state.last_container, "Last container was not fetched"
+ state.last_container = container_ptr
+
+def add_borrowed_object(space, obj):
+ state = space.fromcache(State)
+ container_ptr = state.last_container
+ state.last_container = 0
+ if not container_ptr:
+ raise NullPointerException
+ if container_ptr == -1:
+ return
+ borrowees = state.borrow_mapping.get(container_ptr, None)
+ if borrowees is None:
+ state.borrow_mapping[container_ptr] = borrowees = {}
+ obj_ptr = rffi.cast(ADDR, obj)
+ borrowees[obj_ptr] = None
+
+
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py Wed Mar 31 14:33:26 2010
@@ -1,7 +1,7 @@
from pypy.interpreter.error import OperationError
-from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL,\
- Py_ssize_t, register_container
+from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, Py_ssize_t
+from pypy.module.cpyext.pyobject import PyObject, register_container
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.objspace.std import listobject, tupleobject
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/state.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/state.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/state.py Wed Mar 31 14:33:26 2010
@@ -26,13 +26,13 @@
self.exc_value = w_value
def clear_exception(self):
- from pypy.module.cpyext.macros import Py_DECREF
- from pypy.module.cpyext.api import make_ref, ADDR
+ from pypy.module.cpyext.pyobject import Py_DecRef, make_ref
+ from pypy.module.cpyext.api import ADDR
# handling of borrowed objects, remove when we have
# a weakkeydict
exc_type = make_ref(self.space, self.exc_type, borrowed=True)
if exc_type:
- Py_DECREF(self.space, exc_type)
+ Py_DecRef(self.space, exc_type)
containee_ptr = rffi.cast(ADDR, exc_type)
del self.borrowed_objects[containee_ptr]
self.exc_type = None
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Wed Mar 31 14:33:26 2010
@@ -1,7 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import cpython_api, PyObject, PyVarObjectFields, \
- PyStringObject, Py_ssize_t, cpython_struct, make_ref, from_ref, CANNOT_FAIL, \
- general_check
+from pypy.module.cpyext.api import cpython_api, PyVarObjectFields, \
+ PyStringObject, Py_ssize_t, cpython_struct, CANNOT_FAIL, general_check
+from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref
@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_borrow.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_borrow.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_borrow.py Wed Mar 31 14:33:26 2010
@@ -2,7 +2,7 @@
from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
from pypy.module.cpyext.test.test_api import BaseApiTest
from pypy.module.cpyext.state import State
-from pypy.module.cpyext.api import make_ref, add_borrowed_object
+from pypy.module.cpyext.pyobject import make_ref, add_borrowed_object
class TestBorrowing(BaseApiTest):
@@ -10,14 +10,14 @@
state = space.fromcache(State)
w_int = space.wrap(1)
w_tuple = space.newtuple([w_int])
- api.Py_INCREF(w_tuple)
+ api.Py_IncRef(w_tuple)
api.register_container(w_tuple)
one_pyo = make_ref(space, w_int, borrowed=True)
add_borrowed_object(space, one_pyo)
print state.borrowed_objects
- api.Py_DECREF(w_tuple)
+ api.Py_DecRef(w_tuple)
state.print_refcounts()
- py.test.raises(AssertionError, api.Py_DECREF, one_pyo)
+ py.test.raises(AssertionError, api.Py_DecRef, one_pyo)
class AppTestStringObject(AppTestCpythonExtensionBase):
def test_tuple_borrowing(self):
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Wed Mar 31 14:33:26 2010
@@ -9,7 +9,7 @@
from pypy.translator import platform
from pypy.module.cpyext import api
from pypy.module.cpyext.state import State
-from pypy.module.cpyext.macros import Py_DECREF
+from pypy.module.cpyext.pyobject import Py_DecRef, InvalidPointerException
from pypy.translator.goal import autopath
from pypy.lib.identity_dict import identity_dict
@@ -123,10 +123,10 @@
self.space.wrap('foo'))
self.space.delitem(self.space.sys.get('modules'),
self.space.wrap('foo'))
- Py_DECREF(self.space, w_mod)
+ Py_DecRef(self.space, w_mod)
state = self.space.fromcache(State)
for w_obj in state.non_heaptypes:
- Py_DECREF(self.space, w_obj)
+ Py_DecRef(self.space, w_obj)
except OperationError:
pass
state = self.space.fromcache(State)
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Wed Mar 31 14:33:26 2010
@@ -1,8 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t, \
- general_check, CANNOT_FAIL, register_container, \
- general_check_exact
-from pypy.module.cpyext.macros import Py_DECREF
+from pypy.module.cpyext.api import cpython_api, Py_ssize_t, \
+ general_check, CANNOT_FAIL, general_check_exact
+from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, register_container
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
from pypy.objspace.std.tupleobject import W_TupleObject
@@ -27,7 +26,7 @@
PyErr_BadInternalCall(space)
assert isinstance(w_t, W_TupleObject)
w_t.wrappeditems[pos] = w_obj
- Py_DECREF(space, w_obj) # SetItem steals a reference!
+ Py_DecRef(space, w_obj) # SetItem steals a reference!
return 0
@cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True)
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Wed Mar 31 14:33:26 2010
@@ -10,14 +10,14 @@
from pypy.objspace.std.objectobject import W_ObjectObject
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \
- PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \
- Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, make_ref, \
- PyStringObject, ADDR, from_ref, generic_cpy_call
+ PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, generic_cpy_call, \
+ Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, PyStringObject, ADDR
+from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref
from pypy.interpreter.module import Module
from pypy.module.cpyext.modsupport import convert_method_defs
from pypy.module.cpyext.state import State
from pypy.module.cpyext.methodobject import PyDescr_NewWrapper
-from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF, Py_XDECREF
+from pypy.module.cpyext.pyobject import Py_IncRef, Py_DecRef
from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr, PyTypeObject, \
PyGetSetDef
from pypy.module.cpyext.slotdefs import slotdefs
@@ -129,7 +129,7 @@
# XXX call tp_del if necessary
generic_cpy_call(space, dealloc, obj)
pto = rffi.cast(PyObject, pto)
- Py_DECREF(space, pto)
+ Py_DecRef(space, pto)
@cpython_api([PyObject], lltype.Void, external=False)
@@ -141,7 +141,7 @@
obj_voidp = rffi.cast(rffi.VOIDP_real, obj)
generic_cpy_call(space, pto.c_tp_free, obj_voidp)
pto = rffi.cast(PyObject, pto)
- Py_DECREF(space, pto)
+ Py_DecRef(space, pto)
@cpython_api([PyObject], lltype.Void, external=False)
def type_dealloc(space, obj):
@@ -149,15 +149,15 @@
obj_pto = rffi.cast(PyTypeObjectPtr, obj)
type_pto = rffi.cast(PyTypeObjectPtr, obj.c_ob_type)
base_pyo = rffi.cast(PyObject, obj_pto.c_tp_base)
- Py_XDECREF(space, base_pyo)
- Py_XDECREF(space, obj_pto.c_tp_bases)
- Py_XDECREF(space, obj_pto.c_tp_cache) # lets do it like cpython
+ Py_DecRef(space, base_pyo)
+ Py_DecRef(space, obj_pto.c_tp_bases)
+ Py_DecRef(space, obj_pto.c_tp_cache) # lets do it like cpython
if obj_pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE:
lltype.free(obj_pto.c_tp_name, flavor="raw")
obj_pto_voidp = rffi.cast(rffi.VOIDP_real, obj_pto)
generic_cpy_call(space, type_pto.c_tp_free, obj_pto_voidp)
pto = rffi.cast(PyObject, type_pto)
- Py_DECREF(space, pto)
+ Py_DecRef(space, pto)
def allocate_type_obj(space, w_type):
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py Wed Mar 31 14:33:26 2010
@@ -1,9 +1,9 @@
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.rpython.lltypesystem.lltype import Ptr, FuncType, Void
from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \
- PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \
- Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, make_ref, \
- PyStringObject, ADDR, from_ref
+ PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \
+ Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, PyStringObject, ADDR
+from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref
from pypy.module.cpyext.modsupport import PyMethodDef
More information about the Pypy-commit
mailing list