source: trunk/gcc/libffi/src/java_raw_api.c

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 7.8 KB
Line 
1/* -----------------------------------------------------------------------
2 java_raw_api.c - Copyright (c) 1999 Cygnus Solutions
3
4 Cloned from raw_api.c
5
6 Raw_api.c author: Kresten Krab Thorup <krab@gnu.org>
7 Java_raw_api.c author: Hans-J. Boehm <hboehm@hpl.hp.com>
8
9 $Id $
10
11 Permission is hereby granted, free of charge, to any person obtaining
12 a copy of this software and associated documentation files (the
13 ``Software''), to deal in the Software without restriction, including
14 without limitation the rights to use, copy, modify, merge, publish,
15 distribute, sublicense, and/or sell copies of the Software, and to
16 permit persons to whom the Software is furnished to do so, subject to
17 the following conditions:
18
19 The above copyright notice and this permission notice shall be included
20 in all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 OTHER DEALINGS IN THE SOFTWARE.
29 ----------------------------------------------------------------------- */
30
31/* This defines a Java- and 64-bit specific variant of the raw API. */
32/* It assumes that "raw" argument blocks look like Java stacks on a */
33/* 64-bit machine. Arguments that can be stored in a single stack */
34/* stack slots (longs, doubles) occupy 128 bits, but only the first */
35/* 64 bits are actually used. */
36
37#include <ffi.h>
38#include <ffi_common.h>
39
40#if !defined(NO_JAVA_RAW_API) && !defined(FFI_NO_RAW_API)
41
42size_t
43ffi_java_raw_size (ffi_cif *cif)
44{
45 size_t result = 0;
46 int i;
47
48 ffi_type **at = cif->arg_types;
49
50 for (i = cif->nargs-1; i >= 0; i--, at++)
51 {
52 switch((*at) -> type) {
53 case FFI_TYPE_UINT64:
54 case FFI_TYPE_SINT64:
55 case FFI_TYPE_DOUBLE:
56 result += 2 * SIZEOF_ARG;
57 break;
58 case FFI_TYPE_STRUCT:
59 /* No structure parameters in Java. */
60 abort();
61 default:
62 result += SIZEOF_ARG;
63 }
64 }
65
66 return result;
67}
68
69
70void
71ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
72{
73 unsigned i;
74 ffi_type **tp = cif->arg_types;
75
76#if WORDS_BIGENDIAN
77
78 for (i = 0; i < cif->nargs; i++, tp++, args++)
79 {
80 switch ((*tp)->type)
81 {
82 case FFI_TYPE_UINT8:
83 case FFI_TYPE_SINT8:
84 *args = (void*) ((char*)(raw++) + 3);
85 break;
86
87 case FFI_TYPE_UINT16:
88 case FFI_TYPE_SINT16:
89 *args = (void*) ((char*)(raw++) + 2);
90 break;
91
92#if SIZEOF_ARG == 8
93 case FFI_TYPE_UINT64:
94 case FFI_TYPE_SINT64:
95 case FFI_TYPE_DOUBLE:
96 *args = (void *)raw;
97 raw += 2;
98 break;
99#endif
100
101 case FFI_TYPE_POINTER:
102 *args = (void*) &(raw++)->ptr;
103 break;
104
105 default:
106 *args = raw;
107 raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG;
108 }
109 }
110
111#else /* WORDS_BIGENDIAN */
112
113#if !PDP
114
115 /* then assume little endian */
116 for (i = 0; i < cif->nargs; i++, tp++, args++)
117 {
118#if SIZEOF_ARG == 8
119 switch((*tp)->type) {
120 case FFI_TYPE_UINT64:
121 case FFI_TYPE_SINT64:
122 case FFI_TYPE_DOUBLE:
123 *args = (void*) raw;
124 raw += 2;
125 break;
126 default:
127 *args = (void*) raw++;
128 }
129#else /* SIZEOF_ARG != 8 */
130 *args = (void*) raw;
131 raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
132#endif /* SIZEOF_ARG == 8 */
133 }
134
135#else
136#error "pdp endian not supported"
137#endif /* ! PDP */
138
139#endif /* WORDS_BIGENDIAN */
140}
141
142void
143ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
144{
145 unsigned i;
146 ffi_type **tp = cif->arg_types;
147
148 for (i = 0; i < cif->nargs; i++, tp++, args++)
149 {
150 switch ((*tp)->type)
151 {
152 case FFI_TYPE_UINT8:
153#if WORDS_BIGENDIAN
154 *(UINT32*)(raw++) = *(UINT8*) (*args);
155#else
156 (raw++)->uint = *(UINT8*) (*args);
157#endif
158 break;
159
160 case FFI_TYPE_SINT8:
161#if WORDS_BIGENDIAN
162 *(SINT32*)(raw++) = *(SINT8*) (*args);
163#else
164 (raw++)->sint = *(SINT8*) (*args);
165#endif
166 break;
167
168 case FFI_TYPE_UINT16:
169#if WORDS_BIGENDIAN
170 *(UINT32*)(raw++) = *(UINT16*) (*args);
171#else
172 (raw++)->uint = *(UINT16*) (*args);
173#endif
174 break;
175
176 case FFI_TYPE_SINT16:
177#if WORDS_BIGENDIAN
178 *(SINT32*)(raw++) = *(SINT16*) (*args);
179#else
180 (raw++)->sint = *(SINT16*) (*args);
181#endif
182 break;
183
184 case FFI_TYPE_UINT32:
185#if WORDS_BIGENDIAN
186 *(UINT32*)(raw++) = *(UINT32*) (*args);
187#else
188 (raw++)->uint = *(UINT32*) (*args);
189#endif
190 break;
191
192 case FFI_TYPE_SINT32:
193#if WORDS_BIGENDIAN
194 *(SINT32*)(raw++) = *(SINT32*) (*args);
195#else
196 (raw++)->sint = *(SINT32*) (*args);
197#endif
198 break;
199
200 case FFI_TYPE_FLOAT:
201 (raw++)->flt = *(FLOAT32*) (*args);
202 break;
203
204#if SIZEOF_ARG == 8
205 case FFI_TYPE_UINT64:
206 case FFI_TYPE_SINT64:
207 case FFI_TYPE_DOUBLE:
208 raw->uint = *(UINT64*) (*args);
209 raw += 2;
210 break;
211#endif
212
213 case FFI_TYPE_POINTER:
214 (raw++)->ptr = **(void***) args;
215 break;
216
217 default:
218#if SIZEOF_ARG == 8
219 FFI_ASSERT(FALSE); /* Should have covered all cases */
220#else
221 memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
222 raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG;
223#endif
224 }
225 }
226}
227
228#if !FFI_NATIVE_RAW_API
229
230static void
231ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
232{
233#if WORDS_BIGENDIAN && SIZEOF_ARG == 8
234 switch (cif->rtype->type)
235 {
236 case FFI_TYPE_UINT8:
237 case FFI_TYPE_UINT16:
238 case FFI_TYPE_UINT32:
239 *(UINT64 *)rvalue <<= 32;
240 break;
241
242 case FFI_TYPE_SINT8:
243 case FFI_TYPE_SINT16:
244 case FFI_TYPE_SINT32:
245 case FFI_TYPE_INT:
246 *(SINT64 *)rvalue <<= 32;
247 break;
248
249 default:
250 break;
251 }
252#endif
253}
254
255static void
256ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
257{
258#if WORDS_BIGENDIAN && SIZEOF_ARG == 8
259 switch (cif->rtype->type)
260 {
261 case FFI_TYPE_UINT8:
262 case FFI_TYPE_UINT16:
263 case FFI_TYPE_UINT32:
264 *(UINT64 *)rvalue >>= 32;
265 break;
266
267 case FFI_TYPE_SINT8:
268 case FFI_TYPE_SINT16:
269 case FFI_TYPE_SINT32:
270 case FFI_TYPE_INT:
271 *(SINT64 *)rvalue >>= 32;
272 break;
273
274 default:
275 break;
276 }
277#endif
278}
279
280/* This is a generic definition of ffi_raw_call, to be used if the
281 * native system does not provide a machine-specific implementation.
282 * Having this, allows code to be written for the raw API, without
283 * the need for system-specific code to handle input in that format;
284 * these following couple of functions will handle the translation forth
285 * and back automatically. */
286
287void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
288 void (*fn)(),
289 /*@out@*/ void *rvalue,
290 /*@dependent@*/ ffi_raw *raw)
291{
292 void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
293 ffi_java_raw_to_ptrarray (cif, raw, avalue);
294 ffi_call (cif, fn, rvalue, avalue);
295 ffi_java_rvalue_to_raw (cif, rvalue);
296}
297
298#if FFI_CLOSURES /* base system provides closures */
299
300static void
301ffi_java_translate_args (ffi_cif *cif, void *rvalue,
302 void **avalue, void *user_data)
303{
304 ffi_raw *raw = (ffi_raw*)alloca (ffi_java_raw_size (cif));
305 ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
306
307 ffi_java_ptrarray_to_raw (cif, avalue, raw);
308 (*cl->fun) (cif, rvalue, raw, cl->user_data);
309 ffi_java_raw_to_rvalue (cif, rvalue);
310}
311
312/* Again, here is the generic version of ffi_prep_raw_closure, which
313 * will install an intermediate "hub" for translation of arguments from
314 * the pointer-array format, to the raw format */
315
316ffi_status
317ffi_prep_java_raw_closure (ffi_raw_closure* cl,
318 ffi_cif *cif,
319 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
320 void *user_data)
321{
322 ffi_status status;
323
324 status = ffi_prep_closure ((ffi_closure*) cl,
325 cif,
326 &ffi_java_translate_args,
327 (void*)cl);
328 if (status == FFI_OK)
329 {
330 cl->fun = fun;
331 cl->user_data = user_data;
332 }
333
334 return status;
335}
336
337#endif /* FFI_CLOSURES */
338#endif /* !FFI_NATIVE_RAW_API */
339#endif /* !FFI_NO_RAW_API */
Note: See TracBrowser for help on using the repository browser.