aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/go-ffi.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2015-01-16 14:58:53 -0800
committerIan Lance Taylor <ian@gcc.gnu.org>2015-01-16 22:58:53 +0000
commit38bf819a5f995ae4621496df2324d68b9e24900f (patch)
treec90d2bfba44756e26640c50ad1389375693ef832 /libgo/runtime/go-ffi.c
parent21cb351825d45c42e9e5148715a2fd2051cf4ed1 (diff)
downloadgcc-38bf819a5f995ae4621496df2324d68b9e24900f.zip
gcc-38bf819a5f995ae4621496df2324d68b9e24900f.tar.gz
gcc-38bf819a5f995ae4621496df2324d68b9e24900f.tar.bz2
compiler, reflect, runtime: Use static chain for closures.
Change from using __go_set_closure to passing the closure value in the static chain field. Uses new backend support for setting the closure chain in a call from C via __builtin_call_with_static_chain. Uses new support in libffi for Go closures. The old architecture specific support for reflect.MakeFunc is removed, replaced by the libffi support. All work done by Richard Henderson. * go-gcc.cc (Gcc_backend::call_expression): Add chain_expr argument. (Gcc_backend::static_chain_variable): New method. From-SVN: r219776
Diffstat (limited to 'libgo/runtime/go-ffi.c')
-rw-r--r--libgo/runtime/go-ffi.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/libgo/runtime/go-ffi.c b/libgo/runtime/go-ffi.c
index 175c583..89da23d 100644
--- a/libgo/runtime/go-ffi.c
+++ b/libgo/runtime/go-ffi.c
@@ -30,8 +30,6 @@ static ffi_type *go_struct_to_ffi (const struct __go_struct_type *)
__attribute__ ((no_split_stack));
static ffi_type *go_string_to_ffi (void) __attribute__ ((no_split_stack));
static ffi_type *go_interface_to_ffi (void) __attribute__ ((no_split_stack));
-static ffi_type *go_complex_to_ffi (ffi_type *)
- __attribute__ ((no_split_stack, unused));
static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *)
__attribute__ ((no_split_stack));
static ffi_type *go_func_return_ffi (const struct __go_func_type *)
@@ -155,7 +153,15 @@ go_interface_to_ffi (void)
return ret;
}
-/* Return an ffi_type for a Go complex type. */
+
+#ifndef FFI_TARGET_HAS_COMPLEX_TYPE
+/* If libffi hasn't been updated for this target to support complex,
+ pretend complex is a structure. Warning: This does not work for
+ all ABIs. Eventually libffi should be updated for all targets
+ and this should go away. */
+
+static ffi_type *go_complex_to_ffi (ffi_type *)
+ __attribute__ ((no_split_stack));
static ffi_type *
go_complex_to_ffi (ffi_type *float_type)
@@ -170,6 +176,7 @@ go_complex_to_ffi (ffi_type *float_type)
ret->elements[2] = NULL;
return ret;
}
+#endif
/* Return an ffi_type for a type described by a
__go_type_descriptor. */
@@ -194,23 +201,25 @@ go_type_to_ffi (const struct __go_type_descriptor *descriptor)
return &ffi_type_double;
abort ();
case GO_COMPLEX64:
-#ifdef __alpha__
- runtime_throw("the libffi library does not support Complex64 type with "
- "reflect.Call or runtime.SetFinalizer");
-#else
if (sizeof (float) == 4)
- return go_complex_to_ffi (&ffi_type_float);
- abort ();
+ {
+#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
+ return &ffi_type_complex_float;
+#else
+ return go_complex_to_ffi (&ffi_type_float);
#endif
+ }
+ abort ();
case GO_COMPLEX128:
-#ifdef __alpha__
- runtime_throw("the libffi library does not support Complex128 type with "
- "reflect.Call or runtime.SetFinalizer");
-#else
if (sizeof (double) == 8)
- return go_complex_to_ffi (&ffi_type_double);
- abort ();
+ {
+#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
+ return &ffi_type_complex_double;
+#else
+ return go_complex_to_ffi (&ffi_type_double);
#endif
+ }
+ abort ();
case GO_INT16:
return &ffi_type_sint16;
case GO_INT32: