OSDN Git Service

2002-09-27 Bo Thorsen <bo@suse.de>
[pf3gnuchains/gcc-fork.git] / libffi / include / ffi.h.in
1 /* -----------------------------------------------------------------*-C-*-
2    libffi @VERSION@ - Copyright (c) 1996-2002  Cygnus Solutions
3
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:
11
12    The above copyright notice and this permission notice shall be included
13    in all copies or substantial portions of the Software.
14
15    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
16    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18    IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21    OTHER DEALINGS IN THE SOFTWARE.
22
23    ----------------------------------------------------------------------- */
24
25 /* -------------------------------------------------------------------
26    The basic API is described in the README file.
27
28    The raw API is designed to bypass some of the argument packing
29    and unpacking on architectures for which it can be avoided.
30
31    The closure API allows interpreted functions to be packaged up
32    inside a C function pointer, so that they can be called as C functions,
33    with no understanding on the client side that they are interpreted.
34    It can also be used in other cases in which it is necessary to package
35    up a user specified parameter and a function pointer as a single
36    function pointer.
37
38    The closure API must be implemented in order to get its functionality,
39    e.g. for use by gij.  Routines are provided to emulate the raw API
40    if the underlying platform doesn't allow faster implementation.
41
42    More details on the raw and cloure API can be found in:
43
44    http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
45
46    and
47
48    http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
49    -------------------------------------------------------------------- */
50
51 #ifndef LIBFFI_H
52 #define LIBFFI_H
53
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57
58 /* Specify which architecture libffi is configured for. */
59 #define @TARGET@
60
61 /* ---- System configuration information --------------------------------- */
62
63 #include <fficonfig.h>
64
65 #if !defined(LIBFFI_ASM)
66 #include <stddef.h>
67 #if defined(FFI_DEBUG) 
68 #include <stdio.h>
69 #endif
70 #endif
71
72 /* ---- Generic type definitions ----------------------------------------- */
73
74 #define FLOAT32 float
75 #define FLOAT64 double
76 #define FLOAT80 long double
77
78 #define UINT8   unsigned char
79 #define SINT8   signed char
80
81 #if SIZEOF_INT == 2
82
83 #define UINT16  unsigned int
84 #define SINT16  int
85 #define ffi_type_uint ffi_type_uint16
86 #define ffi_type_sint ffi_type_sint16
87
88 #else 
89 #if SIZEOF_SHORT == 2
90
91 #define UINT16  unsigned short
92 #define SINT16  short
93 #define ffi_type_ushort ffi_type_uint16
94 #define ffi_type_sshort ffi_type_sint16
95
96 #endif
97 #endif
98
99 #if SIZEOF_INT == 4
100
101 #define UINT32  unsigned int
102 #define SINT32  int
103 #define ffi_type_uint ffi_type_uint32
104 #define ffi_type_sint ffi_type_sint32
105
106 #else 
107 #if SIZEOF_SHORT == 4
108
109 #define UINT32  unsigned short
110 #define SINT32  short
111 #define ffi_type_ushort ffi_type_uint32
112 #define ffi_type_sshort ffi_type_sint32
113
114 #else
115 #if SIZEOF_LONG == 4
116
117 #define UINT32  unsigned long
118 #define SINT32  long
119 #define ffi_type_ulong ffi_type_uint32
120 #define ffi_type_slong ffi_type_sint32
121
122 #endif
123 #endif
124 #endif
125
126 #if SIZEOF_INT == 8
127
128 #define UINT64  unsigned int
129 #define SINT64  int
130 #define ffi_type_uint ffi_type_uint64
131 #define ffi_type_sint ffi_type_sint64
132
133 #else
134 #if SIZEOF_LONG == 8
135
136 #define UINT64  unsigned long
137 #define SINT64  long
138 #define ffi_type_ulong ffi_type_uint64
139 #define ffi_type_slong ffi_type_sint64
140
141 #else
142 #if SIZEOF_LONG_LONG == 8
143
144 #define UINT64  unsigned long long
145 #define SINT64  long long
146 #define ffi_type_ulong ffi_type_uint64
147 #define ffi_type_slong ffi_type_sint64
148
149 #endif
150 #endif
151 #endif
152
153 /* ---- System specific configurations ----------------------------------- */
154
155 #ifdef MIPS
156 #include <ffi_mips.h>
157 #else
158 #define SIZEOF_ARG SIZEOF_VOID_P
159 #endif
160
161 #ifdef SPARC
162 #if defined(__arch64__) || defined(__sparcv9)
163 #define SPARC64
164 #endif
165 #endif
166
167 #ifndef LIBFFI_ASM
168
169 /* ---- Generic type definitions ----------------------------------------- */
170
171 #define ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
172 /* The closure code assumes that this works on pointers, i.e. a size_t  */
173 /* can hold a pointer.                                                  */
174
175 typedef enum ffi_abi {
176
177   /* Leave this for debugging purposes */
178   FFI_FIRST_ABI = 0,
179
180   /* ---- Sparc -------------------- */
181 #ifdef SPARC
182   FFI_V8,
183   FFI_V8PLUS,
184   FFI_V9,
185 #ifdef SPARC64
186   FFI_DEFAULT_ABI = FFI_V9,
187 #else
188   FFI_DEFAULT_ABI = FFI_V8,
189 #endif
190 #endif
191
192   /* ---- Intel x86 Win32 ---------- */
193 #ifdef X86_WIN32
194   FFI_SYSV,
195   FFI_DEFAULT_ABI = FFI_SYSV,
196 #endif
197
198   /* ---- Intel x86 and AMD x86-64 - */
199 #if defined(__i386__) || defined(__x86_64__)
200   FFI_SYSV,
201   FFI_UNIX64,   /* Unix variants all use the same ABI for x86-64  */
202 #ifdef __i386__
203   FFI_DEFAULT_ABI = FFI_SYSV,
204 #else
205   FFI_DEFAULT_ABI = FFI_UNIX64,
206 #endif
207 #endif
208
209   /* ---- Intel ia64 ---------------- */
210 #ifdef IA64
211   FFI_UNIX,     /* Linux and all Unix variants use the same conventions */
212   FFI_DEFAULT_ABI = FFI_UNIX,
213 #endif
214
215   /* ---- Mips --------------------- */
216 #ifdef MIPS
217   FFI_O32,
218   FFI_N32,
219   FFI_N64,
220 #endif
221
222   /* ---- Alpha -------------------- */
223 #ifdef ALPHA
224   FFI_OSF,
225   FFI_DEFAULT_ABI = FFI_OSF,
226 #endif
227
228   /* ---- Motorola m68k ------------ */
229 #ifdef M68K
230   FFI_SYSV,
231   FFI_DEFAULT_ABI = FFI_SYSV,
232 #endif
233
234   /* ---- PowerPC ------------------ */
235 #ifdef POWERPC
236   FFI_SYSV,
237   FFI_GCC_SYSV,
238   FFI_DEFAULT_ABI = FFI_GCC_SYSV,
239 #endif
240
241 #ifdef POWERPC_AIX
242   FFI_AIX,
243   FFI_DARWIN,
244   FFI_DEFAULT_ABI = FFI_AIX,
245 #endif
246
247 #ifdef POWERPC_DARWIN
248   FFI_AIX,
249   FFI_DARWIN,
250   FFI_DEFAULT_ABI = FFI_DARWIN,
251 #endif
252
253   /* ---- ARM  --------------------- */
254 #ifdef ARM
255   FFI_SYSV,
256   FFI_DEFAULT_ABI = FFI_SYSV,
257 #endif
258
259   /* ---- S390 --------------------- */
260 #ifdef S390
261   FFI_SYSV,
262   FFI_DEFAULT_ABI = FFI_SYSV,
263 #endif
264
265   /* ---- SuperH ------------------- */
266 #ifdef SH
267   FFI_SYSV,
268   FFI_DEFAULT_ABI = FFI_SYSV,
269 #endif
270
271   /* Leave this for debugging purposes */
272   FFI_LAST_ABI
273
274 } ffi_abi;
275
276 typedef struct _ffi_type
277 {
278   size_t size;
279   unsigned short alignment;
280   unsigned short type;
281   /*@null@*/ struct _ffi_type **elements;
282 } ffi_type;
283
284 /* These are defined in ffi.c */
285 extern ffi_type ffi_type_void;
286 extern ffi_type ffi_type_uint8;
287 extern ffi_type ffi_type_sint8;
288 extern ffi_type ffi_type_uint16;
289 extern ffi_type ffi_type_sint16;
290 extern ffi_type ffi_type_uint32;
291 extern ffi_type ffi_type_sint32;
292 extern ffi_type ffi_type_uint64;
293 extern ffi_type ffi_type_sint64;
294 extern ffi_type ffi_type_float;
295 extern ffi_type ffi_type_double;
296 extern ffi_type ffi_type_longdouble;
297 extern ffi_type ffi_type_pointer;
298
299 /* Characters are 8 bit integral types */
300 #define ffi_type_schar ffi_type_sint8
301 #define ffi_type_uchar ffi_type_uint8
302
303 typedef enum {
304   FFI_OK = 0,
305   FFI_BAD_TYPEDEF,
306   FFI_BAD_ABI 
307 } ffi_status;
308
309 typedef unsigned FFI_TYPE;
310
311 typedef struct {
312   ffi_abi abi;
313   unsigned nargs;
314   /*@dependent@*/ ffi_type **arg_types;
315   /*@dependent@*/ ffi_type *rtype;
316   unsigned bytes;
317   unsigned flags;
318
319 #ifdef MIPS
320 #if _MIPS_SIM == _ABIN32
321   unsigned rstruct_flag;
322 #endif
323 #endif
324
325 } ffi_cif;
326
327 #if SIZEOF_ARG == 4
328 typedef UINT32 ffi_arg;
329 #else
330 #if SIZEOF_ARG == 8
331 typedef UINT64 ffi_arg;
332 #else
333 -- unsupported configuration
334 #endif
335 #endif
336
337 /* ---- Definitions for the raw API -------------------------------------- */
338
339 #if !FFI_NO_RAW_API
340
341 #if SIZEOF_ARG == 4
342
343 #define UINT_ARG UINT32
344 #define SINT_ARG SINT32
345
346 #endif
347
348 #if SIZEOF_ARG == 8
349
350 #define UINT_ARG UINT64
351 #define SINT_ARG SINT64
352
353 #endif
354
355 typedef union {
356   SINT_ARG sint;
357   UINT_ARG uint;
358   float    flt;
359   char     data[SIZEOF_ARG];
360   void*    ptr;
361 } ffi_raw;
362
363 void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, 
364                    void (*fn)(), 
365                    /*@out@*/ void *rvalue, 
366                    /*@dependent@*/ ffi_raw *avalue);
367
368 void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
369 void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
370 size_t ffi_raw_size (ffi_cif *cif);
371
372 #if !NO_JAVA_RAW_API
373
374 /* This is analogous to the raw API, except it uses Java parameter      */
375 /* packing, even on 64-bit machines.  I.e. on 64-bit machines           */
376 /* longs and doubles are followed by an empty 64-bit word.              */
377
378 void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, 
379                         void (*fn)(), 
380                         /*@out@*/ void *rvalue, 
381                         /*@dependent@*/ ffi_raw *avalue);
382
383 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
384 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
385 size_t ffi_java_raw_size (ffi_cif *cif);
386
387 #endif /* !NO_JAVA_RAW_API */
388
389 #endif /* !FFI_NO_RAW_API */
390
391 /* ---- Definitions for closures ----------------------------------------- */
392
393 #ifdef __i386__
394
395 #define FFI_CLOSURES 1          /* x86 supports closures */
396 #define FFI_TRAMPOLINE_SIZE 10
397 #define FFI_NATIVE_RAW_API 1    /* and has native raw api support */
398
399 #elif defined(IA64)
400
401 #define FFI_CLOSURES 1
402 #define FFI_TRAMPOLINE_SIZE 24  /* Really the following struct, which   */
403                                 /* can be interpreted as a C function   */
404                                 /* decriptor:                           */
405
406 struct ffi_ia64_trampoline_struct {
407     void * code_pointer;        /* Pointer to ffi_closure_UNIX  */
408     void * fake_gp;             /* Pointer to closure, installed as gp  */
409     void * real_gp;             /* Real gp value, reinstalled by        */
410                                 /* ffi_closure_UNIX.                    */
411 };
412 #define FFI_NATIVE_RAW_API 0
413
414 #elif defined(ALPHA)
415
416 #define FFI_CLOSURES 1
417 #define FFI_TRAMPOLINE_SIZE 24
418 #define FFI_NATIVE_RAW_API 0
419
420 #elif defined(POWERPC)
421
422 #define FFI_CLOSURES 1
423 #define FFI_TRAMPOLINE_SIZE 40
424 #define FFI_NATIVE_RAW_API 0
425
426 #elif defined(POWERPC_DARWIN)
427
428 #define FFI_CLOSURES 1
429 #define FFI_TRAMPOLINE_SIZE 40
430 #define FFI_NATIVE_RAW_API 0
431
432 #elif defined(POWERPC_AIX)
433
434 #define FFI_CLOSURES 1
435 #define FFI_TRAMPOLINE_SIZE 24 /* see struct below */ 
436 #define FFI_NATIVE_RAW_API 0
437
438 #elif defined(SH)
439
440 #define FFI_CLOSURES 1
441 #define FFI_TRAMPOLINE_SIZE 16
442 #define FFI_NATIVE_RAW_API 0
443
444 #else 
445
446 #define FFI_CLOSURES 0
447 #define FFI_NATIVE_RAW_API 0
448
449 #endif
450
451 #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
452
453 struct ffi_aix_trampoline_struct {
454     void * code_pointer;        /* Pointer to ffi_closure_ASM */
455     void * toc;                 /* TOC */
456     void * static_chain;        /* Pointer to closure */
457 };
458
459 #endif
460
461
462
463 #if FFI_CLOSURES
464
465 typedef struct {
466   char tramp[FFI_TRAMPOLINE_SIZE];
467   ffi_cif   *cif;
468   void     (*fun)(ffi_cif*,void*,void**,void*);
469   void      *user_data;
470 } ffi_closure;
471
472 ffi_status
473 ffi_prep_closure (ffi_closure*,
474                   ffi_cif *,
475                   void (*fun)(ffi_cif*,void*,void**,void*),
476                   void *user_data);
477
478 #if !FFI_NO_RAW_API
479
480 typedef struct {
481   char tramp[FFI_TRAMPOLINE_SIZE];
482
483   ffi_cif   *cif;
484
485 #if !FFI_NATIVE_RAW_API
486
487   /* if this is enabled, then a raw closure has the same layout 
488      as a regular closure.  We use this to install an intermediate 
489      handler to do the transaltion, void** -> ffi_raw*. */
490
491   void     (*translate_args)(ffi_cif*,void*,void**,void*);
492   void      *this_closure;
493
494 #endif
495
496   void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
497   void      *user_data;
498
499 } ffi_raw_closure;
500
501 ffi_status
502 ffi_prep_raw_closure (ffi_raw_closure*,
503                       ffi_cif *cif,
504                       void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
505                       void *user_data);
506
507 #ifndef NO_JAVA_RAW_API
508 ffi_status
509 ffi_prep_java_raw_closure (ffi_raw_closure*,
510                            ffi_cif *cif,
511                            void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
512                            void *user_data);
513 #endif
514
515 #endif /* !FFI_NO_RAW_API */
516 #endif /* FFI_CLOSURES */
517
518 /* ---- Public interface definition -------------------------------------- */
519
520 ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
521                         ffi_abi abi,
522                         unsigned int nargs, 
523                         /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
524                         /*@dependent@*/ ffi_type **atypes);
525
526 void ffi_call(/*@dependent@*/ ffi_cif *cif, 
527               void (*fn)(), 
528               /*@out@*/ void *rvalue, 
529               /*@dependent@*/ void **avalue);
530
531 /* Useful for eliminating compiler warnings */
532 #define FFI_FN(f) ((void (*)())f)
533
534 /* ---- Definitions shared with assembly code ---------------------------- */
535
536 #endif
537
538 #define FFI_TYPE_VOID       0    
539 #define FFI_TYPE_INT        1
540 #define FFI_TYPE_FLOAT      2    
541 #define FFI_TYPE_DOUBLE     3
542 #if SIZEOF_LONG_DOUBLE == SIZEOF_DOUBLE
543 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
544 #else
545 #define FFI_TYPE_LONGDOUBLE 4
546 #endif
547
548 #define FFI_TYPE_UINT8      5   /* If this changes, update ffi_mips.h. */
549 #define FFI_TYPE_SINT8      6   /* If this changes, update ffi_mips.h. */
550 #define FFI_TYPE_UINT16     7 
551 #define FFI_TYPE_SINT16     8
552 #define FFI_TYPE_UINT32     9
553 #define FFI_TYPE_SINT32     10
554 #define FFI_TYPE_UINT64     11
555 #define FFI_TYPE_SINT64     12
556 #define FFI_TYPE_STRUCT     13  /* If this changes, update ffi_mips.h. */
557 #define FFI_TYPE_POINTER    14
558
559 /* This should always refer to the last type code (for sanity checks) */
560 #define FFI_TYPE_LAST       FFI_TYPE_POINTER
561
562 #ifdef __cplusplus
563 }
564 #endif
565
566 #endif
567