ยปCore Development>Code coverage>Modules/_ctypes/libffi_osx/ffi.c

Python code coverage for Modules/_ctypes/libffi_osx/ffi.c

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