2009-06-04 Andrew Haley <aph@redhat.com>
[official-gcc.git] / libffi / include / ffi.h.in
blob5f4c1c1a299d96d18b9788e028045b00799dc8c8
1 /* -----------------------------------------------------------------*-C-*-
2 libffi @VERSION@ - Copyright (c) 1996-2003, 2007 Red Hat, Inc.
4 Permission is hereby granted, free of charge, to any person obtaining
5 a copy of this software and associated documentation files (the
6 ``Software''), to deal in the Software without restriction, including
7 without limitation the rights to use, copy, modify, merge, publish,
8 distribute, sublicense, and/or sell copies of the Software, and to
9 permit persons to whom the Software is furnished to do so, subject to
10 the following conditions:
12 The above copyright notice and this permission notice shall be included
13 in all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
24 ----------------------------------------------------------------------- */
26 /* -------------------------------------------------------------------
27 The basic API is described in the README file.
29 The raw API is designed to bypass some of the argument packing
30 and unpacking on architectures for which it can be avoided.
32 The closure API allows interpreted functions to be packaged up
33 inside a C function pointer, so that they can be called as C functions,
34 with no understanding on the client side that they are interpreted.
35 It can also be used in other cases in which it is necessary to package
36 up a user specified parameter and a function pointer as a single
37 function pointer.
39 The closure API must be implemented in order to get its functionality,
40 e.g. for use by gij. Routines are provided to emulate the raw API
41 if the underlying platform doesn't allow faster implementation.
43 More details on the raw and cloure API can be found in:
45 http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
47 and
49 http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
50 -------------------------------------------------------------------- */
52 #ifndef LIBFFI_H
53 #define LIBFFI_H
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
59 /* Specify which architecture libffi is configured for. */
60 #define @TARGET@
62 /* ---- System configuration information --------------------------------- */
64 #include <ffitarget.h>
66 #ifndef LIBFFI_ASM
68 #include <stddef.h>
69 #include <limits.h>
71 /* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
72 But we can find it either under the correct ANSI name, or under GNU
73 C's internal name. */
74 #ifdef LONG_LONG_MAX
75 # define FFI_LONG_LONG_MAX LONG_LONG_MAX
76 #else
77 # ifdef LLONG_MAX
78 # define FFI_LONG_LONG_MAX LLONG_MAX
79 # else
80 # ifdef __GNUC__
81 # define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
82 # endif
83 # endif
84 #endif
86 /* The closure code assumes that this works on pointers, i.e. a size_t */
87 /* can hold a pointer. */
89 typedef struct _ffi_type
91 size_t size;
92 unsigned short alignment;
93 unsigned short type;
94 struct _ffi_type **elements;
95 } ffi_type;
97 #ifndef LIBFFI_HIDE_BASIC_TYPES
98 #if SCHAR_MAX == 127
99 # define ffi_type_uchar ffi_type_uint8
100 # define ffi_type_schar ffi_type_sint8
101 #else
102 #error "char size not supported"
103 #endif
105 #if SHRT_MAX == 32767
106 # define ffi_type_ushort ffi_type_uint16
107 # define ffi_type_sshort ffi_type_sint16
108 #elif SHRT_MAX == 2147483647
109 # define ffi_type_ushort ffi_type_uint32
110 # define ffi_type_sshort ffi_type_sint32
111 #else
112 #error "short size not supported"
113 #endif
115 #if INT_MAX == 32767
116 # define ffi_type_uint ffi_type_uint16
117 # define ffi_type_sint ffi_type_sint16
118 #elif INT_MAX == 2147483647
119 # define ffi_type_uint ffi_type_uint32
120 # define ffi_type_sint ffi_type_sint32
121 #elif INT_MAX == 9223372036854775807
122 # define ffi_type_uint ffi_type_uint64
123 # define ffi_type_sint ffi_type_sint64
124 #else
125 #error "int size not supported"
126 #endif
128 #if LONG_MAX == 2147483647
129 # if FFI_LONG_LONG_MAX != 9223372036854775807
130 #error "no 64-bit data type supported"
131 # endif
132 #elif LONG_MAX != 9223372036854775807
133 #error "long size not supported"
134 #endif
136 #if LONG_MAX == 2147483647
137 # define ffi_type_ulong ffi_type_uint32
138 # define ffi_type_slong ffi_type_sint32
139 #elif LONG_MAX == 9223372036854775807
140 # define ffi_type_ulong ffi_type_uint64
141 # define ffi_type_slong ffi_type_sint64
142 #else
143 #error "long size not supported"
144 #endif
146 /* These are defined in types.c */
147 extern ffi_type ffi_type_void;
148 extern ffi_type ffi_type_uint8;
149 extern ffi_type ffi_type_sint8;
150 extern ffi_type ffi_type_uint16;
151 extern ffi_type ffi_type_sint16;
152 extern ffi_type ffi_type_uint32;
153 extern ffi_type ffi_type_sint32;
154 extern ffi_type ffi_type_uint64;
155 extern ffi_type ffi_type_sint64;
156 extern ffi_type ffi_type_float;
157 extern ffi_type ffi_type_double;
158 extern ffi_type ffi_type_pointer;
160 #if @HAVE_LONG_DOUBLE@
161 extern ffi_type ffi_type_longdouble;
162 #else
163 #define ffi_type_longdouble ffi_type_double
164 #endif
165 #endif /* LIBFFI_HIDE_BASIC_TYPES */
167 typedef enum {
168 FFI_OK = 0,
169 FFI_BAD_TYPEDEF,
170 FFI_BAD_ABI
171 } ffi_status;
173 typedef unsigned FFI_TYPE;
175 typedef struct {
176 ffi_abi abi;
177 unsigned nargs;
178 ffi_type **arg_types;
179 ffi_type *rtype;
180 unsigned bytes;
181 unsigned flags;
182 #ifdef FFI_EXTRA_CIF_FIELDS
183 FFI_EXTRA_CIF_FIELDS;
184 #endif
185 } ffi_cif;
187 /* ---- Definitions for the raw API -------------------------------------- */
189 #ifndef FFI_SIZEOF_ARG
190 # if LONG_MAX == 2147483647
191 # define FFI_SIZEOF_ARG 4
192 # elif LONG_MAX == 9223372036854775807
193 # define FFI_SIZEOF_ARG 8
194 # endif
195 #endif
197 #ifndef FFI_SIZEOF_JAVA_RAW
198 # define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
199 #endif
201 typedef union {
202 ffi_sarg sint;
203 ffi_arg uint;
204 float flt;
205 char data[FFI_SIZEOF_ARG];
206 void* ptr;
207 } ffi_raw;
209 #if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
210 /* This is a special case for mips64/n32 ABI (and perhaps others) where
211 sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
212 typedef union {
213 signed int sint;
214 unsigned int uint;
215 float flt;
216 char data[FFI_SIZEOF_JAVA_RAW];
217 void* ptr;
218 } ffi_java_raw;
219 #else
220 typedef ffi_raw ffi_java_raw;
221 #endif
224 void ffi_raw_call (ffi_cif *cif,
225 void (*fn)(),
226 void *rvalue,
227 ffi_raw *avalue);
229 void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
230 void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
231 size_t ffi_raw_size (ffi_cif *cif);
233 /* This is analogous to the raw API, except it uses Java parameter */
234 /* packing, even on 64-bit machines. I.e. on 64-bit machines */
235 /* longs and doubles are followed by an empty 64-bit word. */
237 void ffi_java_raw_call (ffi_cif *cif,
238 void (*fn)(),
239 void *rvalue,
240 ffi_java_raw *avalue);
242 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
243 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
244 size_t ffi_java_raw_size (ffi_cif *cif);
246 /* ---- Definitions for closures ----------------------------------------- */
248 #if FFI_CLOSURES
250 typedef struct {
251 char tramp[FFI_TRAMPOLINE_SIZE];
252 ffi_cif *cif;
253 void (*fun)(ffi_cif*,void*,void**,void*);
254 void *user_data;
255 } ffi_closure __attribute__((aligned (8)));
257 void *ffi_closure_alloc (size_t size, void **code);
258 void ffi_closure_free (void *);
260 ffi_status
261 ffi_prep_closure (ffi_closure*,
262 ffi_cif *,
263 void (*fun)(ffi_cif*,void*,void**,void*),
264 void *user_data);
266 ffi_status
267 ffi_prep_closure_loc (ffi_closure*,
268 ffi_cif *,
269 void (*fun)(ffi_cif*,void*,void**,void*),
270 void *user_data,
271 void*codeloc);
273 typedef struct {
274 char tramp[FFI_TRAMPOLINE_SIZE];
276 ffi_cif *cif;
278 #if !FFI_NATIVE_RAW_API
280 /* if this is enabled, then a raw closure has the same layout
281 as a regular closure. We use this to install an intermediate
282 handler to do the transaltion, void** -> ffi_raw*. */
284 void (*translate_args)(ffi_cif*,void*,void**,void*);
285 void *this_closure;
287 #endif
289 void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
290 void *user_data;
292 } ffi_raw_closure;
294 typedef struct {
295 char tramp[FFI_TRAMPOLINE_SIZE];
297 ffi_cif *cif;
299 #if !FFI_NATIVE_RAW_API
301 /* if this is enabled, then a raw closure has the same layout
302 as a regular closure. We use this to install an intermediate
303 handler to do the transaltion, void** -> ffi_raw*. */
305 void (*translate_args)(ffi_cif*,void*,void**,void*);
306 void *this_closure;
308 #endif
310 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
311 void *user_data;
313 } ffi_java_raw_closure;
315 ffi_status
316 ffi_prep_raw_closure (ffi_raw_closure*,
317 ffi_cif *cif,
318 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
319 void *user_data);
321 ffi_status
322 ffi_prep_raw_closure_loc (ffi_raw_closure*,
323 ffi_cif *cif,
324 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
325 void *user_data,
326 void *codeloc);
328 ffi_status
329 ffi_prep_java_raw_closure (ffi_java_raw_closure*,
330 ffi_cif *cif,
331 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
332 void *user_data);
334 ffi_status
335 ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
336 ffi_cif *cif,
337 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
338 void *user_data,
339 void *codeloc);
341 #endif /* FFI_CLOSURES */
343 /* ---- Public interface definition -------------------------------------- */
345 ffi_status ffi_prep_cif(ffi_cif *cif,
346 ffi_abi abi,
347 unsigned int nargs,
348 ffi_type *rtype,
349 ffi_type **atypes);
351 void ffi_call(ffi_cif *cif,
352 void (*fn)(),
353 void *rvalue,
354 void **avalue);
356 /* Useful for eliminating compiler warnings */
357 #define FFI_FN(f) ((void (*)())f)
359 /* ---- Definitions shared with assembly code ---------------------------- */
361 #endif
363 /* If these change, update src/mips/ffitarget.h. */
364 #define FFI_TYPE_VOID 0
365 #define FFI_TYPE_INT 1
366 #define FFI_TYPE_FLOAT 2
367 #define FFI_TYPE_DOUBLE 3
368 #if @HAVE_LONG_DOUBLE@
369 #define FFI_TYPE_LONGDOUBLE 4
370 #else
371 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
372 #endif
373 #define FFI_TYPE_UINT8 5
374 #define FFI_TYPE_SINT8 6
375 #define FFI_TYPE_UINT16 7
376 #define FFI_TYPE_SINT16 8
377 #define FFI_TYPE_UINT32 9
378 #define FFI_TYPE_SINT32 10
379 #define FFI_TYPE_UINT64 11
380 #define FFI_TYPE_SINT64 12
381 #define FFI_TYPE_STRUCT 13
382 #define FFI_TYPE_POINTER 14
384 /* This should always refer to the last type code (for sanity checks) */
385 #define FFI_TYPE_LAST FFI_TYPE_POINTER
387 #ifdef __cplusplus
389 #endif
391 #endif