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