Author: Matti Picus <[email protected]>
Branch: buffer-interface
Changeset: r86897:d765d56cd700
Date: 2016-09-05 23:56 +0300
http://bitbucket.org/pypy/pypy/changeset/d765d56cd700/
Log: create fixed arrays of Py_MAX_NDIMS, arbitrarily set to 32, in
Py_buffer rather than malloc and leak memory
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -122,7 +122,7 @@
METH_COEXIST METH_STATIC METH_CLASS Py_TPFLAGS_BASETYPE
METH_NOARGS METH_VARARGS METH_KEYWORDS METH_O Py_TPFLAGS_HAVE_INPLACEOPS
Py_TPFLAGS_HEAPTYPE Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_HAVE_NEWBUFFER
-Py_LT Py_LE Py_EQ Py_NE Py_GT Py_GE Py_TPFLAGS_CHECKTYPES
+Py_LT Py_LE Py_EQ Py_NE Py_GT Py_GE Py_TPFLAGS_CHECKTYPES Py_MAX_NDIMS
""".split()
for name in constant_names:
setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name))
@@ -645,6 +645,9 @@
('format', rffi.CCHARP),
('shape', Py_ssize_tP),
('strides', Py_ssize_tP),
+ ('_format', rffi.UCHAR),
+ ('_shape', rffi.CFixedArray(Py_ssize_t, Py_MAX_NDIMS)),
+ ('_strides', rffi.CFixedArray(Py_ssize_t, Py_MAX_NDIMS)),
('suboffsets', Py_ssize_tP),
#('smalltable', rffi.CFixedArray(Py_ssize_t, 2)),
('internal', rffi.VOIDP)
diff --git a/pypy/module/cpyext/include/object.h
b/pypy/module/cpyext/include/object.h
--- a/pypy/module/cpyext/include/object.h
+++ b/pypy/module/cpyext/include/object.h
@@ -142,7 +142,8 @@
typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *);
typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **);
-/* Py3k buffer interface */
+/* Py3k buffer interface, adapted for PyPy */
+#define Py_MAX_NDIMS 32
typedef struct bufferinfo {
void *buf;
PyObject *obj; /* owned reference */
@@ -156,12 +157,14 @@
char *format;
Py_ssize_t *shape;
Py_ssize_t *strides;
- Py_ssize_t *suboffsets;
-
+ Py_ssize_t *suboffsets; /* alway NULL for app-level objects*/
+ unsigned char _format;
+ Py_ssize_t _strides[Py_MAX_NDIMS];
+ Py_ssize_t _shape[Py_MAX_NDIMS];
/* static store for shape and strides of
mono-dimensional buffers. */
/* Py_ssize_t smalltable[2]; */
- void *internal;
+ void *internal; /* always NULL for app-level objects */
} Py_buffer;
diff --git a/pypy/module/cpyext/memoryobject.py
b/pypy/module/cpyext/memoryobject.py
--- a/pypy/module/cpyext/memoryobject.py
+++ b/pypy/module/cpyext/memoryobject.py
@@ -1,5 +1,5 @@
from pypy.module.cpyext.api import (cpython_api, Py_buffer, CANNOT_FAIL,
- build_type_checkers, Py_ssize_tP)
+ Py_MAX_NDIMS, build_type_checkers, Py_ssize_tP)
from pypy.module.cpyext.pyobject import PyObject, make_ref, incref
from rpython.rtyper.lltypesystem import lltype, rffi
from pypy.objspace.std.memoryobject import W_MemoryView
@@ -24,6 +24,10 @@
view = lltype.malloc(Py_buffer, flavor='raw', zero=True)
if not isinstance(w_obj, W_MemoryView):
return view
+ ndim = w_obj.buf.getndim()
+ if ndim >= Py_MAX_NDIMS:
+ # XXX warn?
+ return view
try:
view.c_buf = rffi.cast(rffi.VOIDP, w_obj.buf.get_raw_address())
view.c_obj = make_ref(space, w_obj)
@@ -36,11 +40,11 @@
isstr = True
view.c_len = w_obj.getlength()
view.c_itemsize = w_obj.buf.getitemsize()
- ndim = w_obj.buf.getndim()
rffi.setintfield(view, 'c_ndim', ndim)
- view.c_format = rffi.str2charp(w_obj.buf.getformat())
- view.c_shape = lltype.malloc(Py_ssize_tP.TO, ndim, flavor='raw')
- view.c_strides = lltype.malloc(Py_ssize_tP.TO, ndim, flavor='raw')
+ view.c__format = rffi.cast(rffi.UCHAR, w_obj.buf.getformat())
+ view.c_format = rffi.cast(rffi.CCHARP, view.c__format)
+ view.c_shape = rffi.cast(Py_ssize_tP, view.c__shape)
+ view.c_strides = rffi.cast(Py_ssize_tP, view.c__strides)
shape = w_obj.buf.getshape()
strides = w_obj.buf.getstrides()
for i in range(ndim):
@@ -50,4 +54,3 @@
view.c_internal = lltype.nullptr(rffi.VOIDP.TO)
return view
-
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit