aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/cffi/c/cglob.c
blob: 04c3e8bbce0066be176ead16b896f509c2274782 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
 
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) 
    "_cffi_backend.__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; 
}