[pypy-svn] r74382 - pypy/trunk/pypy/module/cpyext

afa at codespeak.net afa at codespeak.net
Wed May 5 18:29:22 CEST 2010


Author: afa
Date: Wed May  5 18:29:20 2010
New Revision: 74382

Modified:
   pypy/trunk/pypy/module/cpyext/typeobject.py
Log:
Reorganize type initialization code:
finish_type_1() uses info already available in the structure itself, to compute things necessary to create the type.
finish_type_2() completes the structure after the type is created in the interpreter (like slot inheritance)


Modified: pypy/trunk/pypy/module/cpyext/typeobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/typeobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/typeobject.py	Wed May  5 18:29:20 2010
@@ -479,9 +479,8 @@
     w_base = best_base(space, w_type.bases_w)
     pto.c_tp_base = rffi.cast(PyTypeObjectPtr, make_ref(space, w_base))
 
-    pto.c_tp_bases = lltype.nullptr(PyObject.TO)
-    PyPyType_Ready(space, pto, w_type)
-
+    finish_type_1(space, pto)
+    finish_type_2(space, pto, w_type)
 
     pto.c_tp_basicsize = rffi.sizeof(typedescr.basestruct)
     if pto.c_tp_base:
@@ -493,11 +492,21 @@
     if space.is_w(w_type, space.w_object):
         pto.c_tp_new = rffi.cast(newfunc, 1)
     update_all_slots(space, w_type, pto)
+    pto.c_tp_flags |= Py_TPFLAGS_READY
     return pto
 
 @cpython_api([PyTypeObjectPtr], rffi.INT_real, error=-1)
 def PyType_Ready(space, pto):
-    return PyPyType_Ready(space, pto, None)
+    if pto.c_tp_flags & Py_TPFLAGS_READY:
+        return
+    assert pto.c_tp_flags & Py_TPFLAGS_READYING == 0
+    pto.c_tp_flags |= Py_TPFLAGS_READYING
+    try:
+        type_realize(space, rffi.cast(PyObject, pto))
+        pto.c_tp_flags |= Py_TPFLAGS_READY
+    finally:
+        pto.c_tp_flags &= ~Py_TPFLAGS_READYING
+    return 0
 
 def solid_base(space, w_type):
     typedef = w_type.instancetypedef
@@ -553,61 +562,63 @@
     """
     Creates an interpreter type from a PyTypeObject structure.
     """
-    return PyPyType_Ready(space, rffi.cast(PyTypeObjectPtr, py_obj), None)
+    # missing:
+    # setting __doc__ if not defined and tp_doc defined
+    # inheriting tp_as_* slots
+    # unsupported:
+    # tp_mro, tp_subclasses
+    py_type = rffi.cast(PyTypeObjectPtr, py_obj)
+
+    if not py_type.c_tp_base:
+        base = make_ref(space, space.w_object, steal=True)
+        py_type.c_tp_base = rffi.cast(PyTypeObjectPtr, base)
 
-def PyPyType_Ready(space, pto, w_obj):
-    try:
-        pto.c_tp_dict = lltype.nullptr(PyObject.TO) # not supported
-        if pto.c_tp_flags & Py_TPFLAGS_READY:
-            return w_obj
-        assert pto.c_tp_flags & Py_TPFLAGS_READYING == 0
-        pto.c_tp_flags |= Py_TPFLAGS_READYING
-        base = pto.c_tp_base
-        if not base:
-            base_pyo = make_ref(space, space.w_object, steal=True)
-            base = pto.c_tp_base = rffi.cast(PyTypeObjectPtr, base_pyo)
-        else:
-            base_pyo = rffi.cast(PyObject, base)
-        if base and not base.c_tp_flags & Py_TPFLAGS_READY:
-            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:
-            if not base:
-                bases = space.newtuple([])
-            else:
-                bases = space.newtuple([from_ref(space, base_pyo)])
-            pto.c_tp_bases = make_ref(space, bases)
-        if w_obj is None:
-            w_obj = PyPyType_Register(space, pto)
-        pto.c_tp_mro = make_ref(space, space.newtuple(w_obj.mro_w))
-        if base:
-            inherit_special(space, pto, base)
-        for w_base in space.fixedview(from_ref(space, pto.c_tp_bases)):
-            inherit_slots(space, pto, w_base)
-        # missing:
-        # setting __doc__ if not defined and tp_doc defined
-        # inheriting tp_as_* slots
-        # unsupported:
-        # tp_mro, tp_subclasses
-    finally:
-        pto.c_tp_flags &= ~Py_TPFLAGS_READYING
-    pto.c_tp_flags |= Py_TPFLAGS_READY
-    return w_obj
+    finish_type_1(space, py_type)
 
-def PyPyType_Register(space, pto):
     w_obj = space.allocate_instance(
         W_PyCTypeObject,
         space.gettypeobject(W_PyCTypeObject.typedef))
+    track_reference(space, py_obj, w_obj)
+    w_obj.__init__(space, py_type)
+    w_obj.ready()
+
+    finish_type_2(space, py_type, w_obj)
+
     state = space.fromcache(State)
     state.non_heaptypes.append(w_obj)
-    py_obj = rffi.cast(PyObject, pto)
 
-    track_reference(space, py_obj, w_obj)
-    w_obj.__init__(space, pto)
-    w_obj.ready()
     return w_obj
 
+def finish_type_1(space, pto):
+    """
+    Sets up tp_bases, necessary before creating the interpreter type.
+    """
+    pto.c_tp_dict = lltype.nullptr(PyObject.TO) # not supported
+
+    base = pto.c_tp_base
+    base_pyo = rffi.cast(PyObject, pto.c_tp_base)
+    if base and not base.c_tp_flags & Py_TPFLAGS_READY:
+        type_realize(space, rffi.cast(PyObject, base_pyo))
+    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:
+        if not base:
+            bases = space.newtuple([])
+        else:
+            bases = space.newtuple([from_ref(space, base_pyo)])
+        pto.c_tp_bases = make_ref(space, bases)
+
+def finish_type_2(space, pto, w_obj):
+    """
+    Sets up other attributes, when the interpreter type has been created.
+    """
+    pto.c_tp_mro = make_ref(space, space.newtuple(w_obj.mro_w))
+    base = pto.c_tp_base
+    if base:
+        inherit_special(space, pto, base)
+    for w_base in space.fixedview(from_ref(space, pto.c_tp_bases)):
+        inherit_slots(space, pto, w_base)
+
 @cpython_api([PyTypeObjectPtr, PyTypeObjectPtr], rffi.INT_real, error=CANNOT_FAIL)
 def PyType_IsSubtype(space, a, b):
     """Return true if a is a subtype of b.



More information about the Pypy-commit mailing list