• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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