[committed][RISC-V][PR target/114139] Verify we have a CONST_INT before extracting...
[official-gcc.git] / libffi / include / ffi.h.in
blobd16f307e64bebd72558a094d5df649e3947dd94d
1 /* -----------------------------------------------------------------*-C-*-
2 libffi @VERSION@
3 - Copyright (c) 2011, 2014, 2019, 2021 Anthony Green
4 - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
6 Permission is hereby granted, free of charge, to any person
7 obtaining a copy of this software and associated documentation
8 files (the ``Software''), to deal in the Software without
9 restriction, including without limitation the rights to use, copy,
10 modify, merge, publish, distribute, sublicense, and/or sell copies
11 of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be
15 included in all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 DEALINGS IN THE SOFTWARE.
26 ----------------------------------------------------------------------- */
28 /* -------------------------------------------------------------------
29 Most of the API is documented in doc/libffi.texi.
31 The raw API is designed to bypass some of the argument packing and
32 unpacking on architectures for which it can be avoided. Routines
33 are provided to emulate the raw API if the underlying platform
34 doesn't allow faster implementation.
36 More details on the raw API can be found in:
38 http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
40 and
42 http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
43 -------------------------------------------------------------------- */
45 #ifndef LIBFFI_H
46 #define LIBFFI_H
48 #ifdef __cplusplus
49 extern "C" {
50 #endif
52 /* Specify which architecture libffi is configured for. */
53 #ifndef @TARGET@
54 #define @TARGET@
55 #endif
57 /* ---- System configuration information --------------------------------- */
59 #include <ffitarget.h>
61 #ifndef LIBFFI_ASM
63 #if defined(_MSC_VER) && !defined(__clang__)
64 #define __attribute__(X)
65 #endif
67 #include <stddef.h>
68 #include <limits.h>
70 /* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
71 But we can find it either under the correct ANSI name, or under GNU
72 C's internal name. */
74 #define FFI_64_BIT_MAX 9223372036854775807
76 #ifdef LONG_LONG_MAX
77 # define FFI_LONG_LONG_MAX LONG_LONG_MAX
78 #else
79 # ifdef LLONG_MAX
80 # define FFI_LONG_LONG_MAX LLONG_MAX
81 # ifdef _AIX52 /* or newer has C99 LLONG_MAX */
82 # undef FFI_64_BIT_MAX
83 # define FFI_64_BIT_MAX 9223372036854775807LL
84 # endif /* _AIX52 or newer */
85 # else
86 # ifdef __GNUC__
87 # define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
88 # endif
89 # ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
90 # ifndef __PPC64__
91 # if defined (__IBMC__) || defined (__IBMCPP__)
92 # define FFI_LONG_LONG_MAX LONGLONG_MAX
93 # endif
94 # endif /* __PPC64__ */
95 # undef FFI_64_BIT_MAX
96 # define FFI_64_BIT_MAX 9223372036854775807LL
97 # endif
98 # endif
99 #endif
101 /* The closure code assumes that this works on pointers, i.e. a size_t
102 can hold a pointer. */
104 typedef struct _ffi_type
106 size_t size;
107 unsigned short alignment;
108 unsigned short type;
109 struct _ffi_type **elements;
110 } ffi_type;
112 /* Need minimal decorations for DLLs to work on Windows. GCC has
113 autoimport and autoexport. Always mark externally visible symbols
114 as dllimport for MSVC clients, even if it means an extra indirection
115 when using the static version of the library.
116 Besides, as a workaround, they can define FFI_BUILDING if they
117 *know* they are going to link with the static library. */
118 #if defined _MSC_VER
119 # if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
120 # define FFI_API __declspec(dllexport)
121 # elif !defined FFI_BUILDING /* Importing libffi.DLL */
122 # define FFI_API __declspec(dllimport)
123 # else /* Building/linking static library */
124 # define FFI_API
125 # endif
126 #else
127 # define FFI_API
128 #endif
130 /* The externally visible type declarations also need the MSVC DLL
131 decorations, or they will not be exported from the object file. */
132 #if defined LIBFFI_HIDE_BASIC_TYPES
133 # define FFI_EXTERN FFI_API
134 #else
135 # define FFI_EXTERN extern FFI_API
136 #endif
138 #ifndef LIBFFI_HIDE_BASIC_TYPES
139 #if SCHAR_MAX == 127
140 # define ffi_type_uchar ffi_type_uint8
141 # define ffi_type_schar ffi_type_sint8
142 #else
143 #error "char size not supported"
144 #endif
146 #if SHRT_MAX == 32767
147 # define ffi_type_ushort ffi_type_uint16
148 # define ffi_type_sshort ffi_type_sint16
149 #elif SHRT_MAX == 2147483647
150 # define ffi_type_ushort ffi_type_uint32
151 # define ffi_type_sshort ffi_type_sint32
152 #else
153 #error "short size not supported"
154 #endif
156 #if INT_MAX == 32767
157 # define ffi_type_uint ffi_type_uint16
158 # define ffi_type_sint ffi_type_sint16
159 #elif INT_MAX == 2147483647
160 # define ffi_type_uint ffi_type_uint32
161 # define ffi_type_sint ffi_type_sint32
162 #elif INT_MAX == 9223372036854775807
163 # define ffi_type_uint ffi_type_uint64
164 # define ffi_type_sint ffi_type_sint64
165 #else
166 #error "int size not supported"
167 #endif
169 #if LONG_MAX == 2147483647
170 # if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
171 #error "no 64-bit data type supported"
172 # endif
173 #elif LONG_MAX != FFI_64_BIT_MAX
174 #error "long size not supported"
175 #endif
177 #if LONG_MAX == 2147483647
178 # define ffi_type_ulong ffi_type_uint32
179 # define ffi_type_slong ffi_type_sint32
180 #elif LONG_MAX == FFI_64_BIT_MAX
181 # define ffi_type_ulong ffi_type_uint64
182 # define ffi_type_slong ffi_type_sint64
183 #else
184 #error "long size not supported"
185 #endif
187 /* These are defined in types.c. */
188 FFI_EXTERN ffi_type ffi_type_void;
189 FFI_EXTERN ffi_type ffi_type_uint8;
190 FFI_EXTERN ffi_type ffi_type_sint8;
191 FFI_EXTERN ffi_type ffi_type_uint16;
192 FFI_EXTERN ffi_type ffi_type_sint16;
193 FFI_EXTERN ffi_type ffi_type_uint32;
194 FFI_EXTERN ffi_type ffi_type_sint32;
195 FFI_EXTERN ffi_type ffi_type_uint64;
196 FFI_EXTERN ffi_type ffi_type_sint64;
197 FFI_EXTERN ffi_type ffi_type_float;
198 FFI_EXTERN ffi_type ffi_type_double;
199 FFI_EXTERN ffi_type ffi_type_pointer;
201 #if @HAVE_LONG_DOUBLE@
202 FFI_EXTERN ffi_type ffi_type_longdouble;
203 #else
204 #define ffi_type_longdouble ffi_type_double
205 #endif
207 #ifdef FFI_TARGET_HAS_COMPLEX_TYPE
208 FFI_EXTERN ffi_type ffi_type_complex_float;
209 FFI_EXTERN ffi_type ffi_type_complex_double;
210 #if @HAVE_LONG_DOUBLE@
211 FFI_EXTERN ffi_type ffi_type_complex_longdouble;
212 #else
213 #define ffi_type_complex_longdouble ffi_type_complex_double
214 #endif
215 #endif
216 #endif /* LIBFFI_HIDE_BASIC_TYPES */
218 typedef enum {
219 FFI_OK = 0,
220 FFI_BAD_TYPEDEF,
221 FFI_BAD_ABI,
222 FFI_BAD_ARGTYPE
223 } ffi_status;
225 typedef struct {
226 ffi_abi abi;
227 unsigned nargs;
228 ffi_type **arg_types;
229 ffi_type *rtype;
230 unsigned bytes;
231 unsigned flags;
232 #ifdef FFI_EXTRA_CIF_FIELDS
233 FFI_EXTRA_CIF_FIELDS;
234 #endif
235 } ffi_cif;
237 /* ---- Definitions for the raw API -------------------------------------- */
239 #ifndef FFI_SIZEOF_ARG
240 # if LONG_MAX == 2147483647
241 # define FFI_SIZEOF_ARG 4
242 # elif LONG_MAX == FFI_64_BIT_MAX
243 # define FFI_SIZEOF_ARG 8
244 # endif
245 #endif
247 #ifndef FFI_SIZEOF_JAVA_RAW
248 # define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
249 #endif
251 typedef union {
252 ffi_sarg sint;
253 ffi_arg uint;
254 float flt;
255 char data[FFI_SIZEOF_ARG];
256 void* ptr;
257 } ffi_raw;
259 #if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
260 /* This is a special case for mips64/n32 ABI (and perhaps others) where
261 sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
262 typedef union {
263 signed int sint;
264 unsigned int uint;
265 float flt;
266 char data[FFI_SIZEOF_JAVA_RAW];
267 void* ptr;
268 } ffi_java_raw;
269 #else
270 typedef ffi_raw ffi_java_raw;
271 #endif
274 FFI_API
275 void ffi_raw_call (ffi_cif *cif,
276 void (*fn)(void),
277 void *rvalue,
278 ffi_raw *avalue);
280 FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
281 FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
282 FFI_API size_t ffi_raw_size (ffi_cif *cif);
284 /* This is analogous to the raw API, except it uses Java parameter
285 packing, even on 64-bit machines. I.e. on 64-bit machines longs
286 and doubles are followed by an empty 64-bit word. */
288 #if !FFI_NATIVE_RAW_API
289 FFI_API
290 void ffi_java_raw_call (ffi_cif *cif,
291 void (*fn)(void),
292 void *rvalue,
293 ffi_java_raw *avalue) __attribute__((deprecated));
294 #endif
296 FFI_API
297 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated));
298 FFI_API
299 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __attribute__((deprecated));
300 FFI_API
301 size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated));
303 /* ---- Definitions for closures ----------------------------------------- */
305 #if FFI_CLOSURES
307 #ifdef _MSC_VER
308 __declspec(align(8))
309 #endif
310 typedef struct {
311 #if @FFI_EXEC_TRAMPOLINE_TABLE@
312 void *trampoline_table;
313 void *trampoline_table_entry;
314 #else
315 union {
316 char tramp[FFI_TRAMPOLINE_SIZE];
317 void *ftramp;
319 #endif
320 ffi_cif *cif;
321 void (*fun)(ffi_cif*,void*,void**,void*);
322 void *user_data;
323 } ffi_closure
324 #ifdef __GNUC__
325 __attribute__((aligned (8)))
326 #endif
329 #ifndef __GNUC__
330 # ifdef __sgi
331 # pragma pack 0
332 # endif
333 #endif
335 FFI_API void *ffi_closure_alloc (size_t size, void **code);
336 FFI_API void ffi_closure_free (void *);
338 #if defined(PA_LINUX) || defined(PA_HPUX)
339 #define FFI_CLOSURE_PTR(X) ((void *)((unsigned int)(X) | 2))
340 #define FFI_RESTORE_PTR(X) ((void *)((unsigned int)(X) & ~3))
341 #else
342 #define FFI_CLOSURE_PTR(X) (X)
343 #define FFI_RESTORE_PTR(X) (X)
344 #endif
346 FFI_API ffi_status
347 ffi_prep_closure (ffi_closure*,
348 ffi_cif *,
349 void (*fun)(ffi_cif*,void*,void**,void*),
350 void *user_data)
351 #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
352 __attribute__((deprecated ("use ffi_prep_closure_loc instead")))
353 #elif defined(__GNUC__) && __GNUC__ >= 3
354 __attribute__((deprecated))
355 #endif
358 FFI_API ffi_status
359 ffi_prep_closure_loc (ffi_closure*,
360 ffi_cif *,
361 void (*fun)(ffi_cif*,void*,void**,void*),
362 void *user_data,
363 void*codeloc);
365 #ifdef __sgi
366 # pragma pack 8
367 #endif
368 typedef struct {
369 #if @FFI_EXEC_TRAMPOLINE_TABLE@
370 void *trampoline_table;
371 void *trampoline_table_entry;
372 #else
373 char tramp[FFI_TRAMPOLINE_SIZE];
374 #endif
375 ffi_cif *cif;
377 #if !FFI_NATIVE_RAW_API
379 /* If this is enabled, then a raw closure has the same layout
380 as a regular closure. We use this to install an intermediate
381 handler to do the transaltion, void** -> ffi_raw*. */
383 void (*translate_args)(ffi_cif*,void*,void**,void*);
384 void *this_closure;
386 #endif
388 void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
389 void *user_data;
391 } ffi_raw_closure;
393 typedef struct {
394 #if @FFI_EXEC_TRAMPOLINE_TABLE@
395 void *trampoline_table;
396 void *trampoline_table_entry;
397 #else
398 char tramp[FFI_TRAMPOLINE_SIZE];
399 #endif
401 ffi_cif *cif;
403 #if !FFI_NATIVE_RAW_API
405 /* If this is enabled, then a raw closure has the same layout
406 as a regular closure. We use this to install an intermediate
407 handler to do the translation, void** -> ffi_raw*. */
409 void (*translate_args)(ffi_cif*,void*,void**,void*);
410 void *this_closure;
412 #endif
414 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
415 void *user_data;
417 } ffi_java_raw_closure;
419 FFI_API ffi_status
420 ffi_prep_raw_closure (ffi_raw_closure*,
421 ffi_cif *cif,
422 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
423 void *user_data);
425 FFI_API ffi_status
426 ffi_prep_raw_closure_loc (ffi_raw_closure*,
427 ffi_cif *cif,
428 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
429 void *user_data,
430 void *codeloc);
432 #if !FFI_NATIVE_RAW_API
433 FFI_API ffi_status
434 ffi_prep_java_raw_closure (ffi_java_raw_closure*,
435 ffi_cif *cif,
436 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
437 void *user_data) __attribute__((deprecated));
439 FFI_API ffi_status
440 ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
441 ffi_cif *cif,
442 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
443 void *user_data,
444 void *codeloc) __attribute__((deprecated));
445 #endif
447 #endif /* FFI_CLOSURES */
449 #if FFI_GO_CLOSURES
451 typedef struct {
452 void *tramp;
453 ffi_cif *cif;
454 void (*fun)(ffi_cif*,void*,void**,void*);
455 } ffi_go_closure;
457 FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
458 void (*fun)(ffi_cif*,void*,void**,void*));
460 FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
461 void **avalue, void *closure);
463 #endif /* FFI_GO_CLOSURES */
465 /* ---- Public interface definition -------------------------------------- */
467 FFI_API
468 ffi_status ffi_prep_cif(ffi_cif *cif,
469 ffi_abi abi,
470 unsigned int nargs,
471 ffi_type *rtype,
472 ffi_type **atypes);
474 FFI_API
475 ffi_status ffi_prep_cif_var(ffi_cif *cif,
476 ffi_abi abi,
477 unsigned int nfixedargs,
478 unsigned int ntotalargs,
479 ffi_type *rtype,
480 ffi_type **atypes);
482 FFI_API
483 void ffi_call(ffi_cif *cif,
484 void (*fn)(void),
485 void *rvalue,
486 void **avalue);
488 FFI_API
489 ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
490 size_t *offsets);
492 /* Useful for eliminating compiler warnings. */
493 #define FFI_FN(f) ((void (*)(void))f)
495 /* ---- Definitions shared with assembly code ---------------------------- */
497 #endif
499 /* If these change, update src/mips/ffitarget.h. */
500 #define FFI_TYPE_VOID 0
501 #define FFI_TYPE_INT 1
502 #define FFI_TYPE_FLOAT 2
503 #define FFI_TYPE_DOUBLE 3
504 #if @HAVE_LONG_DOUBLE@
505 #define FFI_TYPE_LONGDOUBLE 4
506 #else
507 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
508 #endif
509 #define FFI_TYPE_UINT8 5
510 #define FFI_TYPE_SINT8 6
511 #define FFI_TYPE_UINT16 7
512 #define FFI_TYPE_SINT16 8
513 #define FFI_TYPE_UINT32 9
514 #define FFI_TYPE_SINT32 10
515 #define FFI_TYPE_UINT64 11
516 #define FFI_TYPE_SINT64 12
517 #define FFI_TYPE_STRUCT 13
518 #define FFI_TYPE_POINTER 14
519 #define FFI_TYPE_COMPLEX 15
521 /* This should always refer to the last type code (for sanity checks). */
522 #define FFI_TYPE_LAST FFI_TYPE_COMPLEX
524 #ifdef __cplusplus
526 #endif
528 #endif