[46/77] Make widest_int_mode_for_size return a scalar_int_mode
[official-gcc.git] / libgo / go / reflect / makefunc_ffi.go
blob2acf7bb887a2ba6fbd15c9ed8084cd690ecd211e
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package reflect
7 import (
8 "unsafe"
11 // The makeFuncFFI function, written in C, fills in an FFI closure.
12 // It arranges for ffiCall to be invoked directly from FFI.
13 func makeFuncFFI(cif unsafe.Pointer, impl unsafe.Pointer)
15 // The makeCIF function, implemented in the runtime package, allocates a CIF.
16 func makeCIF(ft *funcType) unsafe.Pointer
18 // FFICallbackGo implements the Go side of the libffi callback.
19 // It is exported so that C code can call it.
21 // The call chain arriving here looks like
22 // some_go_caller
23 // ->some_ffi_internals
24 // ->ffi_callback (in C)
25 // ->FFICallbackGo
27 // The ffi_callback handles __go_makefunc_can_recover, and
28 // then passes off the data as received from ffi here.
30 func FFICallbackGo(results unsafe.Pointer, params unsafe.Pointer, impl *makeFuncImpl) {
31 ftyp := impl.typ
32 in := make([]Value, 0, len(ftyp.in))
33 ap := params
34 for _, rt := range ftyp.in {
35 p := unsafe_New(rt)
36 memmove(p, *(*unsafe.Pointer)(ap), rt.size)
37 v := Value{rt, p, flag(rt.Kind()) | flagIndir}
38 in = append(in, v)
39 ap = (unsafe.Pointer)(uintptr(ap) + ptrSize)
42 out := impl.call(in)
44 off := uintptr(0)
45 for i, typ := range ftyp.out {
46 v := out[i]
47 if v.typ != typ {
48 panic("reflect: function created by MakeFunc using " + funcName(impl.fn) +
49 " returned wrong type: have " +
50 out[i].typ.String() + " for " + typ.String())
52 if v.flag&flagRO != 0 {
53 panic("reflect: function created by MakeFunc using " + funcName(impl.fn) +
54 " returned value obtained from unexported field")
57 off = align(off, uintptr(typ.fieldAlign))
58 addr := unsafe.Pointer(uintptr(results) + off)
59 if v.flag&flagIndir == 0 && (v.kind() == Ptr || v.kind() == UnsafePointer) {
60 *(*unsafe.Pointer)(addr) = v.ptr
61 } else {
62 memmove(addr, v.ptr, typ.size)
64 off += typ.size