[pypy-commit] pypy cpyext-gc-support: in-progress

arigo noreply at buildbot.pypy.org
Wed Oct 14 20:21:24 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-gc-support
Changeset: r80216:35dda6474dfa
Date: 2015-10-14 20:21 +0200
http://bitbucket.org/pypy/pypy/changeset/35dda6474dfa/

Log:	in-progress

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
@@ -5,7 +5,7 @@
 import py
 
 from pypy.conftest import pypydir
-from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.rtyper.tool import rffi_platform
 from rpython.rtyper.lltypesystem import ll2ctypes
 from rpython.rtyper.annlowlevel import llhelper
@@ -278,6 +278,10 @@
             raise ValueError("function %s has no return value for exceptions"
                              % func)
         def make_unwrapper(catch_exception):
+            # ZZZ is this whole logic really needed???  It seems to be only
+            # for RPython code calling PyXxx() functions directly.  I would
+            # think that usually directly calling the function is clean
+            # enough now
             names = api_function.argnames
             types_names_enum_ui = unrolling_iterable(enumerate(
                 zip(api_function.argtypes,
@@ -340,13 +344,7 @@
                 if not we_are_translated():
                     got_integer = isinstance(res, (int, long, float))
                     assert got_integer == expect_integer,'got %r not integer' % res
-                ZZZ   # where is the logic to return PyObject??
-                if res is None:
-                    return None
-                elif isinstance(res, Reference):
-                    return res.get_wrapped(space)
-                else:
-                    return res
+                return res
             unwrapper.func = func
             unwrapper.api_func = api_function
             unwrapper._always_inline_ = 'try'
@@ -508,7 +506,8 @@
 # So we need a forward and backward mapping in our State instance
 PyObjectStruct = lltype.ForwardReference()
 PyObject = lltype.Ptr(PyObjectStruct)
-PyObjectFields = (("ob_refcnt", lltype.Signed), ("ob_type", PyTypeObjectPtr))
+PyObjectFields = (("ob_refcnt", lltype.Signed), ("ob_type", PyTypeObjectPtr),
+                  ("ob_pypy_link", llmemory.GCREF))
 PyVarObjectFields = PyObjectFields + (("ob_size", Py_ssize_t), )
 cpython_struct('PyObject', PyObjectFields, PyObjectStruct)
 PyVarObjectStruct = cpython_struct("PyVarObject", PyVarObjectFields)
diff --git a/pypy/module/cpyext/include/object.h b/pypy/module/cpyext/include/object.h
--- a/pypy/module/cpyext/include/object.h
+++ b/pypy/module/cpyext/include/object.h
@@ -18,7 +18,8 @@
 
 #define PyObject_HEAD  \
     long ob_refcnt;       \
-    struct _typeobject *ob_type;
+    struct _typeobject *ob_type; \
+    void *ob_pypy_link;
 
 #define PyObject_VAR_HEAD		\
 	PyObject_HEAD			\
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
@@ -290,9 +290,10 @@
 
 def _create_pyobj_from_w_obj(w_obj):
     # XXX temp, needs cases
-    ob = lltype.malloc(PyObject, flavor='raw', track_allocation=False)
-    ob.ob_refcnt = 0
-    ob.ob_pypy_link = NULL_GCREF
+    ob = lltype.malloc(PyObject.TO, flavor='raw', track_allocation=False)
+    ob.c_ob_refcnt = 0
+    ob.c_ob_pypy_link = NULL_GCREF
+    # ob.c_ob_type = ...
     rawrefcount.create_link_pypy(w_obj, ob)
     return ob
 
@@ -303,7 +304,7 @@
     'None' is returned as a NULL.  This doesn't give a new reference, but
     the returned 'PyObject *' is valid at least as long as 'w_obj' is.
     """
-    assert is_wrapped(w_obj)
+    assert not is_pyobj(w_obj)
     if w_obj is None:
         return lltype.nullptr(PyObject.TO)
     #if isinstance(w_obj, W_CPyExtPlaceHolderObject):
@@ -317,7 +318,7 @@
 
 @specialize.ll()
 def from_ref(pyobj):
-    assert not is_wrapped(pyobj)
+    assert is_pyobj(pyobj)
     if not pyobj:
         return None
     pyobj = rffi.cast(PyObject, pyobj)
diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -20,9 +20,9 @@
 def create_link_pypy(p, ob):
     "NOT_RPYTHON: a link where the PyPy object contains all the data"
     assert not hasattr(p, '__rawrefcount')
-    assert not ob.ob_pypy_link
-    ob.ob_pypy_link = rgc.cast_instance_to_gcref(p)
-    ob.ob_refcnt += REFCNT_FROM_PYPY_OBJECT
+    assert not ob.c_ob_pypy_link
+    ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
+    ob.c_ob_refcnt += REFCNT_FROM_PYPY_OBJECT
     p.__rawrefcount = ob
     _p_list.append(ob)
 
@@ -30,9 +30,9 @@
     """NOT_RPYTHON: a link where the PyObject contains all the data.
        from_obj() will not work on this 'p'."""
     assert not hasattr(p, '__rawrefcount')
-    assert not ob.ob_pypy_link
-    ob.ob_pypy_link = rgc.cast_instance_to_gcref(p)
-    ob.ob_refcnt += REFCNT_FROM_PYPY_OBJECT
+    assert not ob.c_ob_pypy_link
+    ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
+    ob.c_ob_refcnt += REFCNT_FROM_PYPY_OBJECT
     p.__rawrefcount = lltype.nullptr(lltype.typeOf(ob).TO)
     _o_list.append(ob)
 
@@ -40,9 +40,9 @@
     """NOT_RPYTHON: a link where both p and ob contain some data.
        from_obj() will not work on this 'p'."""
     assert not hasattr(p, '__rawrefcount')
-    assert not ob.ob_pypy_link
-    ob.ob_pypy_link = rgc.cast_instance_to_gcref(p)
-    ob.ob_refcnt += REFCNT_FROM_PYPY_OBJECT
+    assert not ob.c_ob_pypy_link
+    ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
+    ob.c_ob_refcnt += REFCNT_FROM_PYPY_OBJECT
     p.__rawrefcount = lltype.nullptr(lltype.typeOf(ob).TO)
     _s_list.append(ob)
 
@@ -55,7 +55,7 @@
 
 @specialize.arg(0)
 def to_obj(Class, ob):
-    pypy_gcref = ob.ob_pypy_link
+    pypy_gcref = ob.c_ob_pypy_link
     if we_are_translated():
         return annlowlevel.cast_gcref_to_instance(Class, pypy_gcref)
     else:
@@ -71,18 +71,18 @@
     from the O list.
     """
     def detach(ob, wr_list):
-        assert ob.ob_refcnt >= REFCNT_FROM_PYPY_OBJECT
-        assert ob.ob_pypy_link
-        p = rgc.try_cast_gcref_to_instance(object, ob.ob_pypy_link)
+        assert ob.c_ob_refcnt >= REFCNT_FROM_PYPY_OBJECT
+        assert ob.c_ob_pypy_link
+        p = rgc.try_cast_gcref_to_instance(object, ob.c_ob_pypy_link)
         assert p is not None
-        ob.ob_pypy_link = lltype.nullptr(llmemory.GCREF.TO)
+        ob.c_ob_pypy_link = lltype.nullptr(llmemory.GCREF.TO)
         wr_list.append((ob, weakref.ref(p)))
 
     global _p_list, _o_list, _s_list
     wr_p_list = []
     new_p_list = []
     for ob in _p_list:
-        if ob.ob_refcnt > REFCNT_FROM_PYPY_OBJECT:
+        if ob.c_ob_refcnt > REFCNT_FROM_PYPY_OBJECT:
             new_p_list.append(ob)
         else:
             wr_p_list.append(weakref.ref(ob))
@@ -92,7 +92,7 @@
     wr_s_list = []
     new_s_list = []
     for ob in _s_list:
-        if ob.ob_refcnt > REFCNT_FROM_PYPY_OBJECT:
+        if ob.c_ob_refcnt > REFCNT_FROM_PYPY_OBJECT:
             new_s_list.append(ob)
         else:
             detach(ob, wr_s_list)
@@ -109,14 +109,14 @@
     rgc.collect()
 
     def attach(ob, wr, final_list):
-        assert ob.ob_refcnt >= REFCNT_FROM_PYPY_OBJECT
+        assert ob.c_ob_refcnt >= REFCNT_FROM_PYPY_OBJECT
         p = wr()
         if p is not None:
-            ob.ob_pypy_link = rgc.cast_instance_to_gcref(p)
+            ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
             final_list.append(ob)
         else:
-            ob.ob_refcnt -= REFCNT_FROM_PYPY_OBJECT
-            if ob.ob_refcnt == 0:
+            ob.c_ob_refcnt -= REFCNT_FROM_PYPY_OBJECT
+            if ob.c_ob_refcnt == 0:
                 dealloc.append(ob)
 
     _p_list = new_p_list
diff --git a/rpython/rlib/test/test_rawrefcount.py b/rpython/rlib/test/test_rawrefcount.py
--- a/rpython/rlib/test/test_rawrefcount.py
+++ b/rpython/rlib/test/test_rawrefcount.py
@@ -7,8 +7,8 @@
         self.intval = intval
 
 PyObjectS = lltype.Struct('PyObjectS',
-                          ('ob_refcnt', lltype.Signed),
-                          ('ob_pypy_link', llmemory.GCREF))
+                          ('c_ob_refcnt', lltype.Signed),
+                          ('c_ob_pypy_link', llmemory.GCREF))
 PyObject = lltype.Ptr(PyObjectS)
 
 
@@ -71,7 +71,7 @@
         assert rawrefcount._p_list == [ob]
         wr_ob = weakref.ref(ob)
         wr_p = weakref.ref(p)
-        ob.ob_refcnt += 1      # <=
+        ob.c_ob_refcnt += 1      # <=
         del ob, p
         rawrefcount._collect()
         ob = wr_ob()
@@ -121,13 +121,13 @@
         assert rawrefcount._o_list == [ob]
         wr_ob = weakref.ref(ob)
         wr_p = weakref.ref(p)
-        ob.ob_refcnt += 1      # <=
+        ob.c_ob_refcnt += 1      # <=
         del p
         dealloc = rawrefcount._collect()
         assert dealloc == []
         p = wr_p()
         assert p is None            # was unlinked
-        assert ob.ob_refcnt == 1    # != REFCNT_FROM_PYPY_OBJECT + 1
+        assert ob.c_ob_refcnt == 1    # != REFCNT_FROM_PYPY_OBJECT + 1
         assert rawrefcount._o_list == []
         assert rawrefcount.to_obj(W_Root, ob) == None
 
@@ -173,7 +173,7 @@
         assert rawrefcount._s_list == [ob]
         wr_ob = weakref.ref(ob)
         wr_p = weakref.ref(p)
-        ob.ob_refcnt += 1      # <=
+        ob.c_ob_refcnt += 1      # <=
         del ob, p
         rawrefcount._collect()
         ob = wr_ob()


More information about the pypy-commit mailing list