OSDN Git Service

2003-01-28 Andrew Haley <aph@redhat.com>
[pf3gnuchains/gcc-fork.git] / libffi / include / ffi.h.in
1 /* -----------------------------------------------------------------*-C-*-
2    libffi @VERSION@ - Copyright (c) 1996-2003  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 #ifdef S390
168 #if defined (__s390x__)
169 #define S390X
170 #endif
171 #endif
172
173 #ifndef LIBFFI_ASM
174
175 /* ---- Generic type definitions ----------------------------------------- */
176
177 #define ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
178 /* The closure code assumes that this works on pointers, i.e. a size_t  */
179 /* can hold a pointer.                                                  */
180
181 typedef enum ffi_abi {
182
183   /* Leave this for debugging purposes */
184   FFI_FIRST_ABI = 0,
185
186   /* ---- Sparc -------------------- */
187 #ifdef SPARC
188   FFI_V8,
189   FFI_V8PLUS,
190   FFI_V9,
191 #ifdef SPARC64
192   FFI_DEFAULT_ABI = FFI_V9,
193 #else
194   FFI_DEFAULT_ABI = FFI_V8,
195 #endif
196 #endif
197
198   /* ---- Intel x86 Win32 ---------- */
199 #ifdef X86_WIN32
200   FFI_SYSV,
201   FFI_STDCALL,
202   /* TODO: Add fastcall support for the sake of completeness */
203   FFI_DEFAULT_ABI = FFI_SYSV,
204 #endif
205
206   /* ---- Intel x86 and AMD x86-64 - */
207 #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
208   FFI_SYSV,
209   FFI_UNIX64,   /* Unix variants all use the same ABI for x86-64  */
210 #ifdef __i386__
211   FFI_DEFAULT_ABI = FFI_SYSV,
212 #else
213   FFI_DEFAULT_ABI = FFI_UNIX64,
214 #endif
215 #endif
216
217   /* ---- Intel ia64 ---------------- */
218 #ifdef IA64
219   FFI_UNIX,     /* Linux and all Unix variants use the same conventions */
220   FFI_DEFAULT_ABI = FFI_UNIX,
221 #endif
222
223   /* ---- Mips --------------------- */
224 #ifdef MIPS
225   FFI_O32,
226   FFI_N32,
227   FFI_N64,
228 #endif
229
230   /* ---- Alpha -------------------- */
231 #ifdef ALPHA
232   FFI_OSF,
233   FFI_DEFAULT_ABI = FFI_OSF,
234 #endif
235
236   /* ---- Motorola m68k ------------ */
237 #ifdef M68K
238   FFI_SYSV,
239   FFI_DEFAULT_ABI = FFI_SYSV,
240 #endif
241
242   /* ---- PowerPC ------------------ */
243 #ifdef POWERPC
244   FFI_SYSV,
245   FFI_GCC_SYSV,
246   FFI_DEFAULT_ABI = FFI_GCC_SYSV,
247 #endif
248
249 #ifdef POWERPC_AIX
250   FFI_AIX,
251   FFI_DARWIN,
252   FFI_DEFAULT_ABI = FFI_AIX,
253 #endif
254
255 #ifdef POWERPC_DARWIN
256   FFI_AIX,
257   FFI_DARWIN,
258   FFI_DEFAULT_ABI = FFI_DARWIN,
259 #endif
260
261   /* ---- ARM  --------------------- */
262 #ifdef ARM
263   FFI_SYSV,
264   FFI_DEFAULT_ABI = FFI_SYSV,
265 #endif
266
267   /* ---- S390 --------------------- */
268 #ifdef S390
269   FFI_SYSV,
270   FFI_DEFAULT_ABI = FFI_SYSV,
271 #endif
272
273   /* ---- SuperH ------------------- */
274 #ifdef SH
275   FFI_SYSV,
276   FFI_DEFAULT_ABI = FFI_SYSV,
277 #endif
278
279   /* Leave this for debugging purposes */
280   FFI_LAST_ABI
281
282 } ffi_abi;
283
284 typedef struct _ffi_type
285 {
286   size_t size;
287   unsigned short alignment;
288   unsigned short type;
289   /*@null@*/ struct _ffi_type **elements;
290 } ffi_type;
291
292 /* These are defined in types.c */
293 extern ffi_type ffi_type_void;
294 extern ffi_type ffi_type_uint8;
295 extern ffi_type ffi_type_sint8;
296 extern ffi_type ffi_type_uint16;
297 extern ffi_type ffi_type_sint16;
298 extern ffi_type ffi_type_uint32;
299 extern ffi_type ffi_type_sint32;
300 extern ffi_type ffi_type_uint64;
301 extern ffi_type ffi_type_sint64;
302 extern ffi_type ffi_type_float;
303 extern ffi_type ffi_type_double;
304 extern ffi_type ffi_type_longdouble;
305 extern ffi_type ffi_type_pointer;
306
307 /* Characters are 8 bit integral types */
308 #define ffi_type_schar ffi_type_sint8
309 #define ffi_type_uchar ffi_type_uint8
310
311 typedef enum {
312   FFI_OK = 0,
313   FFI_BAD_TYPEDEF,
314   FFI_BAD_ABI 
315 } ffi_status;
316
317 typedef unsigned FFI_TYPE;
318
319 typedef struct {
320   ffi_abi abi;
321   unsigned nargs;
322   /*@dependent@*/ ffi_type **arg_types;
323   /*@dependent@*/ ffi_type *rtype;
324   unsigned bytes;
325   unsigned flags;
326
327 #ifdef MIPS
328 #if _MIPS_SIM == _ABIN32
329   unsigned rstruct_flag;
330 #endif
331 #endif
332
333 } ffi_cif;
334
335 #if SIZEOF_ARG == 4
336 typedef UINT32 ffi_arg;
337 #else
338 #if SIZEOF_ARG == 8
339 typedef UINT64 ffi_arg;
340 #else
341 -- unsupported configuration
342 #endif
343 #endif
344
345 /* ---- Definitions for the raw API -------------------------------------- */
346
347 #if !FFI_NO_RAW_API
348
349 #if SIZEOF_ARG == 4
350
351 #define UINT_ARG UINT32
352 #define SINT_ARG SINT32
353
354 #endif
355
356 #if SIZEOF_ARG == 8
357
358 #define UINT_ARG UINT64
359 #define SINT_ARG SINT64
360
361 #endif
362
363 typedef union {
364   SINT_ARG sint;
365   UINT_ARG uint;
366   float    flt;
367   char     data[SIZEOF_ARG];
368   void*    ptr;
369 } ffi_raw;
370
371 void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, 
372                    void (*fn)(), 
373                    /*@out@*/ void *rvalue, 
374                    /*@dependent@*/ ffi_raw *avalue);
375
376 void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
377 void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
378 size_t ffi_raw_size (ffi_cif *cif);
379
380 #if !NO_JAVA_RAW_API
381
382 /* This is analogous to the raw API, except it uses Java parameter      */
383 /* packing, even on 64-bit machines.  I.e. on 64-bit machines           */
384 /* longs and doubles are followed by an empty 64-bit word.              */
385
386 void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, 
387                         void (*fn)(), 
388                         /*@out@*/ void *rvalue, 
389                         /*@dependent@*/ ffi_raw *avalue);
390
391 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
392 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
393 size_t ffi_java_raw_size (ffi_cif *cif);
394
395 #endif /* !NO_JAVA_RAW_API */
396
397 #endif /* !FFI_NO_RAW_API */
398
399 /* ---- Definitions for closures ----------------------------------------- */
400
401 #ifdef __i386__
402
403 #define FFI_CLOSURES 1          /* x86 supports closures */
404 #define FFI_TRAMPOLINE_SIZE 10
405 #define FFI_NATIVE_RAW_API 1    /* and has native raw api support */
406
407 #elif defined(IA64)
408
409 #define FFI_CLOSURES 1
410 #define FFI_TRAMPOLINE_SIZE 24  /* Really the following struct, which   */
411                                 /* can be interpreted as a C function   */
412                                 /* decriptor:                           */
413
414 struct ffi_ia64_trampoline_struct {
415     void * code_pointer;        /* Pointer to ffi_closure_UNIX  */
416     void * fake_gp;             /* Pointer to closure, installed as gp  */
417     void * real_gp;             /* Real gp value, reinstalled by        */
418                                 /* ffi_closure_UNIX.                    */
419 };
420 #define FFI_NATIVE_RAW_API 0
421
422 #elif defined(ALPHA)
423
424 #define FFI_CLOSURES 1
425 #define FFI_TRAMPOLINE_SIZE 24
426 #define FFI_NATIVE_RAW_API 0
427
428 #elif defined(POWERPC)
429
430 #define FFI_CLOSURES 1
431 #define FFI_TRAMPOLINE_SIZE 40
432 #define FFI_NATIVE_RAW_API 0
433
434 #elif defined(POWERPC_DARWIN)
435
436 #define FFI_CLOSURES 1
437 #define FFI_TRAMPOLINE_SIZE 40
438 #define FFI_NATIVE_RAW_API 0
439
440 #elif defined(POWERPC_AIX)
441
442 #define FFI_CLOSURES 1
443 #define FFI_TRAMPOLINE_SIZE 24 /* see struct below */ 
444 #define FFI_NATIVE_RAW_API 0
445
446 #elif defined(SPARC64)
447
448 #define FFI_CLOSURES 1
449 #define FFI_TRAMPOLINE_SIZE 24
450 #define FFI_NATIVE_RAW_API 0
451
452 #elif defined(SPARC)
453
454 #define FFI_CLOSURES 1
455 #define FFI_TRAMPOLINE_SIZE 16
456 #define FFI_NATIVE_RAW_API 0
457
458 #elif defined(S390)
459
460 #define FFI_CLOSURES 1
461 #ifdef S390X
462 #define FFI_TRAMPOLINE_SIZE 32
463 #else
464 #define FFI_TRAMPOLINE_SIZE 16
465 #endif
466 #define FFI_NATIVE_RAW_API 0
467
468 #elif defined(SH)
469
470 #define FFI_CLOSURES 1
471 #define FFI_TRAMPOLINE_SIZE 16
472 #define FFI_NATIVE_RAW_API 0
473
474 #elif defined(__x86_64__)
475
476 #define FFI_CLOSURES 1
477 #define FFI_TRAMPOLINE_SIZE 24
478 #define FFI_NATIVE_RAW_API 0
479
480 #else 
481
482 #define FFI_CLOSURES 0
483 #define FFI_NATIVE_RAW_API 0
484
485 #endif
486
487 #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
488
489 struct ffi_aix_trampoline_struct {
490     void * code_pointer;        /* Pointer to ffi_closure_ASM */
491     void * toc;                 /* TOC */
492     void * static_chain;        /* Pointer to closure */
493 };
494
495 #endif
496
497
498
499 #if FFI_CLOSURES
500
501 typedef struct {
502   char tramp[FFI_TRAMPOLINE_SIZE];
503   ffi_cif   *cif;
504   void     (*fun)(ffi_cif*,void*,void**,void*);
505   void      *user_data;
506 } ffi_closure;
507
508 ffi_status
509 ffi_prep_closure (ffi_closure*,
510                   ffi_cif *,
511                   void (*fun)(ffi_cif*,void*,void**,void*),
512                   void *user_data);
513
514 #if !FFI_NO_RAW_API
515
516 typedef struct {
517   char tramp[FFI_TRAMPOLINE_SIZE];
518
519   ffi_cif   *cif;
520
521 #if !FFI_NATIVE_RAW_API
522
523   /* if this is enabled, then a raw closure has the same layout 
524      as a regular closure.  We use this to install an intermediate 
525      handler to do the transaltion, void** -> ffi_raw*. */
526
527   void     (*translate_args)(ffi_cif*,void*,void**,void*);
528   void      *this_closure;
529
530 #endif
531
532   void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
533   void      *user_data;
534
535 } ffi_raw_closure;
536
537 ffi_status
538 ffi_prep_raw_closure (ffi_raw_closure*,
539                       ffi_cif *cif,
540                       void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
541                       void *user_data);
542
543 #ifndef NO_JAVA_RAW_API
544 ffi_status
545 ffi_prep_java_raw_closure (ffi_raw_closure*,
546                            ffi_cif *cif,
547                            void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
548                            void *user_data);
549 #endif
550
551 #endif /* !FFI_NO_RAW_API */
552 #endif /* FFI_CLOSURES */
553
554 /* ---- Public interface definition -------------------------------------- */
555
556 ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
557                         ffi_abi abi,
558                         unsigned int nargs, 
559                         /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
560                         /*@dependent@*/ ffi_type **atypes);
561
562 void ffi_call(/*@dependent@*/ ffi_cif *cif, 
563               void (*fn)(), 
564               /*@out@*/ void *rvalue, 
565               /*@dependent@*/ void **avalue);
566
567 /* Useful for eliminating compiler warnings */
568 #define FFI_FN(f) ((void (*)())f)
569
570 /* ---- Definitions shared with assembly code ---------------------------- */
571
572 #endif
573
574 #define FFI_TYPE_VOID       0    
575 #define FFI_TYPE_INT        1
576 #define FFI_TYPE_FLOAT      2    
577 #define FFI_TYPE_DOUBLE     3
578 #if SIZEOF_LONG_DOUBLE == SIZEOF_DOUBLE
579 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
580 #else
581 #define FFI_TYPE_LONGDOUBLE 4
582 #endif
583
584 #define FFI_TYPE_UINT8      5   /* If this changes, update ffi_mips.h. */
585 #define FFI_TYPE_SINT8      6   /* If this changes, update ffi_mips.h. */
586 #define FFI_TYPE_UINT16     7 
587 #define FFI_TYPE_SINT16     8
588 #define FFI_TYPE_UINT32     9
589 #define FFI_TYPE_SINT32     10
590 #define FFI_TYPE_UINT64     11
591 #define FFI_TYPE_SINT64     12
592 #define FFI_TYPE_STRUCT     13  /* If this changes, update ffi_mips.h. */
593 #define FFI_TYPE_POINTER    14
594
595 /* This should always refer to the last type code (for sanity checks) */
596 #define FFI_TYPE_LAST       FFI_TYPE_POINTER
597
598 #ifdef __cplusplus
599 }
600 #endif
601
602 #endif
603