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

Python code coverage for Modules/_ctypes/libffi_msvc/prep_cif.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#include <stdlib.h>
27n/a
28n/a
29n/a/* Round up to FFI_SIZEOF_ARG. */
30n/a
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 initialize_aggregate(/*@out@*/ ffi_type *arg)
37n/a{
38n/a ffi_type **ptr;
39n/a
40n/a FFI_ASSERT(arg != NULL);
41n/a
42n/a /*@-usedef@*/
43n/a
44n/a FFI_ASSERT(arg->elements != NULL);
45n/a FFI_ASSERT(arg->size == 0);
46n/a FFI_ASSERT(arg->alignment == 0);
47n/a
48n/a ptr = &(arg->elements[0]);
49n/a
50n/a while ((*ptr) != NULL)
51n/a {
52n/a if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
53n/a return FFI_BAD_TYPEDEF;
54n/a
55n/a /* Perform a sanity check on the argument type */
56n/a FFI_ASSERT_VALID_TYPE(*ptr);
57n/a
58n/a arg->size = ALIGN(arg->size, (*ptr)->alignment);
59n/a arg->size += (*ptr)->size;
60n/a
61n/a arg->alignment = (arg->alignment > (*ptr)->alignment) ?
62n/a arg->alignment : (*ptr)->alignment;
63n/a
64n/a ptr++;
65n/a }
66n/a
67n/a /* Structure size includes tail padding. This is important for
68n/a structures that fit in one register on ABIs like the PowerPC64
69n/a Linux ABI that right justify small structs in a register.
70n/a It's also needed for nested structure layout, for example
71n/a struct A { long a; char b; }; struct B { struct A x; char y; };
72n/a should find y at an offset of 2*sizeof(long) and result in a
73n/a total size of 3*sizeof(long). */
74n/a arg->size = ALIGN (arg->size, arg->alignment);
75n/a
76n/a if (arg->size == 0)
77n/a return FFI_BAD_TYPEDEF;
78n/a else
79n/a return FFI_OK;
80n/a
81n/a /*@=usedef@*/
82n/a}
83n/a
84n/a/* Perform machine independent ffi_cif preparation, then call
85n/a machine dependent routine. */
86n/a
87n/affi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
88n/a ffi_abi abi, unsigned int nargs,
89n/a /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
90n/a /*@dependent@*/ ffi_type **atypes)
91n/a{
92n/a unsigned bytes = 0;
93n/a unsigned int i;
94n/a ffi_type **ptr;
95n/a
96n/a FFI_ASSERT(cif != NULL);
97n/a FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
98n/a
99n/a cif->abi = abi;
100n/a cif->arg_types = atypes;
101n/a cif->nargs = nargs;
102n/a cif->rtype = rtype;
103n/a
104n/a cif->flags = 0;
105n/a
106n/a /* Initialize the return type if necessary */
107n/a /*@-usedef@*/
108n/a if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
109n/a return FFI_BAD_TYPEDEF;
110n/a /*@=usedef@*/
111n/a
112n/a /* Perform a sanity check on the return type */
113n/a FFI_ASSERT_VALID_TYPE(cif->rtype);
114n/a
115n/a /* x86-64 and s390 stack space allocation is handled in prep_machdep. */
116n/a#if !defined M68K && !defined __x86_64__ && !defined S390
117n/a /* Make space for the return structure pointer */
118n/a if (cif->rtype->type == FFI_TYPE_STRUCT
119n/a#ifdef _WIN32
120n/a && (cif->rtype->size > 8) /* MSVC returns small structs in registers */
121n/a#endif
122n/a#ifdef SPARC
123n/a && (cif->abi != FFI_V9 || cif->rtype->size > 32)
124n/a#endif
125n/a )
126n/a bytes = STACK_ARG_SIZE(sizeof(void*));
127n/a#endif
128n/a
129n/a for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
130n/a {
131n/a
132n/a /* Initialize any uninitialized aggregate type definitions */
133n/a if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
134n/a return FFI_BAD_TYPEDEF;
135n/a
136n/a /* Perform a sanity check on the argument type, do this
137n/a check after the initialization. */
138n/a FFI_ASSERT_VALID_TYPE(*ptr);
139n/a
140n/a#if !defined __x86_64__ && !defined S390
141n/a#ifdef SPARC
142n/a if (((*ptr)->type == FFI_TYPE_STRUCT
143n/a && ((*ptr)->size > 16 || cif->abi != FFI_V9))
144n/a || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
145n/a && cif->abi != FFI_V9))
146n/a bytes += sizeof(void*);
147n/a else
148n/a#elif defined (_WIN64)
149n/a if ((*ptr)->type == FFI_TYPE_STRUCT && ((*ptr)->size > 8))
150n/a bytes += sizeof(void*);
151n/a else
152n/a#endif
153n/a {
154n/a#if !defined(_MSC_VER) && !defined(__MINGW32__)
155n/a /* Don't know if this is a libffi bug or not. At least on
156n/a Windows with MSVC, function call parameters are *not*
157n/a aligned in the same way as structure fields are, they are
158n/a only aligned in integer boundaries.
159n/a
160n/a This doesn't do any harm for cdecl functions and closures,
161n/a since the caller cleans up the stack, but it is wrong for
162n/a stdcall functions where the callee cleans.
163n/a */
164n/a
165n/a /* Add any padding if necessary */
166n/a if (((*ptr)->alignment - 1) & bytes)
167n/a bytes = ALIGN(bytes, (*ptr)->alignment);
168n/a
169n/a#endif
170n/a bytes += STACK_ARG_SIZE((*ptr)->size);
171n/a }
172n/a#endif
173n/a }
174n/a
175n/a#ifdef _WIN64
176n/a /* Function call needs at least 40 bytes stack size, on win64 AMD64 */
177n/a if (bytes < 40)
178n/a bytes = 40;
179n/a#endif
180n/a
181n/a cif->bytes = bytes;
182n/a
183n/a /* Perform machine dependent cif processing */
184n/a return ffi_prep_cif_machdep(cif);
185n/a}