github.com/nikandfor/loc@v0.5.1/func.go (about)

     1  package loc
     2  
     3  import (
     4  	"reflect"
     5  	"unsafe"
     6  )
     7  
     8  type (
     9  	// rtype is the common implementation of most values.
    10  	// It is embedded in other struct types.
    11  	//
    12  	// rtype must be kept in sync with ../runtime/type.go:/^type._type.
    13  	//nolint:structcheck,unused
    14  	rtype struct {
    15  		size       uintptr
    16  		ptrdata    uintptr // number of bytes in the type that can contain pointers
    17  		hash       uint32  // hash of type; avoids computation in hash tables
    18  		tflag      uint8   // extra type information flags
    19  		align      uint8   // alignment of variable with this type
    20  		fieldAlign uint8   // alignment of struct field with this type
    21  		kind       uint8   // enumeration for C
    22  		// function for comparing objects of this type
    23  		// (ptr to object A, ptr to object B) -> ==?
    24  		equal  func(unsafe.Pointer, unsafe.Pointer) bool
    25  		gcdata *byte // garbage collection data
    26  		//	str       nameOff // string form
    27  		//	ptrToThis typeOff // type for pointer to this type, may be zero
    28  	}
    29  
    30  	fface struct {
    31  		t *rtype
    32  		e *uintptr
    33  	}
    34  )
    35  
    36  //nolint:deadcode,varcheck
    37  const (
    38  	kindDirectIface = 1 << 5
    39  	kindGCProg      = 1 << 6 // Type.gc points to GC program
    40  	kindMask        = (1 << 5) - 1
    41  )
    42  
    43  func FuncEntryFromFunc(f interface{}) PC {
    44  	ff := (*fface)(unsafe.Pointer(&f))
    45  
    46  	if ff.t == nil {
    47  		return 0
    48  	}
    49  
    50  	if reflect.Kind(ff.t.kind&kindMask) != reflect.Func {
    51  		panic("not a function")
    52  	}
    53  
    54  	if ff.e == nil {
    55  		return 0
    56  	}
    57  
    58  	return PC(*ff.e)
    59  }