libffi (3.4.4)

(root)/
include/
ffi.h
       1  /* -----------------------------------------------------------------*-C-*-
       2     libffi 3.4.4
       3       - Copyright (c) 2011, 2014, 2019, 2021, 2022 Anthony Green
       4       - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
       5  
       6     Permission is hereby granted, free of charge, to any person
       7     obtaining a copy of this software and associated documentation
       8     files (the ``Software''), to deal in the Software without
       9     restriction, including without limitation the rights to use, copy,
      10     modify, merge, publish, distribute, sublicense, and/or sell copies
      11     of the Software, and to permit persons to whom the Software is
      12     furnished to do so, subject to the following conditions:
      13  
      14     The above copyright notice and this permission notice shall be
      15     included in all copies or substantial portions of the Software.
      16  
      17     THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
      18     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      19     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      20     NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      21     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
      22     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      23     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      24     DEALINGS IN THE SOFTWARE.
      25  
      26     ----------------------------------------------------------------------- */
      27  
      28  /* -------------------------------------------------------------------
      29     Most of the API is documented in doc/libffi.texi.
      30  
      31     The raw API is designed to bypass some of the argument packing and
      32     unpacking on architectures for which it can be avoided.  Routines
      33     are provided to emulate the raw API if the underlying platform
      34     doesn't allow faster implementation.
      35  
      36     More details on the raw API can be found in:
      37  
      38     http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
      39  
      40     and
      41  
      42     http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
      43     -------------------------------------------------------------------- */
      44  
      45  #ifndef LIBFFI_H
      46  #define LIBFFI_H
      47  
      48  #ifdef __cplusplus
      49  extern "C" {
      50  #endif
      51  
      52  /* Specify which architecture libffi is configured for. */
      53  #ifndef X86_64
      54  #define X86_64
      55  #endif
      56  
      57  /* ---- System configuration information --------------------------------- */
      58  
      59  /* If these change, update src/mips/ffitarget.h. */
      60  #define FFI_TYPE_VOID       0
      61  #define FFI_TYPE_INT        1
      62  #define FFI_TYPE_FLOAT      2
      63  #define FFI_TYPE_DOUBLE     3
      64  #if 1
      65  #define FFI_TYPE_LONGDOUBLE 4
      66  #else
      67  #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
      68  #endif
      69  #define FFI_TYPE_UINT8      5
      70  #define FFI_TYPE_SINT8      6
      71  #define FFI_TYPE_UINT16     7
      72  #define FFI_TYPE_SINT16     8
      73  #define FFI_TYPE_UINT32     9
      74  #define FFI_TYPE_SINT32     10
      75  #define FFI_TYPE_UINT64     11
      76  #define FFI_TYPE_SINT64     12
      77  #define FFI_TYPE_STRUCT     13
      78  #define FFI_TYPE_POINTER    14
      79  #define FFI_TYPE_COMPLEX    15
      80  
      81  /* This should always refer to the last type code (for sanity checks).  */
      82  #define FFI_TYPE_LAST       FFI_TYPE_COMPLEX
      83  
      84  #include <ffitarget.h>
      85  
      86  #ifndef LIBFFI_ASM
      87  
      88  #if defined(_MSC_VER) && !defined(__clang__)
      89  #define __attribute__(X)
      90  #endif
      91  
      92  #include <stddef.h>
      93  #include <limits.h>
      94  
      95  /* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
      96     But we can find it either under the correct ANSI name, or under GNU
      97     C's internal name.  */
      98  
      99  #define FFI_64_BIT_MAX 9223372036854775807
     100  
     101  #ifdef LONG_LONG_MAX
     102  # define FFI_LONG_LONG_MAX LONG_LONG_MAX
     103  #else
     104  # ifdef LLONG_MAX
     105  #  define FFI_LONG_LONG_MAX LLONG_MAX
     106  #  ifdef _AIX52 /* or newer has C99 LLONG_MAX */
     107  #   undef FFI_64_BIT_MAX
     108  #   define FFI_64_BIT_MAX 9223372036854775807LL
     109  #  endif /* _AIX52 or newer */
     110  # else
     111  #  ifdef __GNUC__
     112  #   define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
     113  #  endif
     114  #  ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
     115  #   ifndef __PPC64__
     116  #    if defined (__IBMC__) || defined (__IBMCPP__)
     117  #     define FFI_LONG_LONG_MAX LONGLONG_MAX
     118  #    endif
     119  #   endif /* __PPC64__ */
     120  #   undef  FFI_64_BIT_MAX
     121  #   define FFI_64_BIT_MAX 9223372036854775807LL
     122  #  endif
     123  # endif
     124  #endif
     125  
     126  /* The closure code assumes that this works on pointers, i.e. a size_t
     127     can hold a pointer.  */
     128  
     129  typedef struct _ffi_type
     130  {
     131    size_t size;
     132    unsigned short alignment;
     133    unsigned short type;
     134    struct _ffi_type **elements;
     135  } ffi_type;
     136  
     137  /* Need minimal decorations for DLLs to work on Windows.  GCC has
     138     autoimport and autoexport.  Always mark externally visible symbols
     139     as dllimport for MSVC clients, even if it means an extra indirection
     140     when using the static version of the library.
     141     Besides, as a workaround, they can define FFI_BUILDING if they
     142     *know* they are going to link with the static library.  */
     143  #if defined _MSC_VER
     144  # if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
     145  #  define FFI_API __declspec(dllexport)
     146  # elif !defined FFI_BUILDING  /* Importing libffi.DLL */
     147  #  define FFI_API __declspec(dllimport)
     148  # else                        /* Building/linking static library */
     149  #  define FFI_API
     150  # endif
     151  #else
     152  # define FFI_API
     153  #endif
     154  
     155  /* The externally visible type declarations also need the MSVC DLL
     156     decorations, or they will not be exported from the object file.  */
     157  #if defined LIBFFI_HIDE_BASIC_TYPES
     158  # define FFI_EXTERN FFI_API
     159  #else
     160  # define FFI_EXTERN extern FFI_API
     161  #endif
     162  
     163  #ifndef LIBFFI_HIDE_BASIC_TYPES
     164  #if SCHAR_MAX == 127
     165  # define ffi_type_uchar                ffi_type_uint8
     166  # define ffi_type_schar                ffi_type_sint8
     167  #else
     168   #error "char size not supported"
     169  #endif
     170  
     171  #if SHRT_MAX == 32767
     172  # define ffi_type_ushort       ffi_type_uint16
     173  # define ffi_type_sshort       ffi_type_sint16
     174  #elif SHRT_MAX == 2147483647
     175  # define ffi_type_ushort       ffi_type_uint32
     176  # define ffi_type_sshort       ffi_type_sint32
     177  #else
     178   #error "short size not supported"
     179  #endif
     180  
     181  #if INT_MAX == 32767
     182  # define ffi_type_uint         ffi_type_uint16
     183  # define ffi_type_sint         ffi_type_sint16
     184  #elif INT_MAX == 2147483647
     185  # define ffi_type_uint         ffi_type_uint32
     186  # define ffi_type_sint         ffi_type_sint32
     187  #elif INT_MAX == 9223372036854775807
     188  # define ffi_type_uint         ffi_type_uint64
     189  # define ffi_type_sint         ffi_type_sint64
     190  #else
     191   #error "int size not supported"
     192  #endif
     193  
     194  #if LONG_MAX == 2147483647
     195  # if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
     196   #error "no 64-bit data type supported"
     197  # endif
     198  #elif LONG_MAX != FFI_64_BIT_MAX
     199   #error "long size not supported"
     200  #endif
     201  
     202  #if LONG_MAX == 2147483647
     203  # define ffi_type_ulong        ffi_type_uint32
     204  # define ffi_type_slong        ffi_type_sint32
     205  #elif LONG_MAX == FFI_64_BIT_MAX
     206  # define ffi_type_ulong        ffi_type_uint64
     207  # define ffi_type_slong        ffi_type_sint64
     208  #else
     209   #error "long size not supported"
     210  #endif
     211  
     212  /* These are defined in types.c.  */
     213  FFI_EXTERN ffi_type ffi_type_void;
     214  FFI_EXTERN ffi_type ffi_type_uint8;
     215  FFI_EXTERN ffi_type ffi_type_sint8;
     216  FFI_EXTERN ffi_type ffi_type_uint16;
     217  FFI_EXTERN ffi_type ffi_type_sint16;
     218  FFI_EXTERN ffi_type ffi_type_uint32;
     219  FFI_EXTERN ffi_type ffi_type_sint32;
     220  FFI_EXTERN ffi_type ffi_type_uint64;
     221  FFI_EXTERN ffi_type ffi_type_sint64;
     222  FFI_EXTERN ffi_type ffi_type_float;
     223  FFI_EXTERN ffi_type ffi_type_double;
     224  FFI_EXTERN ffi_type ffi_type_pointer;
     225  
     226  #if 1
     227  FFI_EXTERN ffi_type ffi_type_longdouble;
     228  #else
     229  #define ffi_type_longdouble ffi_type_double
     230  #endif
     231  
     232  #ifdef FFI_TARGET_HAS_COMPLEX_TYPE
     233  FFI_EXTERN ffi_type ffi_type_complex_float;
     234  FFI_EXTERN ffi_type ffi_type_complex_double;
     235  #if 1
     236  FFI_EXTERN ffi_type ffi_type_complex_longdouble;
     237  #else
     238  #define ffi_type_complex_longdouble ffi_type_complex_double
     239  #endif
     240  #endif
     241  #endif /* LIBFFI_HIDE_BASIC_TYPES */
     242  
     243  typedef enum {
     244    FFI_OK = 0,
     245    FFI_BAD_TYPEDEF,
     246    FFI_BAD_ABI,
     247    FFI_BAD_ARGTYPE
     248  } ffi_status;
     249  
     250  typedef struct {
     251    ffi_abi abi;
     252    unsigned nargs;
     253    ffi_type **arg_types;
     254    ffi_type *rtype;
     255    unsigned bytes;
     256    unsigned flags;
     257  #ifdef FFI_EXTRA_CIF_FIELDS
     258    FFI_EXTRA_CIF_FIELDS;
     259  #endif
     260  } ffi_cif;
     261  
     262  /* ---- Definitions for the raw API -------------------------------------- */
     263  
     264  #ifndef FFI_SIZEOF_ARG
     265  # if LONG_MAX == 2147483647
     266  #  define FFI_SIZEOF_ARG        4
     267  # elif LONG_MAX == FFI_64_BIT_MAX
     268  #  define FFI_SIZEOF_ARG        8
     269  # endif
     270  #endif
     271  
     272  #ifndef FFI_SIZEOF_JAVA_RAW
     273  #  define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
     274  #endif
     275  
     276  typedef union {
     277    ffi_sarg  sint;
     278    ffi_arg   uint;
     279    float	    flt;
     280    char      data[FFI_SIZEOF_ARG];
     281    void*     ptr;
     282  } ffi_raw;
     283  
     284  #if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
     285  /* This is a special case for mips64/n32 ABI (and perhaps others) where
     286     sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8.  */
     287  typedef union {
     288    signed int	sint;
     289    unsigned int	uint;
     290    float		flt;
     291    char		data[FFI_SIZEOF_JAVA_RAW];
     292    void*		ptr;
     293  } ffi_java_raw;
     294  #else
     295  typedef ffi_raw ffi_java_raw;
     296  #endif
     297  
     298  
     299  FFI_API
     300  void ffi_raw_call (ffi_cif *cif,
     301  		   void (*fn)(void),
     302  		   void *rvalue,
     303  		   ffi_raw *avalue);
     304  
     305  FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
     306  FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
     307  FFI_API size_t ffi_raw_size (ffi_cif *cif);
     308  
     309  /* This is analogous to the raw API, except it uses Java parameter
     310     packing, even on 64-bit machines.  I.e. on 64-bit machines longs
     311     and doubles are followed by an empty 64-bit word.  */
     312  
     313  #if !FFI_NATIVE_RAW_API
     314  FFI_API
     315  void ffi_java_raw_call (ffi_cif *cif,
     316  			void (*fn)(void),
     317  			void *rvalue,
     318  			ffi_java_raw *avalue) __attribute__((deprecated));
     319  #endif
     320  
     321  FFI_API
     322  void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated));
     323  FFI_API
     324  void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __attribute__((deprecated));
     325  FFI_API
     326  size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated));
     327  
     328  /* ---- Definitions for closures ----------------------------------------- */
     329  
     330  #if FFI_CLOSURES
     331  
     332  #ifdef _MSC_VER
     333  __declspec(align(8))
     334  #endif
     335  typedef struct {
     336  #if 0
     337    void *trampoline_table;
     338    void *trampoline_table_entry;
     339  #else
     340    union {
     341      char tramp[FFI_TRAMPOLINE_SIZE];
     342      void *ftramp;
     343    };
     344  #endif
     345    ffi_cif   *cif;
     346    void     (*fun)(ffi_cif*,void*,void**,void*);
     347    void      *user_data;
     348  #if defined(_MSC_VER) && defined(_M_IX86)
     349    void      *padding;
     350  #endif
     351  } ffi_closure
     352  #ifdef __GNUC__
     353      __attribute__((aligned (8)))
     354  #endif
     355      ;
     356  
     357  #ifndef __GNUC__
     358  # ifdef __sgi
     359  #  pragma pack 0
     360  # endif
     361  #endif
     362  
     363  FFI_API void *ffi_closure_alloc (size_t size, void **code);
     364  FFI_API void ffi_closure_free (void *);
     365  
     366  #if defined(PA_LINUX) || defined(PA_HPUX)
     367  #define FFI_CLOSURE_PTR(X) ((void *)((unsigned int)(X) | 2))
     368  #define FFI_RESTORE_PTR(X) ((void *)((unsigned int)(X) & ~3))
     369  #else
     370  #define FFI_CLOSURE_PTR(X) (X)
     371  #define FFI_RESTORE_PTR(X) (X)
     372  #endif
     373  
     374  FFI_API ffi_status
     375  ffi_prep_closure (ffi_closure*,
     376  		  ffi_cif *,
     377  		  void (*fun)(ffi_cif*,void*,void**,void*),
     378  		  void *user_data)
     379  #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
     380    __attribute__((deprecated ("use ffi_prep_closure_loc instead")))
     381  #elif defined(__GNUC__) && __GNUC__ >= 3
     382    __attribute__((deprecated))
     383  #endif
     384    ;
     385  
     386  FFI_API ffi_status
     387  ffi_prep_closure_loc (ffi_closure*,
     388  		      ffi_cif *,
     389  		      void (*fun)(ffi_cif*,void*,void**,void*),
     390  		      void *user_data,
     391  		      void *codeloc);
     392  
     393  #ifdef __sgi
     394  # pragma pack 8
     395  #endif
     396  typedef struct {
     397  #if 0
     398    void *trampoline_table;
     399    void *trampoline_table_entry;
     400  #else
     401    char tramp[FFI_TRAMPOLINE_SIZE];
     402  #endif
     403    ffi_cif   *cif;
     404  
     405  #if !FFI_NATIVE_RAW_API
     406  
     407    /* If this is enabled, then a raw closure has the same layout
     408       as a regular closure.  We use this to install an intermediate
     409       handler to do the translation, void** -> ffi_raw*.  */
     410  
     411    void     (*translate_args)(ffi_cif*,void*,void**,void*);
     412    void      *this_closure;
     413  
     414  #endif
     415  
     416    void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
     417    void      *user_data;
     418  
     419  } ffi_raw_closure;
     420  
     421  typedef struct {
     422  #if 0
     423    void *trampoline_table;
     424    void *trampoline_table_entry;
     425  #else
     426    char tramp[FFI_TRAMPOLINE_SIZE];
     427  #endif
     428  
     429    ffi_cif   *cif;
     430  
     431  #if !FFI_NATIVE_RAW_API
     432  
     433    /* If this is enabled, then a raw closure has the same layout
     434       as a regular closure.  We use this to install an intermediate
     435       handler to do the translation, void** -> ffi_raw*.  */
     436  
     437    void     (*translate_args)(ffi_cif*,void*,void**,void*);
     438    void      *this_closure;
     439  
     440  #endif
     441  
     442    void     (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
     443    void      *user_data;
     444  
     445  } ffi_java_raw_closure;
     446  
     447  FFI_API ffi_status
     448  ffi_prep_raw_closure (ffi_raw_closure*,
     449  		      ffi_cif *cif,
     450  		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
     451  		      void *user_data);
     452  
     453  FFI_API ffi_status
     454  ffi_prep_raw_closure_loc (ffi_raw_closure*,
     455  			  ffi_cif *cif,
     456  			  void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
     457  			  void *user_data,
     458  			  void *codeloc);
     459  
     460  #if !FFI_NATIVE_RAW_API
     461  FFI_API ffi_status
     462  ffi_prep_java_raw_closure (ffi_java_raw_closure*,
     463  		           ffi_cif *cif,
     464  		           void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
     465  		           void *user_data) __attribute__((deprecated));
     466  
     467  FFI_API ffi_status
     468  ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
     469  			       ffi_cif *cif,
     470  			       void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
     471  			       void *user_data,
     472  			       void *codeloc) __attribute__((deprecated));
     473  #endif
     474  
     475  #endif /* FFI_CLOSURES */
     476  
     477  #if FFI_GO_CLOSURES
     478  
     479  typedef struct {
     480    void      *tramp;
     481    ffi_cif   *cif;
     482    void     (*fun)(ffi_cif*,void*,void**,void*);
     483  } ffi_go_closure;
     484  
     485  FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
     486  				void (*fun)(ffi_cif*,void*,void**,void*));
     487  
     488  FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
     489  		  void **avalue, void *closure);
     490  
     491  #endif /* FFI_GO_CLOSURES */
     492  
     493  /* ---- Public interface definition -------------------------------------- */
     494  
     495  FFI_API
     496  ffi_status ffi_prep_cif(ffi_cif *cif,
     497  			ffi_abi abi,
     498  			unsigned int nargs,
     499  			ffi_type *rtype,
     500  			ffi_type **atypes);
     501  
     502  FFI_API
     503  ffi_status ffi_prep_cif_var(ffi_cif *cif,
     504  			    ffi_abi abi,
     505  			    unsigned int nfixedargs,
     506  			    unsigned int ntotalargs,
     507  			    ffi_type *rtype,
     508  			    ffi_type **atypes);
     509  
     510  FFI_API
     511  void ffi_call(ffi_cif *cif,
     512  	      void (*fn)(void),
     513  	      void *rvalue,
     514  	      void **avalue);
     515  
     516  FFI_API
     517  ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
     518  				   size_t *offsets);
     519  
     520  /* Useful for eliminating compiler warnings.  */
     521  #define FFI_FN(f) ((void (*)(void))f)
     522  
     523  /* ---- Definitions shared with assembly code ---------------------------- */
     524  
     525  #endif
     526  
     527  #ifdef __cplusplus
     528  }
     529  #endif
     530  
     531  #endif