[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