OSDN Git Service

PR go/48407
[pf3gnuchains/gcc-fork.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 "config.h"
12
13 #include "go-alloc.h"
14 #include "go-assert.h"
15 #include "go-type.h"
16 #include "runtime.h"
17
18 #ifdef USE_LIBFFI
19
20 #include "ffi.h"
21
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.  */
25
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));
48
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.  */
52
53 static ffi_type *
54 go_array_to_ffi (const struct __go_array_type *descriptor)
55 {
56   ffi_type *ret;
57   uintptr_t len;
58   ffi_type *element;
59   uintptr_t i;
60
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;
70 }
71
72 /* Return an ffi_type for a Go slice type.  This describes the
73    __go_open_array type defines in array.h.  */
74
75 static ffi_type *
76 go_slice_to_ffi (
77     const struct __go_slice_type *descriptor __attribute__ ((unused)))
78 {
79   ffi_type *ret;
80
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;
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
114    __go_string struct.  */
115
116 static ffi_type *
117 go_string_to_ffi (void)
118 {
119   ffi_type *ret;
120
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;
128 }
129
130 /* Return an ffi_type for a Go interface type.  This describes the
131    __go_interface and __go_empty_interface structs.  */
132
133 static ffi_type *
134 go_interface_to_ffi (void)
135 {
136   ffi_type *ret;
137
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;
145 }
146
147 /* Return an ffi_type for a Go complex type.  */
148
149 static ffi_type *
150 go_complex_to_ffi (ffi_type *float_type)
151 {
152   ffi_type *ret;
153
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;
161 }
162
163 /* Return an ffi_type for a type described by a
164    __go_type_descriptor.  */
165
166 static ffi_type *
167 go_type_to_ffi (const struct __go_type_descriptor *descriptor)
168 {
169   switch (descriptor->__code & GO_CODE_MASK)
170     {
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 ();
241     }
242 }
243
244 /* Return the return type for a function, given the number of out
245    parameters and their types.  */
246
247 static ffi_type *
248 go_func_return_ffi (const struct __go_func_type *func)
249 {
250   int count;
251   const struct __go_type_descriptor **types;
252   ffi_type *ret;
253   int i;
254
255   count = func->__out.__count;
256   if (count == 0)
257     return &ffi_type_void;
258
259   types = (const struct __go_type_descriptor **) func->__out.__values;
260
261   if (count == 1)
262     return go_type_to_ffi (types[0]);
263
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;
271 }
272
273 /* Build an ffi_cif structure for a function described by a
274    __go_func_type structure.  */
275
276 static void
277 go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
278                 _Bool is_method, ffi_cif *cif)
279 {
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;
288
289   num_params = func->__in.__count;
290   in_types = ((const struct __go_type_descriptor **)
291               func->__in.__values);
292
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)
298     {
299       args[0] = &ffi_type_pointer;
300       off = 1;
301     }
302   else if (is_method)
303     {
304       args[0] = &ffi_type_pointer;
305       i = 1;
306     }
307   for (; i < num_params; ++i)
308     args[i + off] = go_type_to_ffi (in_types[i]);
309
310   rettype = go_func_return_ffi (func);
311
312   status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args);
313   __go_assert (status == FFI_OK);
314 }
315
316 /* Get the total size required for the result parameters of a
317    function.  */
318
319 static size_t
320 go_results_size (const struct __go_func_type *func)
321 {
322   int count;
323   const struct __go_type_descriptor **types;
324   size_t off;
325   size_t maxalign;
326   int i;
327
328   count = func->__out.__count;
329   if (count == 0)
330     return 0;
331
332   types = (const struct __go_type_descriptor **) func->__out.__values;
333
334   /* A single integer return value is always promoted to a full
335      word.  */
336   if (count == 1)
337     {
338       switch (types[0]->__code & GO_CODE_MASK)
339         {
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);
350
351         default:
352           break;
353         }
354     }
355
356   off = 0;
357   maxalign = 0;
358   for (i = 0; i < count; ++i)
359     {
360       size_t align;
361
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;
367     }
368
369   off = (off + maxalign - 1) & ~ (maxalign - 1);
370
371   return off;
372 }
373
374 /* Copy the results of calling a function via FFI from CALL_RESULT
375    into the addresses in RESULTS.  */
376
377 static void
378 go_set_results (const struct __go_func_type *func, unsigned char *call_result,
379                 void **results)
380 {
381   int count;
382   const struct __go_type_descriptor **types;
383   size_t off;
384   int i;
385
386   count = func->__out.__count;
387   if (count == 0)
388     return;
389
390   types = (const struct __go_type_descriptor **) func->__out.__values;
391
392   /* A single integer return value is always promoted to a full
393      word.  */
394   if (count == 1)
395     {
396       switch (types[0]->__code & GO_CODE_MASK)
397         {
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:
407           {
408             union
409             {
410               unsigned char buf[sizeof (ffi_arg)];
411               ffi_arg v;
412             } u;
413             ffi_arg v;
414
415             __builtin_memcpy (&u.buf, call_result, sizeof (ffi_arg));
416             v = u.v;
417
418             switch (types[0]->__size)
419               {
420               case 1:
421                 {
422                   uint8_t b;
423
424                   b = (uint8_t) v;
425                   __builtin_memcpy (results[0], &b, 1);
426                 }
427                 break;
428
429               case 2:
430                 {
431                   uint16_t s;
432
433                   s = (uint16_t) v;
434                   __builtin_memcpy (results[0], &s, 2);
435                 }
436                 break;
437
438               case 4:
439                 {
440                   uint32_t w;
441
442                   w = (uint32_t) v;
443                   __builtin_memcpy (results[0], &w, 4);
444                 }
445                 break;
446
447               case 8:
448                 {
449                   uint64_t d;
450
451                   d = (uint64_t) v;
452                   __builtin_memcpy (results[0], &d, 8);
453                 }
454                 break;
455
456               default:
457                 abort ();
458               }
459           }
460           return;
461
462         default:
463           break;
464         }
465     }
466
467   off = 0;
468   for (i = 0; i < count; ++i)
469     {
470       size_t align;
471       size_t size;
472
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;
478     }
479 }
480
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.  */
484
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)
489 {
490   ffi_cif cif;
491   unsigned char *call_result;
492
493   __go_assert ((func_type->__common.__code & GO_CODE_MASK) == GO_FUNC);
494   go_func_to_cif (func_type, is_interface, is_method, &cif);
495
496   call_result = (unsigned char *) malloc (go_results_size (func_type));
497
498   ffi_call (&cif, func_addr, call_result, params);
499
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);
504
505   free (call_result);
506 }
507
508 #else /* !defined(USE_LIBFFI) */
509
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)))
517 {
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");
521 }
522
523 #endif /* !defined(USE_LIBFFI) */