Home | History | Annotate | Download | only in libffi_arm_wince
      1 /* -----------------------------------------------------------------*-C-*-
      2    libffi 2.00-beta-wince - 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 /*#define @TARGET@*/
     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 #ifndef FFI_SIZEOF_ARG
    178 # if LONG_MAX == 2147483647
    179 #  define FFI_SIZEOF_ARG        4
    180 # elif LONG_MAX == 9223372036854775807
    181 #  define FFI_SIZEOF_ARG        8
    182 # endif
    183 #endif
    184 
    185 typedef union {
    186   ffi_sarg  sint;
    187   ffi_arg   uint;
    188   float	    flt;
    189   char      data[FFI_SIZEOF_ARG];
    190   void*     ptr;
    191 } ffi_raw;
    192 
    193 void ffi_raw_call (/*@dependent@*/ ffi_cif *cif,
    194 		   void (*fn)(),
    195 		   /*@out@*/ void *rvalue,
    196 		   /*@dependent@*/ ffi_raw *avalue);
    197 
    198 void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
    199 void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
    200 size_t ffi_raw_size (ffi_cif *cif);
    201 
    202 /* This is analogous to the raw API, except it uses Java parameter	*/
    203 /* packing, even on 64-bit machines.  I.e. on 64-bit machines		*/
    204 /* longs and doubles are followed by an empty 64-bit word.		*/
    205 
    206 void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
    207 		        void (*fn)(),
    208 		        /*@out@*/ void *rvalue,
    209 		        /*@dependent@*/ ffi_raw *avalue);
    210 
    211 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
    212 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
    213 size_t ffi_java_raw_size (ffi_cif *cif);
    214 
    215 /* ---- Definitions for closures ----------------------------------------- */
    216 
    217 #if FFI_CLOSURES
    218 
    219 typedef struct {
    220   char tramp[FFI_TRAMPOLINE_SIZE];
    221   ffi_cif   *cif;
    222   void     (*fun)(ffi_cif*,void*,void**,void*);
    223   void      *user_data;
    224 } ffi_closure;
    225 
    226 ffi_status
    227 ffi_prep_closure (ffi_closure*,
    228 		  ffi_cif *,
    229 		  void (*fun)(ffi_cif*,void*,void**,void*),
    230 		  void *user_data);
    231 
    232 typedef struct {
    233   char tramp[FFI_TRAMPOLINE_SIZE];
    234 
    235   ffi_cif   *cif;
    236 
    237 #if !FFI_NATIVE_RAW_API
    238 
    239   /* if this is enabled, then a raw closure has the same layout
    240      as a regular closure.  We use this to install an intermediate
    241      handler to do the transaltion, void** -> ffi_raw*. */
    242 
    243   void     (*translate_args)(ffi_cif*,void*,void**,void*);
    244   void      *this_closure;
    245 
    246 #endif
    247 
    248   void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
    249   void      *user_data;
    250 
    251 } ffi_raw_closure;
    252 
    253 ffi_status
    254 ffi_prep_raw_closure (ffi_raw_closure*,
    255 		      ffi_cif *cif,
    256 		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
    257 		      void *user_data);
    258 
    259 ffi_status
    260 ffi_prep_java_raw_closure (ffi_raw_closure*,
    261 		           ffi_cif *cif,
    262 		           void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
    263 		           void *user_data);
    264 
    265 #endif /* FFI_CLOSURES */
    266 
    267 /* ---- Public interface definition -------------------------------------- */
    268 
    269 ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
    270 			ffi_abi abi,
    271 			unsigned int nargs,
    272 			/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
    273 			/*@dependent@*/ ffi_type **atypes);
    274 
    275 /* Return type changed from void for ctypes */
    276 int ffi_call(/*@dependent@*/ ffi_cif *cif,
    277 	      void (*fn)(),
    278 	      /*@out@*/ void *rvalue,
    279 	      /*@dependent@*/ void **avalue);
    280 
    281 /* Useful for eliminating compiler warnings */
    282 #define FFI_FN(f) ((void (*)())f)
    283 
    284 /* ---- Definitions shared with assembly code ---------------------------- */
    285 
    286 #endif
    287 
    288 /* If these change, update src/mips/ffitarget.h. */
    289 #define FFI_TYPE_VOID       0
    290 #define FFI_TYPE_INT        1
    291 #define FFI_TYPE_FLOAT      2
    292 #define FFI_TYPE_DOUBLE     3
    293 #if 0 /*@HAVE_LONG_DOUBLE@*/
    294 #define FFI_TYPE_LONGDOUBLE 4
    295 #else
    296 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
    297 #endif
    298 #define FFI_TYPE_UINT8      5
    299 #define FFI_TYPE_SINT8      6
    300 #define FFI_TYPE_UINT16     7
    301 #define FFI_TYPE_SINT16     8
    302 #define FFI_TYPE_UINT32     9
    303 #define FFI_TYPE_SINT32     10
    304 #define FFI_TYPE_UINT64     11
    305 #define FFI_TYPE_SINT64     12
    306 #define FFI_TYPE_STRUCT     13
    307 #define FFI_TYPE_POINTER    14
    308 
    309 /* This should always refer to the last type code (for sanity checks) */
    310 #define FFI_TYPE_LAST       FFI_TYPE_POINTER
    311 
    312 #ifdef __cplusplus
    313 }
    314 #endif
    315 
    316 #endif
    317 
    318