mirror of https://github.com/python/cpython.git
124 lines
2.7 KiB
C
124 lines
2.7 KiB
C
|
|
#define _RESOLVE_MODINIT_FUNC_NAME(NAME) \
|
|
PyInit_ ## NAME
|
|
#define RESOLVE_MODINIT_FUNC_NAME(NAME) \
|
|
_RESOLVE_MODINIT_FUNC_NAME(NAME)
|
|
|
|
|
|
#define GETDATA(FUNC) ((_PyXIData_getdata_t){.basic=FUNC})
|
|
|
|
static int
|
|
ensure_xid_class(PyTypeObject *cls, _PyXIData_getdata_t getdata)
|
|
{
|
|
PyThreadState *tstate = PyThreadState_Get();
|
|
return _PyXIData_RegisterClass(tstate, cls, getdata);
|
|
}
|
|
|
|
#ifdef REGISTERS_HEAP_TYPES
|
|
static int
|
|
clear_xid_class(PyTypeObject *cls)
|
|
{
|
|
PyThreadState *tstate = PyThreadState_Get();
|
|
return _PyXIData_UnregisterClass(tstate, cls);
|
|
}
|
|
#endif
|
|
|
|
|
|
static inline int64_t
|
|
_get_interpid(_PyXIData_t *data)
|
|
{
|
|
int64_t interpid;
|
|
if (data != NULL) {
|
|
interpid = _PyXIData_INTERPID(data);
|
|
assert(!PyErr_Occurred());
|
|
}
|
|
else {
|
|
interpid = PyInterpreterState_GetID(PyInterpreterState_Get());
|
|
}
|
|
return interpid;
|
|
}
|
|
|
|
|
|
#ifdef HAS_FALLBACK
|
|
static int
|
|
resolve_fallback(int arg, xidata_fallback_t dflt,
|
|
xidata_fallback_t *p_fallback)
|
|
{
|
|
if (arg < 0) {
|
|
*p_fallback = dflt;
|
|
return 0;
|
|
}
|
|
xidata_fallback_t fallback;
|
|
if (arg == _PyXIDATA_XIDATA_ONLY) {
|
|
fallback =_PyXIDATA_XIDATA_ONLY;
|
|
}
|
|
else if (arg == _PyXIDATA_FULL_FALLBACK) {
|
|
fallback = _PyXIDATA_FULL_FALLBACK;
|
|
}
|
|
else {
|
|
PyErr_Format(PyExc_ValueError, "unsupported fallback %d", arg);
|
|
return -1;
|
|
}
|
|
*p_fallback = fallback;
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
/* unbound items ************************************************************/
|
|
|
|
#ifdef HAS_UNBOUND_ITEMS
|
|
|
|
typedef int unboundop_t;
|
|
#define UNBOUND_REMOVE 1
|
|
#define UNBOUND_ERROR 2
|
|
#define UNBOUND_REPLACE 3
|
|
|
|
// It would also be possible to add UNBOUND_REPLACE where the replacement
|
|
// value is user-provided. There would be some limitations there, though.
|
|
// Another possibility would be something like UNBOUND_COPY, where the
|
|
// object is released but the underlying data is copied (with the "raw"
|
|
// allocator) and used when the item is popped off the queue.
|
|
|
|
#ifndef NDEBUG
|
|
static int
|
|
check_unbound(int unboundop)
|
|
{
|
|
switch (unboundop) {
|
|
case UNBOUND_REMOVE:
|
|
case UNBOUND_ERROR:
|
|
case UNBOUND_REPLACE:
|
|
return 1;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static int
|
|
resolve_unboundop(int arg, unboundop_t dflt, unboundop_t *p_unboundop)
|
|
{
|
|
if (arg < 0) {
|
|
*p_unboundop = dflt;
|
|
return 0;
|
|
}
|
|
unboundop_t op;
|
|
if (arg == UNBOUND_REMOVE) {
|
|
op = UNBOUND_REMOVE;
|
|
}
|
|
else if (arg == UNBOUND_ERROR) {
|
|
op = UNBOUND_ERROR;
|
|
}
|
|
else if (arg == UNBOUND_REPLACE) {
|
|
op = UNBOUND_REPLACE;
|
|
}
|
|
else {
|
|
PyErr_Format(PyExc_ValueError, "unsupported unboundop %d", arg);
|
|
return -1;
|
|
}
|
|
*p_unboundop = op;
|
|
return 0;
|
|
}
|
|
|
|
#endif
|