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

     1  //go:build nikandfor_loc_unsafe && go1.21
     2  // +build nikandfor_loc_unsafe,go1.21
     3  
     4  package loc
     5  
     6  import "unsafe"
     7  
     8  type (
     9  	inlineUnwinder struct {
    10  		f       funcInfo
    11  		cache   *uintptr
    12  		inlTree *uintptr
    13  	}
    14  
    15  	inlineFrame struct {
    16  		pc    uintptr
    17  		index int32
    18  	}
    19  
    20  	srcFunc struct {
    21  		datap     *uintptr
    22  		nameOff   int32
    23  		startLine int32
    24  		funcID    funcID
    25  	}
    26  )
    27  
    28  func (l PC) nameFileLine() (name, file string, line int) {
    29  	funcInfo := findfunc(l)
    30  	if funcInfo._func == nil {
    31  		return
    32  	}
    33  
    34  	entry := funcInfoEntry(funcInfo)
    35  
    36  	if l > entry {
    37  		// We store the pc of the start of the instruction following
    38  		// the instruction in question (the call or the inline mark).
    39  		// This is done for historical reasons, and to make FuncForPC
    40  		// work correctly for entries in the result of runtime.Callers.
    41  		l--
    42  	}
    43  
    44  	// It's important that interpret pc non-strictly as cgoTraceback may
    45  	// have added bogus PCs with a valid funcInfo but invalid PCDATA.
    46  	u, uf := newInlineUnwinder(funcInfo, l, nil)
    47  	sf := inlineUnwinder_srcFunc(&u, uf)
    48  
    49  	name = funcNameForPrint(srcFunc_name(sf))
    50  	file, line32 := funcline1(funcInfo, l, false)
    51  	line = int(line32)
    52  
    53  	return
    54  }
    55  
    56  //go:linkname findfunc runtime.findfunc
    57  func findfunc(pc PC) funcInfo
    58  
    59  //go:linkname funcInfoEntry runtime.funcInfo.entry
    60  func funcInfoEntry(f funcInfo) PC
    61  
    62  //go:linkname newInlineUnwinder runtime.newInlineUnwinder
    63  func newInlineUnwinder(f funcInfo, pc PC, cache unsafe.Pointer) (inlineUnwinder, inlineFrame)
    64  
    65  //go:linkname inlineUnwinder_srcFunc runtime.(*inlineUnwinder).srcFunc
    66  func inlineUnwinder_srcFunc(*inlineUnwinder, inlineFrame) srcFunc
    67  
    68  //go:linkname inlineUnwinder_isInlined runtime.(*inlineUnwinder).isInlined
    69  func inlineUnwinder_isInlined(*inlineUnwinder, inlineFrame) bool
    70  
    71  //go:linkname srcFunc_name runtime.srcFunc.name
    72  func srcFunc_name(srcFunc) string
    73  
    74  //go:linkname funcNameForPrint runtime.funcNameForPrint
    75  func funcNameForPrint(name string) string
    76  
    77  //go:linkname funcline1 runtime.funcline1
    78  func funcline1(f funcInfo, targetpc PC, strict bool) (file string, line int32)