type linker struct {
pw pkgbits.PkgEncoder
- pkgs map[string]pkgbits.Index
- decls map[*types.Sym]pkgbits.Index
- bodies map[*types.Sym]pkgbits.Index
+ pkgs map[string]index
+ decls map[*types.Sym]index
+ bodies map[*types.Sym]index
}
// relocAll ensures that all elements specified by pr and relocs are
// relocIdx ensures a single element is copied into the output export
// data file, and returns the corresponding index in the output.
-func (l *linker) relocIdx(pr *pkgReader, k pkgbits.RelocKind, idx pkgbits.Index) pkgbits.Index {
+func (l *linker) relocIdx(pr *pkgReader, k pkgbits.RelocKind, idx index) index {
assert(pr != nil)
absIdx := pr.AbsIdx(k, idx)
return ^newidx
}
- var newidx pkgbits.Index
+ var newidx index
switch k {
case pkgbits.RelocString:
newidx = l.relocString(pr, idx)
// relocString copies the specified string from pr into the output
// export data file, deduplicating it against other strings.
-func (l *linker) relocString(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
+func (l *linker) relocString(pr *pkgReader, idx index) index {
return l.pw.StringIdx(pr.StringIdx(idx))
}
// TODO(mdempsky): Since CL 391014, we already have the compilation
// unit's import path, so there should be no need to rewrite packages
// anymore.
-func (l *linker) relocPkg(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
+func (l *linker) relocPkg(pr *pkgReader, idx index) index {
path := pr.PeekPkgPath(idx)
if newidx, ok := l.pkgs[path]; ok {
// relocObj copies the specified object from pr into the output export
// data file, rewriting its compiler-private extension data (e.g.,
// adding inlining cost and escape analysis results for functions).
-func (l *linker) relocObj(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
+func (l *linker) relocObj(pr *pkgReader, idx index) index {
path, name, tag := pr.PeekObj(idx)
sym := types.NewPkg(path, "").Lookup(name)
// relocCommon copies the specified element from pr into w,
// recursively relocating any referenced elements as well.
-func (l *linker) relocCommon(pr *pkgReader, w *pkgbits.Encoder, k pkgbits.RelocKind, idx pkgbits.Index) {
+func (l *linker) relocCommon(pr *pkgReader, w *pkgbits.Encoder, k pkgbits.RelocKind, idx index) {
r := pr.NewDecoderRaw(k, idx)
w.Relocs = l.relocAll(pr, r.Relocs)
io.Copy(&w.Data, &r.Data)
// offset for rewriting the given (absolute!) index into the output,
// but bitwise inverted so we can detect if we're missing the entry
// or not.
- newindex []pkgbits.Index
+ newindex []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([]pkgbits.Index, pr.TotalElems()),
+ newindex: make([]index, pr.TotalElems()),
}
}
// corresponding dictionary) within a package's export data.
type pkgReaderIndex struct {
pr *pkgReader
- idx pkgbits.Index
+ idx index
dict *readerDict
methodSym *types.Sym
return r
}
-func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
+func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx index, marker pkgbits.SyncMarker) *reader {
return &reader{
Decoder: pr.NewDecoder(k, idx, marker),
p: pr,
// posBaseIdx returns the specified position base, reading it first if
// needed.
-func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) *src.PosBase {
+func (pr *pkgReader) posBaseIdx(idx index) *src.PosBase {
if b := pr.posBases[idx]; b != nil {
return b
}
// pkgIdx returns the specified package from the export data, reading
// it first if needed.
-func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Pkg {
+func (pr *pkgReader) pkgIdx(idx 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: pkgbits.Index(r.Len()), derived: true}
+ return typeInfo{idx: index(r.Len()), derived: true}
}
return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
}
// type arguments, if any.
// If shaped is true, then the shaped variant of the object is returned
// instead.
-func (pr *pkgReader) objIdx(idx pkgbits.Index, implicits, explicits []*types.Type, shaped bool) ir.Node {
+func (pr *pkgReader) objIdx(idx index, implicits, explicits []*types.Type, shaped bool) ir.Node {
n, err := pr.objIdxMayFail(idx, implicits, explicits, shaped)
if err != nil {
base.Fatalf("%v", err)
//
// Other sources of internal failure (such as duplicate definitions) still fail
// the build.
-func (pr *pkgReader) objIdxMayFail(idx pkgbits.Index, implicits, explicits []*types.Type, shaped bool) (ir.Node, error) {
+func (pr *pkgReader) objIdxMayFail(idx index, implicits, explicits []*types.Type, shaped bool) (ir.Node, error) {
rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
_, sym := rname.qualifiedIdent()
tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
}
// objDictIdx reads and returns the specified object dictionary.
-func (pr *pkgReader) objDictIdx(sym *types.Sym, idx pkgbits.Index, implicits, explicits []*types.Type, shaped bool) (*readerDict, error) {
+func (pr *pkgReader) objDictIdx(sym *types.Sym, idx index, implicits, explicits []*types.Type, shaped bool) (*readerDict, error) {
r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
dict := readerDict{
return
}
-func (pr *pkgReader) objDictName(idx pkgbits.Index, implicits, explicits []*types.Type) *ir.Name {
+func (pr *pkgReader) objDictName(idx index, implicits, explicits []*types.Type) *ir.Name {
rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
_, sym := rname.qualifiedIdent()
tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
+++ /dev/null
-// Copyright 2021 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 will evolve, since we plan to do a mix of stenciling and passing
-// around dictionaries.
-
-package noder
-
-import (
- "cmd/compile/internal/base"
-)
-
-func assert(p bool) {
- base.Assert(p)
-}
+++ /dev/null
-// Copyright 2021 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.
-
-package noder
-
-import (
- "cmd/compile/internal/ir"
- "cmd/compile/internal/syntax"
-)
-
-// TODO(mdempsky): Investigate replacing with switch statements or dense arrays.
-
-var branchOps = [...]ir.Op{
- syntax.Break: ir.OBREAK,
- syntax.Continue: ir.OCONTINUE,
- syntax.Fallthrough: ir.OFALL,
- syntax.Goto: ir.OGOTO,
-}
-
-var callOps = [...]ir.Op{
- syntax.Defer: ir.ODEFER,
- syntax.Go: ir.OGO,
-}
l := linker{
pw: pkgbits.NewPkgEncoder(base.Debug.SyncFrames),
- pkgs: make(map[string]pkgbits.Index),
- decls: make(map[*types.Sym]pkgbits.Index),
- bodies: make(map[*types.Sym]pkgbits.Index),
+ pkgs: make(map[string]index),
+ decls: make(map[*types.Sym]index),
+ bodies: make(map[*types.Sym]index),
}
publicRootWriter := l.pw.NewEncoder(pkgbits.RelocMeta, pkgbits.SyncPublic)
assert(publicRootWriter.Idx == pkgbits.PublicRootIdx)
assert(privateRootWriter.Idx == pkgbits.PrivateRootIdx)
- var selfPkgIdx pkgbits.Index
+ var selfPkgIdx index
{
pr := localPkgReader
}
{
- var idxs []pkgbits.Index
+ var idxs []index
for _, idx := range l.decls {
idxs = append(idxs, idx)
}
{
type symIdx struct {
sym *types.Sym
- idx pkgbits.Index
+ idx index
}
var bodies []symIdx
for sym, idx := range l.bodies {
// and better document the file format boundary between public and
// private data.
+type index = pkgbits.Index
+
+func assert(p bool) { base.Assert(p) }
+
// A pkgWriter constructs Unified IR export data from the results of
// running the types2 type checker on a Go compilation unit.
type pkgWriter struct {
// Indices for previously written syntax and types2 things.
- posBasesIdx map[*syntax.PosBase]pkgbits.Index
- pkgsIdx map[*types2.Package]pkgbits.Index
- typsIdx map[types2.Type]pkgbits.Index
- objsIdx map[types2.Object]pkgbits.Index
+ posBasesIdx map[*syntax.PosBase]index
+ pkgsIdx map[*types2.Package]index
+ typsIdx map[types2.Type]index
+ objsIdx map[types2.Object]index
// Maps from types2.Objects back to their syntax.Decl.
info: info,
rangeFuncBodyClosures: otherInfo,
- pkgsIdx: make(map[*types2.Package]pkgbits.Index),
- objsIdx: make(map[types2.Object]pkgbits.Index),
- typsIdx: make(map[types2.Type]pkgbits.Index),
+ pkgsIdx: make(map[*types2.Package]index),
+ objsIdx: make(map[types2.Object]index),
+ typsIdx: make(map[types2.Type]index),
- posBasesIdx: make(map[*syntax.PosBase]pkgbits.Index),
+ posBasesIdx: make(map[*syntax.PosBase]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]pkgbits.Index
+ derivedIdx map[types2.Type]index
// These slices correspond to entries in the runtime dictionary.
typeParamMethodExprs []writerMethodExprInfo
// A derivedInfo represents a reference to an encoded generic Go type.
type derivedInfo struct {
- idx pkgbits.Index
+ idx index
needed bool // TODO(mdempsky): Remove.
}
// Otherwise, the typeInfo represents a non-generic Go type, and idx
// is an index into the reader.typs array instead.
type typeInfo struct {
- idx pkgbits.Index
+ idx index
derived bool
}
// An objInfo represents a reference to an encoded, instantiated (if
// applicable) Go object.
type objInfo struct {
- idx pkgbits.Index // index for the generic function declaration
- explicits []typeInfo // info for the type arguments
+ idx index // index for the generic function declaration
+ explicits []typeInfo // info for the type arguments
}
// A selectorInfo represents a reference to an encoded field or method
// name (i.e., objects that can only be accessed using selector
// expressions).
type selectorInfo struct {
- pkgIdx pkgbits.Index
- nameIdx pkgbits.Index
+ pkgIdx index
+ nameIdx index
}
// anyDerived reports whether any of info's explicit type arguments
}
// posBaseIdx returns the index for the given PosBase.
-func (pw *pkgWriter) posBaseIdx(b *syntax.PosBase) pkgbits.Index {
+func (pw *pkgWriter) posBaseIdx(b *syntax.PosBase) index {
if idx, ok := pw.posBasesIdx[b]; ok {
return idx
}
w.pkgRef(w.p.pkgIdx(pkg))
}
-func (w *writer) pkgRef(idx pkgbits.Index) {
+func (w *writer) pkgRef(idx index) {
w.Sync(pkgbits.SyncPkg)
w.Reloc(pkgbits.RelocPkg, idx)
}
// pkgIdx returns the index for the given package, adding it to the
// package export data if needed.
-func (pw *pkgWriter) pkgIdx(pkg *types2.Package) pkgbits.Index {
+func (pw *pkgWriter) pkgIdx(pkg *types2.Package) index {
if idx, ok := pw.pkgsIdx[pkg]; ok {
return idx
}
}
if w.derived {
- idx := pkgbits.Index(len(dict.derived))
+ idx := index(len(dict.derived))
dict.derived = append(dict.derived, derivedInfo{idx: w.Flush()})
dict.derivedIdx[typ] = idx
return typeInfo{idx: idx, derived: true}
// objIdx returns the index for the given Object, adding it to the
// export data as needed.
-func (pw *pkgWriter) objIdx(obj types2.Object) pkgbits.Index {
+func (pw *pkgWriter) objIdx(obj types2.Object) index {
// TODO(mdempsky): Validate that obj is a global object (or a local
// defined type, which we hoist to global scope anyway).
}
dict := &writerDict{
- derivedIdx: make(map[types2.Type]pkgbits.Index),
+ derivedIdx: make(map[types2.Type]index),
}
if isDefinedType(obj) && obj.Pkg() == pw.curpkg {
// bodyIdx returns the index for the given function body (specified by
// block), adding it to the export data
-func (pw *pkgWriter) bodyIdx(sig *types2.Signature, block *syntax.BlockStmt, dict *writerDict) (idx pkgbits.Index, closureVars []posVar) {
+func (pw *pkgWriter) bodyIdx(sig *types2.Signature, block *syntax.BlockStmt, dict *writerDict) (idx index, closureVars []posVar) {
w := pw.newWriter(pkgbits.RelocBody, pkgbits.SyncFuncBody)
w.sig = sig
w.dict = dict
case *syntax.BranchStmt:
w.Code(stmtBranch)
w.pos(stmt)
- w.op(branchOps[stmt.Tok])
+ var op ir.Op
+ switch stmt.Tok {
+ case syntax.Break:
+ op = ir.OBREAK
+ case syntax.Continue:
+ op = ir.OCONTINUE
+ case syntax.Fallthrough:
+ op = ir.OFALL
+ case syntax.Goto:
+ op = ir.OGOTO
+ }
+ w.op(op)
w.optLabel(stmt.Label)
case *syntax.CallStmt:
w.Code(stmtCall)
w.pos(stmt)
- w.op(callOps[stmt.Tok])
+ var op ir.Op
+ switch stmt.Tok {
+ case syntax.Defer:
+ op = ir.ODEFER
+ case syntax.Go:
+ op = ir.OGO
+ }
+ w.op(op)
w.expr(stmt.Call)
if stmt.Tok == syntax.Defer {
w.optExpr(stmt.DeferAt)
}
return sig.TypeParams()
case *types2.TypeName:
- if !obj.IsAlias() {
- return obj.Type().(*types2.Named).TypeParams()
- }
- if alias, ok := obj.Type().(*types2.Alias); ok {
- return alias.TypeParams()
+ switch t := obj.Type().(type) {
+ case *types2.Named:
+ return t.TypeParams()
+ case *types2.Alias:
+ return t.TypeParams()
}
}
return nil