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.
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
23 // ->some_ffi_internals
24 // ->ffi_callback (in C)
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
) {
32 in
:= make([]Value
, 0, len(ftyp
.in
))
34 for _
, rt
:= range ftyp
.in
{
36 memmove(p
, *(*unsafe
.Pointer
)(ap
), rt
.size
)
37 v
:= Value
{rt
, p
, flag(rt
.Kind()) | flagIndir
}
39 ap
= (unsafe
.Pointer
)(uintptr(ap
) + ptrSize
)
45 for i
, typ
:= range ftyp
.out
{
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
62 memmove(addr
, v
.ptr
, typ
.size
)