sparc: Add support for Go closures

This commit is contained in:
Richard Henderson
2014-11-12 09:36:11 +01:00
parent ad89c2d9e9
commit 92022496ef
5 changed files with 133 additions and 29 deletions
+37 -8
View File
@@ -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;