Commit 307ad639 authored by Kurt Smith's avatar Kurt Smith Committed by Mark Florisson

memoryview utility code pulled in when memview array syntax used in Cython source.

parent 3bed371c
...@@ -91,12 +91,11 @@ class CythonScope(ModuleScope): ...@@ -91,12 +91,11 @@ class CythonScope(ModuleScope):
# #
# cython.view.memoryview declaration # cython.view.memoryview declaration
# #
name = u'memoryview' self.memviewentry = entry = viewscope.declare_c_class(memview_name, None,
entry = viewscope.declare_c_class(name, None,
implementing=1, implementing=1,
objstruct_cname = '__pyx_obj_'+name, objstruct_cname = memviewext_objstruct_cname,
typeobj_cname = '__pyx_tobj_'+name, typeobj_cname = memviewext_typeobj_cname,
typeptr_cname=Naming.typeptr_prefix+name) typeptr_cname= memviewext_typeptr_cname)
entry.utility_code_definition = view_utility_code entry.utility_code_definition = view_utility_code
...@@ -130,8 +129,7 @@ class CythonScope(ModuleScope): ...@@ -130,8 +129,7 @@ class CythonScope(ModuleScope):
for idx, name in enumerate(('__getbuffer__', '__releasebuffer__')): for idx, name in enumerate(('__getbuffer__', '__releasebuffer__')):
entry = arr_scope.declare_pyfunction(name, None) entry = arr_scope.declare_pyfunction(name, None)
# XXX: absolutely horrendous hack right here!!! # FIXME XXX: hack right here!!!
# To be fixed!!!
entry.func_cname = '__pyx_pf_9__pyxutil_5array_%d' % (idx + 1) + name entry.func_cname = '__pyx_pf_9__pyxutil_5array_%d' % (idx + 1) + name
entry.utility_code_definition = cython_array_utility_code entry.utility_code_definition = cython_array_utility_code
...@@ -236,6 +234,10 @@ cdef object _testscope(int value): ...@@ -236,6 +234,10 @@ cdef object _testscope(int value):
return "hello from cython.view scope, value=%d" % value return "hello from cython.view scope, value=%d" % value
""") """)
memview_name = u'memoryview'
memviewext_typeptr_cname = Naming.typeptr_prefix+memview_name
memviewext_typeobj_cname = '__pyx_tobj_'+memview_name
memviewext_objstruct_cname = '__pyx_obj_'+memview_name
view_utility_code = CythonUtilityCode(u""" view_utility_code = CythonUtilityCode(u"""
cdef class Enum: cdef class Enum:
cdef object name cdef object name
...@@ -258,12 +260,19 @@ cdef extern from *: ...@@ -258,12 +260,19 @@ cdef extern from *:
cdef class memoryview: cdef class memoryview:
cdef Py_buffer view cdef Py_buffer view
cdef int gotbuf_flag
def __cinit__(self):
self.gotbuf_flag = 0
def __cinit__(memoryview self, obj, int flags): cdef memoryview from_obj(memoryview self, obj, int flags):
__Pyx_GetBuffer(obj, &self.view, flags) __Pyx_GetBuffer(obj, &self.view, flags)
self.gotbuf_flag = 1
def __dealloc__(memoryview self): def __dealloc__(memoryview self):
__Pyx_ReleaseBuffer(&self.view) if self.gotbuf_flag:
__Pyx_ReleaseBuffer(&self.view)
self.gotbuf_flag = 0
""", prefix="__pyx_viewaxis_") """, prefix="__pyx_viewaxis_")
...@@ -387,4 +396,4 @@ cdef class array: ...@@ -387,4 +396,4 @@ cdef class array:
self.shape = NULL self.shape = NULL
self.format = NULL self.format = NULL
self.itemsize = 0 self.itemsize = 0
''', prefix=cyarray_prefix) ''', prefix=cyarray_prefix)
\ No newline at end of file
...@@ -584,6 +584,11 @@ class ExprNode(Node): ...@@ -584,6 +584,11 @@ class ExprNode(Node):
if dst_type.is_reference: if dst_type.is_reference:
dst_type = dst_type.ref_base_type dst_type = dst_type.ref_base_type
if dst_type.is_memoryview:
src = CoerceToMemViewNode(src, dst_type, env)
# src = AcquireBufferFromNode(src, env)
# src = CheckMemoryViewFormatNode(src, dst_type, env)
if dst_type.is_pyobject: if dst_type.is_pyobject:
if not src.type.is_pyobject: if not src.type.is_pyobject:
if dst_type is bytes_type and src.type.is_int: if dst_type is bytes_type and src.type.is_int:
...@@ -7565,6 +7570,28 @@ class CoercionNode(ExprNode): ...@@ -7565,6 +7570,28 @@ class CoercionNode(ExprNode):
file, line, col = self.pos file, line, col = self.pos
code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type))) code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
class CoerceToMemViewNode(CoercionNode):
def __init__(self, arg, dst_type, env):
assert dst_type.is_memoryview
CoercionNode.__init__(self, arg)
self.type = dst_type
self.is_temp = 1
self.env = env
def generate_result_code(self, code):
# create a cython.memoryview object.
# declare a new temporary cython.memoryview variable.
import MemoryView
# -) initialize cython.memview object with self.arg, it calls
# __Pyx_GetBuffer on it.
# -) check the axes specifiers for the underlying memview's Py_buffer,
# make sure they're compatible with the dst_type's axes specs.
# -) output the temp assignment code (see
# CoerceFromPyTypeNode.generate_result_code for example)
pass
class CastNode(CoercionNode): class CastNode(CoercionNode):
# Wrap a node in a C type cast. # Wrap a node in a C type cast.
...@@ -7809,7 +7836,6 @@ class CoerceFromPyTypeNode(CoercionNode): ...@@ -7809,7 +7836,6 @@ class CoerceFromPyTypeNode(CoercionNode):
CoercionNode.__init__(self, arg) CoercionNode.__init__(self, arg)
self.type = result_type self.type = result_type
self.is_temp = 1 self.is_temp = 1
import pdb; pdb.set_trace()
if not result_type.create_from_py_utility_code(env): if not result_type.create_from_py_utility_code(env):
error(arg.pos, error(arg.pos,
"Cannot convert Python object to '%s'" % result_type) "Cannot convert Python object to '%s'" % result_type)
......
from Errors import CompileError from Errors import CompileError
from ExprNodes import IntNode, NoneNode, IntBinopNode, NameNode, AttributeNode from ExprNodes import IntNode, NoneNode, IntBinopNode, NameNode, AttributeNode
from Visitor import CythonTransform from Visitor import CythonTransform
import Options
import CythonScope
from Code import UtilityCode
START_ERR = "there must be nothing or the value 0 (zero) in the start slot." START_ERR = "there must be nothing or the value 0 (zero) in the start slot."
STOP_ERR = "Axis specification only allowed in the 'stop' slot." STOP_ERR = "Axis specification only allowed in the 'stop' slot."
...@@ -12,6 +15,14 @@ INVALID_ERR = "Invalid axis specification." ...@@ -12,6 +15,14 @@ INVALID_ERR = "Invalid axis specification."
EXPR_ERR = "no expressions allowed in axis spec, only names (e.g. cython.view.contig)." EXPR_ERR = "no expressions allowed in axis spec, only names (e.g. cython.view.contig)."
CF_ERR = "Invalid axis specification for a C/Fortran contiguous array." CF_ERR = "Invalid axis specification for a C/Fortran contiguous array."
def use_memview_util_code(env):
import CythonScope
cythonscope = env.global_scope().context.cython_scope
viewscope = cythonscope.viewscope
memview_entry = viewscope.lookup_here(CythonScope.memview_name)
assert memview_entry is cythonscope.memviewentry
memview_entry.used = 1
def get_axes_specs(env, axes): def get_axes_specs(env, axes):
''' '''
get_axes_specs(env, axes) -> list of (access, packing) specs for each axis. get_axes_specs(env, axes) -> list of (access, packing) specs for each axis.
...@@ -227,3 +238,23 @@ class MemoryViewTransform(CythonTransform): ...@@ -227,3 +238,23 @@ class MemoryViewTransform(CythonTransform):
def visit_SingleAssignmentNode(self, node): def visit_SingleAssignmentNode(self, node):
import pdb; pdb.set_trace() import pdb; pdb.set_trace()
return node return node
memviewstruct_cname = u'__Pyx_memviewstruct'
memviewstruct_declare_code = UtilityCode(proto="""
/* memoryview struct */
typedef struct {
Py_ssize_t shape, strides, suboffsets;
} __Pyx_mv_DimInfo;
typedef struct {
struct %s *memviewext;
char *data;
__Pyx_mv_DimInfo diminfo[%d];
} %s;
""" % (CythonScope.memviewext_objstruct_cname,
Options.buffer_max_dims,
memviewstruct_cname)
)
...@@ -822,7 +822,8 @@ class MemoryViewTypeNode(CBaseTypeNode): ...@@ -822,7 +822,8 @@ class MemoryViewTypeNode(CBaseTypeNode):
self.type = PyrexTypes.ErrorType() self.type = PyrexTypes.ErrorType()
return self.type return self.type
self.type = PyrexTypes.MemoryViewType(base_type, axes_specs) self.type = PyrexTypes.MemoryViewType(base_type, axes_specs, env)
MemoryView.use_memview_util_code(env)
return self.type return self.type
class CNestedBaseTypeNode(CBaseTypeNode): class CNestedBaseTypeNode(CBaseTypeNode):
......
...@@ -113,7 +113,6 @@ def create_pipeline(context, mode, exclude_classes=()): ...@@ -113,7 +113,6 @@ def create_pipeline(context, mode, exclude_classes=()):
from Optimize import DropRefcountingTransform from Optimize import DropRefcountingTransform
from Buffer import IntroduceBufferAuxiliaryVars from Buffer import IntroduceBufferAuxiliaryVars
from ModuleNode import check_c_declarations, check_c_declarations_pxd from ModuleNode import check_c_declarations, check_c_declarations_pxd
from MemoryView import MemoryViewTransform
from ModuleNode import check_c_declarations from ModuleNode import check_c_declarations
...@@ -158,7 +157,6 @@ def create_pipeline(context, mode, exclude_classes=()): ...@@ -158,7 +157,6 @@ def create_pipeline(context, mode, exclude_classes=()):
# MarkAssignments(context), # MarkAssignments(context),
MarkOverflowingArithmetic(context), MarkOverflowingArithmetic(context),
IntroduceBufferAuxiliaryVars(context), IntroduceBufferAuxiliaryVars(context),
MemoryViewTransform(context),
_check_c_declarations, _check_c_declarations,
AnalyseExpressionsTransform(context), AnalyseExpressionsTransform(context),
CreateClosureClasses(context), ## After all lookups and type inference CreateClosureClasses(context), ## After all lookups and type inference
......
...@@ -313,7 +313,7 @@ class MemoryViewType(PyrexType): ...@@ -313,7 +313,7 @@ class MemoryViewType(PyrexType):
is_memoryview = 1 is_memoryview = 1
def __init__(self, base_dtype, axes): def __init__(self, base_dtype, axes, env):
''' '''
MemoryViewType(base, axes) MemoryViewType(base, axes)
...@@ -350,6 +350,7 @@ class MemoryViewType(PyrexType): ...@@ -350,6 +350,7 @@ class MemoryViewType(PyrexType):
self.dtype = base_dtype self.dtype = base_dtype
self.axes = axes self.axes = axes
self.env = env
def is_complete(self): def is_complete(self):
# incomplete since the underlying struct doesn't have a memoryview. # incomplete since the underlying struct doesn't have a memoryview.
...@@ -357,7 +358,14 @@ class MemoryViewType(PyrexType): ...@@ -357,7 +358,14 @@ class MemoryViewType(PyrexType):
def declaration_code(self, entity_code, def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0): for_display = 0, dll_linkage = None, pyrex = 0):
return 'foo' # XXX: we put these guards in for now...
assert not pyrex
assert not dll_linkage
import MemoryView
self.env.use_utility_code(MemoryView.memviewstruct_declare_code)
return self.base_declaration_code(
MemoryView.memviewstruct_cname,
entity_code)
class BufferType(BaseType): class BufferType(BaseType):
# #
......
...@@ -23,9 +23,8 @@ cdef class Foo: ...@@ -23,9 +23,8 @@ cdef class Foo:
class pyfoo: class pyfoo:
def __init__(self): def __init__(self):
cdef int arr[10] self.mview = array((10,), itemsize=sizeof(long), format='l')
# self.mview = array((10,), itemsize=sizeof(long), format='l') # self.mview = arr
self.mview = arr
cdef cdg(): cdef cdg():
cdef double[:] dmv = array((10,), itemsize=sizeof(double), format='d') cdef double[:] dmv = array((10,), itemsize=sizeof(double), format='d')
......
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