Author: Armin Rigo <ar...@tunes.org> Branch: cpyext-gc-support-2 Changeset: r81965:ae316294940c Date: 2016-01-27 01:04 +0100 http://bitbucket.org/pypy/pypy/changeset/ae316294940c/
Log: Hopefully fix the bootstrap cycles in this way 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 @@ -310,13 +310,24 @@ realize=type_realize, dealloc=type_dealloc) - # we create the type "type" manually here, because of the cycle - # through its 'c_ob_type' field + # There is the obvious cycle of 'type(type) == type', but there are + # also several other ones, like 'tuple.tp_bases' being itself a + # tuple instance. We solve the first one by creating the type + # "type" manually here. For the other cycles, we fix them by delaying + # creation of the types here, and hoping nothing breaks by seeing + # uninitialized-yet types (only for a few basic types like 'type', + # 'tuple', 'object', 'str'). + space._cpyext_delay_type_creation = [] + py_type = _type_alloc(space, lltype.nullptr(PyTypeObject)) 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) + while space._cpyext_delay_type_creation: + _type_really_attach(space, *space._cpyext_delay_type_creation.pop()) + del space._cpyext_delay_type_creation + @cpython_api([PyObject], lltype.Void, external=False) def subtype_dealloc(space, obj): @@ -447,6 +458,13 @@ """ Fills a newly allocated PyTypeObject from an existing type. """ + if hasattr(space, '_cpyext_delay_type_creation'): + space._cpyext_delay_type_creation.append((py_obj, w_type)) + else: + _type_really_attach(space, py_obj, w_type) + return rffi.cast(PyTypeObjectPtr, py_obj) + +def _type_really_attach(space, py_obj, w_type): from pypy.module.cpyext.object import PyObject_Del assert isinstance(w_type, W_TypeObject) @@ -499,7 +517,6 @@ pto.c_tp_name = rffi.str2charp(w_type.name) pto.c_tp_flags |= Py_TPFLAGS_READY - return pto def py_type_ready(space, pto): if pto.c_tp_flags & Py_TPFLAGS_READY: @@ -513,6 +530,7 @@ def type_realize(space, py_obj): pto = rffi.cast(PyTypeObjectPtr, py_obj) + assert pto.c_tp_flags & Py_TPFLAGS_READY == 0 assert pto.c_tp_flags & Py_TPFLAGS_READYING == 0 pto.c_tp_flags |= Py_TPFLAGS_READYING try: @@ -590,7 +608,8 @@ 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 not hasattr(space, '_cpyext_delay_type_creation'): + 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: diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -164,6 +164,10 @@ else: w_self.terminator = NoDictTerminator(space, w_self) + def __repr__(self): + "NOT_RPYTHON" + return '<W_TypeObject %r at 0x%x>' % (self.name, id(self)) + def mutated(w_self, key): """ The type is being mutated. key is either the string containing the _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit