2013-10-24 Jan-Benedict Glaw <jbglaw@lug-owl.de>
[official-gcc.git] / libgo / runtime / go-reflect-call.c
blob5cf370798bfe4b0e7049ce1df22c9fc17bc5d322
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 "runtime.h"
12 #include "go-alloc.h"
13 #include "go-assert.h"
14 #include "go-type.h"
16 #ifdef USE_LIBFFI
18 #include "ffi.h"
20 /* The functions in this file are only called from reflect_call. As
21 reflect_call calls a libffi function, which will be compiled
22 without -fsplit-stack, it will always run with a large stack. */
24 static ffi_type *go_array_to_ffi (const struct __go_array_type *)
25 __attribute__ ((no_split_stack));
26 static ffi_type *go_slice_to_ffi (const struct __go_slice_type *)
27 __attribute__ ((no_split_stack));
28 static ffi_type *go_struct_to_ffi (const struct __go_struct_type *)
29 __attribute__ ((no_split_stack));
30 static ffi_type *go_string_to_ffi (void) __attribute__ ((no_split_stack));
31 static ffi_type *go_interface_to_ffi (void) __attribute__ ((no_split_stack));
32 static ffi_type *go_complex_to_ffi (ffi_type *)
33 __attribute__ ((no_split_stack, unused));
34 static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *)
35 __attribute__ ((no_split_stack));
36 static ffi_type *go_func_return_ffi (const struct __go_func_type *)
37 __attribute__ ((no_split_stack));
38 static void go_func_to_cif (const struct __go_func_type *, _Bool, _Bool,
39 ffi_cif *)
40 __attribute__ ((no_split_stack));
41 static size_t go_results_size (const struct __go_func_type *)
42 __attribute__ ((no_split_stack));
43 static void go_set_results (const struct __go_func_type *, unsigned char *,
44 void **)
45 __attribute__ ((no_split_stack));
47 /* Return an ffi_type for a Go array type. The libffi library does
48 not have any builtin support for passing arrays as values. We work
49 around this by pretending that the array is a struct. */
51 static ffi_type *
52 go_array_to_ffi (const struct __go_array_type *descriptor)
54 ffi_type *ret;
55 uintptr_t len;
56 ffi_type *element;
57 uintptr_t i;
59 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
60 ret->type = FFI_TYPE_STRUCT;
61 len = descriptor->__len;
62 ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *));
63 element = go_type_to_ffi (descriptor->__element_type);
64 for (i = 0; i < len; ++i)
65 ret->elements[i] = element;
66 ret->elements[len] = NULL;
67 return ret;
70 /* Return an ffi_type for a Go slice type. This describes the
71 __go_open_array type defines in array.h. */
73 static ffi_type *
74 go_slice_to_ffi (
75 const struct __go_slice_type *descriptor __attribute__ ((unused)))
77 ffi_type *ret;
78 ffi_type *ffi_intgo;
80 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
81 ret->type = FFI_TYPE_STRUCT;
82 ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
83 ret->elements[0] = &ffi_type_pointer;
84 ffi_intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
85 ret->elements[1] = ffi_intgo;
86 ret->elements[2] = ffi_intgo;
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 String
114 struct. */
116 static ffi_type *
117 go_string_to_ffi (void)
119 ffi_type *ret;
120 ffi_type *ffi_intgo;
122 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
123 ret->type = FFI_TYPE_STRUCT;
124 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
125 ret->elements[0] = &ffi_type_pointer;
126 ffi_intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
127 ret->elements[1] = ffi_intgo;
128 ret->elements[2] = NULL;
129 return ret;
132 /* Return an ffi_type for a Go interface type. This describes the
133 __go_interface and __go_empty_interface structs. */
135 static ffi_type *
136 go_interface_to_ffi (void)
138 ffi_type *ret;
140 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
141 ret->type = FFI_TYPE_STRUCT;
142 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
143 ret->elements[0] = &ffi_type_pointer;
144 ret->elements[1] = &ffi_type_pointer;
145 ret->elements[2] = NULL;
146 return ret;
149 /* Return an ffi_type for a Go complex type. */
151 static ffi_type *
152 go_complex_to_ffi (ffi_type *float_type)
154 ffi_type *ret;
156 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
157 ret->type = FFI_TYPE_STRUCT;
158 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
159 ret->elements[0] = float_type;
160 ret->elements[1] = float_type;
161 ret->elements[2] = NULL;
162 return ret;
165 /* Return an ffi_type for a type described by a
166 __go_type_descriptor. */
168 static ffi_type *
169 go_type_to_ffi (const struct __go_type_descriptor *descriptor)
171 switch (descriptor->__code & GO_CODE_MASK)
173 case GO_BOOL:
174 if (sizeof (_Bool) == 1)
175 return &ffi_type_uint8;
176 else if (sizeof (_Bool) == sizeof (int))
177 return &ffi_type_uint;
178 abort ();
179 case GO_FLOAT32:
180 if (sizeof (float) == 4)
181 return &ffi_type_float;
182 abort ();
183 case GO_FLOAT64:
184 if (sizeof (double) == 8)
185 return &ffi_type_double;
186 abort ();
187 case GO_COMPLEX64:
188 #ifdef __alpha__
189 runtime_throw("the libffi library does not support Complex64 type with "
190 "reflect.Call or runtime.SetFinalizer");
191 #else
192 if (sizeof (float) == 4)
193 return go_complex_to_ffi (&ffi_type_float);
194 abort ();
195 #endif
196 case GO_COMPLEX128:
197 #ifdef __alpha__
198 runtime_throw("the libffi library does not support Complex128 type with "
199 "reflect.Call or runtime.SetFinalizer");
200 #else
201 if (sizeof (double) == 8)
202 return go_complex_to_ffi (&ffi_type_double);
203 abort ();
204 #endif
205 case GO_INT16:
206 return &ffi_type_sint16;
207 case GO_INT32:
208 return &ffi_type_sint32;
209 case GO_INT64:
210 return &ffi_type_sint64;
211 case GO_INT8:
212 return &ffi_type_sint8;
213 case GO_INT:
214 return sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
215 case GO_UINT16:
216 return &ffi_type_uint16;
217 case GO_UINT32:
218 return &ffi_type_uint32;
219 case GO_UINT64:
220 return &ffi_type_uint64;
221 case GO_UINT8:
222 return &ffi_type_uint8;
223 case GO_UINT:
224 return sizeof (uintgo) == 4 ? &ffi_type_uint32 : &ffi_type_uint64;
225 case GO_UINTPTR:
226 if (sizeof (void *) == 2)
227 return &ffi_type_uint16;
228 else if (sizeof (void *) == 4)
229 return &ffi_type_uint32;
230 else if (sizeof (void *) == 8)
231 return &ffi_type_uint64;
232 abort ();
233 case GO_ARRAY:
234 return go_array_to_ffi ((const struct __go_array_type *) descriptor);
235 case GO_SLICE:
236 return go_slice_to_ffi ((const struct __go_slice_type *) descriptor);
237 case GO_STRUCT:
238 return go_struct_to_ffi ((const struct __go_struct_type *) descriptor);
239 case GO_STRING:
240 return go_string_to_ffi ();
241 case GO_INTERFACE:
242 return go_interface_to_ffi ();
243 case GO_CHAN:
244 case GO_FUNC:
245 case GO_MAP:
246 case GO_PTR:
247 case GO_UNSAFE_POINTER:
248 /* These types are always pointers, and for FFI purposes nothing
249 else matters. */
250 return &ffi_type_pointer;
251 default:
252 abort ();
256 /* Return the return type for a function, given the number of out
257 parameters and their types. */
259 static ffi_type *
260 go_func_return_ffi (const struct __go_func_type *func)
262 int count;
263 const struct __go_type_descriptor **types;
264 ffi_type *ret;
265 int i;
267 count = func->__out.__count;
268 if (count == 0)
269 return &ffi_type_void;
271 types = (const struct __go_type_descriptor **) func->__out.__values;
273 if (count == 1)
274 return go_type_to_ffi (types[0]);
276 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
277 ret->type = FFI_TYPE_STRUCT;
278 ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *));
279 for (i = 0; i < count; ++i)
280 ret->elements[i] = go_type_to_ffi (types[i]);
281 ret->elements[count] = NULL;
282 return ret;
285 /* Build an ffi_cif structure for a function described by a
286 __go_func_type structure. */
288 static void
289 go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
290 _Bool is_method, ffi_cif *cif)
292 int num_params;
293 const struct __go_type_descriptor **in_types;
294 size_t num_args;
295 ffi_type **args;
296 int off;
297 int i;
298 ffi_type *rettype;
299 ffi_status status;
301 num_params = func->__in.__count;
302 in_types = ((const struct __go_type_descriptor **)
303 func->__in.__values);
305 num_args = num_params + (is_interface ? 1 : 0);
306 args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
307 i = 0;
308 off = 0;
309 if (is_interface)
311 args[0] = &ffi_type_pointer;
312 off = 1;
314 else if (is_method)
316 args[0] = &ffi_type_pointer;
317 i = 1;
319 for (; i < num_params; ++i)
320 args[i + off] = go_type_to_ffi (in_types[i]);
322 rettype = go_func_return_ffi (func);
324 status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args);
325 __go_assert (status == FFI_OK);
328 /* Get the total size required for the result parameters of a
329 function. */
331 static size_t
332 go_results_size (const struct __go_func_type *func)
334 int count;
335 const struct __go_type_descriptor **types;
336 size_t off;
337 size_t maxalign;
338 int i;
340 count = func->__out.__count;
341 if (count == 0)
342 return 0;
344 types = (const struct __go_type_descriptor **) func->__out.__values;
346 /* A single integer return value is always promoted to a full
347 word. */
348 if (count == 1)
350 switch (types[0]->__code & GO_CODE_MASK)
352 case GO_BOOL:
353 case GO_INT8:
354 case GO_INT16:
355 case GO_INT32:
356 case GO_UINT8:
357 case GO_UINT16:
358 case GO_UINT32:
359 case GO_INT:
360 case GO_UINT:
361 return sizeof (ffi_arg);
363 default:
364 break;
368 off = 0;
369 maxalign = 0;
370 for (i = 0; i < count; ++i)
372 size_t align;
374 align = types[i]->__field_align;
375 if (align > maxalign)
376 maxalign = align;
377 off = (off + align - 1) & ~ (align - 1);
378 off += types[i]->__size;
381 off = (off + maxalign - 1) & ~ (maxalign - 1);
383 return off;
386 /* Copy the results of calling a function via FFI from CALL_RESULT
387 into the addresses in RESULTS. */
389 static void
390 go_set_results (const struct __go_func_type *func, unsigned char *call_result,
391 void **results)
393 int count;
394 const struct __go_type_descriptor **types;
395 size_t off;
396 int i;
398 count = func->__out.__count;
399 if (count == 0)
400 return;
402 types = (const struct __go_type_descriptor **) func->__out.__values;
404 /* A single integer return value is always promoted to a full
405 word. */
406 if (count == 1)
408 switch (types[0]->__code & GO_CODE_MASK)
410 case GO_BOOL:
411 case GO_INT8:
412 case GO_INT16:
413 case GO_INT32:
414 case GO_UINT8:
415 case GO_UINT16:
416 case GO_UINT32:
417 case GO_INT:
418 case GO_UINT:
420 union
422 unsigned char buf[sizeof (ffi_arg)];
423 ffi_arg v;
424 } u;
425 ffi_arg v;
427 __builtin_memcpy (&u.buf, call_result, sizeof (ffi_arg));
428 v = u.v;
430 switch (types[0]->__size)
432 case 1:
434 uint8_t b;
436 b = (uint8_t) v;
437 __builtin_memcpy (results[0], &b, 1);
439 break;
441 case 2:
443 uint16_t s;
445 s = (uint16_t) v;
446 __builtin_memcpy (results[0], &s, 2);
448 break;
450 case 4:
452 uint32_t w;
454 w = (uint32_t) v;
455 __builtin_memcpy (results[0], &w, 4);
457 break;
459 case 8:
461 uint64_t d;
463 d = (uint64_t) v;
464 __builtin_memcpy (results[0], &d, 8);
466 break;
468 default:
469 abort ();
472 return;
474 default:
475 break;
479 off = 0;
480 for (i = 0; i < count; ++i)
482 size_t align;
483 size_t size;
485 align = types[i]->__field_align;
486 size = types[i]->__size;
487 off = (off + align - 1) & ~ (align - 1);
488 __builtin_memcpy (results[i], call_result + off, size);
489 off += size;
493 /* Call a function. The type of the function is FUNC_TYPE, and the
494 closure is FUNC_VAL. PARAMS is an array of parameter addresses.
495 RESULTS is an array of result addresses.
497 If IS_INTERFACE is true this is a call to an interface method and
498 the first argument is the receiver, which is always a pointer.
499 This argument, the receiver, is not described in FUNC_TYPE.
501 If IS_METHOD is true this is a call to a method expression. The
502 first argument is the receiver. It is described in FUNC_TYPE, but
503 regardless of FUNC_TYPE, it is passed as a pointer.
505 If neither IS_INTERFACE nor IS_METHOD is true then we are calling a
506 function indirectly, and we must pass a closure pointer via
507 __go_set_closure. The pointer to pass is simply FUNC_VAL. */
509 void
510 reflect_call (const struct __go_func_type *func_type, FuncVal *func_val,
511 _Bool is_interface, _Bool is_method, void **params,
512 void **results)
514 ffi_cif cif;
515 unsigned char *call_result;
517 __go_assert ((func_type->__common.__code & GO_CODE_MASK) == GO_FUNC);
518 go_func_to_cif (func_type, is_interface, is_method, &cif);
520 call_result = (unsigned char *) malloc (go_results_size (func_type));
522 if (!is_interface && !is_method)
523 __go_set_closure (func_val);
524 ffi_call (&cif, func_val->fn, call_result, params);
526 /* Some day we may need to free result values if RESULTS is
527 NULL. */
528 if (results != NULL)
529 go_set_results (func_type, call_result, results);
531 free (call_result);
534 #else /* !defined(USE_LIBFFI) */
536 void
537 reflect_call (const struct __go_func_type *func_type __attribute__ ((unused)),
538 FuncVal *func_val __attribute__ ((unused)),
539 _Bool is_interface __attribute__ ((unused)),
540 _Bool is_method __attribute__ ((unused)),
541 void **params __attribute__ ((unused)),
542 void **results __attribute__ ((unused)))
544 /* Without FFI there is nothing we can do. */
545 runtime_throw("libgo built without FFI does not support "
546 "reflect.Call or runtime.SetFinalizer");
549 #endif /* !defined(USE_LIBFFI) */