[pypy-commit] pypy cpyext-gc-support-2: Hopefully fix the bootstrap cycles in this way
arigo
pypy.commits at gmail.com
Tue Jan 26 19:19:56 EST 2016
Author: Armin Rigo <arigo at 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
More information about the pypy-commit
mailing list