[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