Author: Armin Rigo <ar...@tunes.org>
Branch: cpyext-gc-support-2
Changeset: r81956:20a0b177ddae
Date: 2016-01-26 23:10 +0100
http://bitbucket.org/pypy/pypy/changeset/20a0b177ddae/

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
@@ -37,6 +37,7 @@
 from py.builtin import BaseException
 from rpython.tool.sourcetools import func_with_new_name
 from rpython.rtyper.lltypesystem.lloperation import llop
+from rpython.rlib import rawrefcount
 
 DEBUG_WRAPPER = True
 
@@ -825,14 +826,6 @@
         outputfilename=str(udir / "module_cache" / "pypyapi"))
     modulename = py.path.local(eci.libraries[-1])
 
-    run_bootstrap_functions(space)
-
-    # load the bridge, and init structure
-    import ctypes
-    bridge = ctypes.CDLL(str(modulename), mode=ctypes.RTLD_GLOBAL)
-
-    space.fromcache(State).install_dll(eci)
-
     def dealloc_trigger():
         print 'dealloc_trigger...'
         while True:
@@ -845,6 +838,14 @@
         return "RETRY"
     rawrefcount.init(dealloc_trigger)
 
+    run_bootstrap_functions(space)
+
+    # load the bridge, and init structure
+    import ctypes
+    bridge = ctypes.CDLL(str(modulename), mode=ctypes.RTLD_GLOBAL)
+
+    space.fromcache(State).install_dll(eci)
+
     # populate static data
     for name, (typ, expr) in GLOBALS.iteritems():
         from pypy.module import cpyext    # for the eval() below
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
@@ -13,6 +13,8 @@
 from rpython.rlib.objectmodel import specialize, we_are_translated
 from rpython.rlib.rweakref import RWeakKeyDictionary
 from rpython.rtyper.annlowlevel import llhelper
+from rpython.rlib import rawrefcount
+
 
 #________________________________________________________
 # type description
@@ -31,12 +33,13 @@
         # similar to PyType_GenericAlloc?
         # except that it's not related to any pypy object.
 
-        pytype = rffi.cast(PyTypeObjectPtr, make_ref(space, w_type))
+        pytype = get_pyobj_and_incref(space, w_type)
+        pytype = rffi.cast(PyTypeObjectPtr, pytype)
+        assert pytype
         # Don't increase refcount for non-heaptypes
-        if pytype:
-            flags = rffi.cast(lltype.Signed, pytype.c_tp_flags)
-            if not flags & Py_TPFLAGS_HEAPTYPE:
-                Py_DecRef(space, w_type)
+        flags = rffi.cast(lltype.Signed, pytype.c_tp_flags)
+        if not flags & Py_TPFLAGS_HEAPTYPE:
+            Py_DecRef(space, w_type)
 
         if pytype:
             size = pytype.c_tp_basicsize
@@ -158,19 +161,18 @@
     #state = space.fromcache(RefcountState)
     w_type = space.type(w_obj)
     if w_type.is_cpytype():
-        py_obj = state.get_from_lifeline(w_obj)
+        ZZZ # py_obj = state.get_from_lifeline(w_obj)
         if py_obj:
             Py_IncRef(space, py_obj)
             return py_obj
 
     typedescr = get_typedescr(w_obj.typedef)
     py_obj = typedescr.allocate(space, w_type, itemcount=itemcount)
-    if w_type.is_cpytype():
-        state.set_lifeline(w_obj, py_obj)
+    track_reference(space, py_obj, w_obj)
     typedescr.attach(space, py_obj, w_obj)
     return py_obj
 
-def track_reference(space, py_obj, w_obj, replace=False):
+def track_reference(space, py_obj, w_obj):
     """
     Ties together a PyObject and an interpreter object.
     """
@@ -181,8 +183,6 @@
         debug_refcount("MAKREF", py_obj, w_obj)
         assert w_obj
         assert py_obj
-        if not replace:
-            assert w_obj not in state.py_objects_w2r
     rawrefcount.create_link_pypy(py_obj, w_obj)
 
 def make_ref(space, w_obj):
