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

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

#countcontent
1n/a/* -----------------------------------------------------------------------
2n/a prep_cif.c - Copyright (c) 2011, 2012 Anthony Green
3n/a Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
4n/a
5n/a Permission is hereby granted, free of charge, to any person obtaining
6n/a a copy of this software and associated documentation files (the
7n/a ``Software''), to deal in the Software without restriction, including
8n/a without limitation the rights to use, copy, modify, merge, publish,
9n/a distribute, sublicense, and/or sell copies of the Software, and to
10n/a permit persons to whom the Software is furnished to do so, subject to
11n/a the following conditions:
12n/a
13n/a The above copyright notice and this permission notice shall be included
14n/a in all copies or substantial portions of the Software.
15n/a
16n/a THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
17n/a EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18n/a MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19n/a NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20n/a HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21n/a WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22n/a OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23n/a DEALINGS IN THE SOFTWARE.
24n/a ----------------------------------------------------------------------- */
25n/a
26n/a#include <ffi.h>
27n/a#include <ffi_common.h>
28n/a#include <stdlib.h>
29n/a
30n/a/* Round up to FFI_SIZEOF_ARG. */
31n/a
32n/a#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
33n/a
34n/a/* Perform machine independent initialization of aggregate type
35n/a specifications. */
36n/a
37n/astatic ffi_status initialize_aggregate(ffi_type *arg)
38n/a{
39n/a ffi_type **ptr;
40n/a
41n/a if (UNLIKELY(arg == NULL || arg->elements == NULL))
42n/a return FFI_BAD_TYPEDEF;
43n/a
44n/a arg->size = 0;
45n/a arg->alignment = 0;
46n/a
47n/a ptr = &(arg->elements[0]);
48n/a
49n/a if (UNLIKELY(ptr == 0))
50n/a return FFI_BAD_TYPEDEF;
51n/a
52n/a while ((*ptr) != NULL)
53n/a {
54n/a if (UNLIKELY(((*ptr)->size == 0)
55n/a && (initialize_aggregate((*ptr)) != FFI_OK)))
56n/a return FFI_BAD_TYPEDEF;
57n/a
58n/a /* Perform a sanity check on the argument type */
59n/a FFI_ASSERT_VALID_TYPE(*ptr);
60n/a
61n/a arg->size = ALIGN(arg->size, (*ptr)->alignment);
62n/a arg->size += (*ptr)->size;
63n/a
64n/a arg->alignment = (arg->alignment > (*ptr)->alignment) ?
65n/a arg->alignment : (*ptr)->alignment;
66n/a
67n/a ptr++;
68n/a }
69n/a
70n/a /* Structure size includes tail padding. This is important for
71n/a structures that fit in one register on ABIs like the PowerPC64
72n/a Linux ABI that right justify small structs in a register.
73n/a It's also needed for nested structure layout, for example
74n/a struct A { long a; char b; }; struct B { struct A x; char y; };
75n/a should find y at an offset of 2*sizeof(long) and result in a
76n/a total size of 3*sizeof(long). */
77n/a arg->size = ALIGN (arg->size, arg->alignment);
78n/a
79n/a /* On some targets, the ABI defines that structures have an additional
80n/a alignment beyond the "natural" one based on their elements. */
81n/a#ifdef FFI_AGGREGATE_ALIGNMENT
82n/a if (FFI_AGGREGATE_ALIGNMENT > arg->alignment)
83n/a arg->alignment = FFI_AGGREGATE_ALIGNMENT;
84n/a#endif
85n/a
86n/a if (arg->size == 0)
87n/a return FFI_BAD_TYPEDEF;
88n/a else
89n/a return FFI_OK;
90n/a}
91n/a
92n/a#ifndef __CRIS__
93n/a/* The CRIS ABI specifies structure elements to have byte
94n/a alignment only, so it completely overrides this functions,
95n/a which assumes "natural" alignment and padding. */
96n/a
97n/a/* Perform machine independent ffi_cif preparation, then call
98n/a machine dependent routine. */
99n/a
100n/a/* For non variadic functions isvariadic should be 0 and
101n/a nfixedargs==ntotalargs.
102n/a
103n/a For variadic calls, isvariadic should be 1 and nfixedargs
104n/a and ntotalargs set as appropriate. nfixedargs must always be >=1 */
105n/a
106n/a
107n/affi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
108n/a unsigned int isvariadic,
109n/a unsigned int nfixedargs,
110n/a unsigned int ntotalargs,
111n/a ffi_type *rtype, ffi_type **atypes)
112n/a{
113n/a unsigned bytes = 0;
114n/a unsigned int i;
115n/a ffi_type **ptr;
116n/a
117n/a FFI_ASSERT(cif != NULL);
118n/a FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));
119n/a FFI_ASSERT(nfixedargs <= ntotalargs);
120n/a
121n/a if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
122n/a return FFI_BAD_ABI;
123n/a
124n/a cif->abi = abi;
125n/a cif->arg_types = atypes;
126n/a cif->nargs = ntotalargs;
127n/a cif->rtype = rtype;
128n/a
129n/a cif->flags = 0;
130n/a
131n/a#if HAVE_LONG_DOUBLE_VARIANT
132n/a ffi_prep_types (abi);
133n/a#endif
134n/a
135n/a /* Initialize the return type if necessary */
136n/a if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
137n/a return FFI_BAD_TYPEDEF;
138n/a
139n/a /* Perform a sanity check on the return type */
140n/a FFI_ASSERT_VALID_TYPE(cif->rtype);
141n/a
142n/a /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
143n/a#if !defined M68K && !defined X86_ANY && !defined S390 && !defined PA
144n/a /* Make space for the return structure pointer */
145n/a if (cif->rtype->type == FFI_TYPE_STRUCT
146n/a#ifdef SPARC
147n/a && (cif->abi != FFI_V9 || cif->rtype->size > 32)
148n/a#endif
149n/a#ifdef TILE
150n/a && (cif->rtype->size > 10 * FFI_SIZEOF_ARG)
151n/a#endif
152n/a#ifdef XTENSA
153n/a && (cif->rtype->size > 16)
154n/a#endif
155n/a#ifdef NIOS2
156n/a && (cif->rtype->size > 8)
157n/a#endif
158n/a )
159n/a bytes = STACK_ARG_SIZE(sizeof(void*));
160n/a#endif
161n/a
162n/a for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
163n/a {
164n/a
165n/a /* Initialize any uninitialized aggregate type definitions */
166n/a if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
167n/a return FFI_BAD_TYPEDEF;
168n/a
169n/a /* Perform a sanity check on the argument type, do this
170n/a check after the initialization. */
171n/a FFI_ASSERT_VALID_TYPE(*ptr);
172n/a
173n/a#if !defined X86_ANY && !defined S390 && !defined PA
174n/a#ifdef SPARC
175n/a if (((*ptr)->type == FFI_TYPE_STRUCT
176n/a && ((*ptr)->size > 16 || cif->abi != FFI_V9))
177n/a || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
178n/a && cif->abi != FFI_V9))
179n/a bytes += sizeof(void*);
180n/a else
181n/a#endif
182n/a {
183n/a /* Add any padding if necessary */
184n/a if (((*ptr)->alignment - 1) & bytes)
185n/a bytes = (unsigned)ALIGN(bytes, (*ptr)->alignment);
186n/a
187n/a#ifdef TILE
188n/a if (bytes < 10 * FFI_SIZEOF_ARG &&
189n/a bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG)
190n/a {
191n/a /* An argument is never split between the 10 parameter
192n/a registers and the stack. */
193n/a bytes = 10 * FFI_SIZEOF_ARG;
194n/a }
195n/a#endif
196n/a#ifdef XTENSA
197n/a if (bytes <= 6*4 && bytes + STACK_ARG_SIZE((*ptr)->size) > 6*4)
198n/a bytes = 6*4;
199n/a#endif
200n/a
201n/a bytes += STACK_ARG_SIZE((*ptr)->size);
202n/a }
203n/a#endif
204n/a }
205n/a
206n/a cif->bytes = bytes;
207n/a
208n/a /* Perform machine dependent cif processing */
209n/a#ifdef FFI_TARGET_SPECIFIC_VARIADIC
210n/a if (isvariadic)
211n/a return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs);
212n/a#endif
213n/a
214n/a return ffi_prep_cif_machdep(cif);
215n/a}
216n/a#endif /* not __CRIS__ */
217n/a
218n/affi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
219n/a ffi_type *rtype, ffi_type **atypes)
220n/a{
221n/a return ffi_prep_cif_core(cif, abi, 0, nargs, nargs, rtype, atypes);
222n/a}
223n/a
224n/affi_status ffi_prep_cif_var(ffi_cif *cif,
225n/a ffi_abi abi,
226n/a unsigned int nfixedargs,
227n/a unsigned int ntotalargs,
228n/a ffi_type *rtype,
229n/a ffi_type **atypes)
230n/a{
231n/a return ffi_prep_cif_core(cif, abi, 1, nfixedargs, ntotalargs, rtype, atypes);
232n/a}
233n/a
234n/a#if FFI_CLOSURES
235n/a
236n/affi_status
237n/affi_prep_closure (ffi_closure* closure,
238n/a ffi_cif* cif,
239n/a void (*fun)(ffi_cif*,void*,void**,void*),
240n/a void *user_data)
241n/a{
242n/a return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
243n/a}
244n/a
245n/a#endif