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