1
2 typedef void *(*gs_fetch_addr_fn)(void);
3
4 typedef struct {
5 PyObject_HEAD
6
7 PyObject *gs_name;
8 CTypeDescrObject *gs_type;
9 char *gs_data;
10 gs_fetch_addr_fn gs_fetch_addr;
11
12 } GlobSupportObject;
13
glob_support_dealloc(GlobSupportObject * gs)14 static void glob_support_dealloc(GlobSupportObject *gs)
15 {
16 Py_DECREF(gs->gs_name);
17 Py_DECREF(gs->gs_type);
18 PyObject_Del(gs);
19 }
20
21 static PyTypeObject GlobSupport_Type = {
22 PyVarObject_HEAD_INIT(NULL, 0)
23 "FFIGlobSupport",
24 sizeof(GlobSupportObject),
25 0,
26 (destructor)glob_support_dealloc, /* tp_dealloc */
27 0, /* tp_print */
28 0, /* tp_getattr */
29 0, /* tp_setattr */
30 0, /* tp_compare */
31 0, /* tp_repr */
32 0, /* tp_as_number */
33 0, /* tp_as_sequence */
34 0, /* tp_as_mapping */
35 0, /* tp_hash */
36 0, /* tp_call */
37 0, /* tp_str */
38 PyObject_GenericGetAttr, /* tp_getattro */
39 0, /* tp_setattro */
40 0, /* tp_as_buffer */
41 Py_TPFLAGS_DEFAULT, /* tp_flags */
42 };
43
44 #define GlobSupport_Check(ob) (Py_TYPE(ob) == &GlobSupport_Type)
45
make_global_var(PyObject * name,CTypeDescrObject * type,char * addr,gs_fetch_addr_fn fetch_addr)46 static PyObject *make_global_var(PyObject *name, CTypeDescrObject *type,
47 char *addr, gs_fetch_addr_fn fetch_addr)
48 {
49 GlobSupportObject *gs = PyObject_New(GlobSupportObject, &GlobSupport_Type);
50 if (gs == NULL)
51 return NULL;
52
53 Py_INCREF(name);
54 Py_INCREF(type);
55 gs->gs_name = name;
56 gs->gs_type = type;
57 gs->gs_data = addr;
58 gs->gs_fetch_addr = fetch_addr;
59 return (PyObject *)gs;
60 }
61
fetch_global_var_addr(GlobSupportObject * gs)62 static void *fetch_global_var_addr(GlobSupportObject *gs)
63 {
64 void *data;
65 if (gs->gs_data != NULL) {
66 data = gs->gs_data;
67 }
68 else {
69 Py_BEGIN_ALLOW_THREADS
70 restore_errno();
71 data = gs->gs_fetch_addr();
72 save_errno();
73 Py_END_ALLOW_THREADS
74 }
75 if (data == NULL) {
76 PyErr_Format(FFIError, "global variable '%s' is at address NULL",
77 PyText_AS_UTF8(gs->gs_name));
78 return NULL;
79 }
80 return data;
81 }
82
read_global_var(GlobSupportObject * gs)83 static PyObject *read_global_var(GlobSupportObject *gs)
84 {
85 void *data = fetch_global_var_addr(gs);
86 if (data == NULL)
87 return NULL;
88 return convert_to_object(data, gs->gs_type);
89 }
90
write_global_var(GlobSupportObject * gs,PyObject * obj)91 static int write_global_var(GlobSupportObject *gs, PyObject *obj)
92 {
93 void *data = fetch_global_var_addr(gs);
94 if (data == NULL)
95 return -1;
96 return convert_from_object(data, gs->gs_type, obj);
97 }
98
cg_addressof_global_var(GlobSupportObject * gs)99 static PyObject *cg_addressof_global_var(GlobSupportObject *gs)
100 {
101 void *data;
102 PyObject *x, *ptrtype = new_pointer_type(gs->gs_type);
103 if (ptrtype == NULL)
104 return NULL;
105
106 data = fetch_global_var_addr(gs);
107 if (data != NULL)
108 x = new_simple_cdata(data, (CTypeDescrObject *)ptrtype);
109 else
110 x = NULL;
111 Py_DECREF(ptrtype);
112 return x;
113 }
114