github.com/axw/llgo@v0.0.0-20160805011314-95b5fe4dca20/third_party/gofrontend/libgo/go/reflect/makefunc_ffi.go (about) 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. 4 5 package reflect 6 7 import ( 8 "unsafe" 9 ) 10 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(ftyp *funcType, impl unsafe.Pointer) 14 15 // FFICallbackGo implements the Go side of the libffi callback. 16 // It is exported so that C code can call it. 17 // 18 // The call chain arriving here looks like 19 // some_go_caller 20 // ->some_ffi_internals 21 // ->ffi_callback (in C) 22 // ->FFICallbackGo 23 // 24 // The ffi_callback handles __go_makefunc_can_recover, and 25 // then passes off the data as received from ffi here. 26 27 func FFICallbackGo(results unsafe.Pointer, params unsafe.Pointer, impl *makeFuncImpl) { 28 ftyp := impl.typ 29 in := make([]Value, 0, len(ftyp.in)) 30 ap := params 31 for _, rt := range ftyp.in { 32 p := unsafe_New(rt) 33 memmove(p, *(*unsafe.Pointer)(ap), rt.size) 34 v := Value{rt, p, flag(rt.Kind()) | flagIndir} 35 in = append(in, v) 36 ap = (unsafe.Pointer)(uintptr(ap) + ptrSize) 37 } 38 39 out := impl.call(in) 40 41 off := uintptr(0) 42 for i, typ := range ftyp.out { 43 v := out[i] 44 if v.typ != typ { 45 panic("reflect: function created by MakeFunc using " + funcName(impl.fn) + 46 " returned wrong type: have " + 47 out[i].typ.String() + " for " + typ.String()) 48 } 49 if v.flag&flagRO != 0 { 50 panic("reflect: function created by MakeFunc using " + funcName(impl.fn) + 51 " returned value obtained from unexported field") 52 } 53 54 off = align(off, uintptr(typ.fieldAlign)) 55 addr := unsafe.Pointer(uintptr(results) + off) 56 if v.flag&flagIndir == 0 && (v.kind() == Ptr || v.kind() == UnsafePointer) { 57 *(*unsafe.Pointer)(addr) = v.ptr 58 } else { 59 memmove(addr, v.ptr, typ.size) 60 } 61 off += typ.size 62 } 63 }