github.com/oarkflow/log@v1.0.78/runtime_go1.19.go (about)

     1  //go:build go1.19 && !go1.20
     2  // +build go1.19,!go1.20
     3  
     4  // MIT license, copy and modify from https://github.com/tlog-dev/loc
     5  
     6  //nolint:unused
     7  package log
     8  
     9  import (
    10  	"unsafe"
    11  )
    12  
    13  // inlinedCall is the encoding of entries in the FUNCDATA_InlTree table.
    14  type inlinedCall struct {
    15  	parent   int16 // index of parent in the inltree, or < 0
    16  	funcID   uint8 // type of the called function
    17  	_        byte
    18  	file     int32 // fileno index into filetab
    19  	line     int32 // line number of the call site
    20  	func_    int32 // offset into pclntab for name of called function
    21  	parentPc int32 // position of an instruction whose source position is the call site (offset from entry)
    22  }
    23  
    24  func pcNameFileLine(pc uintptr) (name, file string, line int32) {
    25  	funcInfo := findfunc(pc)
    26  	if funcInfo._func == nil {
    27  		return
    28  	}
    29  
    30  	entry := funcInfoEntry(funcInfo)
    31  
    32  	if pc > entry {
    33  		// We store the pc of the start of the instruction following
    34  		// the instruction in question (the call or the inline mark).
    35  		// This is done for historical reasons, and to make FuncForPC
    36  		// work correctly for entries in the result of runtime.Callers.
    37  		pc--
    38  	}
    39  
    40  	file, line = funcline1(funcInfo, pc, false)
    41  
    42  	name = funcname(funcInfo)
    43  	const _PCDATA_InlTreeIndex = 2
    44  	const _FUNCDATA_InlTree = 3
    45  	if inldata := funcdata(funcInfo, _FUNCDATA_InlTree); inldata != nil {
    46  		ix := pcdatavalue1(funcInfo, _PCDATA_InlTreeIndex, pc, nil, false)
    47  		if ix >= 0 {
    48  			inltree := (*[1 << 20]inlinedCall)(inldata)
    49  			// Note: entry is not modified. It always refers to a real frame, not an inlined one.
    50  			name = funcnameFromNameoff(funcInfo, inltree[ix].func_)
    51  			// File/line is already correct.
    52  			// TODO: remove file/line from InlinedCall?
    53  		}
    54  	}
    55  
    56  	return
    57  }
    58  
    59  //go:linkname funcname runtime.funcname
    60  func funcname(f funcInfo) string
    61  
    62  //go:linkname funcdata runtime.funcdata
    63  func funcdata(f funcInfo, i uint8) unsafe.Pointer
    64  
    65  //go:linkname pcdatavalue runtime.pcdatavalue
    66  func pcdatavalue(f funcInfo, table int32, targetpc uintptr, cache unsafe.Pointer) int32
    67  
    68  //go:linkname pcdatavalue1 runtime.pcdatavalue1
    69  func pcdatavalue1(f funcInfo, table int32, targetpc uintptr, cache unsafe.Pointer, strict bool) int32
    70  
    71  //go:linkname funcnameFromNameoff runtime.funcnameFromNameoff
    72  func funcnameFromNameoff(f funcInfo, nameoff int32) string
    73  
    74  // Fastrandn returns a pseudorandom uint32 in [0,n).
    75  //
    76  //go:noescape
    77  //go:linkname Fastrandn runtime.fastrandn
    78  func Fastrandn(x uint32) uint32