OSDN Git Service

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