Commit c9f5b6648b0f052bbca8b50615284dd975e9ed29

Richard Henderson 2014-11-14T13:04:33

testsuite: Add trivial tests for Go closures

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
+# <http://www.gnu.org/licenses/>.
+
+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