"cmd/compile/internal/types2"
"fmt"
"go/token"
+ "internal/pkgbits"
"sync"
)
// See cmd/compile/internal/noder.derivedInfo.
type derivedInfo struct {
- idx int
+ idx pkgbits.Index
needed bool
}
// See cmd/compile/internal/noder.typeInfo.
type typeInfo struct {
- idx int
+ idx pkgbits.Index
derived bool
}
boundIdx int
}
-func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx int, marker pkgbits.SyncMarker) *reader {
+func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
return &reader{
Decoder: pr.NewDecoder(k, idx, marker),
p: pr,
return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase))
}
-func (pr *pkgReader) posBaseIdx(idx int) *syntax.PosBase {
+func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) *syntax.PosBase {
if b := pr.posBases[idx]; b != nil {
return b
}
return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
}
-func (pr *pkgReader) pkgIdx(idx int) *types2.Package {
+func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types2.Package {
// TODO(mdempsky): Consider using some non-nil pointer to indicate
// the universe scope, so we don't need to keep re-reading it.
if pkg := pr.pkgs[idx]; pkg != nil {
func (r *reader) typInfo() typeInfo {
r.Sync(pkgbits.SyncType)
if r.Bool() {
- return typeInfo{idx: r.Len(), derived: true}
+ return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
}
return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
}
return obj, targs
}
-func (pr *pkgReader) objIdx(idx int) (*types2.Package, string) {
+func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types2.Package, string) {
rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
objPkg, objName := rname.qualifiedIdent()
return objPkg, objName
}
-func (pr *pkgReader) objDictIdx(idx int) *readerDict {
+func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
var dict readerDict
type linker struct {
pw pkgbits.PkgEncoder
- pkgs map[string]int
- decls map[*types.Sym]int
+ pkgs map[string]pkgbits.Index
+ decls map[*types.Sym]pkgbits.Index
}
func (l *linker) relocAll(pr *pkgReader, relocs []pkgbits.RelocEnt) []pkgbits.RelocEnt {
return res
}
-func (l *linker) relocIdx(pr *pkgReader, k pkgbits.RelocKind, idx int) int {
+func (l *linker) relocIdx(pr *pkgReader, k pkgbits.RelocKind, idx pkgbits.Index) pkgbits.Index {
assert(pr != nil)
absIdx := pr.AbsIdx(k, idx)
return ^newidx
}
- var newidx int
+ var newidx pkgbits.Index
switch k {
case pkgbits.RelocString:
newidx = l.relocString(pr, idx)
return newidx
}
-func (l *linker) relocString(pr *pkgReader, idx int) int {
+func (l *linker) relocString(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
return l.pw.StringIdx(pr.StringIdx(idx))
}
-func (l *linker) relocPkg(pr *pkgReader, idx int) int {
+func (l *linker) relocPkg(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
path := pr.PeekPkgPath(idx)
if newidx, ok := l.pkgs[path]; ok {
return w.Flush()
}
-func (l *linker) relocObj(pr *pkgReader, idx int) int {
+func (l *linker) relocObj(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
path, name, tag := pr.PeekObj(idx)
sym := types.NewPkg(path, "").Lookup(name)
return w.Idx
}
-func (l *linker) relocCommon(pr *pkgReader, w *pkgbits.Encoder, k pkgbits.RelocKind, idx int) {
+func (l *linker) relocCommon(pr *pkgReader, w *pkgbits.Encoder, k pkgbits.RelocKind, idx pkgbits.Index) {
r := pr.NewDecoderRaw(k, idx)
w.Relocs = l.relocAll(pr, r.Relocs)
io.Copy(&w.Data, &r.Data)
// offset for rewriting the given index into the output,
// but bitwise inverted so we can detect if we're missing the entry or not.
- newindex []int
+ newindex []pkgbits.Index
}
func newPkgReader(pr pkgbits.PkgDecoder) *pkgReader {
pkgs: make([]*types.Pkg, pr.NumElems(pkgbits.RelocPkg)),
typs: make([]*types.Type, pr.NumElems(pkgbits.RelocType)),
- newindex: make([]int, pr.TotalElems()),
+ newindex: make([]pkgbits.Index, pr.TotalElems()),
}
}
type pkgReaderIndex struct {
pr *pkgReader
- idx int
+ idx pkgbits.Index
dict *readerDict
}
return r
}
-func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx int, marker pkgbits.SyncMarker) *reader {
+func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
return &reader{
Decoder: pr.NewDecoder(k, idx, marker),
p: pr,
return r.inlPosBase(r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)))
}
-func (pr *pkgReader) posBaseIdx(idx int) *src.PosBase {
+func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) *src.PosBase {
if b := pr.posBases[idx]; b != nil {
return b
}
return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
}
-func (pr *pkgReader) pkgIdx(idx int) *types.Pkg {
+func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Pkg {
if pkg := pr.pkgs[idx]; pkg != nil {
return pkg
}
func (r *reader) typInfo() typeInfo {
r.Sync(pkgbits.SyncType)
if r.Bool() {
- return typeInfo{idx: r.Len(), derived: true}
+ return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
}
return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
}
return r.p.objIdx(idx, implicits, explicits)
}
-func (pr *pkgReader) objIdx(idx int, implicits, explicits []*types.Type) ir.Node {
+func (pr *pkgReader) objIdx(idx pkgbits.Index, implicits, explicits []*types.Type) ir.Node {
rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
_, sym := rname.qualifiedIdent()
tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
return sym.Pkg.Lookup(buf.String())
}
-func (pr *pkgReader) objDictIdx(sym *types.Sym, idx int, implicits, explicits []*types.Type) *readerDict {
+func (pr *pkgReader) objDictIdx(sym *types.Sym, idx pkgbits.Index, implicits, explicits []*types.Type) *readerDict {
r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
var dict readerDict
dict.itabs = make([]itabInfo2, r.Len())
for i := range dict.itabs {
- typ := pr.typIdx(typeInfo{idx: r.Len(), derived: true}, &dict, true)
+ typ := pr.typIdx(typeInfo{idx: pkgbits.Index(r.Len()), derived: true}, &dict, true)
ifaceInfo := r.typInfo()
var lsym *obj.LSym
l := linker{
pw: pkgbits.NewPkgEncoder(base.Debug.SyncFrames),
- pkgs: make(map[string]int),
- decls: make(map[*types.Sym]int),
+ pkgs: make(map[string]pkgbits.Index),
+ decls: make(map[*types.Sym]pkgbits.Index),
}
publicRootWriter := l.pw.NewEncoder(pkgbits.RelocMeta, pkgbits.SyncPublic)
assert(publicRootWriter.Idx == pkgbits.PublicRootIdx)
- var selfPkgIdx int
+ var selfPkgIdx pkgbits.Index
{
pr := localPkgReader
}
{
- var idxs []int
+ var idxs []pkgbits.Index
for _, idx := range l.decls {
idxs = append(idxs, idx)
}
- sort.Ints(idxs)
+ sort.Slice(idxs, func(i, j int) bool { return idxs[i] < idxs[j] })
w := publicRootWriter
curpkg *types2.Package
info *types2.Info
- posBasesIdx map[*syntax.PosBase]int
- pkgsIdx map[*types2.Package]int
- typsIdx map[types2.Type]int
- globalsIdx map[types2.Object]int
+ posBasesIdx map[*syntax.PosBase]pkgbits.Index
+ pkgsIdx map[*types2.Package]pkgbits.Index
+ typsIdx map[types2.Type]pkgbits.Index
+ globalsIdx map[types2.Object]pkgbits.Index
funDecls map[*types2.Func]*syntax.FuncDecl
typDecls map[*types2.TypeName]typeDeclGen
curpkg: pkg,
info: info,
- pkgsIdx: make(map[*types2.Package]int),
- globalsIdx: make(map[types2.Object]int),
- typsIdx: make(map[types2.Type]int),
+ pkgsIdx: make(map[*types2.Package]pkgbits.Index),
+ globalsIdx: make(map[types2.Object]pkgbits.Index),
+ typsIdx: make(map[types2.Type]pkgbits.Index),
- posBasesIdx: make(map[*syntax.PosBase]int),
+ posBasesIdx: make(map[*syntax.PosBase]pkgbits.Index),
funDecls: make(map[*types2.Func]*syntax.FuncDecl),
typDecls: make(map[*types2.TypeName]typeDeclGen),
// derivedIdx maps a Type to its corresponding index within the
// derived slice, if present.
- derivedIdx map[types2.Type]int
+ derivedIdx map[types2.Type]pkgbits.Index
// funcs lists references to generic functions that were
// instantiated with derived types (i.e., that require
// A derivedInfo represents a reference to an encoded generic Go type.
type derivedInfo struct {
- idx int
+ idx pkgbits.Index
needed bool
}
// Otherwise, the typeInfo represents a non-generic Go type, and idx
// is an index into the reader.typs array instead.
type typeInfo struct {
- idx int
+ idx pkgbits.Index
derived bool
}
type objInfo struct {
- idx int // index for the generic function declaration
- explicits []typeInfo // info for the type arguments
+ idx pkgbits.Index // index for the generic function declaration
+ explicits []typeInfo // info for the type arguments
}
type itabInfo struct {
- typIdx int // always a derived type index
- iface typeInfo // always a non-empty interface type
+ typIdx pkgbits.Index // always a derived type index
+ iface typeInfo // always a non-empty interface type
}
func (info objInfo) anyDerived() bool {
w.Reloc(pkgbits.RelocPosBase, w.p.posBaseIdx(b))
}
-func (pw *pkgWriter) posBaseIdx(b *syntax.PosBase) int {
+func (pw *pkgWriter) posBaseIdx(b *syntax.PosBase) pkgbits.Index {
if idx, ok := pw.posBasesIdx[b]; ok {
return idx
}
w.Reloc(pkgbits.RelocPkg, w.p.pkgIdx(pkg))
}
-func (pw *pkgWriter) pkgIdx(pkg *types2.Package) int {
+func (pw *pkgWriter) pkgIdx(pkg *types2.Package) pkgbits.Index {
if idx, ok := pw.pkgsIdx[pkg]; ok {
return idx
}
func (w *writer) typInfo(info typeInfo) {
w.Sync(pkgbits.SyncType)
if w.Bool(info.derived) {
- w.Len(info.idx)
+ w.Len(int(info.idx))
w.derived = true
} else {
w.Reloc(pkgbits.RelocType, info.idx)
}
if w.derived {
- idx := len(dict.derived)
+ idx := pkgbits.Index(len(dict.derived))
dict.derived = append(dict.derived, derivedInfo{idx: w.Flush()})
dict.derivedIdx[typ] = idx
return typeInfo{idx: idx, derived: true}
}
}
-func (pw *pkgWriter) objIdx(obj types2.Object) int {
+func (pw *pkgWriter) objIdx(obj types2.Object) pkgbits.Index {
if idx, ok := pw.globalsIdx[obj]; ok {
return idx
}
dict := &writerDict{
- derivedIdx: make(map[types2.Type]int),
+ derivedIdx: make(map[types2.Type]pkgbits.Index),
}
if isDefinedType(obj) && obj.Pkg() == pw.curpkg {
nitabs := len(dict.itabs)
w.Len(nitabs)
for _, itab := range dict.itabs {
- w.Len(itab.typIdx)
+ w.Len(int(itab.typIdx))
w.typInfo(itab.iface)
}
// @@@ Function bodies
-func (pw *pkgWriter) bodyIdx(pkg *types2.Package, sig *types2.Signature, block *syntax.BlockStmt, dict *writerDict) (idx int, closureVars []posObj) {
+func (pw *pkgWriter) bodyIdx(pkg *types2.Package, sig *types2.Signature, block *syntax.BlockStmt, dict *writerDict) (idx pkgbits.Index, closureVars []posObj) {
w := pw.newWriter(pkgbits.RelocBody, pkgbits.SyncFuncBody)
w.dict = dict
"fmt"
"go/token"
"go/types"
+ "internal/pkgbits"
"sync"
)
// See cmd/compile/internal/noder.derivedInfo.
type derivedInfo struct {
- idx int
+ idx pkgbits.Index
needed bool
}
// See cmd/compile/internal/noder.typeInfo.
type typeInfo struct {
- idx int
+ idx pkgbits.Index
derived bool
}
derivedTypes []types.Type // lazily instantiated from derived
}
-func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx int, marker pkgbits.SyncMarker) *reader {
+func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
return &reader{
Decoder: pr.NewDecoder(k, idx, marker),
p: pr,
return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase))
}
-func (pr *pkgReader) posBaseIdx(idx int) string {
+func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string {
if b := pr.posBases[idx]; b != "" {
return b
}
return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
}
-func (pr *pkgReader) pkgIdx(idx int) *types.Package {
+func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package {
// TODO(mdempsky): Consider using some non-nil pointer to indicate
// the universe scope, so we don't need to keep re-reading it.
if pkg := pr.pkgs[idx]; pkg != nil {
func (r *reader) typInfo() typeInfo {
r.Sync(pkgbits.SyncType)
if r.Bool() {
- return typeInfo{idx: r.Len(), derived: true}
+ return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
}
return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
}
return obj, targs
}
-func (pr *pkgReader) objIdx(idx int) (*types.Package, string) {
+func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
objPkg, objName := rname.qualifiedIdent()
return objPkg, objName
}
-func (pr *pkgReader) objDictIdx(idx int) *readerDict {
+func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
var dict readerDict
// AbsIdx returns the absolute index for the given (section, index)
// pair.
-func (pr *PkgDecoder) AbsIdx(k RelocKind, idx int) int {
- absIdx := idx
+func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int {
+ absIdx := int(idx)
if k > 0 {
absIdx += int(pr.elemEndsEnds[k-1])
}
// DataIdx returns the raw element bitstream for the given (section,
// index) pair.
-func (pr *PkgDecoder) DataIdx(k RelocKind, idx int) string {
+func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string {
absIdx := pr.AbsIdx(k, idx)
var start uint32
}
// StringIdx returns the string value for the given string index.
-func (pr *PkgDecoder) StringIdx(idx int) string {
+func (pr *PkgDecoder) StringIdx(idx Index) string {
return pr.DataIdx(RelocString, idx)
}
// NewDecoder returns a Decoder for the given (section, index) pair,
// and decodes the given SyncMarker from the element bitstream.
-func (pr *PkgDecoder) NewDecoder(k RelocKind, idx int, marker SyncMarker) Decoder {
+func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder {
r := pr.NewDecoderRaw(k, idx)
r.Sync(marker)
return r
// NewDecoderRaw returns a Decoder for the given (section, index) pair.
//
// Most callers should use NewDecoder instead.
-func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx int) Decoder {
+func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder {
r := Decoder{
common: pr,
k: k,
r.Relocs = make([]RelocEnt, r.Len())
for i := range r.Relocs {
r.Sync(SyncReloc)
- r.Relocs[i] = RelocEnt{RelocKind(r.Len()), r.Len()}
+ r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())}
}
return r
Data strings.Reader
k RelocKind
- Idx int
+ Idx Index
}
func (r *Decoder) checkErr(err error) {
return x
}
-func (r *Decoder) rawReloc(k RelocKind, idx int) int {
+func (r *Decoder) rawReloc(k RelocKind, idx int) Index {
e := r.Relocs[idx]
assert(e.Kind == k)
return e.Idx
// Reloc decodes a relocation of expected section k from the element
// bitstream and returns an index to the referenced element.
-func (r *Decoder) Reloc(k RelocKind) int {
+func (r *Decoder) Reloc(k RelocKind) Index {
r.Sync(SyncUseReloc)
return r.rawReloc(k, r.Len())
}
// PeekPkgPath returns the package path for the specified package
// index.
-func (pr *PkgDecoder) PeekPkgPath(idx int) string {
+func (pr *PkgDecoder) PeekPkgPath(idx Index) string {
r := pr.NewDecoder(RelocPkg, idx, SyncPkgDef)
path := r.String()
if path == "" {
// PeekObj returns the package path, object name, and CodeObj for the
// specified object index.
-func (pr *PkgDecoder) PeekObj(idx int) (string, string, CodeObj) {
+func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) {
r := pr.NewDecoder(RelocName, idx, SyncObject1)
r.Sync(SyncSym)
r.Sync(SyncPkg)
// stringsIdx maps previously encoded strings to their index within
// the RelocString section, to allow deduplication. That is,
// elems[RelocString][stringsIdx[s]] == s (if present).
- stringsIdx map[string]int
+ stringsIdx map[string]Index
syncFrames int
}
// higher-level Unified IR reader/writer code.
func NewPkgEncoder(syncFrames int) PkgEncoder {
return PkgEncoder{
- stringsIdx: make(map[string]int),
+ stringsIdx: make(map[string]Index),
syncFrames: syncFrames,
}
}
// StringIdx adds a string value to the strings section, if not
// already present, and returns its index.
-func (pw *PkgEncoder) StringIdx(s string) int {
+func (pw *PkgEncoder) StringIdx(s string) Index {
if idx, ok := pw.stringsIdx[s]; ok {
assert(pw.elems[RelocString][idx] == s)
return idx
}
- idx := len(pw.elems[RelocString])
+ idx := Index(len(pw.elems[RelocString]))
pw.elems[RelocString] = append(pw.elems[RelocString], s)
pw.stringsIdx[s] = idx
return idx
//
// Most callers should use NewEncoder instead.
func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder {
- idx := len(pw.elems[k])
+ idx := Index(len(pw.elems[k]))
pw.elems[k] = append(pw.elems[k], "") // placeholder
return Encoder{
encodingRelocHeader bool
k RelocKind
- Idx int // index within relocation section
+ Idx Index // index within relocation section
}
// Flush finalizes the element's bitstream and returns its Index.
-func (w *Encoder) Flush() int {
+func (w *Encoder) Flush() Index {
var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved
// Backup the data so we write the relocations at the front.
for _, rEnt := range w.Relocs {
w.Sync(SyncReloc)
w.Len(int(rEnt.Kind))
- w.Len(rEnt.Idx)
+ w.Len(int(rEnt.Idx))
}
io.Copy(&sb, &w.Data)
w.rawUvarint(ux)
}
-func (w *Encoder) rawReloc(r RelocKind, idx int) int {
+func (w *Encoder) rawReloc(r RelocKind, idx Index) int {
// TODO(mdempsky): Use map for lookup; this takes quadratic time.
for i, rEnt := range w.Relocs {
if rEnt.Kind == r && rEnt.Idx == idx {
// Note: Only the index is formally written into the element
// bitstream, so bitstream decoders must know from context which
// section an encoded relocation refers to.
-func (w *Encoder) Reloc(r RelocKind, idx int) {
+func (w *Encoder) Reloc(r RelocKind, idx Index) {
w.Sync(SyncUseReloc)
w.Len(w.rawReloc(r, idx))
}
// A RelocKind indicates a particular section within a unified IR export.
type RelocKind int
+// An Index represents a bitstream element index within a particular
+// section.
+type Index int
+
// A relocEnt (relocation entry) is an entry in an element's local
// reference table.
//
// TODO(mdempsky): Rename this too.
type RelocEnt struct {
Kind RelocKind
- Idx int
+ Idx Index
}
// Reserved indices within the meta relocation section.
const (
- PublicRootIdx = 0
- PrivateRootIdx = 1
+ PublicRootIdx Index = 0
+ PrivateRootIdx Index = 1
)
const (