summaryrefslogtreecommitdiff
path: root/vendor/github.com/twitchyliquid64/golang-asm/src/pos.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/twitchyliquid64/golang-asm/src/pos.go')
-rw-r--r--vendor/github.com/twitchyliquid64/golang-asm/src/pos.go470
1 files changed, 0 insertions, 470 deletions
diff --git a/vendor/github.com/twitchyliquid64/golang-asm/src/pos.go b/vendor/github.com/twitchyliquid64/golang-asm/src/pos.go
deleted file mode 100644
index b6816a56e..000000000
--- a/vendor/github.com/twitchyliquid64/golang-asm/src/pos.go
+++ /dev/null
@@ -1,470 +0,0 @@
-// 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, "<unknown line number>")
- 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 := &copy
- 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<<lineBits - 2
- bogusLine = 1 // Used to disrupt infinite loops to prevent debugger looping
- isStmtBits, isStmtMax = 2, 1<<isStmtBits - 1
- xlogueBits, xlogueMax = 2, 1<<xlogueBits - 1
- colBits, colMax = 32 - lineBits - xlogueBits - isStmtBits, 1<<colBits - 1
-
- isStmtShift = 0
- isStmtMask = isStmtMax << isStmtShift
- xlogueShift = isStmtBits + isStmtShift
- xlogueMask = xlogueMax << xlogueShift
- colShift = xlogueBits + xlogueShift
- lineShift = colBits + colShift
-)
-const (
- // It is expected that the front end or a phase in SSA will usually generate positions tagged with
- // PosDefaultStmt, but note statement boundaries with PosIsStmt. Simple statements will have a single
- // boundary; for loops with initialization may have one for their entry and one for their back edge
- // (this depends on exactly how the loop is compiled; the intent is to provide a good experience to a
- // user debugging a program; the goal is that a breakpoint set on the loop line fires both on entry
- // and on iteration). Proper treatment of non-gofmt input with multiple simple statements on a single
- // line is TBD.
- //
- // Optimizing compilation will move instructions around, and some of these will become known-bad as
- // step targets for debugging purposes (examples: register spills and reloads; code generated into
- // the entry block; invariant code hoisted out of loops) but those instructions will still have interesting
- // positions for profiling purposes. To reflect this these positions will be changed to PosNotStmt.
- //
- // When the optimizer removes an instruction marked PosIsStmt; it should attempt to find a nearby
- // instruction with the same line marked PosDefaultStmt to be the new statement boundary. I.e., the
- // optimizer should make a best-effort to conserve statement boundary positions, and might be enhanced
- // to note when a statement boundary is not conserved.
- //
- // Code cloning, e.g. loop unrolling or loop unswitching, is an exception to the conservation rule
- // because a user running a debugger would expect to see breakpoints active in the copies of the code.
- //
- // In non-optimizing compilation there is still a role for PosNotStmt because of code generation
- // into the entry block. PosIsStmt statement positions should be conserved.
- //
- // When code generation occurs any remaining default-marked positions are replaced with not-statement
- // positions.
- //
- PosDefaultStmt uint = iota // Default; position is not a statement boundary, but might be if optimization removes the designated statement boundary
- PosIsStmt // Position is a statement boundary; if optimization removes the corresponding instruction, it should attempt to find a new instruction to be the boundary.
- PosNotStmt // Position should not be a statement boundary, but line should be preserved for profiling and low-level debugging purposes.
-)
-
-type PosXlogue uint
-
-const (
- PosDefaultLogue PosXlogue = iota
- PosPrologueEnd
- PosEpilogueBegin
-)
-
-func makeLicoRaw(line, col uint) lico {
- return lico(line<<lineShift | col<<colShift)
-}
-
-// This is a not-position that will not be elided.
-// Depending on the debugger (gdb or delve) it may or may not be displayed.
-func makeBogusLico() lico {
- return makeLicoRaw(bogusLine, 0).withIsStmt()
-}
-
-func makeLico(line, col uint) lico {
- if line > 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<<lineShift-1) }
-func (x lico) Col() uint { return uint(x) >> 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<<xlogueShift) | (uint(xlogue) << xlogueShift))
-}
-
-// withStmt returns a lico for the same location with specified is_stmt attribute
-func (x lico) withStmt(stmt uint) lico {
- if x == 0 {
- return lico(0)
- }
- return lico(uint(x) & ^uint(isStmtMax<<isStmtShift) | (stmt << isStmtShift))
-}
-
-func (x lico) lineNumber() string {
- return fmt.Sprintf("%d", x.Line())
-}
-
-func (x lico) lineNumberHTML() string {
- if x.IsStmt() == PosDefaultStmt {
- return fmt.Sprintf("%d", x.Line())
- }
- style, pfx := "b", "+"
- if x.IsStmt() == PosNotStmt {
- style = "s" // /strike not supported in HTML5
- pfx = ""
- }
- return fmt.Sprintf("<%s>%s%d</%s>", style, pfx, x.Line(), style)
-}
-
-func (x lico) atColumn1() lico {
- return makeLico(x.Line(), 1).withIsStmt()
-}