[pypy-svn] r72778 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test
xoraxax at codespeak.net
xoraxax at codespeak.net
Thu Mar 25 01:52:03 CET 2010
Author: xoraxax
Date: Thu Mar 25 01:52:01 2010
New Revision: 72778
Modified:
pypy/branch/cpython-extension/pypy/module/cpyext/api.py
pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py
pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py
Log:
Refactored memory management, now we should have less issues.
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 Thu Mar 25 01:52:01 2010
@@ -68,6 +68,13 @@
self.argnames = argnames[1:]
assert len(self.argnames) == len(self.argtypes)
+ def get_llhelper(self, space):
+ llh = getattr(self, '_llhelper', None)
+ if llh is None:
+ llh = llhelper(self.functype, make_wrapper(space, self.callable))
+ self._llhelper = llh
+ return llh
+
def cpython_api(argtypes, restype, borrowed=False, error=_NOT_SPECIFIED, external=True):
if error is _NOT_SPECIFIED:
if restype is PyObject:
@@ -143,7 +150,7 @@
'Py_False': ('PyObject*', 'space.w_False'),
'PyExc_Exception': ('PyObject*', 'space.w_Exception'),
'PyExc_TypeError': ('PyObject*', 'space.w_TypeError'),
- 'PyType_Type': ('PyTypeObject*', 'space.w_type'),
+ 'PyType_Type#': ('PyTypeObject*', 'space.w_type'),
'PyBaseObject_Type#': ('PyTypeObject*', 'space.w_object'),
}
@@ -400,6 +407,10 @@
ptr = ctypes.c_void_p.in_dll(bridge, name)
ptr.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, w_obj)),
ctypes.c_void_p).value
+ # hack, init base of the type type
+ if name == "PyType_Type":
+ pto = rffi.cast(PyTypeObjectPtr, ptr)
+ pto.c_tp_base = make_ref(space, w_object)
# implement structure initialization code
for name, func in FUNCTIONS.iteritems():
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Thu Mar 25 01:52:01 2010
@@ -130,7 +130,7 @@
self.w_import_module = self.space.wrap(self.import_module)
self.w_import_extension = self.space.wrap(self.import_extension)
self.w_check_refcnts = self.space.wrap(self.check_refcnts)
- #self.check_refcnts("Object has refcnt != 1: %r -- Not executing test!")
+ self.check_refcnts("Object has refcnt != 1: %r -- Not executing test!")
#self.space.fromcache(State).print_refcounts()
def teardown_method(self, func):
@@ -143,7 +143,7 @@
except OperationError:
pass
self.space.fromcache(State).print_refcounts()
- #self.check_refcnts("Test leaks object: %r")
+ self.check_refcnts("Test leaks object: %r")
def check_refcnts(self, message):
# check for sane refcnts
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 Thu Mar 25 01:52:01 2010
@@ -9,14 +9,14 @@
from pypy.objspace.std.typeobject import W_TypeObject
from pypy.objspace.std.objectobject import W_ObjectObject
from pypy.interpreter.typedef import TypeDef, GetSetProperty
-from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct
-from pypy.module.cpyext.api import PyObject, PyVarObjectFields, Py_ssize_t
-from pypy.module.cpyext.api import Py_TPFLAGS_READYING, Py_TPFLAGS_READY
-from pypy.module.cpyext.api import make_wrapper, Py_TPFLAGS_HEAPTYPE
+from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \
+ PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \
+ Py_TPFLAGS_READY, make_wrapper, Py_TPFLAGS_HEAPTYPE, make_ref
from pypy.interpreter.module import Module
from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs
from pypy.module.cpyext.state import State
from pypy.module.cpyext.methodobject import generic_cpy_call
+from pypy.module.cpyext.macros import Py_DECREF
PyTypeObject = lltype.ForwardReference()
@@ -209,25 +209,30 @@
def __init__(self, space):
self.space = space
- def __del__(self):
- space = self.space
- self.clear_all_weakrefs()
- w_type = space.type(self)
- assert isinstance(w_type, W_PyCTypeObject)
- pto = w_type.pto
- generic_cpy_call(space, pto.c_tp_dealloc, self)
+# def __del__(self):
+# space = self.space
+# self.clear_all_weakrefs()
+# w_type = space.type(self)
+# assert isinstance(w_type, W_PyCTypeObject)
+# pto = w_type.pto
+# generic_cpy_call(space, pto.c_tp_dealloc, self)
@cpython_api([PyObject], lltype.Void, external=False)
def subtype_dealloc(space, obj):
+ print "Dealloc of", obj
pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type)
assert pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE
base = pto
- #basedealloc = pto.c_tp_dealloc
- # XXX lookup basedealloc which is not subtype_dealloc
+ this_func_ptr = subtype_dealloc.api_func.get_llhelper(space)
+ ref_of_object_type = rffi.cast(PyTypeObjectPtr, make_ref(space, space.w_object))
+ while base.c_tp_dealloc == this_func_ptr:
+ base = base.c_tp_base
+ assert base
+ dealloc = base.c_tp_dealloc
# XXX call tp_del if necessary
- # XXX call basedealloc instead of a fixed type_dealloc
- type_dealloc(space, obj)
+ generic_cpy_call(space, dealloc, obj)
+ pto = rffi.cast(PyObject, pto)
Py_DECREF(space, pto)
@@ -240,29 +245,32 @@
# tp_subclasses
# free tp_doc
lltype.free(obj_pto.c_tp_name, flavor="raw")
- generic_cpy_call(space, type_pto.c_tp_free, obj)
-
-
+ obj_pto_voidp = rffi.cast(rffi.VOIDP_real, obj_pto)
+ generic_cpy_call(space, type_pto.c_tp_free, obj_pto_voidp)
def allocate_type_obj(space, w_type):
""" Allocates a pto from a w_type which must be a PyPy type. """
from pypy.module.cpyext.object import PyObject_dealloc, PyObject_Del
assert not isinstance(w_type, W_PyCTypeObject)
+ assert isinstance(w_type, W_TypeObject)
pto = lltype.malloc(PyTypeObject, None, flavor="raw")
- if space.is_w(w_type, space.w_type):
- callable = subtype_dealloc
- pto.c_tp_dealloc = llhelper(callable.api_func.functype,
- make_wrapper(space, callable))
+ if space.is_w(w_type, space.w_object):
+ pto.c_tp_dealloc = PyObject_dealloc.api_func.get_llhelper(space)
+ elif space.is_w(w_type, space.w_type):
+ pto.c_tp_dealloc = type_dealloc.api_func.get_llhelper(space)
else:
- callable = PyObject_dealloc
- pto.c_tp_dealloc = llhelper(callable.api_func.functype,
- make_wrapper(space, callable))
+ pto.c_tp_dealloc = subtype_dealloc.api_func.get_llhelper(space)
pto.c_tp_flags = Py_TPFLAGS_HEAPTYPE
- callable = PyObject_Del
- pto.c_tp_free = llhelper(callable.api_func.functype,
- make_wrapper(space, callable))
+ pto.c_tp_free = PyObject_Del.api_func.get_llhelper(space)
pto.c_tp_name = rffi.str2charp(w_type.getname(space, "?"))
pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out
+ bases_w = w_type.bases_w
+ assert len(bases_w) <= 1
+ if not bases_w:
+ pto.c_tp_base = lltype.nullptr(PyTypeObject)
+ elif not space.is_w(w_type, space.w_type): # avoid endless recursion
+ ref = make_ref(space, bases_w[0])
+ pto.c_tp_base = rffi.cast(PyTypeObjectPtr, ref)
# XXX fill slots in pto
return pto
More information about the Pypy-commit
mailing list