blob: 9ee402531019c402c257feea8c6238c0e529ef9d [file] [log] [blame]
typedef void *(*gs_fetch_addr_fn)(void);
typedef struct {
PyObject_HEAD
PyObject *gs_name;
CTypeDescrObject *gs_type;
char *gs_data;
gs_fetch_addr_fn gs_fetch_addr;
} GlobSupportObject;
static void glob_support_dealloc(GlobSupportObject *gs)
{
Py_DECREF(gs->gs_name);
Py_DECREF(gs->gs_type);
PyObject_Del(gs);
}
static PyTypeObject GlobSupport_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"FFIGlobSupport",
sizeof(GlobSupportObject),
0,
(destructor)glob_support_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
};
#define GlobSupport_Check(ob) (Py_TYPE(ob) == &GlobSupport_Type)
static PyObject *make_global_var(PyObject *name, CTypeDescrObject *type,
char *addr, gs_fetch_addr_fn fetch_addr)
{
GlobSupportObject *gs = PyObject_New(GlobSupportObject, &GlobSupport_Type);
if (gs == NULL)
return NULL;
Py_INCREF(name);
Py_INCREF(type);
gs->gs_name = name;
gs->gs_type = type;
gs->gs_data = addr;
gs->gs_fetch_addr = fetch_addr;
return (PyObject *)gs;
}
static void *fetch_global_var_addr(GlobSupportObject *gs)
{
void *data;
if (gs->gs_data != NULL) {
data = gs->gs_data;
}
else {
Py_BEGIN_ALLOW_THREADS
restore_errno();
data = gs->gs_fetch_addr();
save_errno();
Py_END_ALLOW_THREADS
}
if (data == NULL) {
PyErr_Format(FFIError, "global variable '%s' is at address NULL",
PyText_AS_UTF8(gs->gs_name));
return NULL;
}
return data;
}
static PyObject *read_global_var(GlobSupportObject *gs)
{
void *data = fetch_global_var_addr(gs);
if (data == NULL)
return NULL;
return convert_to_object(data, gs->gs_type);
}
static int write_global_var(GlobSupportObject *gs, PyObject *obj)
{
void *data = fetch_global_var_addr(gs);
if (data == NULL)
return -1;
return convert_from_object(data, gs->gs_type, obj);
}
static PyObject *cg_addressof_global_var(GlobSupportObject *gs)
{
void *data;
PyObject *x, *ptrtype = new_pointer_type(gs->gs_type);
if (ptrtype == NULL)
return NULL;
data = fetch_global_var_addr(gs);
if (data != NULL)
x = new_simple_cdata(data, (CTypeDescrObject *)ptrtype);
else
x = NULL;
Py_DECREF(ptrtype);
return x;
}