* gcc.dg/stack-usage-1.c: Remove dg-options line for sh targets
[official-gcc.git] / libgo / runtime / go-reflect-call.c
blob688c68e581e6a936aba399ed551a70fe765707a3
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. */
7 #include <stdio.h>
8 #include <stdint.h>
9 #include <stdlib.h>
11 #include "config.h"
13 #include "go-alloc.h"
14 #include "go-assert.h"
15 #include "go-type.h"
16 #include "runtime.h"
18 #ifdef USE_LIBFFI
20 #include "ffi.h"
22 /* The functions in this file are only called from reflect_call. As
23 reflect_call calls a libffi function, which will be compiled
24 without -fsplit-stack, it will always run with a large stack. */
26 static ffi_type *go_array_to_ffi (const struct __go_array_type *)
27 __attribute__ ((no_split_stack));
28 static ffi_type *go_slice_to_ffi (const struct __go_slice_type *)
29 __attribute__ ((no_split_stack));
30 static ffi_type *go_struct_to_ffi (const struct __go_struct_type *)
31 __attribute__ ((no_split_stack));
32 static ffi_type *go_string_to_ffi (void) __attribute__ ((no_split_stack));
33 static ffi_type *go_interface_to_ffi (void) __attribute__ ((no_split_stack));
34 static ffi_type *go_complex_to_ffi (ffi_type *)
35 __attribute__ ((no_split_stack));
36 static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *)
37 __attribute__ ((no_split_stack));
38 static ffi_type *go_func_return_ffi (const struct __go_func_type *)
39 __attribute__ ((no_split_stack));
40 static void go_func_to_cif (const struct __go_func_type *, _Bool, _Bool,
41 ffi_cif *)
42 __attribute__ ((no_split_stack));
43 static size_t go_results_size (const struct __go_func_type *)
44 __attribute__ ((no_split_stack));
45 static void go_set_results (const struct __go_func_type *, unsigned char *,
46 void **)
47 __attribute__ ((no_split_stack));
49 /* Return an ffi_type for a Go array type. The libffi library does
50 not have any builtin support for passing arrays as values. We work
51 around this by pretending that the array is a struct. */
53 static ffi_type *
54 go_array_to_ffi (const struct __go_array_type *descriptor)
56 ffi_type *ret;
57 uintptr_t len;
58 ffi_type *element;
59 uintptr_t i;
61 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
62 ret->type = FFI_TYPE_STRUCT;
63 len = descriptor->__len;
64 ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *));
65 element = go_type_to_ffi (descriptor->__element_type);
66 for (i = 0; i < len; ++i)
67 ret->elements[i] = element;
68 ret->elements[len] = NULL;
69 return ret;
72 /* Return an ffi_type for a Go slice type. This describes the
73 __go_open_array type defines in array.h. */
75 static ffi_type *
76 go_slice_to_ffi (
77 const struct __go_slice_type *descriptor __attribute__ ((unused)))
79 ffi_type *ret;
81 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
82 ret->type = FFI_TYPE_STRUCT;
83 ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
84 ret->elements[0] = &ffi_type_pointer;
85 ret->elements[1] = &ffi_type_sint;
86 ret->elements[2] = &ffi_type_sint;
87 ret->elements[3] = NULL;
88 return ret;
91 /* Return an ffi_type for a Go struct type. */
93 static ffi_type *
94 go_struct_to_ffi (const struct __go_struct_type *descriptor)
96 ffi_type *ret;
97 int field_count;
98 const struct __go_struct_field *fields;
99 int i;
101 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
102 ret->type = FFI_TYPE_STRUCT;
103 field_count = descriptor->__fields.__count;
104 fields = (const struct __go_struct_field *) descriptor->__fields.__values;
105 ret->elements = (ffi_type **) __go_alloc ((field_count + 1)
106 * sizeof (ffi_type *));
107 for (i = 0; i < field_count; ++i)
108 ret->elements[i] = go_type_to_ffi (fields[i].__type);
109 ret->elements[field_count] = NULL;
110 return ret;
113 /* Return an ffi_type for a Go string type. This describes the
114 __go_string struct. */
116 static ffi_type *
117 go_string_to_ffi (void)
119 ffi_type *ret;
121 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
122 ret->type = FFI_TYPE_STRUCT;
123 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
124 ret->elements[0] = &ffi_type_pointer;
125 ret->elements[1] = &ffi_type_sint;
126 ret->elements[2] = NULL;
127 return ret;
130 /* Return an ffi_type for a Go interface type. This describes the
131 __go_interface and __go_empty_interface structs. */
133 static ffi_type *
134 go_interface_to_ffi (void)
136 ffi_type *ret;
138 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
139 ret->type = FFI_TYPE_STRUCT;
140 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
141 ret->elements[0] = &ffi_type_pointer;
142 ret->elements[1] = &ffi_type_pointer;
143 ret->elements[2] = NULL;
144 return ret;
147 /* Return an ffi_type for a Go complex type. */
149 static ffi_type *
150 go_complex_to_ffi (ffi_type *float_type)
152 ffi_type *ret;
154 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
155 ret->type = FFI_TYPE_STRUCT;
156 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
157 ret->elements[0] = float_type;
158 ret->elements[1] = float_type;
159 ret->elements[2] = NULL;
160 return ret;
163 /* Return an ffi_type for a type described by a
164 __go_type_descriptor. */
166 static ffi_type *
167 go_type_to_ffi (const struct __go_type_descriptor *descriptor)
169 switch (descriptor->__code & GO_CODE_MASK)
171 case GO_BOOL:
172 if (sizeof (_Bool) == 1)
173 return &ffi_type_uint8;
174 else if (sizeof (_Bool) == sizeof (int))
175 return &ffi_type_uint;
176 abort ();
177 case GO_FLOAT32:
178 if (sizeof (float) == 4)
179 return &ffi_type_float;
180 abort ();
181 case GO_FLOAT64:
182 if (sizeof (double) == 8)
183 return &ffi_type_double;
184 abort ();
185 case GO_COMPLEX64:
186 if (sizeof (float) == 4)
187 return go_complex_to_ffi (&ffi_type_float);
188 abort ();
189 case GO_COMPLEX128:
190 if (sizeof (double) == 8)
191 return go_complex_to_ffi (&ffi_type_double);
192 abort ();
193 case GO_INT16:
194 return &ffi_type_sint16;
195 case GO_INT32:
196 return &ffi_type_sint32;
197 case GO_INT64:
198 return &ffi_type_sint64;
199 case GO_INT8:
200 return &ffi_type_sint8;
201 case GO_INT:
202 return &ffi_type_sint;
203 case GO_UINT16:
204 return &ffi_type_uint16;
205 case GO_UINT32:
206 return &ffi_type_uint32;
207 case GO_UINT64:
208 return &ffi_type_uint64;
209 case GO_UINT8:
210 return &ffi_type_uint8;
211 case GO_UINT:
212 return &ffi_type_uint;
213 case GO_UINTPTR:
214 if (sizeof (void *) == 2)
215 return &ffi_type_uint16;
216 else if (sizeof (void *) == 4)
217 return &ffi_type_uint32;
218 else if (sizeof (void *) == 8)
219 return &ffi_type_uint64;
220 abort ();
221 case GO_ARRAY:
222 return go_array_to_ffi ((const struct __go_array_type *) descriptor);
223 case GO_SLICE:
224 return go_slice_to_ffi ((const struct __go_slice_type *) descriptor);
225 case GO_STRUCT:
226 return go_struct_to_ffi ((const struct __go_struct_type *) descriptor);
227 case GO_STRING:
228 return go_string_to_ffi ();
229 case GO_INTERFACE:
230 return go_interface_to_ffi ();
231 case GO_CHAN:
232 case GO_FUNC:
233 case GO_MAP:
234 case GO_PTR:
235 case GO_UNSAFE_POINTER:
236 /* These types are always pointers, and for FFI purposes nothing
237 else matters. */
238 return &ffi_type_pointer;
239 default:
240 abort ();
244 /* Return the return type for a function, given the number of out
245 parameters and their types. */
247 static ffi_type *
248 go_func_return_ffi (const struct __go_func_type *func)
250 int count;
251 const struct __go_type_descriptor **types;
252 ffi_type *ret;
253 int i;
255 count = func->__out.__count;
256 if (count == 0)
257 return &ffi_type_void;
259 types = (const struct __go_type_descriptor **) func->__out.__values;
261 if (count == 1)
262 return go_type_to_ffi (types[0]);
264 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
265 ret->type = FFI_TYPE_STRUCT;
266 ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *));
267 for (i = 0; i < count; ++i)
268 ret->elements[i] = go_type_to_ffi (types[i]);
269 ret->elements[count] = NULL;
270 return ret;
273 /* Build an ffi_cif structure for a function described by a
274 __go_func_type structure. */
276 static void
277 go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
278 _Bool is_method, ffi_cif *cif)
280 int num_params;
281 const struct __go_type_descriptor **in_types;
282 size_t num_args;
283 ffi_type **args;
284 int off;
285 int i;
286 ffi_type *rettype;
287 ffi_status status;
289 num_params = func->__in.__count;
290 in_types = ((const struct __go_type_descriptor **)
291 func->__in.__values);
293 num_args = num_params + (is_interface ? 1 : 0);
294 args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
295 i = 0;
296 off = 0;
297 if (is_interface)
299 args[0] = &ffi_type_pointer;
300 off = 1;
302 else if (is_method)
304 args[0] = &ffi_type_pointer;
305 i = 1;
307 for (; i < num_params; ++i)
308 args[i + off] = go_type_to_ffi (in_types[i]);
310 rettype = go_func_return_ffi (func);
312 status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args);
313 __go_assert (status == FFI_OK);
316 /* Get the total size required for the result parameters of a
317 function. */
319 static size_t
320 go_results_size (const struct __go_func_type *func)
322 int count;
323 const struct __go_type_descriptor **types;
324 size_t off;
325 size_t maxalign;
326 int i;
328 count = func->__out.__count;
329 if (count == 0)
330 return 0;
332 types = (const struct __go_type_descriptor **) func->__out.__values;
334 /* A single integer return value is always promoted to a full
335 word. */
336 if (count == 1)
338 switch (types[0]->__code & GO_CODE_MASK)
340 case GO_BOOL:
341 case GO_INT8:
342 case GO_INT16:
343 case GO_INT32:
344 case GO_UINT8:
345 case GO_UINT16:
346 case GO_UINT32:
347 case GO_INT:
348 case GO_UINT:
349 return sizeof (ffi_arg);
351 default:
352 break;
356 off = 0;
357 maxalign = 0;
358 for (i = 0; i < count; ++i)
360 size_t align;
362 align = types[i]->__field_align;
363 if (align > maxalign)
364 maxalign = align;
365 off = (off + align - 1) & ~ (align - 1);
366 off += types[i]->__size;
369 off = (off + maxalign - 1) & ~ (maxalign - 1);
371 return off;
374 /* Copy the results of calling a function via FFI from CALL_RESULT
375 into the addresses in RESULTS. */
377 static void
378 go_set_results (const struct __go_func_type *func, unsigned char *call_result,
379 void **results)
381 int count;
382 const struct __go_type_descriptor **types;
383 size_t off;
384 int i;
386 count = func->__out.__count;
387 if (count == 0)
388 return;
390 types = (const struct __go_type_descriptor **) func->__out.__values;
392 /* A single integer return value is always promoted to a full
393 word. */
394 if (count == 1)
396 switch (types[0]->__code & GO_CODE_MASK)
398 case GO_BOOL:
399 case GO_INT8:
400 case GO_INT16:
401 case GO_INT32:
402 case GO_UINT8:
403 case GO_UINT16:
404 case GO_UINT32:
405 case GO_INT:
406 case GO_UINT:
408 union
410 unsigned char buf[sizeof (ffi_arg)];
411 ffi_arg v;
412 } u;
413 ffi_arg v;
415 __builtin_memcpy (&u.buf, call_result, sizeof (ffi_arg));
416 v = u.v;
418 switch (types[0]->__size)
420 case 1:
422 uint8_t b;
424 b = (uint8_t) v;
425 __builtin_memcpy (results[0], &b, 1);
427 break;
429 case 2:
431 uint16_t s;
433 s = (uint16_t) v;
434 __builtin_memcpy (results[0], &s, 2);
436 break;
438 case 4:
440 uint32_t w;
442 w = (uint32_t) v;
443 __builtin_memcpy (results[0], &w, 4);
445 break;
447 case 8:
449 uint64_t d;
451 d = (uint64_t) v;
452 __builtin_memcpy (results[0], &d, 8);
454 break;
456 default:
457 abort ();
460 return;
462 default:
463 break;
467 off = 0;
468 for (i = 0; i < count; ++i)
470 size_t align;
471 size_t size;
473 align = types[i]->__field_align;
474 size = types[i]->__size;
475 off = (off + align - 1) & ~ (align - 1);
476 __builtin_memcpy (results[i], call_result + off, size);
477 off += size;
481 /* Call a function. The type of the function is FUNC_TYPE, and the
482 address is FUNC_ADDR. PARAMS is an array of parameter addresses.
483 RESULTS is an array of result addresses. */
485 void
486 reflect_call (const struct __go_func_type *func_type, const void *func_addr,
487 _Bool is_interface, _Bool is_method, void **params,
488 void **results)
490 ffi_cif cif;
491 unsigned char *call_result;
493 __go_assert ((func_type->__common.__code & GO_CODE_MASK) == GO_FUNC);
494 go_func_to_cif (func_type, is_interface, is_method, &cif);
496 call_result = (unsigned char *) malloc (go_results_size (func_type));
498 ffi_call (&cif, func_addr, call_result, params);
500 /* Some day we may need to free result values if RESULTS is
501 NULL. */
502 if (results != NULL)
503 go_set_results (func_type, call_result, results);
505 free (call_result);
508 #else /* !defined(USE_LIBFFI) */
510 void
511 reflect_call (const struct __go_func_type *func_type __attribute__ ((unused)),
512 const void *func_addr __attribute__ ((unused)),
513 _Bool is_interface __attribute__ ((unused)),
514 _Bool is_method __attribute__ ((unused)),
515 void **params __attribute__ ((unused)),
516 void **results __attribute__ ((unused)))
518 /* Without FFI there is nothing we can do. */
519 runtime_throw("libgo built without FFI does not support "
520 "reflect.Call or runtime.SetFinalizer");
523 #endif /* !defined(USE_LIBFFI) */