[pypy-svn] r72761 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test
xoraxax at codespeak.net
xoraxax at codespeak.net
Wed Mar 24 22:15:24 CET 2010
Author: xoraxax
Date: Wed Mar 24 22:15:22 2010
New Revision: 72761
Modified:
pypy/branch/cpython-extension/pypy/module/cpyext/TODO
pypy/branch/cpython-extension/pypy/module/cpyext/api.py
pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py
pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py
pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py
pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py
Log:
Support non-external functions. These are the ones that would be declared static in the CPython code (yes, not really part of the API but I need them to fill the slots).
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/TODO (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/TODO Wed Mar 24 22:15:22 2010
@@ -1,7 +1,6 @@
- Generate header files programmatically.
- Implement C API.
- Complete the PyTypeObject initialization code.
- - Free pto.c_tp_name correctly
- properly support "borrowed" references: the PyObject must be stored
somewhere
- lltype.free in PyObject_Del() sometimes raise an exception (but all
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 Wed Mar 24 22:15:22 2010
@@ -38,6 +38,7 @@
constant_names = """
Py_TPFLAGS_READY Py_TPFLAGS_READYING
METH_COEXIST METH_STATIC METH_CLASS METH_NOARGS
+Py_TPFLAGS_HEAPTYPE
""".split()
for name in constant_names:
setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name))
@@ -64,7 +65,7 @@
self.argnames = argnames[1:]
assert len(self.argnames) == len(self.argtypes)
-def cpython_api(argtypes, restype, borrowed=False, error=_NOT_SPECIFIED):
+def cpython_api(argtypes, restype, borrowed=False, error=_NOT_SPECIFIED, external=True):
if error is _NOT_SPECIFIED:
if restype is PyObject:
error = lltype.nullptr(PyObject.TO)
@@ -108,7 +109,9 @@
func.api_func = api_function
unwrapper.api_func = api_function
- FUNCTIONS[func.func_name] = api_function
+ unwrapper.func = func
+ if external:
+ FUNCTIONS[func.func_name] = api_function
INTERPLEVEL_API[func.func_name] = unwrapper
return unwrapper
return decorate
@@ -190,7 +193,7 @@
if space.is_w(w_type, w_obj):
pto = py_obj
else:
- pto = make_ref(space, w_type, borrowed=True)
+ pto = make_ref(space, w_type)
elif isinstance(w_obj, W_PyCObject):
w_type = space.type(w_obj)
assert isinstance(w_type, W_PyCTypeObject)
@@ -200,7 +203,7 @@
py_obj = lltype.malloc(T, None, flavor="raw")
else:
py_obj = lltype.malloc(PyObject.TO, None, flavor="raw")
- pto = make_ref(space, space.type(w_obj), borrowed=True)
+ pto = make_ref(space, space.type(w_obj))
py_obj.c_obj_type = rffi.cast(PyObject, pto)
py_obj.c_obj_refcnt = 1
ctypes_obj = ll2ctypes.lltype2ctypes(py_obj)
@@ -304,6 +307,8 @@
renamed_symbols = []
if rename:
for name in export_symbols:
+ if name.startswith("PyPy"):
+ continue
if "#" in name:
deref = "*"
else:
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py Wed Mar 24 22:15:22 2010
@@ -1,5 +1,6 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL
+from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL, \
+ general_check
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
@cpython_api([], PyObject)
@@ -9,8 +10,7 @@
@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
def PyDict_Check(space, w_obj):
w_type = space.w_dict
- w_obj_type = space.type(w_obj)
- return space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type))
+ return general_check(space, w_obj, w_type)
@cpython_api([PyObject, rffi.CCHARP, PyObject], rffi.INT_real, error=-1)
@@ -22,4 +22,4 @@
space.setitem(w_dict, space.wrap(key), w_obj)
return 0
else:
- PyErr_BadInternalCall()
+ PyErr_BadInternalCall(space)
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Wed Mar 24 22:15:22 2010
@@ -80,4 +80,4 @@
assert isinstance(w_mod, Module)
return w_mod.getdict()
else:
- PyErr_BadInternalCall()
+ PyErr_BadInternalCall(space)
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 Wed Mar 24 22:15:22 2010
@@ -139,6 +139,7 @@
self.space.wrap('foo'))
self.space.delitem(self.space.sys.get('modules'),
self.space.wrap('foo'))
+ Py_DECREF(self.space, w_mod)
except OperationError:
pass
self.space.fromcache(State).print_refcounts()
@@ -372,6 +373,8 @@
Py_InitModule("foo", methods);
"""
body = """
+ PyObject* PyPy_Crash1(void);
+ long PyPy_Crash2(void);
static PyObject* foo_crash1(PyObject* self, PyObject *args)
{
return PyPy_Crash1();
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 Wed Mar 24 22:15:22 2010
@@ -12,7 +12,7 @@
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
+from pypy.module.cpyext.api import make_wrapper, Py_TPFLAGS_HEAPTYPE
from pypy.interpreter.module import Module
from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs
from pypy.module.cpyext.state import State
@@ -215,22 +215,57 @@
w_type = space.type(self)
assert isinstance(w_type, W_PyCTypeObject)
pto = w_type.pto
+ print "Called W_PyCObject.__del__"
generic_cpy_call(space, pto.c_tp_dealloc, self)
+ at cpython_api([PyObject], lltype.Void, external=False)
+def subtype_dealloc(space, 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
+ # XXX call tp_del if necessary
+ # XXX call basedealloc instead of a fixed type_dealloc
+ type_dealloc(space, obj)
+ Py_DECREF(space, pto)
+
+
+ at cpython_api([PyObject], lltype.Void, external=False)
+def type_dealloc(space, obj):
+ print "type_dealloc of", obj
+ obj_pto = rffi.cast(PyTypeObjectPtr, obj)
+ type_pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type)
+ # type_dealloc code follows:
+ # XXX XDECREF tp_base, tp_dict, tp_bases, tp_mro, tp_cache,
+ # tp_subclasses
+ # free tp_doc
+ lltype.free(obj_pto.c_tp_name, flavor="raw")
+ generic_cpy_call(space, type_pto.c_tp_free, obj)
+
+
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)
pto = lltype.malloc(PyTypeObject, None, flavor="raw")
- callable = PyObject_dealloc
- pto.c_tp_dealloc = llhelper(callable.api_func.functype,
- make_wrapper(space, callable))
+ 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))
+ else:
+ callable = PyObject_dealloc
+ pto.c_tp_dealloc = llhelper(callable.api_func.functype,
+ make_wrapper(space, callable))
+ print "Chose dealloc strategy %r for %r" % (callable.func, w_type)
callable = PyObject_Del
+ pto.c_tp_flags = Py_TPFLAGS_HEAPTYPE
pto.c_tp_free = llhelper(callable.api_func.functype,
make_wrapper(space, callable))
- # XXX free c_tp_name again!
pto.c_tp_name = rffi.str2charp(w_type.getname(space, "?"))
- pto.c_tp_basicsize = -1 # hopefully this makes malloc bail
+ pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out
# XXX fill slots in pto
return pto
More information about the Pypy-commit
mailing list