From c9f5b6648b0f052bbca8b50615284dd975e9ed29 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 14 Nov 2014 13:04:33 +0100 Subject: [PATCH] testsuite: Add trivial tests for Go closures --- testsuite/libffi.go/aa-direct.c | 34 ++++++++++++++++++++++++++++++++++ testsuite/libffi.go/closure1.c | 28 ++++++++++++++++++++++++++++ testsuite/libffi.go/ffitest.h | 1 + testsuite/libffi.go/go.exp | 36 ++++++++++++++++++++++++++++++++++++ testsuite/libffi.go/static-chain.h | 19 +++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 testsuite/libffi.go/aa-direct.c create mode 100644 testsuite/libffi.go/closure1.c create mode 100644 testsuite/libffi.go/ffitest.h create mode 100644 testsuite/libffi.go/go.exp create mode 100644 testsuite/libffi.go/static-chain.h diff --git a/testsuite/libffi.go/aa-direct.c b/testsuite/libffi.go/aa-direct.c new file mode 100644 index 0000000..b00c404 --- /dev/null +++ b/testsuite/libffi.go/aa-direct.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ + +#include "static-chain.h" + +#if defined(__GNUC__) && !defined(__clang__) && defined(STATIC_CHAIN_REG) + +#include "ffitest.h" + +/* Blatent assumption here that the prologue doesn't clobber the + static chain for trivial functions. If this is not true, don't + define STATIC_CHAIN_REG, and we'll test what we can via other tests. */ +void *doit(void) +{ + register void *chain __asm__(STATIC_CHAIN_REG); + return chain; +} + +int main() +{ + ffi_cif cif; + void *result; + + CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK); + + ffi_call_go(&cif, FFI_FN(doit), &result, NULL, &result); + + CHECK(result == &result); + + return 0; +} + +#else /* UNSUPPORTED */ +int main() { return 0; } +#endif diff --git a/testsuite/libffi.go/closure1.c b/testsuite/libffi.go/closure1.c new file mode 100644 index 0000000..7b34afc --- /dev/null +++ b/testsuite/libffi.go/closure1.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +#include "ffitest.h" + +void doit(ffi_cif *cif, void *rvalue, void **avalue, void *closure) +{ + (void)cif; + (void)avalue; + *(void **)rvalue = closure; +} + +typedef void * (*FN)(void); + +int main() +{ + ffi_cif cif; + ffi_go_closure cl; + void *result; + + CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK); + CHECK(ffi_prep_go_closure(&cl, &cif, doit) == FFI_OK); + + ffi_call_go(&cif, FFI_FN(*(FN *)&cl), &result, NULL, &cl); + + CHECK(result == &cl); + + exit(0); +} diff --git a/testsuite/libffi.go/ffitest.h b/testsuite/libffi.go/ffitest.h new file mode 100644 index 0000000..d27d362 --- /dev/null +++ b/testsuite/libffi.go/ffitest.h @@ -0,0 +1 @@ +#include "../libffi.call/ffitest.h" diff --git a/testsuite/libffi.go/go.exp b/testsuite/libffi.go/go.exp new file mode 100644 index 0000000..100c5e7 --- /dev/null +++ b/testsuite/libffi.go/go.exp @@ -0,0 +1,36 @@ +# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING3. If not see +# . + +dg-init +libffi-init + +global srcdir subdir + +set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] + +if { [libffi_feature_test "#ifdef FFI_GO_CLOSURES"] } { + run-many-tests $tlist "" +} else { + foreach test $tlist { + unsupported "$test" + } +} + +dg-finish + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/testsuite/libffi.go/static-chain.h b/testsuite/libffi.go/static-chain.h new file mode 100644 index 0000000..56b7e31 --- /dev/null +++ b/testsuite/libffi.go/static-chain.h @@ -0,0 +1,19 @@ +#ifdef __aarch64__ +# define STATIC_CHAIN_REG "x18" +#elif defined(__alpha__) +# define STATIC_CHAIN_REG "r1" +#elif defined(__arm__) +# define STATIC_CHAIN_REG "ip" +#elif defined(__sparc__) +# if defined(__arch64__) || defined(__sparcv9) +# define STATIC_CHAIN_REG "g5" +# else +# define STATIC_CHAIN_REG "g2" +# endif +#elif defined(__x86_64__) +# define STATIC_CHAIN_REG "r10" +#elif defined(__i386__) +# ifndef ABI_NUM +# define STATIC_CHAIN_REG "ecx" /* FFI_DEFAULT_ABI only */ +# endif +#endif -- 2.7.4