github.com/gotranspile/cxgo@v0.3.7/runtime/libc/conv.go (about) 1 package libc 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 func BoolToInt(v bool) int32 { 9 if v { 10 return 1 11 } 12 return 0 13 } 14 15 // interfaceAddr extracts an address of an object stored in the interface value. 16 func interfaceAddr(v interface{}) uintptr { 17 ifc := *(*[2]uintptr)(unsafe.Pointer(&v)) 18 return ifc[1] 19 } 20 21 // interfaceType extracts a type of an object stored in the interface value. 22 func interfaceType(v interface{}) uintptr { 23 ifc := *(*[2]uintptr)(unsafe.Pointer(&v)) 24 return ifc[0] 25 } 26 27 // makeInterface creates a new interface value from an object address and a type. 28 func makeInterface(typ, ptr uintptr) interface{} { 29 v := [2]uintptr{typ, ptr} 30 return *(*interface{})(unsafe.Pointer(&v)) 31 } 32 33 // FuncAddr converts a function value to a uintptr. 34 func FuncAddr(v interface{}) uintptr { 35 if reflect.TypeOf(v).Kind() != reflect.Func { 36 panic(v) 37 } 38 return interfaceAddr(v) 39 } 40 41 // FuncAddrUnsafe converts a function value to a unsafe.Pointer. 42 func FuncAddrUnsafe(v interface{}) unsafe.Pointer { 43 return unsafe.Pointer(FuncAddr(v)) 44 } 45 46 // AddrAsFunc converts a function address to a function value. 47 // The caller must type-assert to an expected function type. 48 // The function type can be specified as (*func())(nil). 49 func AddrAsFunc(addr uintptr, typ interface{}) interface{} { 50 tp := reflect.TypeOf(typ).Elem() 51 if tp.Kind() != reflect.Func { 52 panic(typ) 53 } 54 t := interfaceType(reflect.Zero(tp).Interface()) 55 return makeInterface(t, addr) 56 } 57 58 var ( 59 reflUnsafePtr = reflect.TypeOf(unsafe.Pointer(nil)) 60 reflUintptr = reflect.TypeOf(uintptr(0)) 61 ) 62 63 // AsFunc is a less restrictive version of AddrAsFunc. 64 // It accepts a pointer value that may be one of: uintptr, unsafe.Pointer, *T, int, uint. 65 func AsFunc(p interface{}, typ interface{}) interface{} { 66 switch p := p.(type) { 67 case uintptr: 68 return AddrAsFunc(p, typ) 69 case unsafe.Pointer: 70 return AddrAsFunc(uintptr(p), typ) 71 case uint: 72 return AddrAsFunc(uintptr(p), typ) 73 case uint64: 74 return AddrAsFunc(uintptr(p), typ) 75 case uint32: 76 return AddrAsFunc(uintptr(p), typ) 77 case int: 78 return AddrAsFunc(uintptr(p), typ) 79 case int64: 80 return AddrAsFunc(uintptr(p), typ) 81 case int32: 82 return AddrAsFunc(uintptr(p), typ) 83 } 84 if t := reflect.TypeOf(p); t.Kind() != reflect.Ptr { 85 panic("unsupported type: " + t.String()) 86 } 87 pv := reflect.ValueOf(p).Pointer() 88 return AddrAsFunc(pv, typ) 89 }