add support for go closure support on mips

This commit is contained in:
foxsen
2015-08-04 12:53:33 +08:00
parent 17ffc3655a
commit 697dd4e8a0
4 changed files with 194 additions and 31 deletions
+65 -13
View File
@@ -581,14 +581,15 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* Low level routine for calling O32 functions */
extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
extended_cif *, unsigned,
unsigned, unsigned *, void (*)(void));
unsigned, unsigned *, void (*)(void), void *closure);
/* Low level routine for calling N32 functions */
extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
extended_cif *, unsigned,
unsigned, void *, void (*)(void));
unsigned, void *, void (*)(void), void *closure);
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
void ffi_call_int(ffi_cif *cif, void (*fn)(void), void *rvalue,
void **avalue, void *closure)
{
extended_cif ecif;
@@ -610,7 +611,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
case FFI_O32:
case FFI_O32_SOFT_FLOAT:
ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn);
cif->flags, ecif.rvalue, fn, closure);
break;
#endif
@@ -642,7 +643,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
#endif
}
ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
cif->flags, rvalue_copy, fn);
cif->flags, rvalue_copy, fn, closure);
if (copy_rvalue)
memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
}
@@ -655,6 +656,20 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
}
}
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);
}
#if FFI_CLOSURES
#if defined(FFI_MIPS_O32)
extern void ffi_closure_O32(void);
@@ -762,17 +777,17 @@ ffi_prep_closure_loc (ffi_closure *closure,
* Based on the similar routine for sparc.
*/
int
ffi_closure_mips_inner_O32 (ffi_closure *closure,
ffi_closure_mips_inner_O32 (ffi_cif *cif,
void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data;
void *rvalue, ffi_arg *ar,
double *fpr)
{
ffi_cif *cif;
void **avaluep;
ffi_arg *avalue;
ffi_type **arg_types;
int i, avn, argn, seen_int;
cif = closure->cif;
avalue = alloca (cif->nargs * sizeof (ffi_arg));
avaluep = alloca (cif->nargs * sizeof (ffi_arg));
@@ -840,7 +855,7 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure,
}
/* Invoke the closure. */
(closure->fun) (cif, rvalue, avaluep, closure->user_data);
fun(cif, rvalue, avaluep, user_data);
if (cif->abi == FFI_O32_SOFT_FLOAT)
{
@@ -916,11 +931,12 @@ copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
*
*/
int
ffi_closure_mips_inner_N32 (ffi_closure *closure,
ffi_closure_mips_inner_N32 (ffi_cif *cif,
void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data,
void *rvalue, ffi_arg *ar,
ffi_arg *fpr)
{
ffi_cif *cif;
void **avaluep;
ffi_arg *avalue;
ffi_type **arg_types;
@@ -928,7 +944,6 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
int soft_float;
ffi_arg *argp;
cif = closure->cif;
soft_float = cif->abi == FFI_N64_SOFT_FLOAT
|| cif->abi == FFI_N32_SOFT_FLOAT;
avalue = alloca (cif->nargs * sizeof (ffi_arg));
@@ -1040,11 +1055,48 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
}
/* Invoke the closure. */
(closure->fun) (cif, rvalue, avaluep, closure->user_data);
fun (cif, rvalue, avaluep, user_data);
return cif->flags >> (FFI_FLAG_BITS * 8);
}
#endif /* FFI_MIPS_N32 */
#if defined(FFI_MIPS_O32)
extern void ffi_closure_O32(void);
#else
extern void ffi_closure_N32(void);
#endif /* FFI_MIPS_O32 */
void
ffi_status
ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*))
{
void * fn;
#if defined(FFI_MIPS_O32)
if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT)
return FFI_BAD_ABI;
fn = ffi_go_closure_O32;
#else
#if _MIPS_SIM ==_ABIN32
if (cif->abi != FFI_N32
&& cif->abi != FFI_N32_SOFT_FLOAT)
return FFI_BAD_ABI;
#else
if (cif->abi != FFI_N64
&& cif->abi != FFI_N64_SOFT_FLOAT)
return FFI_BAD_ABI;
#endif
fn = ffi_go_closure_N32;
#endif /* FFI_MIPS_O32 */
closure->tramp = (void *)fn;
closure->cif = cif;
closure->fun = fun;
return FFI_OK;
}
#endif /* FFI_CLOSURES */