/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
- /* -----------------------------------------------------------------------
- java_raw_api.c - Copyright (c) 1999, 2007, 2008 Red Hat, Inc.
- Cloned from raw_api.c
- Raw_api.c author: Kresten Krab Thorup <krab@gnu.org>
- Java_raw_api.c author: Hans-J. Boehm <hboehm@hpl.hp.com>
- $Id $
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- /* This defines a Java- and 64-bit specific variant of the raw API. */
- /* It assumes that "raw" argument blocks look like Java stacks on a */
- /* 64-bit machine. Arguments that can be stored in a single stack */
- /* stack slots (longs, doubles) occupy 128 bits, but only the first */
- /* 64 bits are actually used. */
- #include <ffi.h>
- #include <ffi_common.h>
- #include <stdlib.h>
- #if !defined(NO_JAVA_RAW_API) && !defined(FFI_NO_RAW_API)
- size_t
- ffi_java_raw_size (ffi_cif *cif)
- {
- size_t result = 0;
- int i;
- ffi_type **at = cif->arg_types;
- for (i = cif->nargs-1; i >= 0; i--, at++)
- {
- switch((*at) -> type) {
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_DOUBLE:
- result += 2 * FFI_SIZEOF_JAVA_RAW;
- break;
- case FFI_TYPE_STRUCT:
- /* No structure parameters in Java. */
- abort();
- default:
- result += FFI_SIZEOF_JAVA_RAW;
- }
- }
- return result;
- }
- void
- ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args)
- {
- unsigned i;
- ffi_type **tp = cif->arg_types;
- #if WORDS_BIGENDIAN
- for (i = 0; i < cif->nargs; i++, tp++, args++)
- {
- switch ((*tp)->type)
- {
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- *args = (void*) ((char*)(raw++) + 3);
- break;
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- *args = (void*) ((char*)(raw++) + 2);
- break;
- #if FFI_SIZEOF_JAVA_RAW == 8
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_DOUBLE:
- *args = (void *)raw;
- raw += 2;
- break;
- #endif
- case FFI_TYPE_POINTER:
- *args = (void*) &(raw++)->ptr;
- break;
- default:
- *args = raw;
- raw +=
- ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
- }
- }
- #else /* WORDS_BIGENDIAN */
- #if !PDP
- /* then assume little endian */
- for (i = 0; i < cif->nargs; i++, tp++, args++)
- {
- #if FFI_SIZEOF_JAVA_RAW == 8
- switch((*tp)->type) {
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_DOUBLE:
- *args = (void*) raw;
- raw += 2;
- break;
- default:
- *args = (void*) raw++;
- }
- #else /* FFI_SIZEOF_JAVA_RAW != 8 */
- *args = (void*) raw;
- raw +=
- ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
- #endif /* FFI_SIZEOF_JAVA_RAW == 8 */
- }
- #else
- #error "pdp endian not supported"
- #endif /* ! PDP */
- #endif /* WORDS_BIGENDIAN */
- }
- void
- ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw)
- {
- unsigned i;
- ffi_type **tp = cif->arg_types;
- for (i = 0; i < cif->nargs; i++, tp++, args++)
- {
- switch ((*tp)->type)
- {
- case FFI_TYPE_UINT8:
- #if WORDS_BIGENDIAN
- *(UINT32*)(raw++) = *(UINT8*) (*args);
- #else
- (raw++)->uint = *(UINT8*) (*args);
- #endif
- break;
- case FFI_TYPE_SINT8:
- #if WORDS_BIGENDIAN
- *(SINT32*)(raw++) = *(SINT8*) (*args);
- #else
- (raw++)->sint = *(SINT8*) (*args);
- #endif
- break;
- case FFI_TYPE_UINT16:
- #if WORDS_BIGENDIAN
- *(UINT32*)(raw++) = *(UINT16*) (*args);
- #else
- (raw++)->uint = *(UINT16*) (*args);
- #endif
- break;
- case FFI_TYPE_SINT16:
- #if WORDS_BIGENDIAN
- *(SINT32*)(raw++) = *(SINT16*) (*args);
- #else
- (raw++)->sint = *(SINT16*) (*args);
- #endif
- break;
- case FFI_TYPE_UINT32:
- #if WORDS_BIGENDIAN
- *(UINT32*)(raw++) = *(UINT32*) (*args);
- #else
- (raw++)->uint = *(UINT32*) (*args);
- #endif
- break;
- case FFI_TYPE_SINT32:
- #if WORDS_BIGENDIAN
- *(SINT32*)(raw++) = *(SINT32*) (*args);
- #else
- (raw++)->sint = *(SINT32*) (*args);
- #endif
- break;
- case FFI_TYPE_FLOAT:
- (raw++)->flt = *(FLOAT32*) (*args);
- break;
- #if FFI_SIZEOF_JAVA_RAW == 8
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_DOUBLE:
- raw->uint = *(UINT64*) (*args);
- raw += 2;
- break;
- #endif
- case FFI_TYPE_POINTER:
- (raw++)->ptr = **(void***) args;
- break;
- default:
- #if FFI_SIZEOF_JAVA_RAW == 8
- FFI_ASSERT(0); /* Should have covered all cases */
- #else
- memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
- raw +=
- ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
- #endif
- }
- }
- }
- #if !FFI_NATIVE_RAW_API
- static void
- ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
- {
- #if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
- switch (cif->rtype->type)
- {
- case FFI_TYPE_UINT8:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_UINT32:
- *(UINT64 *)rvalue <<= 32;
- break;
- case FFI_TYPE_SINT8:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_INT:
- #if FFI_SIZEOF_JAVA_RAW == 4
- case FFI_TYPE_POINTER:
- #endif
- *(SINT64 *)rvalue <<= 32;
- break;
- default:
- break;
- }
- #endif
- }
- static void
- ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
- {
- #if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
- switch (cif->rtype->type)
- {
- case FFI_TYPE_UINT8:
- case FFI_TYPE_UINT16:
- case FFI_TYPE_UINT32:
- *(UINT64 *)rvalue >>= 32;
- break;
- case FFI_TYPE_SINT8:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_INT:
- *(SINT64 *)rvalue >>= 32;
- break;
- default:
- break;
- }
- #endif
- }
- /* This is a generic definition of ffi_raw_call, to be used if the
- * native system does not provide a machine-specific implementation.
- * Having this, allows code to be written for the raw API, without
- * the need for system-specific code to handle input in that format;
- * these following couple of functions will handle the translation forth
- * and back automatically. */
- void ffi_java_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue,
- ffi_java_raw *raw)
- {
- void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
- ffi_java_raw_to_ptrarray (cif, raw, avalue);
- ffi_call (cif, fn, rvalue, avalue);
- ffi_java_rvalue_to_raw (cif, rvalue);
- }
- #if FFI_CLOSURES /* base system provides closures */
- static void
- ffi_java_translate_args (ffi_cif *cif, void *rvalue,
- void **avalue, void *user_data)
- {
- ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif));
- ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
- ffi_java_ptrarray_to_raw (cif, avalue, raw);
- (*cl->fun) (cif, rvalue, raw, cl->user_data);
- ffi_java_raw_to_rvalue (cif, rvalue);
- }
- ffi_status
- ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl,
- ffi_cif *cif,
- void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
- void *user_data,
- void *codeloc)
- {
- ffi_status status;
- status = ffi_prep_closure_loc ((ffi_closure*) cl,
- cif,
- &ffi_java_translate_args,
- codeloc,
- codeloc);
- if (status == FFI_OK)
- {
- cl->fun = fun;
- cl->user_data = user_data;
- }
- return status;
- }
- /* Again, here is the generic version of ffi_prep_raw_closure, which
- * will install an intermediate "hub" for translation of arguments from
- * the pointer-array format, to the raw format */
- ffi_status
- ffi_prep_java_raw_closure (ffi_java_raw_closure* cl,
- ffi_cif *cif,
- void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
- void *user_data)
- {
- return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl);
- }
- #endif /* FFI_CLOSURES */
- #endif /* !FFI_NATIVE_RAW_API */
- #endif /* !FFI_NO_RAW_API */