[pypy-svn] r73803 - pypy/branch/cpython-extension/pypy/module/cpyext

afa at codespeak.net afa at codespeak.net
Fri Apr 16 10:40:38 CEST 2010


Author: afa
Date: Fri Apr 16 10:40:36 2010
New Revision: 73803

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/api.py
   pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py
Log:
Change the logic to bootstrap basic types (object, type, tuple)
- insert null references in the w2r table
- then create references
- fix cycles
- update the w2r table with complete objects

This removes most of special cases in make_ref.


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	Fri Apr 16 10:40:36 2010
@@ -435,27 +435,52 @@
     return func
 
 def bootstrap_types(space):
-    from pypy.module.cpyext.pyobject import make_ref
-    from pypy.module.cpyext.typeobject import PyTypeObjectPtr, PyPyType_Ready, \
-            inherit_slots
+    from pypy.module.cpyext.pyobject import make_ref, create_ref, track_reference
+    from pypy.module.cpyext.typeobject import PyTypeObjectPtr
 
     for func in BOOTSTRAP_FUNCTIONS:
         func(space)
 
-    # bootstrap this damn cycle
-    type_pto = make_ref(space, space.w_type)
-    type_pto = rffi.cast(PyTypeObjectPtr, type_pto)
-    
-    object_pto = make_ref(space, space.w_object)
-    object_pto = rffi.cast(PyTypeObjectPtr, object_pto)
-    type_pto.c_tp_base = object_pto
-    type_pto.c_ob_type = rffi.cast(PyTypeObjectPtr, make_ref(space, space.w_type))
-    object_pto.c_ob_type = rffi.cast(PyTypeObjectPtr, make_ref(space, space.w_type))
-    PyPyType_Ready(space, object_pto, space.w_object)
-    PyPyType_Ready(space, type_pto, space.w_type)
-    type_pto.c_tp_bases = make_ref(space, space.newtuple([space.w_object]))
-    object_pto.c_tp_bases = make_ref(space, space.newtuple([]))
-    inherit_slots(space, type_pto, space.w_object)
+    # 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
+
+    # insert null placeholders to please make_ref()
+    state = space.fromcache(State)
+    state.py_objects_w2r[space.w_type] = lltype.nullptr(PyObject.TO)
+    state.py_objects_w2r[space.w_object] = lltype.nullptr(PyObject.TO)
+    state.py_objects_w2r[space.w_tuple] = lltype.nullptr(PyObject.TO)
+
+    # create the objects
+    py_type = create_ref(space, space.w_type)
+    py_object = create_ref(space, space.w_object)
+    py_tuple = create_ref(space, space.w_tuple)
+
+    # 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.c_tp_base = pto_object
+
+    pto_tuple = rffi.cast(PyTypeObjectPtr, py_tuple)
+    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
+
+    # Restore the mapping
+    track_reference(space, py_type, space.w_type)
+    track_reference(space, py_object, space.w_object)
+    track_reference(space, py_tuple, space.w_tuple)
 
 
 #_____________________________________________________

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py	Fri Apr 16 10:40:36 2010
@@ -62,8 +62,7 @@
                 obj = lltype.malloc(tp_basestruct, flavor='raw', zero=True)
                 pyobj = rffi.cast(PyObject, obj)
                 pyobj.c_ob_refcnt = 1
-                if w_type is not space.w_type:
-                    pyobj.c_ob_type = rffi.cast(PyTypeObjectPtr, make_ref(space, w_type))
+                pyobj.c_ob_type = rffi.cast(PyTypeObjectPtr, make_ref(space, w_type))
                 return pyobj
 
         if tp_attach:
@@ -134,20 +133,7 @@
     w_type = space.type(w_obj)
     typedescr = get_typedescr(w_obj.typedef)
 
-    if space.is_w(w_type, space.w_type) or space.is_w(w_type,
-            space.gettypeobject(W_PyCTypeObject.typedef)):
-        py_obj = typedescr.allocate(space, w_type)
-
-        # put the type object early into the dict
-        # to support dependency cycles like object/type
-        state = space.fromcache(State)
-        state.py_objects_w2r[w_obj] = py_obj
-        py_obj.c_ob_type = rffi.cast(
-            PyTypeObjectPtr, make_ref(space, w_type,
-                                      steal=not space.is_w(w_type, space.w_type)))
-
-        typedescr.attach(space, py_obj, w_obj)
-    elif isinstance(w_type, W_PyCTypeObject):
+    if isinstance(w_type, W_PyCTypeObject):
         lifeline = w_obj.get_pyolifeline()
         if lifeline is not None: # make old PyObject ready for use in C code
             py_obj = lifeline.pyo
@@ -171,23 +157,31 @@
         typedescr.attach(space, py_obj, w_obj)
     return py_obj
 
+def track_reference(space, py_obj, w_obj, borrowed=False):
+    # XXX looks like a PyObject_GC_TRACK
+    ptr = rffi.cast(ADDR, py_obj)
+    if DEBUG_REFCOUNT:
+        debug_refcount("MAKREF", py_obj, w_obj)
+    state = space.fromcache(State)
+    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
+
 def make_ref(space, w_obj, borrowed=False, steal=False, items=0):
     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:
+    try:
+        py_obj = state.py_objects_w2r[w_obj]
+    except KeyError:
         assert not steal
         py_obj = create_ref(space, w_obj, items)
-        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:
+        track_reference(space, py_obj, w_obj, borrowed=borrowed)
+        return py_obj
+
+    if not steal:
         if borrowed:
             py_obj_addr = rffi.cast(ADDR, py_obj)
             if py_obj_addr not in state.borrowed_objects:

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	Fri Apr 16 10:40:36 2010
@@ -457,8 +457,7 @@
         assert pto.c_tp_flags & Py_TPFLAGS_READYING == 0
         pto.c_tp_flags |= Py_TPFLAGS_READYING
         base = pto.c_tp_base
-        if not base and not (w_obj is not None and
-            space.is_w(w_obj, space.w_object)):
+        if not base and not space.is_w(w_obj, space.w_object):
             base_pyo = make_ref(space, space.w_object, steal=True)
             base = pto.c_tp_base = rffi.cast(PyTypeObjectPtr, base_pyo)
         else:
@@ -467,8 +466,7 @@
             PyPyType_Ready(space, base, None)
         if base and not pto.c_ob_type: # will be filled later
             pto.c_ob_type = base.c_ob_type
-        if not pto.c_tp_bases and not (space.is_w(w_obj, space.w_object)
-                or space.is_w(w_obj, space.w_type)):
+        if not pto.c_tp_bases:
             if not base:
                 bases = space.newtuple([])
             else:



More information about the Pypy-commit mailing list