summaryrefslogtreecommitdiff
path: root/libgo/runtime/go-reflect-call.c
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-20 00:18:15 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-20 00:18:15 +0000
commit84911de8492fb75007eec6bfa4abb7905439f93c (patch)
treec891bdec1e6f073f73fedeef23718bc3ac30d499 /libgo/runtime/go-reflect-call.c
parentad33e6a8510b48571eaef50af339892925108830 (diff)
downloadgcc-84911de8492fb75007eec6bfa4abb7905439f93c.tar.gz
Update to current version of Go library.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@173931 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/runtime/go-reflect-call.c')
-rw-r--r--libgo/runtime/go-reflect-call.c55
1 files changed, 42 insertions, 13 deletions
diff --git a/libgo/runtime/go-reflect-call.c b/libgo/runtime/go-reflect-call.c
index 6ae749f9a56..a769142c3df 100644
--- a/libgo/runtime/go-reflect-call.c
+++ b/libgo/runtime/go-reflect-call.c
@@ -14,9 +14,32 @@
#include "go-type.h"
#include "runtime.h"
-/* Forward declaration. */
-
-static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *);
+/* The functions in this file are only called from reflect_call. As
+ reflect_call calls a libffi function, which will be compiled
+ without -fsplit-stack, it will always run with a large stack. */
+
+static ffi_type *go_array_to_ffi (const struct __go_array_type *)
+ __attribute__ ((no_split_stack));
+static ffi_type *go_slice_to_ffi (const struct __go_slice_type *)
+ __attribute__ ((no_split_stack));
+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));
+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 *)
+ __attribute__ ((no_split_stack));
+static void go_func_to_cif (const struct __go_func_type *, _Bool, _Bool,
+ ffi_cif *)
+ __attribute__ ((no_split_stack));
+static size_t go_results_size (const struct __go_func_type *)
+ __attribute__ ((no_split_stack));
+static void go_set_results (const struct __go_func_type *, unsigned char *,
+ void **)
+ __attribute__ ((no_split_stack));
/* Return an ffi_type for a Go array type. The libffi library does
not have any builtin support for passing arrays as values. We work
@@ -31,7 +54,6 @@ go_array_to_ffi (const struct __go_array_type *descriptor)
uintptr_t i;
ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
- __builtin_memset (ret, 0, sizeof (ffi_type));
ret->type = FFI_TYPE_STRUCT;
len = descriptor->__len;
ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *));
@@ -52,7 +74,6 @@ go_slice_to_ffi (
ffi_type *ret;
ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
- __builtin_memset (ret, 0, sizeof (ffi_type));
ret->type = FFI_TYPE_STRUCT;
ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
ret->elements[0] = &ffi_type_pointer;
@@ -73,7 +94,6 @@ go_struct_to_ffi (const struct __go_struct_type *descriptor)
int i;
ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
- __builtin_memset (ret, 0, sizeof (ffi_type));
ret->type = FFI_TYPE_STRUCT;
field_count = descriptor->__fields.__count;
fields = (const struct __go_struct_field *) descriptor->__fields.__values;
@@ -237,7 +257,6 @@ go_func_return_ffi (const struct __go_func_type *func)
return go_type_to_ffi (types[0]);
ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
- __builtin_memset (ret, 0, sizeof (ffi_type));
ret->type = FFI_TYPE_STRUCT;
ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *));
for (i = 0; i < count; ++i)
@@ -251,7 +270,7 @@ go_func_return_ffi (const struct __go_func_type *func)
static void
go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
- ffi_cif *cif)
+ _Bool is_method, ffi_cif *cif)
{
int num_params;
const struct __go_type_descriptor **in_types;
@@ -268,10 +287,19 @@ go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
num_args = num_params + (is_interface ? 1 : 0);
args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
+ i = 0;
+ off = 0;
if (is_interface)
- args[0] = &ffi_type_pointer;
- off = is_interface ? 1 : 0;
- for (i = 0; i < num_params; ++i)
+ {
+ args[0] = &ffi_type_pointer;
+ off = 1;
+ }
+ else if (is_method)
+ {
+ args[0] = &ffi_type_pointer;
+ i = 1;
+ }
+ for (; i < num_params; ++i)
args[i + off] = go_type_to_ffi (in_types[i]);
rettype = go_func_return_ffi (func);
@@ -354,13 +382,14 @@ go_set_results (const struct __go_func_type *func, unsigned char *call_result,
void
reflect_call (const struct __go_func_type *func_type, const void *func_addr,
- _Bool is_interface, void **params, void **results)
+ _Bool is_interface, _Bool is_method, void **params,
+ void **results)
{
ffi_cif cif;
unsigned char *call_result;
__go_assert (func_type->__common.__code == GO_FUNC);
- go_func_to_cif (func_type, is_interface, &cif);
+ go_func_to_cif (func_type, is_interface, is_method, &cif);
call_result = (unsigned char *) malloc (go_results_size (func_type));