@@ -239,14 +239,17 @@
     """
     Returns a 'PyObject *' representing the given intepreter object.
     This doesn't give a new reference, but the returned 'PyObject *'
-    is valid at least as long as 'w_obj' is.  To be safe, you should
-    use keepalive_until_here(w_obj) some time later.
-
-    NOTE: get_pyobj_and_incref() is safer.
+    is valid at least as long as 'w_obj' is.  **To be safe, you should
+    use keepalive_until_here(w_obj) some time later.**  In case of
+    doubt, use the safer get_pyobj_and_incref().
     """
     if w_obj is not None:
         assert not is_pyobj(w_obj)
-        return XXXXXXXXXXX
+        py_obj = rawrefcount.from_obj(PyObject, w_obj)
+        if not py_obj:
+            py_obj = create_ref(space, w_obj)
+            #track_reference(space, py_obj, w_obj) -- included with 
create_ref()
+        return py_obj
     else:
         return lltype.nullptr(PyObject.TO)
 as_pyobj._always_inline_ = 'try'
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -311,54 +311,12 @@
                    realize=type_realize,
                    dealloc=type_dealloc)
 
-    # some types are difficult to create because of cycles.
-    # - object.ob_type = type
-    # - type.ob_type   = type
-    # - tuple.ob_type  = type
-    # - type.tp_base   = object
-    # - tuple.tp_base  = object
-    # - type.tp_bases is a tuple
-    # - object.tp_bases is a tuple
-    # - tuple.tp_bases is a tuple
-
-    # we create the types manually here
+    # we create the type "type" manually here, because of the cycle
+    # through its 'c_ob_type' field
     py_type   = _type_alloc(space, lltype.nullptr(PyTypeObject))
-    py_object = _type_alloc(space, lltype.nullptr(PyTypeObject))
-    py_tuple  = _type_alloc(space, lltype.nullptr(PyTypeObject))
-    py_str    = _type_alloc(space, lltype.nullptr(PyTypeObject))
-    ...
-    
-    py_type = create_ref(space, space.w_type)
-    py_object = create_ref(space, space.w_object)
-    py_tuple = create_ref(space, space.w_tuple)
-    py_str = create_ref(space, space.w_str)
-    # XXX py_str is not initialized here correctly, because we are
-    #     not tracking it, it gets an empty c_ob_type from py_basestring
-
-    # form cycles
-    pto_type = rffi.cast(PyTypeObjectPtr, py_type)
-    py_type.c_ob_type = pto_type
-    py_object.c_ob_type = pto_type
-    py_tuple.c_ob_type = pto_type
-
-    pto_object = rffi.cast(PyTypeObjectPtr, py_object)
-    pto_type.c_tp_base = pto_object
-    pto_tuple = rffi.cast(PyTypeObjectPtr, py_tuple)
-    pto_tuple.c_tp_base = pto_object
-
-    pto_type.c_tp_bases.c_ob_type = pto_tuple
-    pto_object.c_tp_bases.c_ob_type = pto_tuple
-    pto_tuple.c_tp_bases.c_ob_type = pto_tuple
-
-    for typ in (py_type, py_object, py_tuple, py_str):
-        heaptype = rffi.cast(PyHeapTypeObject, typ)
-        heaptype.c_ht_name.c_ob_type = pto_type
-
-    # Restore the mapping
-    track_reference(space, py_type, space.w_type, replace=True)
-    track_reference(space, py_object, space.w_object, replace=True)
-    track_reference(space, py_tuple, space.w_tuple, replace=True)
-    track_reference(space, py_str, space.w_str, replace=True)
+    py_type.c_ob_type = rffi.cast(PyTypeObjectPtr, py_type)
+    track_reference(space, py_type, space.w_type)
+    type_attach(space, py_type, space.w_type)
 
 
 @cpython_api([PyObject], lltype.Void, external=False)
@@ -510,7 +468,7 @@
     if pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE:
         w_typename = space.getattr(w_type, space.wrap('__name__'))
         heaptype = rffi.cast(PyHeapTypeObject, pto)
-        heaptype.c_ht_name = make_ref(space, w_typename)
+        heaptype.c_ht_name = get_pyobj_and_incref(space, w_typename)
         from pypy.module.cpyext.stringobject import PyString_AsString
         pto.c_tp_name = PyString_AsString(space, heaptype.c_ht_name)
     else:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to