Commit d58cd33d authored by Mark Florisson's avatar Mark Florisson

Get rid of a lot of entry declarations + optional argument to not allocate buffer in cython.array

parent 06c02d31
......@@ -535,6 +535,7 @@ class GetAndReleaseBufferUtilityCode(object):
# which has the right tp_flags set, but emulation otherwise.
requires = None
is_cython_utility = False
def __init__(self):
pass
......
......@@ -73,6 +73,7 @@ class CythonScope(ModuleScope):
# "end-users" but nobody will know it is there anyway...
cython_testscope_utility_code.declare_in_scope(self)
cython_test_extclass_utility_code.declare_in_scope(self)
cython_array_utility_code.declare_in_scope(self)
#
# The view sub-scope
......@@ -84,66 +85,7 @@ class CythonScope(ModuleScope):
cythonview_testscope_utility_code.declare_in_scope(viewscope)
for x in ('strided', 'contig', 'follow', 'direct', 'ptr', 'full'):
entry = viewscope.declare_var(x, py_object_type, None,
cname='__pyx_viewaxis_%s' % x,
is_cdef=True)
entry.utility_code_definition = view_utility_code
#
# cython.view.memoryview declaration
#
self.memviewentry = entry = viewscope.declare_c_class(memview_name, None,
implementing=1,
objstruct_cname = memview_objstruct_cname,
typeobj_cname = memview_typeobj_cname,
typeptr_cname= memview_typeptr_cname)
entry.utility_code_definition = view_utility_code
#
# cython.array declaration
#
name = u'array'
entry = self.declare_c_class(name, None,
implementing=1,
objstruct_cname='__pyx_obj_array',
typeobj_cname='__pyx_tobj_array',
typeptr_cname=Naming.typeptr_prefix+name)
# NOTE: the typeptr_cname is constrained to be '__pyx_ptype_<name>'
# (name is 'array' in this case). otherwise the code generation for
# the struct pointers will not work!
entry.utility_code_definition = cython_array_utility_code
arr_scope = entry.type.scope
arr_scope.declare_var(u'data', c_char_ptr_type, None, is_cdef = 1)
arr_scope.declare_var(u'len', c_size_t_type, None, is_cdef = 1)
arr_scope.declare_var(u'format', c_char_ptr_type, None, is_cdef = 1)
arr_scope.declare_var(u'ndim', c_int_type, None, is_cdef = 1)
arr_scope.declare_var(u'shape', c_py_ssize_t_ptr_type, None, is_cdef = 1)
arr_scope.declare_var(u'strides', c_py_ssize_t_ptr_type, None, is_cdef = 1)
arr_scope.declare_var(u'itemsize', c_py_ssize_t_type, None, is_cdef = 1)
# declare the __getbuffer__ & __releasebuffer__ functions
for idx, name in enumerate(('__getbuffer__', '__releasebuffer__')):
entry = arr_scope.declare_pyfunction(name, None)
# FIXME XXX: hack right here!!!
entry.func_cname = '__pyx_pf_9__pyxutil_5array_%d' % (idx + 1) + name
entry.utility_code_definition = cython_array_utility_code
#
# Declare the array modes
#
entry = self.declare_var(u'PyBUF_C_CONTIGUOUS', c_int_type, None,
cname='PyBUF_C_CONTIGUOUS',is_cdef = 1)
entry = self.declare_var(u'PyBUF_F_CONTIGUOUS', c_int_type, None,
is_cdef = 1)
entry = self.declare_var(u'PyBUF_ANY_CONTIGUOUS', c_int_type, None,
is_cdef = 1)
view_utility_code.declare_in_scope(viewscope)
def create_cython_scope(context, create_testscope):
......@@ -167,9 +109,9 @@ cdef object _testscope(int value):
undecorated_methods_protos = UtilityCode(proto=u"""
/* These methods are undecorated and have therefore no prototype */
static PyObject *__pyx_TestClass_cdef_method(
struct __pyx_TestClass *self, int value);
struct __pyx_TestClass_obj *self, int value);
static PyObject *__pyx_TestClass_cpdef_method(
struct __pyx_TestClass *self, int value, int skip_dispatch);
struct __pyx_TestClass_obj *self, int value, int skip_dispatch);
static PyObject *__pyx_TestClass_def_method(
PyObject *self, PyObject *value);
""")
......@@ -237,9 +179,8 @@ cdef object _testscope(int value):
""")
memview_name = u'memoryview'
memview_typeptr_cname = Naming.typeptr_prefix+memview_name
memview_typeobj_cname = '__pyx_tobj_'+memview_name
memview_objstruct_cname = '__pyx_obj_'+memview_name
memview_typeptr_cname = '__pyx_memoryview_type'
memview_objstruct_cname = '__pyx_memoryview_obj'
view_utility_code = CythonUtilityCode(
u"""
cdef class Enum(object):
......@@ -260,6 +201,7 @@ cdef extern from *:
int __Pyx_GetBuffer(object, Py_buffer *, int)
void __Pyx_ReleaseBuffer(Py_buffer *)
@cname('__pyx_memoryview')
cdef class memoryview(object):
cdef object obj
......@@ -274,13 +216,11 @@ cdef class memoryview(object):
self.obj = None
__Pyx_ReleaseBuffer(&self.view)
@cname('__pyx_memoryview_new')
cdef memoryview memoryview_cwrapper(object o, int flags):
return memoryview(o, flags)
""", name="view_code",
prefix="__pyx_viewaxis_",
requires=(Buffer.GetAndReleaseBufferUtilityCode(),))
""", name="view_code", requires=(Buffer.GetAndReleaseBufferUtilityCode(),))
cyarray_prefix = u'__pyx_cythonarray_'
cython_array_utility_code = CythonUtilityCode(u'''
cdef extern from "stdlib.h":
void *malloc(size_t)
......@@ -293,6 +233,7 @@ cdef extern from "Python.h":
PyBUF_F_CONTIGUOUS,
PyBUF_ANY_CONTIGUOUS
@cname("__pyx_array")
cdef class array:
cdef:
......@@ -304,20 +245,22 @@ cdef class array:
Py_ssize_t *strides
Py_ssize_t itemsize
str mode
void (*callback_free_data)(char *data)
def __cinit__(array self, tuple shape, Py_ssize_t itemsize, char *format, mode="c"):
def __cinit__(array self, tuple shape, Py_ssize_t itemsize, char *format,
mode="c", bint allocate_buffer=True):
self.ndim = len(shape)
self.itemsize = itemsize
if not self.ndim:
raise ValueError("Empty shape tuple for cython.array")
if self.itemsize <= 0:
raise ValueError("itemsize <= 0 for cython.array")
self.format = format
self.shape = <Py_ssize_t *>malloc(sizeof(Py_ssize_t)*self.ndim)
self.strides = <Py_ssize_t *>malloc(sizeof(Py_ssize_t)*self.ndim)
......@@ -358,9 +301,14 @@ cdef class array:
self.mode = mode
self.data = <char *>malloc(self.len)
if not self.data:
raise MemoryError("unable to allocate array data.")
if allocate_buffer:
self.data = <char *>malloc(self.len)
if not self.data:
raise MemoryError("unable to allocate array data.")
else:
self.data = NULL
self.callback_free_data = NULL
def __getbuffer__(self, Py_buffer *info, int flags):
......@@ -383,13 +331,16 @@ cdef class array:
info.obj = None
def __releasebuffer__(array self, Py_buffer* info):
# array.__releasebuffer__ should not be called,
# array.__releasebuffer__ should not be called,
# because the Py_buffer's 'obj' field is set to None.
raise NotImplementedError()
def __dealloc__(array self):
if self.data:
free(self.data)
if self.callback_free_data != NULL:
self.callback_free_data(self.data)
else:
free(self.data)
self.data = NULL
if self.strides:
free(self.strides)
......@@ -400,7 +351,7 @@ cdef class array:
self.format = NULL
self.itemsize = 0
@cname("__pyx_array_new")
cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, char *mode):
return array(shape, itemsize, format, mode)
''', prefix=cyarray_prefix)
''')
......@@ -7630,9 +7630,8 @@ class CoerceToMemViewSliceNode(CoercionNode):
import MemoryView, Buffer
memviewobj = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
buf_flag = MemoryView.get_buf_flag(self.type.axes)
code.putln("%s = (PyObject *)"
"__pyx_viewaxis_memoryview_cwrapper(%s, %s);" %\
(memviewobj, self.arg.py_result(), buf_flag))
code.putln("%s = (PyObject *) __pyx_memoryview_new(%s, %s);" %
(memviewobj, self.arg.py_result(), buf_flag))
code.putln(code.error_goto_if_PyErr(self.pos))
ndim = len(self.type.axes)
spec_int_arr = code.funcstate.allocate_temp(
......@@ -7658,7 +7657,7 @@ class CoerceToMemViewSliceNode(CoercionNode):
else:
c_or_f_flag = "0"
code.putln(code.error_goto_if("-1 == __Pyx_ValidateAndInit_memviewslice("
"(struct __pyx_obj_memoryview *) %(memviewobj)s,"
"(struct __pyx_memoryview_obj *) %(memviewobj)s,"
" %(spec_int_arr)s, %(c_or_f_flag)s, %(ndim)d,"
" &%(dtype_typeinfo)s, __pyx_stack, &%(result)s)" % locals(), self.pos))
code.putln("}")
......
......@@ -378,7 +378,7 @@ static int %(cfunc_name)s(const __Pyx_memviewslice *from_mvs, __Pyx_memviewslice
char *to_buf = (char *)to_mvs->data;
char *from_buf = (char *)from_mvs->data;
struct __pyx_obj_memoryview *temp_memview = 0;
struct __pyx_memoryview_obj *temp_memview = 0;
char *temp_data = 0;
int ndim_idx = 0;
......@@ -700,13 +700,13 @@ static __Pyx_memviewslice %(copy_name)s(const __Pyx_memviewslice from_mvs) {
__Pyx_RefNannyDeclarations
int i;
__Pyx_memviewslice new_mvs = {0, 0};
struct __pyx_obj_memoryview *from_memview = from_mvs.memview;
struct __pyx_memoryview_obj *from_memview = from_mvs.memview;
Py_buffer *buf = &from_memview->view;
PyObject *shape_tuple = 0;
PyObject *temp_int = 0;
struct __pyx_obj_array *array_obj = 0;
struct __pyx_obj_memoryview *memview_obj = 0;
char mode[] = "%(mode)s";
struct __pyx_array_obj *array_obj = 0;
struct __pyx_memoryview_obj *memview_obj = 0;
char *mode = "%(mode)s";
__Pyx_RefNannySetupContext("%(copy_name)s");
......@@ -726,13 +726,13 @@ static __Pyx_memviewslice %(copy_name)s(const __Pyx_memviewslice from_mvs) {
}
}
array_obj = __pyx_cythonarray_array_cwrapper(shape_tuple, %(sizeof_dtype)s, buf->format, mode);
array_obj = __pyx_array_new(shape_tuple, %(sizeof_dtype)s, buf->format, mode);
if (unlikely(!array_obj)) {
goto fail;
}
__Pyx_GOTREF(array_obj);
memview_obj = __pyx_viewaxis_memoryview_cwrapper((PyObject *)array_obj, %(contig_flag)s);
memview_obj = __pyx_memoryview_new((PyObject *) array_obj, %(contig_flag)s);
if (unlikely(!memview_obj)) {
goto fail;
}
......@@ -810,18 +810,18 @@ memviewslice_init_code = UtilityCode(proto="""\
#define __Pyx_IS_C_CONTIG 1
#define __Pyx_IS_F_CONTIG 2
static int __Pyx_ValidateAndInit_memviewslice(struct __pyx_obj_memoryview *memview,
static int __Pyx_ValidateAndInit_memviewslice(struct __pyx_memoryview_obj *memview,
int *axes_specs, int c_or_f_flag, int ndim, __Pyx_TypeInfo *dtype,
__Pyx_BufFmt_StackElem stack[], __Pyx_memviewslice *memviewslice);
static int __Pyx_init_memviewslice(
struct __pyx_obj_memoryview *memview,
struct __pyx_memoryview_obj *memview,
int ndim,
__Pyx_memviewslice *memviewslice);
""" % {'BUF_MAX_NDIMS' :Options.buffer_max_dims},
impl = """\
static int __Pyx_ValidateAndInit_memviewslice(
struct __pyx_obj_memoryview *memview,
struct __pyx_memoryview_obj *memview,
int *axes_specs,
int c_or_f_flag,
int ndim,
......@@ -951,7 +951,7 @@ no_fail:
}
static int __Pyx_init_memviewslice(
struct __pyx_obj_memoryview *memview,
struct __pyx_memoryview_obj *memview,
int ndim,
__Pyx_memviewslice *memviewslice) {
......
......@@ -6986,9 +6986,9 @@ class CnameDecoratorNode(StatNode):
scope = self.node.scope
e.cname = self.cname
e.type.objstruct_cname = self.cname
e.type.objstruct_cname = self.cname + '_obj'
e.type.typeobj_cname = Naming.typeobj_prefix + self.cname
e.type.typeptr_cname = Naming.typeptr_prefix + self.cname
e.type.typeptr_cname = self.cname + '_type'
e.as_variable.cname = py_object_type.cast_code(e.type.typeptr_cname)
......@@ -7002,6 +7002,7 @@ class CnameDecoratorNode(StatNode):
self.node.analyse_expressions(env)
def generate_function_definitions(self, env, code):
"Ensure a prototype for every @cname method in the right place"
if self.is_function and env.is_c_class_scope:
# method in cdef class, generate a prototype in the header
h_code = code.globalstate['utility_code_proto']
......
......@@ -2075,7 +2075,7 @@ def is_memoryviewslice_access(s):
if s.sy == ':':
retval = True
for sv in reversed(saved):
for sv in saved[::-1]:
s.put_back(*sv)
return retval
......
......@@ -2690,8 +2690,8 @@ c_pyx_buffer_ptr_type = CPtrType(c_pyx_buffer_type)
c_pyx_buffer_nd_type = CStructOrUnionType("__Pyx_LocalBuf_ND", "struct",
None, 1, "__Pyx_LocalBuf_ND")
cython_memoryview_type = CStructOrUnionType("__pyx_obj_memoryview", "struct",
None, 0, "__pyx_obj_memoryview")
cython_memoryview_type = CStructOrUnionType("__pyx_memoryview_obj", "struct",
None, 0, "__pyx_memoryview_obj")
cython_memoryview_ptr_type = CPtrType(cython_memoryview_type)
......
......@@ -51,8 +51,8 @@ class CythonUtilityCode(object):
Functions decorated with @cname('c_func_name') get the given cname.
For cdef classes the rules are as follows:
obj struct -> <cname>
obj type ptr -> __pyx_ptype_<cname>
obj struct -> <cname>_obj
obj type ptr -> <cname>_type
methods -> <class_cname>_<method_cname>
For methods the cname decorator is optional, but without the decorator the
......
......@@ -5,13 +5,15 @@ from cython cimport TestClass, _testclass_new as TestClass_New
from cython cimport test_call, test_dep
from cython.view cimport _testscope as viewtester
from cpython cimport PyObject
cdef extern from *:
# TestClass stuff
cdef struct __pyx_TestClass:
cdef struct __pyx_TestClass_obj:
int value
# Type pointer
cdef __pyx_TestClass *TestClassType "__pyx_ptype___pyx_TestClass"
cdef PyObject *TestClassType "__pyx_TestClass_type"
# This is a cdef function
cdef __pyx_TestClass_New(int)
......@@ -50,14 +52,14 @@ def test_cdef_class_cython_utility():
TestClass(20)
TestClass(50)
"""
cdef __pyx_TestClass *objstruct
cdef __pyx_TestClass_obj *objstruct
obj = TestClass_New(7)
objstruct = <__pyx_TestClass *> obj
objstruct = <__pyx_TestClass_obj *> obj
print objstruct.value
obj = __pyx_TestClass_New(14)
objstruct = <__pyx_TestClass *> obj
objstruct = <__pyx_TestClass_obj *> obj
print objstruct.value
print (<object> TestClassType)(20)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment