1 /* go-reflect-call.c -- call reflection support for Go.
3 Copyright 2009 The Go Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file. */
14 #include "go-assert.h"
18 /* The functions in this file are only called from reflect_call. As
19 reflect_call calls a libffi function, which will be compiled
20 without -fsplit-stack, it will always run with a large stack. */
22 static ffi_type *go_array_to_ffi (const struct __go_array_type *)
23 __attribute__ ((no_split_stack));
24 static ffi_type *go_slice_to_ffi (const struct __go_slice_type *)
25 __attribute__ ((no_split_stack));
26 static ffi_type *go_struct_to_ffi (const struct __go_struct_type *)
27 __attribute__ ((no_split_stack));
28 static ffi_type *go_string_to_ffi (void) __attribute__ ((no_split_stack));
29 static ffi_type *go_interface_to_ffi (void) __attribute__ ((no_split_stack));
30 static ffi_type *go_complex_to_ffi (ffi_type *)
31 __attribute__ ((no_split_stack));
32 static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *)
33 __attribute__ ((no_split_stack));
34 static ffi_type *go_func_return_ffi (const struct __go_func_type *)
35 __attribute__ ((no_split_stack));
36 static void go_func_to_cif (const struct __go_func_type *, _Bool, _Bool,
38 __attribute__ ((no_split_stack));
39 static size_t go_results_size (const struct __go_func_type *)
40 __attribute__ ((no_split_stack));
41 static void go_set_results (const struct __go_func_type *, unsigned char *,
43 __attribute__ ((no_split_stack));
45 /* Return an ffi_type for a Go array type. The libffi library does
46 not have any builtin support for passing arrays as values. We work
47 around this by pretending that the array is a struct. */
50 go_array_to_ffi (const struct __go_array_type *descriptor)
57 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
58 ret->type = FFI_TYPE_STRUCT;
59 len = descriptor->__len;
60 ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *));
61 element = go_type_to_ffi (descriptor->__element_type);
62 for (i = 0; i < len; ++i)
63 ret->elements[i] = element;
64 ret->elements[len] = NULL;
68 /* Return an ffi_type for a Go slice type. This describes the
69 __go_open_array type defines in array.h. */
73 const struct __go_slice_type *descriptor __attribute__ ((unused)))
77 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
78 ret->type = FFI_TYPE_STRUCT;
79 ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
80 ret->elements[0] = &ffi_type_pointer;
81 ret->elements[1] = &ffi_type_sint;
82 ret->elements[2] = &ffi_type_sint;
83 ret->elements[3] = NULL;
87 /* Return an ffi_type for a Go struct type. */
90 go_struct_to_ffi (const struct __go_struct_type *descriptor)
94 const struct __go_struct_field *fields;
97 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
98 ret->type = FFI_TYPE_STRUCT;
99 field_count = descriptor->__fields.__count;
100 fields = (const struct __go_struct_field *) descriptor->__fields.__values;
101 ret->elements = (ffi_type **) __go_alloc ((field_count + 1)
102 * sizeof (ffi_type *));
103 for (i = 0; i < field_count; ++i)
104 ret->elements[i] = go_type_to_ffi (fields[i].__type);
105 ret->elements[field_count] = NULL;
109 /* Return an ffi_type for a Go string type. This describes the
110 __go_string struct. */
113 go_string_to_ffi (void)
117 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
118 ret->type = FFI_TYPE_STRUCT;
119 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
120 ret->elements[0] = &ffi_type_pointer;
121 ret->elements[1] = &ffi_type_sint;
122 ret->elements[2] = NULL;
126 /* Return an ffi_type for a Go interface type. This describes the
127 __go_interface and __go_empty_interface structs. */
130 go_interface_to_ffi (void)
134 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
135 ret->type = FFI_TYPE_STRUCT;
136 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
137 ret->elements[0] = &ffi_type_pointer;
138 ret->elements[1] = &ffi_type_pointer;
139 ret->elements[2] = NULL;
143 /* Return an ffi_type for a Go complex type. */
146 go_complex_to_ffi (ffi_type *float_type)
150 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
151 ret->type = FFI_TYPE_STRUCT;
152 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
153 ret->elements[0] = float_type;
154 ret->elements[1] = float_type;
155 ret->elements[2] = NULL;
159 /* Return an ffi_type for a type described by a
160 __go_type_descriptor. */
163 go_type_to_ffi (const struct __go_type_descriptor *descriptor)
165 switch (descriptor->__code & GO_CODE_MASK)
168 if (sizeof (_Bool) == 1)
169 return &ffi_type_uint8;
170 else if (sizeof (_Bool) == sizeof (int))
171 return &ffi_type_uint;
174 if (sizeof (float) == 4)
175 return &ffi_type_float;
178 if (sizeof (double) == 8)
179 return &ffi_type_double;
182 if (sizeof (float) == 4)
183 return go_complex_to_ffi (&ffi_type_float);
186 if (sizeof (double) == 8)
187 return go_complex_to_ffi (&ffi_type_double);
190 return &ffi_type_sint16;
192 return &ffi_type_sint32;
194 return &ffi_type_sint64;
196 return &ffi_type_sint8;
198 return &ffi_type_sint;
200 return &ffi_type_uint16;
202 return &ffi_type_uint32;
204 return &ffi_type_uint64;
206 return &ffi_type_uint8;
208 return &ffi_type_uint;
210 if (sizeof (void *) == 2)
211 return &ffi_type_uint16;
212 else if (sizeof (void *) == 4)
213 return &ffi_type_uint32;
214 else if (sizeof (void *) == 8)
215 return &ffi_type_uint64;
218 return go_array_to_ffi ((const struct __go_array_type *) descriptor);
220 return go_slice_to_ffi ((const struct __go_slice_type *) descriptor);
222 return go_struct_to_ffi ((const struct __go_struct_type *) descriptor);
224 return go_string_to_ffi ();
226 return go_interface_to_ffi ();
231 case GO_UNSAFE_POINTER:
232 /* These types are always pointers, and for FFI purposes nothing
234 return &ffi_type_pointer;
240 /* Return the return type for a function, given the number of out
241 parameters and their types. */
244 go_func_return_ffi (const struct __go_func_type *func)
247 const struct __go_type_descriptor **types;
251 count = func->__out.__count;
253 return &ffi_type_void;
255 types = (const struct __go_type_descriptor **) func->__out.__values;
258 return go_type_to_ffi (types[0]);
260 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
261 ret->type = FFI_TYPE_STRUCT;
262 ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *));
263 for (i = 0; i < count; ++i)
264 ret->elements[i] = go_type_to_ffi (types[i]);
265 ret->elements[count] = NULL;
269 /* Build an ffi_cif structure for a function described by a
270 __go_func_type structure. */
273 go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
274 _Bool is_method, ffi_cif *cif)
277 const struct __go_type_descriptor **in_types;
285 num_params = func->__in.__count;
286 in_types = ((const struct __go_type_descriptor **)
287 func->__in.__values);
289 num_args = num_params + (is_interface ? 1 : 0);
290 args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
295 args[0] = &ffi_type_pointer;
300 args[0] = &ffi_type_pointer;
303 for (; i < num_params; ++i)
304 args[i + off] = go_type_to_ffi (in_types[i]);
306 rettype = go_func_return_ffi (func);
308 status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args);
309 __go_assert (status == FFI_OK);
312 /* Get the total size required for the result parameters of a
316 go_results_size (const struct __go_func_type *func)
319 const struct __go_type_descriptor **types;
324 count = func->__out.__count;
328 types = (const struct __go_type_descriptor **) func->__out.__values;
330 /* A single integer return value is always promoted to a full
334 switch (types[0]->__code & GO_CODE_MASK)
345 return sizeof (ffi_arg);
354 for (i = 0; i < count; ++i)
358 align = types[i]->__field_align;
359 if (align > maxalign)
361 off = (off + align - 1) & ~ (align - 1);
362 off += types[i]->__size;
365 off = (off + maxalign - 1) & ~ (maxalign - 1);
370 /* Copy the results of calling a function via FFI from CALL_RESULT
371 into the addresses in RESULTS. */
374 go_set_results (const struct __go_func_type *func, unsigned char *call_result,
378 const struct __go_type_descriptor **types;
382 count = func->__out.__count;
386 types = (const struct __go_type_descriptor **) func->__out.__values;
388 /* A single integer return value is always promoted to a full
392 switch (types[0]->__code & GO_CODE_MASK)
406 unsigned char buf[sizeof (ffi_arg)];
411 __builtin_memcpy (&u.buf, call_result, sizeof (ffi_arg));
414 switch (types[0]->__size)
421 __builtin_memcpy (results[0], &b, 1);
430 __builtin_memcpy (results[0], &s, 2);
439 __builtin_memcpy (results[0], &w, 4);
448 __builtin_memcpy (results[0], &d, 8);
464 for (i = 0; i < count; ++i)
469 align = types[i]->__field_align;
470 size = types[i]->__size;
471 off = (off + align - 1) & ~ (align - 1);
472 __builtin_memcpy (results[i], call_result + off, size);
477 /* Call a function. The type of the function is FUNC_TYPE, and the
478 address is FUNC_ADDR. PARAMS is an array of parameter addresses.
479 RESULTS is an array of result addresses. */
482 reflect_call (const struct __go_func_type *func_type, const void *func_addr,
483 _Bool is_interface, _Bool is_method, void **params,
487 unsigned char *call_result;
489 __go_assert ((func_type->__common.__code & GO_CODE_MASK) == GO_FUNC);
490 go_func_to_cif (func_type, is_interface, is_method, &cif);
492 call_result = (unsigned char *) malloc (go_results_size (func_type));
494 ffi_call (&cif, func_addr, call_result, params);
496 /* Some day we may need to free result values if RESULTS is
499 go_set_results (func_type, call_result, results);