ยปCore Development>Code coverage>Modules/_ctypes/libffi/src/raw_api.c

Python code coverage for Modules/_ctypes/libffi/src/raw_api.c

#countcontent
1n/a/* -----------------------------------------------------------------------
2n/a raw_api.c - Copyright (c) 1999, 2008 Red Hat, Inc.
3n/a
4n/a Author: Kresten Krab Thorup <krab@gnu.org>
5n/a
6n/a Permission is hereby granted, free of charge, to any person obtaining
7n/a a copy of this software and associated documentation files (the
8n/a ``Software''), to deal in the Software without restriction, including
9n/a without limitation the rights to use, copy, modify, merge, publish,
10n/a distribute, sublicense, and/or sell copies of the Software, and to
11n/a permit persons to whom the Software is furnished to do so, subject to
12n/a the following conditions:
13n/a
14n/a The above copyright notice and this permission notice shall be included
15n/a in all copies or substantial portions of the Software.
16n/a
17n/a THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18n/a EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19n/a MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20n/a NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21n/a HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22n/a WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23n/a OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24n/a DEALINGS IN THE SOFTWARE.
25n/a ----------------------------------------------------------------------- */
26n/a
27n/a/* This file defines generic functions for use with the raw api. */
28n/a
29n/a#include <ffi.h>
30n/a#include <ffi_common.h>
31n/a
32n/a#if !FFI_NO_RAW_API
33n/a
34n/asize_t
35n/affi_raw_size (ffi_cif *cif)
36n/a{
37n/a size_t result = 0;
38n/a int i;
39n/a
40n/a ffi_type **at = cif->arg_types;
41n/a
42n/a for (i = cif->nargs-1; i >= 0; i--, at++)
43n/a {
44n/a#if !FFI_NO_STRUCTS
45n/a if ((*at)->type == FFI_TYPE_STRUCT)
46n/a result += ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
47n/a else
48n/a#endif
49n/a result += ALIGN ((*at)->size, FFI_SIZEOF_ARG);
50n/a }
51n/a
52n/a return result;
53n/a}
54n/a
55n/a
56n/avoid
57n/affi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
58n/a{
59n/a unsigned i;
60n/a ffi_type **tp = cif->arg_types;
61n/a
62n/a#if WORDS_BIGENDIAN
63n/a
64n/a for (i = 0; i < cif->nargs; i++, tp++, args++)
65n/a {
66n/a switch ((*tp)->type)
67n/a {
68n/a case FFI_TYPE_UINT8:
69n/a case FFI_TYPE_SINT8:
70n/a *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 1);
71n/a break;
72n/a
73n/a case FFI_TYPE_UINT16:
74n/a case FFI_TYPE_SINT16:
75n/a *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 2);
76n/a break;
77n/a
78n/a#if FFI_SIZEOF_ARG >= 4
79n/a case FFI_TYPE_UINT32:
80n/a case FFI_TYPE_SINT32:
81n/a *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 4);
82n/a break;
83n/a#endif
84n/a
85n/a#if !FFI_NO_STRUCTS
86n/a case FFI_TYPE_STRUCT:
87n/a *args = (raw++)->ptr;
88n/a break;
89n/a#endif
90n/a
91n/a case FFI_TYPE_POINTER:
92n/a *args = (void*) &(raw++)->ptr;
93n/a break;
94n/a
95n/a default:
96n/a *args = raw;
97n/a raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
98n/a }
99n/a }
100n/a
101n/a#else /* WORDS_BIGENDIAN */
102n/a
103n/a#if !PDP
104n/a
105n/a /* then assume little endian */
106n/a for (i = 0; i < cif->nargs; i++, tp++, args++)
107n/a {
108n/a#if !FFI_NO_STRUCTS
109n/a if ((*tp)->type == FFI_TYPE_STRUCT)
110n/a {
111n/a *args = (raw++)->ptr;
112n/a }
113n/a else
114n/a#endif
115n/a {
116n/a *args = (void*) raw;
117n/a raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
118n/a }
119n/a }
120n/a
121n/a#else
122n/a#error "pdp endian not supported"
123n/a#endif /* ! PDP */
124n/a
125n/a#endif /* WORDS_BIGENDIAN */
126n/a}
127n/a
128n/avoid
129n/affi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
130n/a{
131n/a unsigned i;
132n/a ffi_type **tp = cif->arg_types;
133n/a
134n/a for (i = 0; i < cif->nargs; i++, tp++, args++)
135n/a {
136n/a switch ((*tp)->type)
137n/a {
138n/a case FFI_TYPE_UINT8:
139n/a (raw++)->uint = *(UINT8*) (*args);
140n/a break;
141n/a
142n/a case FFI_TYPE_SINT8:
143n/a (raw++)->sint = *(SINT8*) (*args);
144n/a break;
145n/a
146n/a case FFI_TYPE_UINT16:
147n/a (raw++)->uint = *(UINT16*) (*args);
148n/a break;
149n/a
150n/a case FFI_TYPE_SINT16:
151n/a (raw++)->sint = *(SINT16*) (*args);
152n/a break;
153n/a
154n/a#if FFI_SIZEOF_ARG >= 4
155n/a case FFI_TYPE_UINT32:
156n/a (raw++)->uint = *(UINT32*) (*args);
157n/a break;
158n/a
159n/a case FFI_TYPE_SINT32:
160n/a (raw++)->sint = *(SINT32*) (*args);
161n/a break;
162n/a#endif
163n/a
164n/a#if !FFI_NO_STRUCTS
165n/a case FFI_TYPE_STRUCT:
166n/a (raw++)->ptr = *args;
167n/a break;
168n/a#endif
169n/a
170n/a case FFI_TYPE_POINTER:
171n/a (raw++)->ptr = **(void***) args;
172n/a break;
173n/a
174n/a default:
175n/a memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
176n/a raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
177n/a }
178n/a }
179n/a}
180n/a
181n/a#if !FFI_NATIVE_RAW_API
182n/a
183n/a
184n/a/* This is a generic definition of ffi_raw_call, to be used if the
185n/a * native system does not provide a machine-specific implementation.
186n/a * Having this, allows code to be written for the raw API, without
187n/a * the need for system-specific code to handle input in that format;
188n/a * these following couple of functions will handle the translation forth
189n/a * and back automatically. */
190n/a
191n/avoid ffi_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *raw)
192n/a{
193n/a void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
194n/a ffi_raw_to_ptrarray (cif, raw, avalue);
195n/a ffi_call (cif, fn, rvalue, avalue);
196n/a}
197n/a
198n/a#if FFI_CLOSURES /* base system provides closures */
199n/a
200n/astatic void
201n/affi_translate_args (ffi_cif *cif, void *rvalue,
202n/a void **avalue, void *user_data)
203n/a{
204n/a ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif));
205n/a ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
206n/a
207n/a ffi_ptrarray_to_raw (cif, avalue, raw);
208n/a (*cl->fun) (cif, rvalue, raw, cl->user_data);
209n/a}
210n/a
211n/affi_status
212n/affi_prep_raw_closure_loc (ffi_raw_closure* cl,
213n/a ffi_cif *cif,
214n/a void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
215n/a void *user_data,
216n/a void *codeloc)
217n/a{
218n/a ffi_status status;
219n/a
220n/a status = ffi_prep_closure_loc ((ffi_closure*) cl,
221n/a cif,
222n/a &ffi_translate_args,
223n/a codeloc,
224n/a codeloc);
225n/a if (status == FFI_OK)
226n/a {
227n/a cl->fun = fun;
228n/a cl->user_data = user_data;
229n/a }
230n/a
231n/a return status;
232n/a}
233n/a
234n/a#endif /* FFI_CLOSURES */
235n/a#endif /* !FFI_NATIVE_RAW_API */
236n/a
237n/a#if FFI_CLOSURES
238n/a
239n/a/* Again, here is the generic version of ffi_prep_raw_closure, which
240n/a * will install an intermediate "hub" for translation of arguments from
241n/a * the pointer-array format, to the raw format */
242n/a
243n/affi_status
244n/affi_prep_raw_closure (ffi_raw_closure* cl,
245n/a ffi_cif *cif,
246n/a void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
247n/a void *user_data)
248n/a{
249n/a return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl);
250n/a}
251n/a
252n/a#endif /* FFI_CLOSURES */
253n/a
254n/a#endif /* !FFI_NO_RAW_API */