Author: Armin Rigo <[email protected]>
Branch: cpyext-gc-support
Changeset: r80384:b641872f318e
Date: 2015-10-22 09:36 +0200
http://bitbucket.org/pypy/pypy/changeset/b641872f318e/
Log: progress
diff --git a/pypy/module/cpyext/include/intobject.h
b/pypy/module/cpyext/include/intobject.h
--- a/pypy/module/cpyext/include/intobject.h
+++ b/pypy/module/cpyext/include/intobject.h
@@ -20,4 +20,4 @@
#ifdef __cplusplus
}
#endif
-#endif /* !Py_BOOLOBJECT_H */
+#endif /* !Py_INTOBJECT_H */
diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py
--- a/pypy/module/cpyext/intobject.py
+++ b/pypy/module/cpyext/intobject.py
@@ -172,9 +172,9 @@
LONG_MAX, a long integer object is returned.
"""
if ival <= LONG_MAX:
- return new_pyint(rffi.cast(rffi.LONG, ival))
+ return new_pyint(space, rffi.cast(rffi.LONG, ival))
else:
- return get_pyobj_and_incref(space.wrap(ival))
+ return get_pyobj_and_incref(space, space.wrap(ival))
@cpython_api([Py_ssize_t], PyObject)
def PyInt_FromSsize_t(space, ival):
@@ -183,7 +183,7 @@
returned.
"""
# XXX win64
- return new_pyint(ival)
+ return new_pyint(space, ival)
@cpython_api([CONST_STRING, rffi.CCHARPP, rffi.INT_real], PyObject)
def PyInt_FromString(space, str, pend, base):
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -1,11 +1,12 @@
-from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rlib.rarithmetic import intmask, ovfcheck
from pypy.module.cpyext.api import (
cpython_api, generic_cpy_call, CANNOT_FAIL, Py_ssize_t, Py_ssize_tP,
PyVarObject, Py_buffer,
Py_TPFLAGS_HEAPTYPE, Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT,
Py_GE, CONST_STRING, FILEP, fwrite)
from pypy.module.cpyext.pyobject import (
- PyObject, PyObjectP, create_ref, from_ref, Py_IncRef, Py_DecRef,
+ PyObject, PyObjectP, create_ref, from_pyobj, Py_IncRef, Py_DecRef,
track_reference, get_typedescr, _Py_NewReference, RefcountState)
from pypy.module.cpyext.typeobject import PyTypeObjectPtr
from pypy.module.cpyext.pyerrors import PyErr_NoMemory, PyErr_BadInternalCall
@@ -17,11 +18,12 @@
@cpython_api([Py_ssize_t], rffi.VOIDP)
def PyObject_MALLOC(space, size):
return lltype.malloc(rffi.VOIDP.TO, size,
- flavor='raw', zero=True)
+ flavor='raw', zero=True,
+ track_allocation=False)
@cpython_api([rffi.VOIDP], lltype.Void)
def PyObject_FREE(space, ptr):
- lltype.free(ptr, flavor='raw')
+ lltype.free(ptr, flavor='raw', track_allocation=False)
@cpython_api([PyTypeObjectPtr], PyObject)
def _PyObject_New(space, type):
@@ -29,16 +31,26 @@
@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject)
def _PyObject_NewVar(space, type, itemcount):
- w_type = from_ref(space, rffi.cast(PyObject, type))
- assert isinstance(w_type, W_TypeObject)
- typedescr = get_typedescr(w_type.instancetypedef)
- py_obj = typedescr.allocate(space, w_type, itemcount=itemcount)
- py_obj.c_ob_refcnt = 0
- if type.c_tp_itemsize == 0:
- w_obj = PyObject_Init(space, py_obj, type)
+ # XXX lots and lots of speed improvements pending: these kind of functions
+ # should be written in C in the first place, mostly as copy-pastes of the
+ # CPython source code
+ size = intmask(type.c_tp_basicsize)
+ assert size > 0
+ itemsize = intmask(type.c_tp_itemsize)
+ if itemsize > 0:
+ try:
+ varsize = ovfcheck(itemsize * itemcount)
+ size = ovfcheck(size + varsize)
+ except OverflowError:
+ PyErr_NoMemory(space)
+ mem = lltype.malloc(rffi.VOIDP.TO, size, flavor='raw', zero=True,
+ track_allocation=False)
+ py_obj = rffi.cast(PyObject, mem)
+ if itemsize == 0:
+ PyObject_Init(space, py_obj, type)
else:
py_objvar = rffi.cast(PyVarObject, py_obj)
- w_obj = PyObject_InitVar(space, py_objvar, type, itemcount)
+ PyObject_InitVar(space, py_objvar, type, itemcount)
return py_obj
@cpython_api([rffi.VOIDP], lltype.Void)
@@ -193,6 +205,7 @@
if not obj:
PyErr_NoMemory(space)
obj.c_ob_type = type
+ obj.c_ob_pypy_link = 0
obj.c_ob_refcnt = 1
return obj
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -207,6 +207,11 @@
def cpyext_as_pyobj(self, space):
return self.cpyext_pyobj
+ def getclass(self, space):
+ w_type = from_pyobj(space, self.cpyext_pyobj.c_ob_type)
+ assert isinstance(w_type, W_TypeObject)
+ return w_type
+
# ZZZ getclass(), getweakref(), etc.? like interpreter/typedef.py
W_CPyExtPlaceHolder.__name__ = W_Class.__name__ + '_CPyExtPlaceHolder'
@@ -232,6 +237,7 @@
def _create_w_obj_from_pyobj(space, pyobj):
w_type = from_pyobj(space, pyobj.c_ob_type)
+ assert isinstance(w_type, W_TypeObject)
return w_type.instancetypedef.cpyext_create_pypy(space, pyobj)
#________________________________________________________
diff --git a/pypy/module/cpyext/structmember.py
b/pypy/module/cpyext/structmember.py
--- a/pypy/module/cpyext/structmember.py
+++ b/pypy/module/cpyext/structmember.py
@@ -5,7 +5,8 @@
from pypy.module.cpyext.api import ADDR, PyObjectP, cpython_api
from pypy.module.cpyext.intobject import PyInt_AsLong, PyInt_AsUnsignedLong
from pypy.module.cpyext.pyerrors import PyErr_Occurred
-from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, from_ref, make_ref
+from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, from_pyobj
+from pypy.module.cpyext.pyobject import get_pyobj_and_xincref
from pypy.module.cpyext.stringobject import (
PyString_FromString, PyString_FromStringAndSize)
from pypy.module.cpyext.floatobject import PyFloat_AsDouble
@@ -67,13 +68,13 @@
elif member_type == T_OBJECT:
obj_ptr = rffi.cast(PyObjectP, addr)
if obj_ptr[0]:
- w_result = from_ref(space, obj_ptr[0])
+ w_result = from_pyobj(space, obj_ptr[0])
else:
w_result = space.w_None
elif member_type == T_OBJECT_EX:
obj_ptr = rffi.cast(PyObjectP, addr)
if obj_ptr[0]:
- w_result = from_ref(space, obj_ptr[0])
+ w_result = from_pyobj(space, obj_ptr[0])
else:
w_name = space.wrap(rffi.charp2str(w_member.c_name))
raise OperationError(space.w_AttributeError, w_name)
@@ -122,7 +123,7 @@
array = rffi.cast(PyObjectP, addr)
if array[0]:
Py_DecRef(space, array[0])
- array[0] = make_ref(space, w_value)
+ array[0] = get_pyobj_and_xincref(space, w_value)
else:
raise OperationError(space.w_SystemError,
space.wrap("bad memberdescr type"))
diff --git a/pypy/module/cpyext/test/test_intobject.py
b/pypy/module/cpyext/test/test_intobject.py
--- a/pypy/module/cpyext/test/test_intobject.py
+++ b/pypy/module/cpyext/test/test_intobject.py
@@ -10,9 +10,7 @@
assert not api.PyInt_Check(space.wrap((1, 2, 3)))
for i in [3, -5, -1, -sys.maxint, sys.maxint - 1]:
x = api.PyInt_AsLong(space.wrap(i))
- y = api.PyInt_AS_LONG(space.wrap(i))
assert x == i
- assert y == i
w_x = from_pyobj(space, api.PyInt_FromLong(x + 1))
assert space.type(w_x) is space.w_int
assert space.eq_w(w_x, space.wrap(i + 1))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit