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  }