Home | History | Annotate | Download | only in libffi_msvc
      1 /* -----------------------------------------------------------------*-C-*-
      2    libffi 2.00-beta - Copyright (c) 1996-2003  Red Hat, Inc.
      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 //XXX #define X86
     60 
     61 /* ---- System configuration information --------------------------------- */
     62 
     63 #include <ffitarget.h>
     64 
     65 #ifndef LIBFFI_ASM
     66 
     67 #include <stddef.h>
     68 #include <limits.h>
     69 
     70 /* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
     71    But we can find it either under the correct ANSI name, or under GNU
     72    C's internal name.  */
     73 #ifdef LONG_LONG_MAX
     74 # define FFI_LONG_LONG_MAX LONG_LONG_MAX
     75 #else
     76 # ifdef LLONG_MAX
     77 #  define FFI_LONG_LONG_MAX LLONG_MAX
     78 # else
     79 #  ifdef __GNUC__
     80 #   define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
     81 #  endif
     82 #  ifdef _MSC_VER
     83 #   define FFI_LONG_LONG_MAX _I64_MAX
     84 #  endif
     85 # endif
     86 #endif
     87 
     88 #if SCHAR_MAX == 127
     89 # define ffi_type_uchar                ffi_type_uint8
     90 # define ffi_type_schar                ffi_type_sint8
     91 #else
     92  #error "char size not supported"
     93 #endif
     94 
     95 #if SHRT_MAX == 32767
     96 # define ffi_type_ushort       ffi_type_uint16
     97 # define ffi_type_sshort       ffi_type_sint16
     98 #elif SHRT_MAX == 2147483647
     99 # define ffi_type_ushort       ffi_type_uint32
    100 # define ffi_type_sshort       ffi_type_sint32
    101 #else
    102  #error "short size not supported"
    103 #endif
    104 
    105 #if INT_MAX == 32767
    106 # define ffi_type_uint         ffi_type_uint16
    107 # define ffi_type_sint         ffi_type_sint16
    108 #elif INT_MAX == 2147483647
    109 # define ffi_type_uint         ffi_type_uint32
    110 # define ffi_type_sint         ffi_type_sint32
    111 #elif INT_MAX == 9223372036854775807
    112 # define ffi_type_uint         ffi_type_uint64
    113 # define ffi_type_sint         ffi_type_sint64
    114 #else
    115  #error "int size not supported"
    116 #endif
    117 
    118 #define ffi_type_ulong         ffi_type_uint64
    119 #define ffi_type_slong         ffi_type_sint64
    120 #if LONG_MAX == 2147483647
    121 # if FFI_LONG_LONG_MAX != 9223372036854775807
    122   #error "no 64-bit data type supported"
    123 # endif
    124 #elif LONG_MAX != 9223372036854775807
    125  #error "long size not supported"
    126 #endif
    127 
    128 /* The closure code assumes that this works on pointers, i.e. a size_t	*/
    129 /* can hold a pointer.							*/
    130 
    131 typedef struct _ffi_type
    132 {
    133   size_t size;
    134   unsigned short alignment;
    135   unsigned short type;
    136   /*@null@*/ struct _ffi_type **elements;
    137 } ffi_type;
    138 
    139 /* These are defined in types.c */
    140 extern ffi_type ffi_type_void;
    141 extern ffi_type ffi_type_uint8;
    142 extern ffi_type ffi_type_sint8;
    143 extern ffi_type ffi_type_uint16;
    144 extern ffi_type ffi_type_sint16;
    145 extern ffi_type ffi_type_uint32;
    146 extern ffi_type ffi_type_sint32;
    147 extern ffi_type ffi_type_uint64;
    148 extern ffi_type ffi_type_sint64;
    149 extern ffi_type ffi_type_float;
    150 extern ffi_type ffi_type_double;
    151 extern ffi_type ffi_type_longdouble;
    152 extern ffi_type ffi_type_pointer;
    153 
    154 
    155 typedef enum {
    156   FFI_OK = 0,
    157   FFI_BAD_TYPEDEF,
    158   FFI_BAD_ABI
    159 } ffi_status;
    160 
    161 typedef unsigned FFI_TYPE;
    162 
    163 typedef struct {
    164   ffi_abi abi;
    165   unsigned nargs;
    166   /*@dependent@*/ ffi_type **arg_types;
    167   /*@dependent@*/ ffi_type *rtype;
    168   unsigned bytes;
    169   unsigned flags;
    170 #ifdef FFI_EXTRA_CIF_FIELDS
    171   FFI_EXTRA_CIF_FIELDS;
    172 #endif
    173 } ffi_cif;
    174 
    175 /* ---- Definitions for the raw API -------------------------------------- */
    176 
    177 #ifdef _WIN64
    178 #define FFI_SIZEOF_ARG 8
    179 #else
    180 #define FFI_SIZEOF_ARG 4
    181 #endif
    182 
    183 typedef union {
    184   ffi_sarg  sint;
    185   ffi_arg   uint;
    186   float	    flt;
    187   char      data[FFI_SIZEOF_ARG];
    188   void*     ptr;
    189 } ffi_raw;
    190 
    191 void ffi_raw_call (/*@dependent@*/ ffi_cif *cif,
    192 		   void (*fn)(),
    193 		   /*@out@*/ void *rvalue,
    194 		   /*@dependent@*/ ffi_raw *avalue);
    195 
    196 void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
    197 void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
    198 size_t ffi_raw_size (ffi_cif *cif);
    199 
    200 /* This is analogous to the raw API, except it uses Java parameter	*/
    201 /* packing, even on 64-bit machines.  I.e. on 64-bit machines		*/
    202 /* longs and doubles are followed by an empty 64-bit word.		*/
    203 
    204 void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
    205 		        void (*fn)(),
    206 		        /*@out@*/ void *rvalue,
    207 		        /*@dependent@*/ ffi_raw *avalue);
    208 
    209 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
    210 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
    211 size_t ffi_java_raw_size (ffi_cif *cif);
    212 
    213 /* ---- Definitions for closures ----------------------------------------- */
    214 
    215 #if FFI_CLOSURES
    216 
    217 typedef struct {
    218   char tramp[FFI_TRAMPOLINE_SIZE];
    219   ffi_cif   *cif;
    220   void     (*fun)(ffi_cif*,void*,void**,void*);
    221   void      *user_data;
    222 } ffi_closure;
    223 
    224 void ffi_closure_free(void *);
    225 void *ffi_closure_alloc (size_t size, void **code);
    226 
    227 ffi_status
    228 ffi_prep_closure_loc (ffi_closure*,
    229 		  ffi_cif *,
    230 		  void (*fun)(ffi_cif*,void*,void**,void*),
    231 		  void *user_data,
    232 		  void *codeloc);
    233 
    234 typedef struct {
    235   char tramp[FFI_TRAMPOLINE_SIZE];
    236 
    237   ffi_cif   *cif;
    238 
    239 #if !FFI_NATIVE_RAW_API
    240 
    241   /* if this is enabled, then a raw closure has the same layout
    242      as a regular closure.  We use this to install an intermediate
    243      handler to do the transaltion, void** -> ffi_raw*. */
    244 
    245   void     (*translate_args)(ffi_cif*,void*,void**,void*);
    246   void      *this_closure;
    247 
    248 #endif
    249 
    250   void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
    251   void      *user_data;
    252 
    253 } ffi_raw_closure;
    254 
    255 ffi_status
    256 ffi_prep_raw_closure (ffi_raw_closure*,
    257 		      ffi_cif *cif,
    258 		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
    259 		      void *user_data);
    260 
    261 ffi_status
    262 ffi_prep_java_raw_closure (ffi_raw_closure*,
    263 		           ffi_cif *cif,
    264 		           void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
    265 		           void *user_data);
    266 
    267 #endif /* FFI_CLOSURES */
    268 
    269 /* ---- Public interface definition -------------------------------------- */
    270 
    271 ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
    272 			ffi_abi abi,
    273 			unsigned int nargs,
    274 			/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
    275 			/*@dependent@*/ ffi_type **atypes);
    276 
    277 int
    278 ffi_call(/*@dependent@*/ ffi_cif *cif,
    279 	 void (*fn)(),
    280 	 /*@out@*/ void *rvalue,
    281 	 /*@dependent@*/ void **avalue);
    282 
    283 /* Useful for eliminating compiler warnings */
    284 #define FFI_FN(f) ((void (*)())f)
    285 
    286 /* ---- Definitions shared with assembly code ---------------------------- */
    287 
    288 #endif
    289 
    290 /* If these change, update src/mips/ffitarget.h. */
    291 #define FFI_TYPE_VOID       0
    292 #define FFI_TYPE_INT        1
    293 #define FFI_TYPE_FLOAT      2
    294 #define FFI_TYPE_DOUBLE     3
    295 #if 1
    296 #define FFI_TYPE_LONGDOUBLE 4
    297 #else
    298 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
    299 #endif
    300 #define FFI_TYPE_UINT8      5
    301 #define FFI_TYPE_SINT8      6
    302 #define FFI_TYPE_UINT16     7
    303 #define FFI_TYPE_SINT16     8
    304 #define FFI_TYPE_UINT32     9
    305 #define FFI_TYPE_SINT32     10
    306 #define FFI_TYPE_UINT64     11
    307 #define FFI_TYPE_SINT64     12
    308 #define FFI_TYPE_STRUCT     13
    309 #define FFI_TYPE_POINTER    14
    310 
    311 /* This should always refer to the last type code (for sanity checks) */
    312 #define FFI_TYPE_LAST       FFI_TYPE_POINTER
    313 
    314 #ifdef __cplusplus
    315 }
    316 #endif
    317 
    318 #endif
    319 
    320