1 : /* -----------------------------------------------------------------*-C-*-
2 : libffi 3.0.10rc0 - Copyright (c) 1996-2003, 2007, 2008 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,
16 : EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 : MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 : NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 : HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 : WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 : DEALINGS IN THE SOFTWARE.
23 :
24 : ----------------------------------------------------------------------- */
25 :
26 : /* -------------------------------------------------------------------
27 : The basic API is described in the README file.
28 :
29 : The raw API is designed to bypass some of the argument packing
30 : and unpacking on architectures for which it can be avoided.
31 :
32 : The closure API allows interpreted functions to be packaged up
33 : inside a C function pointer, so that they can be called as C functions,
34 : with no understanding on the client side that they are interpreted.
35 : It can also be used in other cases in which it is necessary to package
36 : up a user specified parameter and a function pointer as a single
37 : function pointer.
38 :
39 : The closure API must be implemented in order to get its functionality,
40 : e.g. for use by gij. Routines are provided to emulate the raw API
41 : if the underlying platform doesn't allow faster implementation.
42 :
43 : More details on the raw and cloure API can be found in:
44 :
45 : http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
46 :
47 : and
48 :
49 : http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
50 : -------------------------------------------------------------------- */
51 :
52 : #ifndef LIBFFI_H
53 : #define LIBFFI_H
54 :
55 : #ifdef __cplusplus
56 : extern "C" {
57 : #endif
58 :
59 : /* Specify which architecture libffi is configured for. */
60 : #ifndef X86
61 : #define X86
62 : #endif
63 :
64 : /* ---- System configuration information --------------------------------- */
65 :
66 : #include <ffitarget.h>
67 :
68 : #ifndef LIBFFI_ASM
69 :
70 : #ifdef _MSC_VER
71 : #define __attribute__(X)
72 : #endif
73 :
74 : #include <stddef.h>
75 : #include <limits.h>
76 :
77 : /* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
78 : But we can find it either under the correct ANSI name, or under GNU
79 : C's internal name. */
80 :
81 : #define FFI_64_BIT_MAX 9223372036854775807
82 :
83 : #ifdef LONG_LONG_MAX
84 : # define FFI_LONG_LONG_MAX LONG_LONG_MAX
85 : #else
86 : # ifdef LLONG_MAX
87 : # define FFI_LONG_LONG_MAX LLONG_MAX
88 : # else
89 : # ifdef __GNUC__
90 : # define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
91 : # endif
92 : # ifdef _AIX
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 :
107 : typedef struct _ffi_type
108 13 : {
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 : /* These are defined in types.c */
165 : extern ffi_type ffi_type_void;
166 : extern ffi_type ffi_type_uint8;
167 : extern ffi_type ffi_type_sint8;
168 : extern ffi_type ffi_type_uint16;
169 : extern ffi_type ffi_type_sint16;
170 : extern ffi_type ffi_type_uint32;
171 : extern ffi_type ffi_type_sint32;
172 : extern ffi_type ffi_type_uint64;
173 : extern ffi_type ffi_type_sint64;
174 : extern ffi_type ffi_type_float;
175 : extern ffi_type ffi_type_double;
176 : extern ffi_type ffi_type_pointer;
177 :
178 : #if 1
179 : extern ffi_type ffi_type_longdouble;
180 : #else
181 : #define ffi_type_longdouble ffi_type_double
182 : #endif
183 : #endif /* LIBFFI_HIDE_BASIC_TYPES */
184 :
185 : typedef enum {
186 : FFI_OK = 0,
187 : FFI_BAD_TYPEDEF,
188 : FFI_BAD_ABI
189 : } ffi_status;
190 :
191 : typedef unsigned FFI_TYPE;
192 :
193 : typedef struct {
194 : ffi_abi abi;
195 : unsigned nargs;
196 : ffi_type **arg_types;
197 : ffi_type *rtype;
198 : unsigned bytes;
199 : unsigned flags;
200 : #ifdef FFI_EXTRA_CIF_FIELDS
201 : FFI_EXTRA_CIF_FIELDS;
202 : #endif
203 : } ffi_cif;
204 :
205 : /* ---- Definitions for the raw API -------------------------------------- */
206 :
207 : #ifndef FFI_SIZEOF_ARG
208 : # if LONG_MAX == 2147483647
209 : # define FFI_SIZEOF_ARG 4
210 : # elif LONG_MAX == FFI_64_BIT_MAX
211 : # define FFI_SIZEOF_ARG 8
212 : # endif
213 : #endif
214 :
215 : #ifndef FFI_SIZEOF_JAVA_RAW
216 : # define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
217 : #endif
218 :
219 : typedef union {
220 : ffi_sarg sint;
221 : ffi_arg uint;
222 : float flt;
223 : char data[FFI_SIZEOF_ARG];
224 : void* ptr;
225 : } ffi_raw;
226 :
227 : #if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
228 : /* This is a special case for mips64/n32 ABI (and perhaps others) where
229 : sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
230 : typedef union {
231 : signed int sint;
232 : unsigned int uint;
233 : float flt;
234 : char data[FFI_SIZEOF_JAVA_RAW];
235 : void* ptr;
236 : } ffi_java_raw;
237 : #else
238 : typedef ffi_raw ffi_java_raw;
239 : #endif
240 :
241 :
242 : void ffi_raw_call (ffi_cif *cif,
243 : void (*fn)(void),
244 : void *rvalue,
245 : ffi_raw *avalue);
246 :
247 : void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
248 : void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
249 : size_t ffi_raw_size (ffi_cif *cif);
250 :
251 : /* This is analogous to the raw API, except it uses Java parameter */
252 : /* packing, even on 64-bit machines. I.e. on 64-bit machines */
253 : /* longs and doubles are followed by an empty 64-bit word. */
254 :
255 : void ffi_java_raw_call (ffi_cif *cif,
256 : void (*fn)(void),
257 : void *rvalue,
258 : ffi_java_raw *avalue);
259 :
260 : void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
261 : void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
262 : size_t ffi_java_raw_size (ffi_cif *cif);
263 :
264 : /* ---- Definitions for closures ----------------------------------------- */
265 :
266 : #if FFI_CLOSURES
267 :
268 : #ifdef _MSC_VER
269 : __declspec(align(8))
270 : #endif
271 : typedef struct {
272 : char tramp[FFI_TRAMPOLINE_SIZE];
273 : ffi_cif *cif;
274 : void (*fun)(ffi_cif*,void*,void**,void*);
275 : void *user_data;
276 : #ifdef __GNUC__
277 : } ffi_closure __attribute__((aligned (8)));
278 : #else
279 : } ffi_closure;
280 : #endif
281 :
282 : void *ffi_closure_alloc (size_t size, void **code);
283 : void ffi_closure_free (void *);
284 :
285 : ffi_status
286 : ffi_prep_closure (ffi_closure*,
287 : ffi_cif *,
288 : void (*fun)(ffi_cif*,void*,void**,void*),
289 : void *user_data);
290 :
291 : ffi_status
292 : ffi_prep_closure_loc (ffi_closure*,
293 : ffi_cif *,
294 : void (*fun)(ffi_cif*,void*,void**,void*),
295 : void *user_data,
296 : void*codeloc);
297 :
298 : typedef struct {
299 : char tramp[FFI_TRAMPOLINE_SIZE];
300 :
301 : ffi_cif *cif;
302 :
303 : #if !FFI_NATIVE_RAW_API
304 :
305 : /* if this is enabled, then a raw closure has the same layout
306 : as a regular closure. We use this to install an intermediate
307 : handler to do the transaltion, void** -> ffi_raw*. */
308 :
309 : void (*translate_args)(ffi_cif*,void*,void**,void*);
310 : void *this_closure;
311 :
312 : #endif
313 :
314 : void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
315 : void *user_data;
316 :
317 : } ffi_raw_closure;
318 :
319 : typedef struct {
320 : char tramp[FFI_TRAMPOLINE_SIZE];
321 :
322 : ffi_cif *cif;
323 :
324 : #if !FFI_NATIVE_RAW_API
325 :
326 : /* if this is enabled, then a raw closure has the same layout
327 : as a regular closure. We use this to install an intermediate
328 : handler to do the transaltion, void** -> ffi_raw*. */
329 :
330 : void (*translate_args)(ffi_cif*,void*,void**,void*);
331 : void *this_closure;
332 :
333 : #endif
334 :
335 : void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
336 : void *user_data;
337 :
338 : } ffi_java_raw_closure;
339 :
340 : ffi_status
341 : ffi_prep_raw_closure (ffi_raw_closure*,
342 : ffi_cif *cif,
343 : void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
344 : void *user_data);
345 :
346 : ffi_status
347 : ffi_prep_raw_closure_loc (ffi_raw_closure*,
348 : ffi_cif *cif,
349 : void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
350 : void *user_data,
351 : void *codeloc);
352 :
353 : ffi_status
354 : ffi_prep_java_raw_closure (ffi_java_raw_closure*,
355 : ffi_cif *cif,
356 : void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
357 : void *user_data);
358 :
359 : ffi_status
360 : ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
361 : ffi_cif *cif,
362 : void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
363 : void *user_data,
364 : void *codeloc);
365 :
366 : #endif /* FFI_CLOSURES */
367 :
368 : /* ---- Public interface definition -------------------------------------- */
369 :
370 : ffi_status ffi_prep_cif(ffi_cif *cif,
371 : ffi_abi abi,
372 : unsigned int nargs,
373 : ffi_type *rtype,
374 : ffi_type **atypes);
375 :
376 : void ffi_call(ffi_cif *cif,
377 : void (*fn)(void),
378 : void *rvalue,
379 : void **avalue);
380 :
381 : /* Useful for eliminating compiler warnings */
382 : #define FFI_FN(f) ((void (*)(void))f)
383 :
384 : /* ---- Definitions shared with assembly code ---------------------------- */
385 :
386 : #endif
387 :
388 : /* If these change, update src/mips/ffitarget.h. */
389 : #define FFI_TYPE_VOID 0
390 : #define FFI_TYPE_INT 1
391 : #define FFI_TYPE_FLOAT 2
392 : #define FFI_TYPE_DOUBLE 3
393 : #if 1
394 : #define FFI_TYPE_LONGDOUBLE 4
395 : #else
396 : #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
397 : #endif
398 : #define FFI_TYPE_UINT8 5
399 : #define FFI_TYPE_SINT8 6
400 : #define FFI_TYPE_UINT16 7
401 : #define FFI_TYPE_SINT16 8
402 : #define FFI_TYPE_UINT32 9
403 : #define FFI_TYPE_SINT32 10
404 : #define FFI_TYPE_UINT64 11
405 : #define FFI_TYPE_SINT64 12
406 : #define FFI_TYPE_STRUCT 13
407 : #define FFI_TYPE_POINTER 14
408 :
409 : /* This should always refer to the last type code (for sanity checks) */
410 : #define FFI_TYPE_LAST FFI_TYPE_POINTER
411 :
412 : #ifdef __cplusplus
413 : }
414 : #endif
415 :
416 : #endif
|