[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