9
9
#include "pycore_code.h" // _PyCode_HAS_EXECUTORS()
10
10
#include "pycore_crossinterp.h" // _PyXIData_t
11
11
#include "pycore_interp.h" // _PyInterpreterState_IDIncref()
12
+ #include "pycore_memoryobject.h" // _PyMemoryView_GetXIBuffewViewType()
12
13
#include "pycore_modsupport.h" // _PyArg_BadArgument()
13
14
#include "pycore_namespace.h" // _PyNamespace_New()
14
15
#include "pycore_pybuffer.h" // _PyBuffer_ReleaseInInterpreterAndRawFree()
@@ -36,23 +37,6 @@ _get_current_interp(void)
36
37
#define look_up_interp _PyInterpreterState_LookUpIDObject
37
38
38
39
39
- static PyObject *
40
- _get_current_module (void )
41
- {
42
- PyObject * name = PyUnicode_FromString (MODULE_NAME_STR );
43
- if (name == NULL ) {
44
- return NULL ;
45
- }
46
- PyObject * mod = PyImport_GetModule (name );
47
- Py_DECREF (name );
48
- if (mod == NULL ) {
49
- return NULL ;
50
- }
51
- assert (mod != Py_None );
52
- return mod ;
53
- }
54
-
55
-
56
40
static int
57
41
is_running_main (PyInterpreterState * interp )
58
42
{
@@ -71,204 +55,10 @@ is_running_main(PyInterpreterState *interp)
71
55
}
72
56
73
57
74
- /* Cross-interpreter Buffer Views *******************************************/
75
-
76
- // XXX Release when the original interpreter is destroyed.
77
-
78
- typedef struct {
79
- PyObject base ;
80
- Py_buffer * view ;
81
- int64_t interpid ;
82
- } XIBufferViewObject ;
83
-
84
- #define XIBufferViewObject_CAST (op ) ((XIBufferViewObject *)(op))
85
-
86
- static PyObject *
87
- xibufferview_from_buffer (PyTypeObject * cls , Py_buffer * view , int64_t interpid )
88
- {
89
- assert (interpid >= 0 );
90
-
91
- Py_buffer * copied = PyMem_RawMalloc (sizeof (Py_buffer ));
92
- if (copied == NULL ) {
93
- return NULL ;
94
- }
95
- /* This steals the view->obj reference */
96
- * copied = * view ;
97
-
98
- XIBufferViewObject * self = PyObject_Malloc (sizeof (XIBufferViewObject ));
99
- if (self == NULL ) {
100
- PyMem_RawFree (copied );
101
- return NULL ;
102
- }
103
- PyObject_Init (& self -> base , cls );
104
- * self = (XIBufferViewObject ){
105
- .base = self -> base ,
106
- .view = copied ,
107
- .interpid = interpid ,
108
- };
109
- return (PyObject * )self ;
110
- }
111
-
112
- static void
113
- xibufferview_dealloc (PyObject * op )
114
- {
115
- XIBufferViewObject * self = XIBufferViewObject_CAST (op );
116
-
117
- if (self -> view != NULL ) {
118
- PyInterpreterState * interp =
119
- _PyInterpreterState_LookUpID (self -> interpid );
120
- if (interp == NULL ) {
121
- /* The interpreter is no longer alive. */
122
- PyErr_Clear ();
123
- PyMem_RawFree (self -> view );
124
- }
125
- else {
126
- if (_PyBuffer_ReleaseInInterpreterAndRawFree (interp ,
127
- self -> view ) < 0 )
128
- {
129
- // XXX Emit a warning?
130
- PyErr_Clear ();
131
- }
132
- }
133
- }
134
-
135
- PyTypeObject * tp = Py_TYPE (self );
136
- tp -> tp_free (self );
137
- /* "Instances of heap-allocated types hold a reference to their type."
138
- * See: https://docs.python.org/3.11/howto/isolating-extensions.html#garbage-collection-protocol
139
- * See: https://docs.python.org/3.11/c-api/typeobj.html#c.PyTypeObject.tp_traverse
140
- */
141
- // XXX Why don't we implement Py_TPFLAGS_HAVE_GC, e.g. Py_tp_traverse,
142
- // like we do for _abc._abc_data?
143
- Py_DECREF (tp );
144
- }
145
-
146
- static int
147
- xibufferview_getbuf (PyObject * op , Py_buffer * view , int flags )
148
- {
149
- /* Only PyMemoryView_FromObject() should ever call this,
150
- via _memoryview_from_xid() below. */
151
- XIBufferViewObject * self = XIBufferViewObject_CAST (op );
152
- * view = * self -> view ;
153
- view -> obj = op ;
154
- // XXX Should we leave it alone?
155
- view -> internal = NULL ;
156
- return 0 ;
157
- }
158
-
159
- static PyType_Slot XIBufferViewType_slots [] = {
160
- {Py_tp_dealloc , xibufferview_dealloc },
161
- {Py_bf_getbuffer , xibufferview_getbuf },
162
- // We don't bother with Py_bf_releasebuffer since we don't need it.
163
- {0 , NULL },
164
- };
165
-
166
- static PyType_Spec XIBufferViewType_spec = {
167
- .name = MODULE_NAME_STR ".CrossInterpreterBufferView" ,
168
- .basicsize = sizeof (XIBufferViewObject ),
169
- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
170
- Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE ),
171
- .slots = XIBufferViewType_slots ,
172
- };
173
-
174
-
175
- static PyTypeObject * _get_current_xibufferview_type (void );
176
-
177
-
178
- struct xibuffer {
179
- Py_buffer view ;
180
- int used ;
181
- };
182
-
183
- static PyObject *
184
- _memoryview_from_xid (_PyXIData_t * data )
185
- {
186
- assert (_PyXIData_DATA (data ) != NULL );
187
- assert (_PyXIData_OBJ (data ) == NULL );
188
- assert (_PyXIData_INTERPID (data ) >= 0 );
189
- struct xibuffer * view = (struct xibuffer * )_PyXIData_DATA (data );
190
- assert (!view -> used );
191
-
192
- PyTypeObject * cls = _get_current_xibufferview_type ();
193
- if (cls == NULL ) {
194
- return NULL ;
195
- }
196
-
197
- PyObject * obj = xibufferview_from_buffer (
198
- cls , & view -> view , _PyXIData_INTERPID (data ));
199
- if (obj == NULL ) {
200
- return NULL ;
201
- }
202
- PyObject * res = PyMemoryView_FromObject (obj );
203
- if (res == NULL ) {
204
- Py_DECREF (obj );
205
- return NULL ;
206
- }
207
- view -> used = 1 ;
208
- return res ;
209
- }
210
-
211
- static void
212
- _pybuffer_shared_free (void * data )
213
- {
214
- struct xibuffer * view = (struct xibuffer * )data ;
215
- if (!view -> used ) {
216
- PyBuffer_Release (& view -> view );
217
- }
218
- PyMem_RawFree (data );
219
- }
220
-
221
- static int
222
- _pybuffer_shared (PyThreadState * tstate , PyObject * obj , _PyXIData_t * data )
223
- {
224
- struct xibuffer * view = PyMem_RawMalloc (sizeof (struct xibuffer ));
225
- if (view == NULL ) {
226
- return -1 ;
227
- }
228
- view -> used = 0 ;
229
- if (PyObject_GetBuffer (obj , & view -> view , PyBUF_FULL_RO ) < 0 ) {
230
- PyMem_RawFree (view );
231
- return -1 ;
232
- }
233
- _PyXIData_Init (data , tstate -> interp , view , NULL , _memoryview_from_xid );
234
- data -> free = _pybuffer_shared_free ;
235
- return 0 ;
236
- }
237
-
238
- static int
239
- register_memoryview_xid (PyObject * mod , PyTypeObject * * p_state )
240
- {
241
- // XIBufferView
242
- assert (* p_state == NULL );
243
- PyTypeObject * cls = (PyTypeObject * )PyType_FromModuleAndSpec (
244
- mod , & XIBufferViewType_spec , NULL );
245
- if (cls == NULL ) {
246
- return -1 ;
247
- }
248
- if (PyModule_AddType (mod , cls ) < 0 ) {
249
- Py_DECREF (cls );
250
- return -1 ;
251
- }
252
- * p_state = cls ;
253
-
254
- // Register XID for the builtin memoryview type.
255
- if (ensure_xid_class (& PyMemoryView_Type , _pybuffer_shared ) < 0 ) {
256
- return -1 ;
257
- }
258
- // We don't ever bother un-registering memoryview.
259
-
260
- return 0 ;
261
- }
262
-
263
-
264
-
265
58
/* module state *************************************************************/
266
59
267
60
typedef struct {
268
61
int _notused ;
269
-
270
- /* heap types */
271
- PyTypeObject * XIBufferViewType ;
272
62
} module_state ;
273
63
274
64
static inline module_state *
@@ -280,51 +70,19 @@ get_module_state(PyObject *mod)
280
70
return state ;
281
71
}
282
72
283
- static module_state *
284
- _get_current_module_state (void )
285
- {
286
- PyObject * mod = _get_current_module ();
287
- if (mod == NULL ) {
288
- // XXX import it?
289
- PyErr_SetString (PyExc_RuntimeError ,
290
- MODULE_NAME_STR " module not imported yet" );
291
- return NULL ;
292
- }
293
- module_state * state = get_module_state (mod );
294
- Py_DECREF (mod );
295
- return state ;
296
- }
297
-
298
73
static int
299
74
traverse_module_state (module_state * state , visitproc visit , void * arg )
300
75
{
301
- /* heap types */
302
- Py_VISIT (state -> XIBufferViewType );
303
-
304
76
return 0 ;
305
77
}
306
78
307
79
static int
308
80
clear_module_state (module_state * state )
309
81
{
310
- /* heap types */
311
- Py_CLEAR (state -> XIBufferViewType );
312
-
313
82
return 0 ;
314
83
}
315
84
316
85
317
- static PyTypeObject *
318
- _get_current_xibufferview_type (void )
319
- {
320
- module_state * state = _get_current_module_state ();
321
- if (state == NULL ) {
322
- return NULL ;
323
- }
324
- return state -> XIBufferViewType ;
325
- }
326
-
327
-
328
86
/* Python code **************************************************************/
329
87
330
88
static const char *
@@ -1545,6 +1303,7 @@ module_exec(PyObject *mod)
1545
1303
{
1546
1304
PyInterpreterState * interp = PyInterpreterState_Get ();
1547
1305
module_state * state = get_module_state (mod );
1306
+ (void )state ;
1548
1307
1549
1308
_PyXIData_lookup_context_t ctx ;
1550
1309
if (_PyXIData_GetLookupContext (interp , & ctx ) < 0 ) {
@@ -1576,9 +1335,14 @@ module_exec(PyObject *mod)
1576
1335
goto error ;
1577
1336
}
1578
1337
1579
- if (register_memoryview_xid (mod , & state -> XIBufferViewType ) < 0 ) {
1338
+ PyTypeObject * XIBufferViewType = _PyMemoryView_GetXIBuffewViewType ();
1339
+ if (XIBufferViewType == NULL ) {
1580
1340
goto error ;
1581
1341
}
1342
+ if (PyModule_AddType (mod , XIBufferViewType ) < 0 ) {
1343
+ Py_DECREF (XIBufferViewType );
1344
+ return -1 ;
1345
+ }
1582
1346
1583
1347
return 0 ;
1584
1348
0 commit comments