Importing Upstream version 4.8.2
[platform/upstream/gcc48.git] / libgo / runtime / go-reflect-call.c
1 /* go-reflect-call.c -- call reflection support for Go.
2
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.  */
6
7 #include <stdio.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10
11 #include "runtime.h"
12 #include "go-alloc.h"
13 #include "go-assert.h"
14 #include "go-type.h"
15
16 #ifdef USE_LIBFFI
17
18 #include "ffi.h"
19
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.  */
23
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));
46
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.  */
50
51 static ffi_type *
52 go_array_to_ffi (const struct __go_array_type *descriptor)
53 {
54   ffi_type *ret;
55   uintptr_t len;
56   ffi_type *element;
57   uintptr_t i;
58
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;
68 }
69
70 /* Return an ffi_type for a Go slice type.  This describes the
71    __go_open_array type defines in array.h.  */
72
73 static ffi_type *
74 go_slice_to_ffi (
75     const struct __go_slice_type *descriptor __attribute__ ((unused)))
76 {
77   ffi_type *ret;
78   ffi_type *ffi_intgo;
79
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;
89 }
90
91 /* Return an ffi_type for a Go struct type.  */
92
93 static ffi_type *
94 go_struct_to_ffi (const struct __go_struct_type *descriptor)
95 {
96   ffi_type *ret;
97   int field_count;
98   const struct __go_struct_field *fields;
99   int i;
100
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;
111 }
112
113 /* Return an ffi_type for a Go string type.  This describes the String
114    struct.  */
115
116 static ffi_type *
117 go_string_to_ffi (void)
118 {
119   ffi_type *ret;
120   ffi_type *ffi_intgo;
121
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;
130 }
131
132 /* Return an ffi_type for a Go interface type.  This describes the
133    __go_interface and __go_empty_interface structs.  */
134
135 static ffi_type *
136 go_interface_to_ffi (void)
137 {
138   ffi_type *ret;
139
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;
147 }
148
149 /* Return an ffi_type for a Go complex type.  */
150
151 static ffi_type *
152 go_complex_to_ffi (ffi_type *float_type)
153 {
154   ffi_type *ret;
155
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;
163 }
164
165 /* Return an ffi_type for a type described by a
166    __go_type_descriptor.  */
167
168 static ffi_type *
169 go_type_to_ffi (const struct __go_type_descriptor *descriptor)
170 {
171   switch (descriptor->__code & GO_CODE_MASK)
172     {
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 ();
253     }
254 }
255
256 /* Return the return type for a function, given the number of out
257    parameters and their types.  */
258
259 static ffi_type *
260 go_func_return_ffi (const struct __go_func_type *func)
261 {
262   int count;
263   const struct __go_type_descriptor **types;
264   ffi_type *ret;
265   int i;
266
267   count = func->__out.__count;
268   if (count == 0)
269     return &ffi_type_void;
270
271   types = (const struct __go_type_descriptor **) func->__out.__values;
272
273   if (count == 1)
274     return go_type_to_ffi (types[0]);
275
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;
283 }
284
285 /* Build an ffi_cif structure for a function described by a
286    __go_func_type structure.  */
287
288 static void
289 go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
290                 _Bool is_method, ffi_cif *cif)
291 {
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;
300
301   num_params = func->__in.__count;
302   in_types = ((const struct __go_type_descriptor **)
303               func->__in.__values);
304
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)
310     {
311       args[0] = &ffi_type_pointer;
312       off = 1;
313     }
314   else if (is_method)
315     {
316       args[0] = &ffi_type_pointer;
317       i = 1;
318     }
319   for (; i < num_params; ++i)
320     args[i + off] = go_type_to_ffi (in_types[i]);
321
322   rettype = go_func_return_ffi (func);
323
324   status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args);
325   __go_assert (status == FFI_OK);
326 }
327
328 /* Get the total size required for the result parameters of a
329    function.  */
330
331 static size_t
332 go_results_size (const struct __go_func_type *func)
333 {
334   int count;
335   const struct __go_type_descriptor **types;
336   size_t off;
337   size_t maxalign;
338   int i;
339
340   count = func->__out.__count;
341   if (count == 0)
342     return 0;
343
344   types = (const struct __go_type_descriptor **) func->__out.__values;
345
346   /* A single integer return value is always promoted to a full
347      word.  */
348   if (count == 1)
349     {
350       switch (types[0]->__code & GO_CODE_MASK)
351         {
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);
362
363         default:
364           break;
365         }
366     }
367
368   off = 0;
369   maxalign = 0;
370   for (i = 0; i < count; ++i)
371     {
372       size_t align;
373
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;
379     }
380
381   off = (off + maxalign - 1) & ~ (maxalign - 1);
382
383   return off;
384 }
385
386 /* Copy the results of calling a function via FFI from CALL_RESULT
387    into the addresses in RESULTS.  */
388
389 static void
390 go_set_results (const struct __go_func_type *func, unsigned char *call_result,
391                 void **results)
392 {
393   int count;
394   const struct __go_type_descriptor **types;
395   size_t off;
396   int i;
397
398   count = func->__out.__count;
399   if (count == 0)
400     return;
401
402   types = (const struct __go_type_descriptor **) func->__out.__values;
403
404   /* A single integer return value is always promoted to a full
405      word.  */
406   if (count == 1)
407     {
408       switch (types[0]->__code & GO_CODE_MASK)
409         {
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:
419           {
420             union
421             {
422               unsigned char buf[sizeof (ffi_arg)];
423               ffi_arg v;
424             } u;
425             ffi_arg v;
426
427             __builtin_memcpy (&u.buf, call_result, sizeof (ffi_arg));
428             v = u.v;
429
430             switch (types[0]->__size)
431               {
432               case 1:
433                 {
434                   uint8_t b;
435
436                   b = (uint8_t) v;
437                   __builtin_memcpy (results[0], &b, 1);
438                 }
439                 break;
440
441               case 2:
442                 {
443                   uint16_t s;
444
445                   s = (uint16_t) v;
446                   __builtin_memcpy (results[0], &s, 2);
447                 }
448                 break;
449
450               case 4:
451                 {
452                   uint32_t w;
453
454                   w = (uint32_t) v;
455                   __builtin_memcpy (results[0], &w, 4);
456                 }
457                 break;
458
459               case 8:
460                 {
461                   uint64_t d;
462
463                   d = (uint64_t) v;
464                   __builtin_memcpy (results[0], &d, 8);
465                 }
466                 break;
467
468               default:
469                 abort ();
470               }
471           }
472           return;
473
474         default:
475           break;
476         }
477     }
478
479   off = 0;
480   for (i = 0; i < count; ++i)
481     {
482       size_t align;
483       size_t size;
484
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;
490     }
491 }
492
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.
496
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.
500
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.
504
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.  */
508
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)
513 {
514   ffi_cif cif;
515   unsigned char *call_result;
516
517   __go_assert ((func_type->__common.__code & GO_CODE_MASK) == GO_FUNC);
518   go_func_to_cif (func_type, is_interface, is_method, &cif);
519
520   call_result = (unsigned char *) malloc (go_results_size (func_type));
521
522   if (!is_interface && !is_method)
523     __go_set_closure (func_val);
524   ffi_call (&cif, func_val->fn, call_result, params);
525
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);
530
531   free (call_result);
532 }
533
534 #else /* !defined(USE_LIBFFI) */
535
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)))
543 {
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");
547 }
548
549 #endif /* !defined(USE_LIBFFI) */