OSDN Git Service

a818dba438ee693f35b4a0a15b58d81a057a66d9
[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 "ffi.h"
12
13 #include "go-alloc.h"
14 #include "go-assert.h"
15 #include "go-type.h"
16 #include "runtime.h"
17
18 /* The functions in this file are only called from reflect_call.  As
19    reflect_call calls a libffi function, which will be compiled
20    without -fsplit-stack, it will always run with a large stack.  */
21
22 static ffi_type *go_array_to_ffi (const struct __go_array_type *)
23   __attribute__ ((no_split_stack));
24 static ffi_type *go_slice_to_ffi (const struct __go_slice_type *)
25   __attribute__ ((no_split_stack));
26 static ffi_type *go_struct_to_ffi (const struct __go_struct_type *)
27   __attribute__ ((no_split_stack));
28 static ffi_type *go_string_to_ffi (void) __attribute__ ((no_split_stack));
29 static ffi_type *go_interface_to_ffi (void) __attribute__ ((no_split_stack));
30 static ffi_type *go_complex_to_ffi (ffi_type *)
31   __attribute__ ((no_split_stack));
32 static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *)
33   __attribute__ ((no_split_stack));
34 static ffi_type *go_func_return_ffi (const struct __go_func_type *)
35   __attribute__ ((no_split_stack));
36 static void go_func_to_cif (const struct __go_func_type *, _Bool, _Bool,
37                             ffi_cif *)
38   __attribute__ ((no_split_stack));
39 static size_t go_results_size (const struct __go_func_type *)
40   __attribute__ ((no_split_stack));
41 static void go_set_results (const struct __go_func_type *, unsigned char *,
42                             void **)
43   __attribute__ ((no_split_stack));
44
45 /* Return an ffi_type for a Go array type.  The libffi library does
46    not have any builtin support for passing arrays as values.  We work
47    around this by pretending that the array is a struct.  */
48
49 static ffi_type *
50 go_array_to_ffi (const struct __go_array_type *descriptor)
51 {
52   ffi_type *ret;
53   uintptr_t len;
54   ffi_type *element;
55   uintptr_t i;
56
57   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
58   ret->type = FFI_TYPE_STRUCT;
59   len = descriptor->__len;
60   ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *));
61   element = go_type_to_ffi (descriptor->__element_type);
62   for (i = 0; i < len; ++i)
63     ret->elements[i] = element;
64   ret->elements[len] = NULL;
65   return ret;
66 }
67
68 /* Return an ffi_type for a Go slice type.  This describes the
69    __go_open_array type defines in array.h.  */
70
71 static ffi_type *
72 go_slice_to_ffi (
73     const struct __go_slice_type *descriptor __attribute__ ((unused)))
74 {
75   ffi_type *ret;
76
77   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
78   ret->type = FFI_TYPE_STRUCT;
79   ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
80   ret->elements[0] = &ffi_type_pointer;
81   ret->elements[1] = &ffi_type_sint;
82   ret->elements[2] = &ffi_type_sint;
83   ret->elements[3] = NULL;
84   return ret;
85 }
86
87 /* Return an ffi_type for a Go struct type.  */
88
89 static ffi_type *
90 go_struct_to_ffi (const struct __go_struct_type *descriptor)
91 {
92   ffi_type *ret;
93   int field_count;
94   const struct __go_struct_field *fields;
95   int i;
96
97   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
98   ret->type = FFI_TYPE_STRUCT;
99   field_count = descriptor->__fields.__count;
100   fields = (const struct __go_struct_field *) descriptor->__fields.__values;
101   ret->elements = (ffi_type **) __go_alloc ((field_count + 1)
102                                             * sizeof (ffi_type *));
103   for (i = 0; i < field_count; ++i)
104     ret->elements[i] = go_type_to_ffi (fields[i].__type);
105   ret->elements[field_count] = NULL;
106   return ret;
107 }
108
109 /* Return an ffi_type for a Go string type.  This describes the
110    __go_string struct.  */
111
112 static ffi_type *
113 go_string_to_ffi (void)
114 {
115   ffi_type *ret;
116
117   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
118   ret->type = FFI_TYPE_STRUCT;
119   ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
120   ret->elements[0] = &ffi_type_pointer;
121   ret->elements[1] = &ffi_type_sint;
122   ret->elements[2] = NULL;
123   return ret;
124 }
125
126 /* Return an ffi_type for a Go interface type.  This describes the
127    __go_interface and __go_empty_interface structs.  */
128
129 static ffi_type *
130 go_interface_to_ffi (void)
131 {
132   ffi_type *ret;
133
134   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
135   ret->type = FFI_TYPE_STRUCT;
136   ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
137   ret->elements[0] = &ffi_type_pointer;
138   ret->elements[1] = &ffi_type_pointer;
139   ret->elements[2] = NULL;
140   return ret;
141 }
142
143 /* Return an ffi_type for a Go complex type.  */
144
145 static ffi_type *
146 go_complex_to_ffi (ffi_type *float_type)
147 {
148   ffi_type *ret;
149
150   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
151   ret->type = FFI_TYPE_STRUCT;
152   ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
153   ret->elements[0] = float_type;
154   ret->elements[1] = float_type;
155   ret->elements[2] = NULL;
156   return ret;
157 }
158
159 /* Return an ffi_type for a type described by a
160    __go_type_descriptor.  */
161
162 static ffi_type *
163 go_type_to_ffi (const struct __go_type_descriptor *descriptor)
164 {
165   switch (descriptor->__code & GO_CODE_MASK)
166     {
167     case GO_BOOL:
168       if (sizeof (_Bool) == 1)
169         return &ffi_type_uint8;
170       else if (sizeof (_Bool) == sizeof (int))
171         return &ffi_type_uint;
172       abort ();
173     case GO_FLOAT32:
174       if (sizeof (float) == 4)
175         return &ffi_type_float;
176       abort ();
177     case GO_FLOAT64:
178       if (sizeof (double) == 8)
179         return &ffi_type_double;
180       abort ();
181     case GO_COMPLEX64:
182       if (sizeof (float) == 4)
183         return go_complex_to_ffi (&ffi_type_float);
184       abort ();
185     case GO_COMPLEX128:
186       if (sizeof (double) == 8)
187         return go_complex_to_ffi (&ffi_type_double);
188       abort ();
189     case GO_INT16:
190       return &ffi_type_sint16;
191     case GO_INT32:
192       return &ffi_type_sint32;
193     case GO_INT64:
194       return &ffi_type_sint64;
195     case GO_INT8:
196       return &ffi_type_sint8;
197     case GO_INT:
198       return &ffi_type_sint;
199     case GO_UINT16:
200       return &ffi_type_uint16;
201     case GO_UINT32:
202       return &ffi_type_uint32;
203     case GO_UINT64:
204       return &ffi_type_uint64;
205     case GO_UINT8:
206       return &ffi_type_uint8;
207     case GO_UINT:
208       return &ffi_type_uint;
209     case GO_UINTPTR:
210       if (sizeof (void *) == 2)
211         return &ffi_type_uint16;
212       else if (sizeof (void *) == 4)
213         return &ffi_type_uint32;
214       else if (sizeof (void *) == 8)
215         return &ffi_type_uint64;
216       abort ();
217     case GO_ARRAY:
218       return go_array_to_ffi ((const struct __go_array_type *) descriptor);
219     case GO_SLICE:
220       return go_slice_to_ffi ((const struct __go_slice_type *) descriptor);
221     case GO_STRUCT:
222       return go_struct_to_ffi ((const struct __go_struct_type *) descriptor);
223     case GO_STRING:
224       return go_string_to_ffi ();
225     case GO_INTERFACE:
226       return go_interface_to_ffi ();
227     case GO_CHAN:
228     case GO_FUNC:
229     case GO_MAP:
230     case GO_PTR:
231     case GO_UNSAFE_POINTER:
232       /* These types are always pointers, and for FFI purposes nothing
233          else matters.  */
234       return &ffi_type_pointer;
235     default:
236       abort ();
237     }
238 }
239
240 /* Return the return type for a function, given the number of out
241    parameters and their types.  */
242
243 static ffi_type *
244 go_func_return_ffi (const struct __go_func_type *func)
245 {
246   int count;
247   const struct __go_type_descriptor **types;
248   ffi_type *ret;
249   int i;
250
251   count = func->__out.__count;
252   if (count == 0)
253     return &ffi_type_void;
254
255   types = (const struct __go_type_descriptor **) func->__out.__values;
256
257   if (count == 1)
258     return go_type_to_ffi (types[0]);
259
260   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
261   ret->type = FFI_TYPE_STRUCT;
262   ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *));
263   for (i = 0; i < count; ++i)
264     ret->elements[i] = go_type_to_ffi (types[i]);
265   ret->elements[count] = NULL;
266   return ret;
267 }
268
269 /* Build an ffi_cif structure for a function described by a
270    __go_func_type structure.  */
271
272 static void
273 go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
274                 _Bool is_method, ffi_cif *cif)
275 {
276   int num_params;
277   const struct __go_type_descriptor **in_types;
278   size_t num_args;
279   ffi_type **args;
280   int off;
281   int i;
282   ffi_type *rettype;
283   ffi_status status;
284
285   num_params = func->__in.__count;
286   in_types = ((const struct __go_type_descriptor **)
287               func->__in.__values);
288
289   num_args = num_params + (is_interface ? 1 : 0);
290   args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
291   i = 0;
292   off = 0;
293   if (is_interface)
294     {
295       args[0] = &ffi_type_pointer;
296       off = 1;
297     }
298   else if (is_method)
299     {
300       args[0] = &ffi_type_pointer;
301       i = 1;
302     }
303   for (; i < num_params; ++i)
304     args[i + off] = go_type_to_ffi (in_types[i]);
305
306   rettype = go_func_return_ffi (func);
307
308   status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args);
309   __go_assert (status == FFI_OK);
310 }
311
312 /* Get the total size required for the result parameters of a
313    function.  */
314
315 static size_t
316 go_results_size (const struct __go_func_type *func)
317 {
318   int count;
319   const struct __go_type_descriptor **types;
320   size_t off;
321   size_t maxalign;
322   int i;
323
324   count = func->__out.__count;
325   if (count == 0)
326     return 0;
327
328   types = (const struct __go_type_descriptor **) func->__out.__values;
329
330   /* A single integer return value is always promoted to a full
331      word.  */
332   if (count == 1)
333     {
334       switch (types[0]->__code & GO_CODE_MASK)
335         {
336         case GO_BOOL:
337         case GO_INT8:
338         case GO_INT16:
339         case GO_INT32:
340         case GO_UINT8:
341         case GO_UINT16:
342         case GO_UINT32:
343         case GO_INT:
344         case GO_UINT:
345           return sizeof (ffi_arg);
346
347         default:
348           break;
349         }
350     }
351
352   off = 0;
353   maxalign = 0;
354   for (i = 0; i < count; ++i)
355     {
356       size_t align;
357
358       align = types[i]->__field_align;
359       if (align > maxalign)
360         maxalign = align;
361       off = (off + align - 1) & ~ (align - 1);
362       off += types[i]->__size;
363     }
364
365   off = (off + maxalign - 1) & ~ (maxalign - 1);
366
367   return off;
368 }
369
370 /* Copy the results of calling a function via FFI from CALL_RESULT
371    into the addresses in RESULTS.  */
372
373 static void
374 go_set_results (const struct __go_func_type *func, unsigned char *call_result,
375                 void **results)
376 {
377   int count;
378   const struct __go_type_descriptor **types;
379   size_t off;
380   int i;
381
382   count = func->__out.__count;
383   if (count == 0)
384     return;
385
386   types = (const struct __go_type_descriptor **) func->__out.__values;
387
388   /* A single integer return value is always promoted to a full
389      word.  */
390   if (count == 1)
391     {
392       switch (types[0]->__code & GO_CODE_MASK)
393         {
394         case GO_BOOL:
395         case GO_INT8:
396         case GO_INT16:
397         case GO_INT32:
398         case GO_UINT8:
399         case GO_UINT16:
400         case GO_UINT32:
401         case GO_INT:
402         case GO_UINT:
403           {
404             union
405             {
406               unsigned char buf[sizeof (ffi_arg)];
407               ffi_arg v;
408             } u;
409             ffi_arg v;
410
411             __builtin_memcpy (&u.buf, call_result, sizeof (ffi_arg));
412             v = u.v;
413
414             switch (types[0]->__size)
415               {
416               case 1:
417                 {
418                   uint8_t b;
419
420                   b = (uint8_t) v;
421                   __builtin_memcpy (results[0], &b, 1);
422                 }
423                 break;
424
425               case 2:
426                 {
427                   uint16_t s;
428
429                   s = (uint16_t) v;
430                   __builtin_memcpy (results[0], &s, 2);
431                 }
432                 break;
433
434               case 4:
435                 {
436                   uint32_t w;
437
438                   w = (uint32_t) v;
439                   __builtin_memcpy (results[0], &w, 4);
440                 }
441                 break;
442
443               case 8:
444                 {
445                   uint64_t d;
446
447                   d = (uint64_t) v;
448                   __builtin_memcpy (results[0], &d, 8);
449                 }
450                 break;
451
452               default:
453                 abort ();
454               }
455           }
456           return;
457
458         default:
459           break;
460         }
461     }
462
463   off = 0;
464   for (i = 0; i < count; ++i)
465     {
466       size_t align;
467       size_t size;
468
469       align = types[i]->__field_align;
470       size = types[i]->__size;
471       off = (off + align - 1) & ~ (align - 1);
472       __builtin_memcpy (results[i], call_result + off, size);
473       off += size;
474     }
475 }
476
477 /* Call a function.  The type of the function is FUNC_TYPE, and the
478    address is FUNC_ADDR.  PARAMS is an array of parameter addresses.
479    RESULTS is an array of result addresses.  */
480
481 void
482 reflect_call (const struct __go_func_type *func_type, const void *func_addr,
483               _Bool is_interface, _Bool is_method, void **params,
484               void **results)
485 {
486   ffi_cif cif;
487   unsigned char *call_result;
488
489   __go_assert ((func_type->__common.__code & GO_CODE_MASK) == GO_FUNC);
490   go_func_to_cif (func_type, is_interface, is_method, &cif);
491
492   call_result = (unsigned char *) malloc (go_results_size (func_type));
493
494   ffi_call (&cif, func_addr, call_result, params);
495
496   /* Some day we may need to free result values if RESULTS is
497      NULL.  */
498   if (results != NULL)
499     go_set_results (func_type, call_result, results);
500
501   free (call_result);
502 }