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. */
13 #include "go-assert.h"
17 /* The functions in this file are only called from reflect_call. As
18 reflect_call calls a libffi function, which will be compiled
19 without -fsplit-stack, it will always run with a large stack. */
21 static ffi_type *go_array_to_ffi (const struct __go_array_type *)
22 __attribute__ ((no_split_stack));
23 static ffi_type *go_slice_to_ffi (const struct __go_slice_type *)
24 __attribute__ ((no_split_stack));
25 static ffi_type *go_struct_to_ffi (const struct __go_struct_type *)
26 __attribute__ ((no_split_stack));
27 static ffi_type *go_string_to_ffi (void) __attribute__ ((no_split_stack));
28 static ffi_type *go_interface_to_ffi (void) __attribute__ ((no_split_stack));
29 static ffi_type *go_complex_to_ffi (ffi_type *)
30 __attribute__ ((no_split_stack));
31 static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *)
32 __attribute__ ((no_split_stack));
33 static ffi_type *go_func_return_ffi (const struct __go_func_type *)
34 __attribute__ ((no_split_stack));
35 static void go_func_to_cif (const struct __go_func_type *, _Bool, _Bool,
37 __attribute__ ((no_split_stack));
38 static size_t go_results_size (const struct __go_func_type *)
39 __attribute__ ((no_split_stack));
40 static void go_set_results (const struct __go_func_type *, unsigned char *,
42 __attribute__ ((no_split_stack));
44 /* Return an ffi_type for a Go array type. The libffi library does
45 not have any builtin support for passing arrays as values. We work
46 around this by pretending that the array is a struct. */
49 go_array_to_ffi (const struct __go_array_type *descriptor)
56 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
57 ret->type = FFI_TYPE_STRUCT;
58 len = descriptor->__len;
59 ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *));
60 element = go_type_to_ffi (descriptor->__element_type);
61 for (i = 0; i < len; ++i)
62 ret->elements[i] = element;
63 ret->elements[len] = NULL;
67 /* Return an ffi_type for a Go slice type. This describes the
68 __go_open_array type defines in array.h. */
72 const struct __go_slice_type *descriptor __attribute__ ((unused)))
76 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
77 ret->type = FFI_TYPE_STRUCT;
78 ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
79 ret->elements[0] = &ffi_type_pointer;
80 ret->elements[1] = &ffi_type_sint;
81 ret->elements[2] = &ffi_type_sint;
82 ret->elements[3] = NULL;
86 /* Return an ffi_type for a Go struct type. */
89 go_struct_to_ffi (const struct __go_struct_type *descriptor)
93 const struct __go_struct_field *fields;
96 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
97 ret->type = FFI_TYPE_STRUCT;
98 field_count = descriptor->__fields.__count;
99 fields = (const struct __go_struct_field *) descriptor->__fields.__values;
100 ret->elements = (ffi_type **) __go_alloc ((field_count + 1)
101 * sizeof (ffi_type *));
102 for (i = 0; i < field_count; ++i)
103 ret->elements[i] = go_type_to_ffi (fields[i].__type);
104 ret->elements[field_count] = NULL;
108 /* Return an ffi_type for a Go string type. This describes the
109 __go_string struct. */
112 go_string_to_ffi (void)
116 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
117 ret->type = FFI_TYPE_STRUCT;
118 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
119 ret->elements[0] = &ffi_type_pointer;
120 ret->elements[1] = &ffi_type_sint;
121 ret->elements[2] = NULL;
125 /* Return an ffi_type for a Go interface type. This describes the
126 __go_interface and __go_empty_interface structs. */
129 go_interface_to_ffi (void)
133 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
134 ret->type = FFI_TYPE_STRUCT;
135 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
136 ret->elements[0] = &ffi_type_pointer;
137 ret->elements[1] = &ffi_type_pointer;
138 ret->elements[2] = NULL;
142 /* Return an ffi_type for a Go complex type. */
145 go_complex_to_ffi (ffi_type *float_type)
149 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
150 ret->type = FFI_TYPE_STRUCT;
151 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
152 ret->elements[0] = float_type;
153 ret->elements[1] = float_type;
154 ret->elements[2] = NULL;
158 /* Return an ffi_type for a type described by a
159 __go_type_descriptor. */
162 go_type_to_ffi (const struct __go_type_descriptor *descriptor)
164 switch (descriptor->__code & GO_CODE_MASK)
167 if (sizeof (_Bool) == 1)
168 return &ffi_type_uint8;
169 else if (sizeof (_Bool) == sizeof (int))
170 return &ffi_type_uint;
173 if (sizeof (float) == 4)
174 return &ffi_type_float;
177 if (sizeof (double) == 8)
178 return &ffi_type_double;
181 if (sizeof (float) == 4)
182 return go_complex_to_ffi (&ffi_type_float);
185 if (sizeof (double) == 8)
186 return go_complex_to_ffi (&ffi_type_double);
189 return &ffi_type_sint16;
191 return &ffi_type_sint32;
193 return &ffi_type_sint64;
195 return &ffi_type_sint8;
197 return &ffi_type_sint;
199 return &ffi_type_uint16;
201 return &ffi_type_uint32;
203 return &ffi_type_uint64;
205 return &ffi_type_uint8;
207 return &ffi_type_uint;
209 if (sizeof (void *) == 2)
210 return &ffi_type_uint16;
211 else if (sizeof (void *) == 4)
212 return &ffi_type_uint32;
213 else if (sizeof (void *) == 8)
214 return &ffi_type_uint64;
217 return go_array_to_ffi ((const struct __go_array_type *) descriptor);
219 return go_slice_to_ffi ((const struct __go_slice_type *) descriptor);
221 return go_struct_to_ffi ((const struct __go_struct_type *) descriptor);
223 return go_string_to_ffi ();
225 return go_interface_to_ffi ();
230 case GO_UNSAFE_POINTER:
231 /* These types are always pointers, and for FFI purposes nothing
233 return &ffi_type_pointer;
239 /* Return the return type for a function, given the number of out
240 parameters and their types. */
243 go_func_return_ffi (const struct __go_func_type *func)
246 const struct __go_type_descriptor **types;
250 count = func->__out.__count;
252 return &ffi_type_void;
254 types = (const struct __go_type_descriptor **) func->__out.__values;
257 return go_type_to_ffi (types[0]);
259 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
260 ret->type = FFI_TYPE_STRUCT;
261 ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *));
262 for (i = 0; i < count; ++i)
263 ret->elements[i] = go_type_to_ffi (types[i]);
264 ret->elements[count] = NULL;
268 /* Build an ffi_cif structure for a function described by a
269 __go_func_type structure. */
272 go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
273 _Bool is_method, ffi_cif *cif)
276 const struct __go_type_descriptor **in_types;
284 num_params = func->__in.__count;
285 in_types = ((const struct __go_type_descriptor **)
286 func->__in.__values);
288 num_args = num_params + (is_interface ? 1 : 0);
289 args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
294 args[0] = &ffi_type_pointer;
299 args[0] = &ffi_type_pointer;
302 for (; i < num_params; ++i)
303 args[i + off] = go_type_to_ffi (in_types[i]);
305 rettype = go_func_return_ffi (func);
307 status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args);
308 __go_assert (status == FFI_OK);
311 /* Get the total size required for the result parameters of a
315 go_results_size (const struct __go_func_type *func)
318 const struct __go_type_descriptor **types;
323 count = func->__out.__count;
327 types = (const struct __go_type_descriptor **) func->__out.__values;
331 for (i = 0; i < count; ++i)
335 align = types[i]->__field_align;
336 if (align > maxalign)
338 off = (off + align - 1) & ~ (align - 1);
339 off += types[i]->__size;
342 off = (off + maxalign - 1) & ~ (maxalign - 1);
347 /* Copy the results of calling a function via FFI from CALL_RESULT
348 into the addresses in RESULTS. */
351 go_set_results (const struct __go_func_type *func, unsigned char *call_result,
355 const struct __go_type_descriptor **types;
359 count = func->__out.__count;
363 types = (const struct __go_type_descriptor **) func->__out.__values;
366 for (i = 0; i < count; ++i)
371 align = types[i]->__field_align;
372 size = types[i]->__size;
373 off = (off + align - 1) & ~ (align - 1);
374 __builtin_memcpy (results[i], call_result + off, size);
379 /* Call a function. The type of the function is FUNC_TYPE, and the
380 address is FUNC_ADDR. PARAMS is an array of parameter addresses.
381 RESULTS is an array of result addresses. */
384 reflect_call (const struct __go_func_type *func_type, const void *func_addr,
385 _Bool is_interface, _Bool is_method, void **params,
389 unsigned char *call_result;
391 __go_assert (func_type->__common.__code == GO_FUNC);
392 go_func_to_cif (func_type, is_interface, is_method, &cif);
394 call_result = (unsigned char *) malloc (go_results_size (func_type));
396 ffi_call (&cif, func_addr, call_result, params);
398 /* Some day we may need to free result values if RESULTS is
401 go_set_results (func_type, call_result, results);