/js/src/ctypes/libffi/src/java_raw_api.c

http://github.com/zpao/v8monkey · C · 356 lines · 261 code · 49 blank · 46 comment · 22 complexity · 797fe5e8686ab2b9f496e7c991ad685e MD5 · raw file

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