You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
3.3 KiB
114 lines
3.3 KiB
|
|
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;
|
|
}
|