mirror of
https://github.com/partic2/libffi
synced 2026-11-11 02:27:19 +00:00
sparc: Add support for Go closures
This commit is contained in:
+37
-8
@@ -176,7 +176,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
}
|
||||
|
||||
extern void ffi_call_v8(ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
void **avalue, size_t bytes) FFI_HIDDEN;
|
||||
void **avalue, size_t bytes, void *closure) FFI_HIDDEN;
|
||||
|
||||
int FFI_HIDDEN
|
||||
ffi_prep_args_v8(ffi_cif *cif, unsigned long *argp, void *rvalue, void **avalue)
|
||||
@@ -280,8 +280,9 @@ ffi_prep_args_v8(ffi_cif *cif, unsigned long *argp, void *rvalue, void **avalue)
|
||||
return flags;
|
||||
}
|
||||
|
||||
void
|
||||
ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
static void
|
||||
ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
void **avalue, void *closure)
|
||||
{
|
||||
size_t bytes = cif->bytes;
|
||||
|
||||
@@ -292,7 +293,20 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
if (rvalue == NULL && cif->flags == SPARC_RET_STRUCT)
|
||||
bytes += ALIGN (cif->rtype->size, 8);
|
||||
|
||||
ffi_call_v8(cif, fn, rvalue, avalue, -bytes);
|
||||
ffi_call_v8(cif, fn, rvalue, avalue, -bytes, closure);
|
||||
}
|
||||
|
||||
void
|
||||
ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
ffi_call_int (cif, fn, rvalue, avalue, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
||||
void **avalue, void *closure)
|
||||
{
|
||||
ffi_call_int (cif, fn, rvalue, avalue, closure);
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
@@ -308,6 +322,7 @@ extern void ffi_flush_icache (void *) FFI_HIDDEN;
|
||||
#endif
|
||||
|
||||
extern void ffi_closure_v8(void) FFI_HIDDEN;
|
||||
extern void ffi_go_closure_v8(void) FFI_HIDDEN;
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure *closure,
|
||||
@@ -337,16 +352,30 @@ ffi_prep_closure_loc (ffi_closure *closure,
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
ffi_status
|
||||
ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*))
|
||||
{
|
||||
if (cif->abi != FFI_V8)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
closure->tramp = ffi_go_closure_v8;
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
int FFI_HIDDEN
|
||||
ffi_closure_sparc_inner_v8(ffi_closure *closure, void *rvalue,
|
||||
ffi_closure_sparc_inner_v8(ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*),
|
||||
void *user_data, void *rvalue,
|
||||
unsigned long *argp)
|
||||
{
|
||||
ffi_cif *cif;
|
||||
ffi_type **arg_types;
|
||||
void **avalue;
|
||||
int i, nargs, flags;
|
||||
|
||||
cif = closure->cif;
|
||||
arg_types = cif->arg_types;
|
||||
nargs = cif->nargs;
|
||||
flags = cif->flags;
|
||||
@@ -424,7 +453,7 @@ ffi_closure_sparc_inner_v8(ffi_closure *closure, void *rvalue,
|
||||
}
|
||||
|
||||
/* Invoke the closure. */
|
||||
(closure->fun) (cif, rvalue, avalue, closure->user_data);
|
||||
fun (cif, rvalue, avalue, user_data);
|
||||
|
||||
/* Tell ffi_closure_sparc how to perform return type promotions. */
|
||||
return flags;
|
||||
|
||||
Reference in New Issue
Block a user