github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/runtime/go-ffi.c (about) 1 /* go-ffi.c -- convert Go type description to libffi. 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 and 21 reflect.ffi. As these functions call libffi functions, which will 22 be compiled without -fsplit-stack, they will always run with a 23 large stack. */ 24 25 static ffi_type *go_array_to_ffi (const struct __go_array_type *) 26 __attribute__ ((no_split_stack)); 27 static ffi_type *go_slice_to_ffi (const struct __go_slice_type *) 28 __attribute__ ((no_split_stack)); 29 static ffi_type *go_struct_to_ffi (const struct __go_struct_type *) 30 __attribute__ ((no_split_stack)); 31 static ffi_type *go_string_to_ffi (void) __attribute__ ((no_split_stack)); 32 static ffi_type *go_interface_to_ffi (void) __attribute__ ((no_split_stack)); 33 static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *) 34 __attribute__ ((no_split_stack)); 35 static ffi_type *go_func_return_ffi (const struct __go_func_type *) 36 __attribute__ ((no_split_stack)); 37 38 /* Return an ffi_type for a Go array type. The libffi library does 39 not have any builtin support for passing arrays as values. We work 40 around this by pretending that the array is a struct. */ 41 42 static ffi_type * 43 go_array_to_ffi (const struct __go_array_type *descriptor) 44 { 45 ffi_type *ret; 46 uintptr_t len; 47 ffi_type *element; 48 uintptr_t i; 49 50 ret = (ffi_type *) __go_alloc (sizeof (ffi_type)); 51 ret->type = FFI_TYPE_STRUCT; 52 len = descriptor->__len; 53 if (len == 0) 54 { 55 /* The libffi library won't accept an empty struct. */ 56 ret->elements = (ffi_type **) __go_alloc (2 * sizeof (ffi_type *)); 57 ret->elements[0] = &ffi_type_void; 58 ret->elements[1] = NULL; 59 return ret; 60 } 61 ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *)); 62 element = go_type_to_ffi (descriptor->__element_type); 63 for (i = 0; i < len; ++i) 64 ret->elements[i] = element; 65 ret->elements[len] = NULL; 66 return ret; 67 } 68 69 /* Return an ffi_type for a Go slice type. This describes the 70 __go_open_array type defines in array.h. */ 71 72 static ffi_type * 73 go_slice_to_ffi ( 74 const struct __go_slice_type *descriptor __attribute__ ((unused))) 75 { 76 ffi_type *ret; 77 ffi_type *ffi_intgo; 78 79 ret = (ffi_type *) __go_alloc (sizeof (ffi_type)); 80 ret->type = FFI_TYPE_STRUCT; 81 ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *)); 82 ret->elements[0] = &ffi_type_pointer; 83 ffi_intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64; 84 ret->elements[1] = ffi_intgo; 85 ret->elements[2] = ffi_intgo; 86 ret->elements[3] = NULL; 87 return ret; 88 } 89 90 /* Return an ffi_type for a Go struct type. */ 91 92 static ffi_type * 93 go_struct_to_ffi (const struct __go_struct_type *descriptor) 94 { 95 ffi_type *ret; 96 int field_count; 97 const struct __go_struct_field *fields; 98 int i; 99 100 field_count = descriptor->__fields.__count; 101 ret = (ffi_type *) __go_alloc (sizeof (ffi_type)); 102 ret->type = FFI_TYPE_STRUCT; 103 if (field_count == 0) 104 { 105 /* The libffi library won't accept an empty struct. */ 106 ret->elements = (ffi_type **) __go_alloc (2 * sizeof (ffi_type *)); 107 ret->elements[0] = &ffi_type_void; 108 ret->elements[1] = NULL; 109 return ret; 110 } 111 fields = (const struct __go_struct_field *) descriptor->__fields.__values; 112 ret->elements = (ffi_type **) __go_alloc ((field_count + 1) 113 * sizeof (ffi_type *)); 114 for (i = 0; i < field_count; ++i) 115 ret->elements[i] = go_type_to_ffi (fields[i].__type); 116 ret->elements[field_count] = NULL; 117 return ret; 118 } 119 120 /* Return an ffi_type for a Go string type. This describes the String 121 struct. */ 122 123 static ffi_type * 124 go_string_to_ffi (void) 125 { 126 ffi_type *ret; 127 ffi_type *ffi_intgo; 128 129 ret = (ffi_type *) __go_alloc (sizeof (ffi_type)); 130 ret->type = FFI_TYPE_STRUCT; 131 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *)); 132 ret->elements[0] = &ffi_type_pointer; 133 ffi_intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64; 134 ret->elements[1] = ffi_intgo; 135 ret->elements[2] = NULL; 136 return ret; 137 } 138 139 /* Return an ffi_type for a Go interface type. This describes the 140 __go_interface and __go_empty_interface structs. */ 141 142 static ffi_type * 143 go_interface_to_ffi (void) 144 { 145 ffi_type *ret; 146 147 ret = (ffi_type *) __go_alloc (sizeof (ffi_type)); 148 ret->type = FFI_TYPE_STRUCT; 149 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *)); 150 ret->elements[0] = &ffi_type_pointer; 151 ret->elements[1] = &ffi_type_pointer; 152 ret->elements[2] = NULL; 153 return ret; 154 } 155 156 157 #ifndef FFI_TARGET_HAS_COMPLEX_TYPE 158 /* If libffi hasn't been updated for this target to support complex, 159 pretend complex is a structure. Warning: This does not work for 160 all ABIs. Eventually libffi should be updated for all targets 161 and this should go away. */ 162 163 static ffi_type *go_complex_to_ffi (ffi_type *) 164 __attribute__ ((no_split_stack)); 165 166 static ffi_type * 167 go_complex_to_ffi (ffi_type *float_type) 168 { 169 ffi_type *ret; 170 171 ret = (ffi_type *) __go_alloc (sizeof (ffi_type)); 172 ret->type = FFI_TYPE_STRUCT; 173 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *)); 174 ret->elements[0] = float_type; 175 ret->elements[1] = float_type; 176 ret->elements[2] = NULL; 177 return ret; 178 } 179 #endif 180 181 /* Return an ffi_type for a type described by a 182 __go_type_descriptor. */ 183 184 static ffi_type * 185 go_type_to_ffi (const struct __go_type_descriptor *descriptor) 186 { 187 switch (descriptor->__code & GO_CODE_MASK) 188 { 189 case GO_BOOL: 190 if (sizeof (_Bool) == 1) 191 return &ffi_type_uint8; 192 else if (sizeof (_Bool) == sizeof (int)) 193 return &ffi_type_uint; 194 abort (); 195 case GO_FLOAT32: 196 if (sizeof (float) == 4) 197 return &ffi_type_float; 198 abort (); 199 case GO_FLOAT64: 200 if (sizeof (double) == 8) 201 return &ffi_type_double; 202 abort (); 203 case GO_COMPLEX64: 204 if (sizeof (float) == 4) 205 { 206 #ifdef FFI_TARGET_HAS_COMPLEX_TYPE 207 return &ffi_type_complex_float; 208 #else 209 return go_complex_to_ffi (&ffi_type_float); 210 #endif 211 } 212 abort (); 213 case GO_COMPLEX128: 214 if (sizeof (double) == 8) 215 { 216 #ifdef FFI_TARGET_HAS_COMPLEX_TYPE 217 return &ffi_type_complex_double; 218 #else 219 return go_complex_to_ffi (&ffi_type_double); 220 #endif 221 } 222 abort (); 223 case GO_INT16: 224 return &ffi_type_sint16; 225 case GO_INT32: 226 return &ffi_type_sint32; 227 case GO_INT64: 228 return &ffi_type_sint64; 229 case GO_INT8: 230 return &ffi_type_sint8; 231 case GO_INT: 232 return sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64; 233 case GO_UINT16: 234 return &ffi_type_uint16; 235 case GO_UINT32: 236 return &ffi_type_uint32; 237 case GO_UINT64: 238 return &ffi_type_uint64; 239 case GO_UINT8: 240 return &ffi_type_uint8; 241 case GO_UINT: 242 return sizeof (uintgo) == 4 ? &ffi_type_uint32 : &ffi_type_uint64; 243 case GO_UINTPTR: 244 if (sizeof (void *) == 2) 245 return &ffi_type_uint16; 246 else if (sizeof (void *) == 4) 247 return &ffi_type_uint32; 248 else if (sizeof (void *) == 8) 249 return &ffi_type_uint64; 250 abort (); 251 case GO_ARRAY: 252 return go_array_to_ffi ((const struct __go_array_type *) descriptor); 253 case GO_SLICE: 254 return go_slice_to_ffi ((const struct __go_slice_type *) descriptor); 255 case GO_STRUCT: 256 return go_struct_to_ffi ((const struct __go_struct_type *) descriptor); 257 case GO_STRING: 258 return go_string_to_ffi (); 259 case GO_INTERFACE: 260 return go_interface_to_ffi (); 261 case GO_CHAN: 262 case GO_FUNC: 263 case GO_MAP: 264 case GO_PTR: 265 case GO_UNSAFE_POINTER: 266 /* These types are always pointers, and for FFI purposes nothing 267 else matters. */ 268 return &ffi_type_pointer; 269 default: 270 abort (); 271 } 272 } 273 274 /* Return the return type for a function, given the number of out 275 parameters and their types. */ 276 277 static ffi_type * 278 go_func_return_ffi (const struct __go_func_type *func) 279 { 280 int count; 281 const struct __go_type_descriptor **types; 282 ffi_type *ret; 283 int i; 284 285 count = func->__out.__count; 286 if (count == 0) 287 return &ffi_type_void; 288 289 types = (const struct __go_type_descriptor **) func->__out.__values; 290 291 if (count == 1) 292 return go_type_to_ffi (types[0]); 293 294 ret = (ffi_type *) __go_alloc (sizeof (ffi_type)); 295 ret->type = FFI_TYPE_STRUCT; 296 ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *)); 297 for (i = 0; i < count; ++i) 298 ret->elements[i] = go_type_to_ffi (types[i]); 299 ret->elements[count] = NULL; 300 return ret; 301 } 302 303 /* Build an ffi_cif structure for a function described by a 304 __go_func_type structure. */ 305 306 void 307 __go_func_to_cif (const struct __go_func_type *func, _Bool is_interface, 308 _Bool is_method, ffi_cif *cif) 309 { 310 int num_params; 311 const struct __go_type_descriptor **in_types; 312 size_t num_args; 313 ffi_type **args; 314 int off; 315 int i; 316 ffi_type *rettype; 317 ffi_status status; 318 319 num_params = func->__in.__count; 320 in_types = ((const struct __go_type_descriptor **) 321 func->__in.__values); 322 323 num_args = num_params + (is_interface ? 1 : 0); 324 args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *)); 325 i = 0; 326 off = 0; 327 if (is_interface) 328 { 329 args[0] = &ffi_type_pointer; 330 off = 1; 331 } 332 else if (is_method) 333 { 334 args[0] = &ffi_type_pointer; 335 i = 1; 336 } 337 for (; i < num_params; ++i) 338 args[i + off] = go_type_to_ffi (in_types[i]); 339 340 rettype = go_func_return_ffi (func); 341 342 status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args); 343 __go_assert (status == FFI_OK); 344 } 345 346 #endif /* defined(USE_LIBFFI) */