40
40
*/
41
41
#include "capi.h"
42
42
43
+ #if SIZEOF_SIZE_T == 8
44
+ #define polyglot_from_size_array polyglot_from_i64_array
45
+ #elif SIZEOF_SIZE_T == 4
46
+ #define polyglot_from_size_array polyglot_from_i32_array
47
+ #endif
48
+
49
+ /* Macros taken from CPython */
50
+ /* Memoryview buffer properties */
51
+ #define MV_C_CONTIGUOUS (flags ) (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C))
52
+ #define MV_F_CONTIGUOUS (flags ) \
53
+ (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_FORTRAN))
54
+ #define MV_ANY_CONTIGUOUS (flags ) \
55
+ (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN))
56
+
57
+ /* getbuffer() requests */
58
+ #define REQ_INDIRECT (flags ) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT)
59
+ #define REQ_C_CONTIGUOUS (flags ) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS)
60
+ #define REQ_F_CONTIGUOUS (flags ) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS)
61
+ #define REQ_ANY_CONTIGUOUS (flags ) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS)
62
+ #define REQ_STRIDES (flags ) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES)
63
+ #define REQ_SHAPE (flags ) ((flags&PyBUF_ND) == PyBUF_ND)
64
+ #define REQ_WRITABLE (flags ) (flags&PyBUF_WRITABLE)
65
+ #define REQ_FORMAT (flags ) (flags&PyBUF_FORMAT)
66
+
67
+ #define BASE_INACCESSIBLE (mv ) \
68
+ (((PyMemoryViewObject *)mv)->flags&_Py_MEMORYVIEW_RELEASED)
69
+ #define CHECK_RELEASED (mv ) \
70
+ if (BASE_INACCESSIBLE(mv)) { \
71
+ PyErr_SetString(PyExc_ValueError, \
72
+ "operation forbidden on released memoryview object"); \
73
+ return NULL; \
74
+ }
75
+ #define CHECK_RELEASED_INT (mv ) \
76
+ if (BASE_INACCESSIBLE(mv)) { \
77
+ PyErr_SetString(PyExc_ValueError, \
78
+ "operation forbidden on released memoryview object"); \
79
+ return -1; \
80
+ }
81
+
43
82
PyTypeObject PyMemoryView_Type = PY_TRUFFLE_TYPE_WITH_ITEMSIZE ("memoryview" , & PyType_Type , Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC , offsetof(PyMemoryViewObject , ob_array ), sizeof (Py_ssize_t ));
44
83
PyTypeObject PyBuffer_Type = PY_TRUFFLE_TYPE ("buffer" , & PyType_Type , Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC , sizeof (PyBufferDecorator ));
45
84
@@ -59,13 +98,36 @@ PyObject* PyMemoryView_FromObject(PyObject *v) {
59
98
60
99
/* called back from the above upcall only if the object was native */
61
100
PyObject * PyTruffle_MemoryViewFromObject (PyObject * v ) {
62
- Py_buffer buffer ;
63
101
if (PyObject_CheckBuffer (v )) {
64
- PyObject * ret ;
65
- if (PyObject_GetBuffer (v , & buffer , PyBUF_FULL_RO ) < 0 ) {
102
+ Py_buffer * buffer = malloc ( sizeof ( Py_buffer )) ;
103
+ if (PyObject_GetBuffer (v , buffer , PyBUF_FULL_RO ) < 0 ) {
66
104
return NULL ;
67
105
}
68
- return PyMemoryView_FromBuffer (& buffer );
106
+ Py_ssize_t ndim = buffer -> ndim ;
107
+ int needs_release = 0 ;
108
+ if (buffer -> obj != NULL ) {
109
+ PyBufferProcs * pb ;
110
+ pb = Py_TYPE (buffer -> obj )-> tp_as_buffer ;
111
+ if (pb ) {
112
+ needs_release = pb -> bf_releasebuffer != NULL ;
113
+ }
114
+ }
115
+ PyObject * mv = polyglot_invoke (PY_TRUFFLE_CEXT , "PyTruffle_MemoryViewFromBuffer" ,
116
+ needs_release ? buffer : NULL , /* We only need the ptr for the release */
117
+ native_to_java (buffer -> obj ),
118
+ buffer -> len ,
119
+ buffer -> readonly ,
120
+ buffer -> itemsize ,
121
+ polyglot_from_string (buffer -> format ? buffer -> format : "B" , "ascii" ),
122
+ buffer -> ndim ,
123
+ polyglot_from_i8_array (buffer -> buf , buffer -> len ),
124
+ buffer -> shape ? polyglot_from_size_array (buffer -> shape , ndim ) : NULL ,
125
+ buffer -> strides ? polyglot_from_size_array (buffer -> strides , ndim ) : NULL ,
126
+ buffer -> suboffsets ? polyglot_from_size_array (buffer -> suboffsets , ndim ) : NULL );
127
+ if (!needs_release ) {
128
+ free (buffer );
129
+ }
130
+ return mv ;
69
131
}
70
132
71
133
PyErr_Format (PyExc_TypeError ,
@@ -74,27 +136,23 @@ PyObject* PyTruffle_MemoryViewFromObject(PyObject *v) {
74
136
return NULL ;
75
137
}
76
138
77
- #if SIZEOF_SIZE_T == 8
78
- #define polyglot_from_size_array polyglot_from_i64_array
79
- #elif SIZEOF_SIZE_T == 4
80
- #define polyglot_from_size_array polyglot_from_i32_array
81
- #endif
82
-
83
-
84
- PyObject * PyMemoryView_FromBuffer (Py_buffer * buffer ) {
85
- Py_ssize_t ndim = buffer -> ndim ;
86
- releasebufferproc releasefn = NULL ;
139
+ /* Release buffer struct allocated in PyTruffle_MemoryViewFromObject */
140
+ void PyTruffle_ReleaseBuffer (Py_buffer * buffer ) {
87
141
if (buffer -> obj != NULL ) {
88
142
PyBufferProcs * pb ;
89
143
pb = Py_TYPE (buffer -> obj )-> tp_as_buffer ;
90
144
if (pb ) {
91
- releasefn = pb -> bf_releasebuffer ;
145
+ pb -> bf_releasebuffer ( buffer -> obj , buffer ) ;
92
146
}
93
147
}
148
+ free (buffer );
149
+ }
150
+
151
+ PyObject * PyMemoryView_FromBuffer (Py_buffer * buffer ) {
152
+ Py_ssize_t ndim = buffer -> ndim ;
94
153
return polyglot_invoke (PY_TRUFFLE_CEXT , "PyTruffle_MemoryViewFromBuffer" ,
95
- buffer ,
96
- native_to_java (buffer -> obj ),
97
- releasefn ,
154
+ NULL ,
155
+ NULL ,
98
156
buffer -> len ,
99
157
buffer -> readonly ,
100
158
buffer -> itemsize ,
@@ -111,47 +169,14 @@ PyObject *PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags) {
111
169
assert (flags == PyBUF_READ || flags == PyBUF_WRITE );
112
170
int readonly = (flags == PyBUF_WRITE ) ? 0 : 1 ;
113
171
return polyglot_invoke (PY_TRUFFLE_CEXT , "PyTruffle_MemoryViewFromBuffer" ,
114
- NULL , NULL , NULL , size , readonly , 1 , polyglot_from_string ("B" , "ascii" ), 1 , polyglot_from_i8_array ((int8_t * )mem , size ), NULL , NULL , NULL );
172
+ NULL , NULL , size , readonly , 1 , polyglot_from_string ("B" , "ascii" ), 1 , polyglot_from_i8_array ((int8_t * )mem , size ), NULL , NULL , NULL );
115
173
}
116
174
117
175
UPCALL_ID (PyMemoryView_GetContiguous )
118
176
PyObject * PyMemoryView_GetContiguous (PyObject * obj , int buffertype , char order ) {
119
177
return UPCALL_CEXT_O (_jls_PyMemoryView_GetContiguous , native_to_java (obj ), buffertype , (int )order );
120
178
}
121
179
122
- /* Macros taken from CPython */
123
- /* Memoryview buffer properties */
124
- #define MV_C_CONTIGUOUS (flags ) (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C))
125
- #define MV_F_CONTIGUOUS (flags ) \
126
- (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_FORTRAN))
127
- #define MV_ANY_CONTIGUOUS (flags ) \
128
- (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN))
129
-
130
- /* getbuffer() requests */
131
- #define REQ_INDIRECT (flags ) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT)
132
- #define REQ_C_CONTIGUOUS (flags ) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS)
133
- #define REQ_F_CONTIGUOUS (flags ) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS)
134
- #define REQ_ANY_CONTIGUOUS (flags ) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS)
135
- #define REQ_STRIDES (flags ) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES)
136
- #define REQ_SHAPE (flags ) ((flags&PyBUF_ND) == PyBUF_ND)
137
- #define REQ_WRITABLE (flags ) (flags&PyBUF_WRITABLE)
138
- #define REQ_FORMAT (flags ) (flags&PyBUF_FORMAT)
139
-
140
- #define BASE_INACCESSIBLE (mv ) \
141
- (((PyMemoryViewObject *)mv)->flags&_Py_MEMORYVIEW_RELEASED)
142
- #define CHECK_RELEASED (mv ) \
143
- if (BASE_INACCESSIBLE(mv)) { \
144
- PyErr_SetString(PyExc_ValueError, \
145
- "operation forbidden on released memoryview object"); \
146
- return NULL; \
147
- }
148
- #define CHECK_RELEASED_INT (mv ) \
149
- if (BASE_INACCESSIBLE(mv)) { \
150
- PyErr_SetString(PyExc_ValueError, \
151
- "operation forbidden on released memoryview object"); \
152
- return -1; \
153
- }
154
-
155
180
/* Taken from CPython memoryobject.c: memory_getbuf */
156
181
int memoryview_getbuffer (PyMemoryViewObject * self , Py_buffer * view , int flags )
157
182
{
0 commit comments