From ecdc8379fa8f9d88faca626e7de748c2afbe4910 Mon Sep 17 00:00:00 2001 From: Daenney Date: Sat, 25 Feb 2023 13:12:40 +0100 Subject: [chore] Update gin to v1.9.0 (#1553) --- .../twitchyliquid64/golang-asm/src/pos.go | 470 +++++++++++++++++++++ 1 file changed, 470 insertions(+) create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/src/pos.go (limited to 'vendor/github.com/twitchyliquid64/golang-asm/src/pos.go') diff --git a/vendor/github.com/twitchyliquid64/golang-asm/src/pos.go b/vendor/github.com/twitchyliquid64/golang-asm/src/pos.go new file mode 100644 index 000000000..b6816a56e --- /dev/null +++ b/vendor/github.com/twitchyliquid64/golang-asm/src/pos.go @@ -0,0 +1,470 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements the encoding of source positions. + +package src + +import ( + "bytes" + "fmt" + "io" +) + +// A Pos encodes a source position consisting of a (line, column) number pair +// and a position base. A zero Pos is a ready to use "unknown" position (nil +// position base and zero line number). +// +// The (line, column) values refer to a position in a file independent of any +// position base ("absolute" file position). +// +// The position base is used to determine the "relative" position, that is the +// filename and line number relative to the position base. If the base refers +// to the current file, there is no difference between absolute and relative +// positions. If it refers to a //line directive, a relative position is relative +// to that directive. A position base in turn contains the position at which it +// was introduced in the current file. +type Pos struct { + base *PosBase + lico +} + +// NoPos is a valid unknown position. +var NoPos Pos + +// MakePos creates a new Pos value with the given base, and (file-absolute) +// line and column. +func MakePos(base *PosBase, line, col uint) Pos { + return Pos{base, makeLico(line, col)} +} + +// IsKnown reports whether the position p is known. +// A position is known if it either has a non-nil +// position base, or a non-zero line number. +func (p Pos) IsKnown() bool { + return p.base != nil || p.Line() != 0 +} + +// Before reports whether the position p comes before q in the source. +// For positions in different files, ordering is by filename. +func (p Pos) Before(q Pos) bool { + n, m := p.Filename(), q.Filename() + return n < m || n == m && p.lico < q.lico +} + +// After reports whether the position p comes after q in the source. +// For positions in different files, ordering is by filename. +func (p Pos) After(q Pos) bool { + n, m := p.Filename(), q.Filename() + return n > m || n == m && p.lico > q.lico +} + +func (p Pos) LineNumber() string { + if !p.IsKnown() { + return "?" + } + return p.lico.lineNumber() +} + +func (p Pos) LineNumberHTML() string { + if !p.IsKnown() { + return "?" + } + return p.lico.lineNumberHTML() +} + +// Filename returns the name of the actual file containing this position. +func (p Pos) Filename() string { return p.base.Pos().RelFilename() } + +// Base returns the position base. +func (p Pos) Base() *PosBase { return p.base } + +// SetBase sets the position base. +func (p *Pos) SetBase(base *PosBase) { p.base = base } + +// RelFilename returns the filename recorded with the position's base. +func (p Pos) RelFilename() string { return p.base.Filename() } + +// RelLine returns the line number relative to the position's base. +func (p Pos) RelLine() uint { + b := p.base + if b.Line() == 0 { + // base line is unknown => relative line is unknown + return 0 + } + return b.Line() + (p.Line() - b.Pos().Line()) +} + +// RelCol returns the column number relative to the position's base. +func (p Pos) RelCol() uint { + b := p.base + if b.Col() == 0 { + // base column is unknown => relative column is unknown + // (the current specification for line directives requires + // this to apply until the next PosBase/line directive, + // not just until the new newline) + return 0 + } + if p.Line() == b.Pos().Line() { + // p on same line as p's base => column is relative to p's base + return b.Col() + (p.Col() - b.Pos().Col()) + } + return p.Col() +} + +// AbsFilename() returns the absolute filename recorded with the position's base. +func (p Pos) AbsFilename() string { return p.base.AbsFilename() } + +// SymFilename() returns the absolute filename recorded with the position's base, +// prefixed by FileSymPrefix to make it appropriate for use as a linker symbol. +func (p Pos) SymFilename() string { return p.base.SymFilename() } + +func (p Pos) String() string { + return p.Format(true, true) +} + +// Format formats a position as "filename:line" or "filename:line:column", +// controlled by the showCol flag and if the column is known (!= 0). +// For positions relative to line directives, the original position is +// shown as well, as in "filename:line[origfile:origline:origcolumn] if +// showOrig is set. +func (p Pos) Format(showCol, showOrig bool) string { + buf := new(bytes.Buffer) + p.WriteTo(buf, showCol, showOrig) + return buf.String() +} + +// WriteTo a position to w, formatted as Format does. +func (p Pos) WriteTo(w io.Writer, showCol, showOrig bool) { + if !p.IsKnown() { + io.WriteString(w, "") + return + } + + if b := p.base; b == b.Pos().base { + // base is file base (incl. nil) + format(w, p.Filename(), p.Line(), p.Col(), showCol) + return + } + + // base is relative + // Print the column only for the original position since the + // relative position's column information may be bogus (it's + // typically generated code and we can't say much about the + // original source at that point but for the file:line info + // that's provided via a line directive). + // TODO(gri) This may not be true if we have an inlining base. + // We may want to differentiate at some point. + format(w, p.RelFilename(), p.RelLine(), p.RelCol(), showCol) + if showOrig { + io.WriteString(w, "[") + format(w, p.Filename(), p.Line(), p.Col(), showCol) + io.WriteString(w, "]") + } +} + +// format formats a (filename, line, col) tuple as "filename:line" (showCol +// is false or col == 0) or "filename:line:column" (showCol is true and col != 0). +func format(w io.Writer, filename string, line, col uint, showCol bool) { + io.WriteString(w, filename) + io.WriteString(w, ":") + fmt.Fprint(w, line) + // col == 0 and col == colMax are interpreted as unknown column values + if showCol && 0 < col && col < colMax { + io.WriteString(w, ":") + fmt.Fprint(w, col) + } +} + +// formatstr wraps format to return a string. +func formatstr(filename string, line, col uint, showCol bool) string { + buf := new(bytes.Buffer) + format(buf, filename, line, col, showCol) + return buf.String() +} + +// ---------------------------------------------------------------------------- +// PosBase + +// A PosBase encodes a filename and base position. +// Typically, each file and line directive introduce a PosBase. +type PosBase struct { + pos Pos // position at which the relative position is (line, col) + filename string // file name used to open source file, for error messages + absFilename string // absolute file name, for PC-Line tables + symFilename string // cached symbol file name, to avoid repeated string concatenation + line, col uint // relative line, column number at pos + inl int // inlining index (see cmd/internal/obj/inl.go) +} + +// NewFileBase returns a new *PosBase for a file with the given (relative and +// absolute) filenames. +func NewFileBase(filename, absFilename string) *PosBase { + base := &PosBase{ + filename: filename, + absFilename: absFilename, + symFilename: FileSymPrefix + absFilename, + line: 1, + col: 1, + inl: -1, + } + base.pos = MakePos(base, 1, 1) + return base +} + +// NewLinePragmaBase returns a new *PosBase for a line directive of the form +// //line filename:line:col +// /*line filename:line:col*/ +// at position pos. +func NewLinePragmaBase(pos Pos, filename, absFilename string, line, col uint) *PosBase { + return &PosBase{pos, filename, absFilename, FileSymPrefix + absFilename, line, col, -1} +} + +// NewInliningBase returns a copy of the old PosBase with the given inlining +// index. If old == nil, the resulting PosBase has no filename. +func NewInliningBase(old *PosBase, inlTreeIndex int) *PosBase { + if old == nil { + base := &PosBase{line: 1, col: 1, inl: inlTreeIndex} + base.pos = MakePos(base, 1, 1) + return base + } + copy := *old + base := © + base.inl = inlTreeIndex + if old == old.pos.base { + base.pos.base = base + } + return base +} + +var noPos Pos + +// Pos returns the position at which base is located. +// If b == nil, the result is the zero position. +func (b *PosBase) Pos() *Pos { + if b != nil { + return &b.pos + } + return &noPos +} + +// Filename returns the filename recorded with the base. +// If b == nil, the result is the empty string. +func (b *PosBase) Filename() string { + if b != nil { + return b.filename + } + return "" +} + +// AbsFilename returns the absolute filename recorded with the base. +// If b == nil, the result is the empty string. +func (b *PosBase) AbsFilename() string { + if b != nil { + return b.absFilename + } + return "" +} + +const FileSymPrefix = "gofile.." + +// SymFilename returns the absolute filename recorded with the base, +// prefixed by FileSymPrefix to make it appropriate for use as a linker symbol. +// If b is nil, SymFilename returns FileSymPrefix + "??". +func (b *PosBase) SymFilename() string { + if b != nil { + return b.symFilename + } + return FileSymPrefix + "??" +} + +// Line returns the line number recorded with the base. +// If b == nil, the result is 0. +func (b *PosBase) Line() uint { + if b != nil { + return b.line + } + return 0 +} + +// Col returns the column number recorded with the base. +// If b == nil, the result is 0. +func (b *PosBase) Col() uint { + if b != nil { + return b.col + } + return 0 +} + +// InliningIndex returns the index into the global inlining +// tree recorded with the base. If b == nil or the base has +// not been inlined, the result is < 0. +func (b *PosBase) InliningIndex() int { + if b != nil { + return b.inl + } + return -1 +} + +// ---------------------------------------------------------------------------- +// lico + +// A lico is a compact encoding of a LIne and COlumn number. +type lico uint32 + +// Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue +// (If this is too tight, we can either make lico 64b wide, +// or we can introduce a tiered encoding where we remove column +// information as line numbers grow bigger; similar to what gcc +// does.) +// The bitfield order is chosen to make IsStmt be the least significant +// part of a position; its use is to communicate statement edges through +// instruction scrambling in code generation, not to impose an order. +// TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, +// because they have almost no interaction with other uses of the position. +const ( + lineBits, lineMax = 20, 1< lineMax { + // cannot represent line, use max. line so we have some information + line = lineMax + } + if col > colMax { + // cannot represent column, use max. column so we have some information + col = colMax + } + // default is not-sure-if-statement + return makeLicoRaw(line, col) +} + +func (x lico) Line() uint { return uint(x) >> lineShift } +func (x lico) SameLine(y lico) bool { return 0 == (x^y)&^lico(1<> colShift & colMax } +func (x lico) IsStmt() uint { + if x == 0 { + return PosNotStmt + } + return uint(x) >> isStmtShift & isStmtMax +} +func (x lico) Xlogue() PosXlogue { + return PosXlogue(uint(x) >> xlogueShift & xlogueMax) +} + +// withNotStmt returns a lico for the same location, but not a statement +func (x lico) withNotStmt() lico { + return x.withStmt(PosNotStmt) +} + +// withDefaultStmt returns a lico for the same location, with default isStmt +func (x lico) withDefaultStmt() lico { + return x.withStmt(PosDefaultStmt) +} + +// withIsStmt returns a lico for the same location, tagged as definitely a statement +func (x lico) withIsStmt() lico { + return x.withStmt(PosIsStmt) +} + +// withLogue attaches a prologue/epilogue attribute to a lico +func (x lico) withXlogue(xlogue PosXlogue) lico { + if x == 0 { + if xlogue == 0 { + return x + } + // Normalize 0 to "not a statement" + x = lico(PosNotStmt << isStmtShift) + } + return lico(uint(x) & ^uint(xlogueMax<%s%d", style, pfx, x.Line(), style) +} + +func (x lico) atColumn1() lico { + return makeLico(x.Line(), 1).withIsStmt() +} -- cgit v1.2.3