Ruby  2.4.2p198(2017-09-14revision59899)
java_raw_api.c
Go to the documentation of this file.
1 /* -----------------------------------------------------------------------
2  java_raw_api.c - Copyright (c) 1999, 2007, 2008 Red Hat, Inc.
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,
23  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29  DEALINGS IN THE SOFTWARE.
30  ----------------------------------------------------------------------- */
31 
32 /* This defines a Java- and 64-bit specific variant of the raw API. */
33 /* It assumes that "raw" argument blocks look like Java stacks on a */
34 /* 64-bit machine. Arguments that can be stored in a single stack */
35 /* stack slots (longs, doubles) occupy 128 bits, but only the first */
36 /* 64 bits are actually used. */
37 
38 #include <ffi.h>
39 #include <ffi_common.h>
40 #include <stdlib.h>
41 
42 #if !defined(NO_JAVA_RAW_API)
43 
44 size_t
45 ffi_java_raw_size (ffi_cif *cif)
46 {
47  size_t result = 0;
48  int i;
49 
50  ffi_type **at = cif->arg_types;
51 
52  for (i = cif->nargs-1; i >= 0; i--, at++)
53  {
54  switch((*at) -> type) {
55  case FFI_TYPE_UINT64:
56  case FFI_TYPE_SINT64:
57  case FFI_TYPE_DOUBLE:
58  result += 2 * FFI_SIZEOF_JAVA_RAW;
59  break;
60  case FFI_TYPE_STRUCT:
61  /* No structure parameters in Java. */
62  abort();
63  case FFI_TYPE_COMPLEX:
64  /* Not supported yet. */
65  abort();
66  default:
67  result += FFI_SIZEOF_JAVA_RAW;
68  }
69  }
70 
71  return result;
72 }
73 
74 
75 void
76 ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args)
77 {
78  unsigned i;
79  ffi_type **tp = cif->arg_types;
80 
81 #if WORDS_BIGENDIAN
82 
83  for (i = 0; i < cif->nargs; i++, tp++, args++)
84  {
85  switch ((*tp)->type)
86  {
87  case FFI_TYPE_UINT8:
88  case FFI_TYPE_SINT8:
89  *args = (void*) ((char*)(raw++) + 3);
90  break;
91 
92  case FFI_TYPE_UINT16:
93  case FFI_TYPE_SINT16:
94  *args = (void*) ((char*)(raw++) + 2);
95  break;
96 
97 #if FFI_SIZEOF_JAVA_RAW == 8
98  case FFI_TYPE_UINT64:
99  case FFI_TYPE_SINT64:
100  case FFI_TYPE_DOUBLE:
101  *args = (void *)raw;
102  raw += 2;
103  break;
104 #endif
105 
106  case FFI_TYPE_POINTER:
107  *args = (void*) &(raw++)->ptr;
108  break;
109 
110  case FFI_TYPE_COMPLEX:
111  /* Not supported yet. */
112  abort();
113 
114  default:
115  *args = raw;
116  raw +=
117  ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
118  }
119  }
120 
121 #else /* WORDS_BIGENDIAN */
122 
123 #if !PDP
124 
125  /* then assume little endian */
126  for (i = 0; i < cif->nargs; i++, tp++, args++)
127  {
128 #if FFI_SIZEOF_JAVA_RAW == 8
129  switch((*tp)->type) {
130  case FFI_TYPE_UINT64:
131  case FFI_TYPE_SINT64:
132  case FFI_TYPE_DOUBLE:
133  *args = (void*) raw;
134  raw += 2;
135  break;
136  case FFI_TYPE_COMPLEX:
137  /* Not supported yet. */
138  abort();
139  default:
140  *args = (void*) raw++;
141  }
142 #else /* FFI_SIZEOF_JAVA_RAW != 8 */
143  *args = (void*) raw;
144  raw +=
145  ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
146 #endif /* FFI_SIZEOF_JAVA_RAW == 8 */
147  }
148 
149 #else
150 #error "pdp endian not supported"
151 #endif /* ! PDP */
152 
153 #endif /* WORDS_BIGENDIAN */
154 }
155 
156 void
157 ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw)
158 {
159  unsigned i;
160  ffi_type **tp = cif->arg_types;
161 
162  for (i = 0; i < cif->nargs; i++, tp++, args++)
163  {
164  switch ((*tp)->type)
165  {
166  case FFI_TYPE_UINT8:
167 #if WORDS_BIGENDIAN
168  *(UINT32*)(raw++) = *(UINT8*) (*args);
169 #else
170  (raw++)->uint = *(UINT8*) (*args);
171 #endif
172  break;
173 
174  case FFI_TYPE_SINT8:
175 #if WORDS_BIGENDIAN
176  *(SINT32*)(raw++) = *(SINT8*) (*args);
177 #else
178  (raw++)->sint = *(SINT8*) (*args);
179 #endif
180  break;
181 
182  case FFI_TYPE_UINT16:
183 #if WORDS_BIGENDIAN
184  *(UINT32*)(raw++) = *(UINT16*) (*args);
185 #else
186  (raw++)->uint = *(UINT16*) (*args);
187 #endif
188  break;
189 
190  case FFI_TYPE_SINT16:
191 #if WORDS_BIGENDIAN
192  *(SINT32*)(raw++) = *(SINT16*) (*args);
193 #else
194  (raw++)->sint = *(SINT16*) (*args);
195 #endif
196  break;
197 
198  case FFI_TYPE_UINT32:
199 #if WORDS_BIGENDIAN
200  *(UINT32*)(raw++) = *(UINT32*) (*args);
201 #else
202  (raw++)->uint = *(UINT32*) (*args);
203 #endif
204  break;
205 
206  case FFI_TYPE_SINT32:
207 #if WORDS_BIGENDIAN
208  *(SINT32*)(raw++) = *(SINT32*) (*args);
209 #else
210  (raw++)->sint = *(SINT32*) (*args);
211 #endif
212  break;
213 
214  case FFI_TYPE_FLOAT:
215  (raw++)->flt = *(FLOAT32*) (*args);
216  break;
217 
218 #if FFI_SIZEOF_JAVA_RAW == 8
219  case FFI_TYPE_UINT64:
220  case FFI_TYPE_SINT64:
221  case FFI_TYPE_DOUBLE:
222  raw->uint = *(UINT64*) (*args);
223  raw += 2;
224  break;
225 #endif
226 
227  case FFI_TYPE_POINTER:
228  (raw++)->ptr = **(void***) args;
229  break;
230 
231  default:
232 #if FFI_SIZEOF_JAVA_RAW == 8
233  FFI_ASSERT(0); /* Should have covered all cases */
234 #else
235  memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
236  raw +=
237  ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
238 #endif
239  }
240  }
241 }
242 
243 #if !FFI_NATIVE_RAW_API
244 
245 static void
246 ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
247 {
248 #if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
249  switch (cif->rtype->type)
250  {
251  case FFI_TYPE_UINT8:
252  case FFI_TYPE_UINT16:
253  case FFI_TYPE_UINT32:
254  *(UINT64 *)rvalue <<= 32;
255  break;
256 
257  case FFI_TYPE_SINT8:
258  case FFI_TYPE_SINT16:
259  case FFI_TYPE_SINT32:
260  case FFI_TYPE_INT:
261 #if FFI_SIZEOF_JAVA_RAW == 4
262  case FFI_TYPE_POINTER:
263 #endif
264  *(SINT64 *)rvalue <<= 32;
265  break;
266 
267  case FFI_TYPE_COMPLEX:
268  /* Not supported yet. */
269  abort();
270 
271  default:
272  break;
273  }
274 #endif
275 }
276 
277 static void
278 ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
279 {
280 #if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
281  switch (cif->rtype->type)
282  {
283  case FFI_TYPE_UINT8:
284  case FFI_TYPE_UINT16:
285  case FFI_TYPE_UINT32:
286  *(UINT64 *)rvalue >>= 32;
287  break;
288 
289  case FFI_TYPE_SINT8:
290  case FFI_TYPE_SINT16:
291  case FFI_TYPE_SINT32:
292  case FFI_TYPE_INT:
293  *(SINT64 *)rvalue >>= 32;
294  break;
295 
296  case FFI_TYPE_COMPLEX:
297  /* Not supported yet. */
298  abort();
299 
300  default:
301  break;
302  }
303 #endif
304 }
305 
306 /* This is a generic definition of ffi_raw_call, to be used if the
307  * native system does not provide a machine-specific implementation.
308  * Having this, allows code to be written for the raw API, without
309  * the need for system-specific code to handle input in that format;
310  * these following couple of functions will handle the translation forth
311  * and back automatically. */
312 
313 void ffi_java_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue,
314  ffi_java_raw *raw)
315 {
316  void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
317  ffi_java_raw_to_ptrarray (cif, raw, avalue);
318  ffi_call (cif, fn, rvalue, avalue);
319  ffi_java_rvalue_to_raw (cif, rvalue);
320 }
321 
322 #if FFI_CLOSURES /* base system provides closures */
323 
324 static void
325 ffi_java_translate_args (ffi_cif *cif, void *rvalue,
326  void **avalue, void *user_data)
327 {
328  ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif));
329  ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
330 
331  ffi_java_ptrarray_to_raw (cif, avalue, raw);
332  (*cl->fun) (cif, rvalue, (ffi_raw*)raw, cl->user_data);
333  ffi_java_raw_to_rvalue (cif, rvalue);
334 }
335 
336 ffi_status
337 ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl,
338  ffi_cif *cif,
339  void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
340  void *user_data,
341  void *codeloc)
342 {
343  ffi_status status;
344 
345  status = ffi_prep_closure_loc ((ffi_closure*) cl,
346  cif,
347  &ffi_java_translate_args,
348  codeloc,
349  codeloc);
350  if (status == FFI_OK)
351  {
352  cl->fun = fun;
353  cl->user_data = user_data;
354  }
355 
356  return status;
357 }
358 
359 /* Again, here is the generic version of ffi_prep_raw_closure, which
360  * will install an intermediate "hub" for translation of arguments from
361  * the pointer-array format, to the raw format */
362 
363 ffi_status
364 ffi_prep_java_raw_closure (ffi_java_raw_closure* cl,
365  ffi_cif *cif,
366  void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
367  void *user_data)
368 {
369  return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl);
370 }
371 
372 #endif /* FFI_CLOSURES */
373 #endif /* !FFI_NATIVE_RAW_API */
374 #endif /* !NO_JAVA_RAW_API */
static void ffi_java_rvalue_to_raw(ffi_cif *cif, void *rvalue)
Definition: java_raw_api.c:246
void ffi_java_raw_to_ptrarray(ffi_cif *cif, ffi_java_raw *raw, void **args)
Definition: java_raw_api.c:76
size_t ffi_java_raw_size(ffi_cif *cif)
Definition: java_raw_api.c:45
#define ALIGN(v, a)
Definition: ffi_common.h:77
#define FFI_SIZEOF_JAVA_RAW
Definition: ffitarget.h:79
#define FFI_ASSERT(x)
Definition: ffi_common.h:72
ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void(*fun)(ffi_cif *, void *, void **, void *), void *user_data, void *codeloc)
Definition: ffi.c:928
void ffi_java_raw_call(ffi_cif *cif, void(*fn)(void), void *rvalue, ffi_java_raw *raw)
Definition: java_raw_api.c:313
float FLOAT32
Definition: ffi_common.h:120
void ffi_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue)
Definition: ffi.c:813
static VALUE result
Definition: nkf.c:40
void ffi_java_ptrarray_to_raw(ffi_cif *cif, void **args, ffi_java_raw *raw)
Definition: java_raw_api.c:157
char * alloca()
static void ffi_java_raw_to_rvalue(ffi_cif *cif, void *rvalue)
Definition: java_raw_api.c:278
#define memcpy(d, s, n)
Definition: ffi_common.h:55