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