aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/reader2.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2022-02-28 20:35:24 -0800
committerMatthew Dempsky <mdempsky@google.com>2022-03-01 19:32:51 +0000
commit44e92e11c74fdb9ac016c65b319afa49737871ea (patch)
treeeda38390ebed09033fa4b22e1b973c71873c144c /src/cmd/compile/internal/noder/reader2.go
parent620a3c0596a2c0dd04964c3655e4f631fb85c0bb (diff)
downloadgo-44e92e11c74fdb9ac016c65b319afa49737871ea.tar.xz
cmd/compile: move unified IR's reader2 into importer package
This keeps cmd/compile/internal/importer similar to how go/internal/gcimporter will work after unified IR support is added in a subsequent CL. Change-Id: Id3c000f3a13a54a725602552c6b3191d1affb184 Reviewed-on: https://go-review.googlesource.com/c/go/+/388614 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Trust: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Diffstat (limited to 'src/cmd/compile/internal/noder/reader2.go')
-rw-r--r--src/cmd/compile/internal/noder/reader2.go512
1 files changed, 0 insertions, 512 deletions
diff --git a/src/cmd/compile/internal/noder/reader2.go b/src/cmd/compile/internal/noder/reader2.go
deleted file mode 100644
index 8d1f9087a5..0000000000
--- a/src/cmd/compile/internal/noder/reader2.go
+++ /dev/null
@@ -1,512 +0,0 @@
-// UNREVIEWED
-
-// 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/base"
- "cmd/compile/internal/syntax"
- "cmd/compile/internal/types2"
- "cmd/internal/src"
- "internal/pkgbits"
-)
-
-type pkgReader2 struct {
- pkgbits.PkgDecoder
-
- ctxt *types2.Context
- imports map[string]*types2.Package
-
- posBases []*syntax.PosBase
- pkgs []*types2.Package
- typs []types2.Type
-}
-
-func readPackage2(ctxt *types2.Context, imports map[string]*types2.Package, input pkgbits.PkgDecoder) *types2.Package {
- pr := pkgReader2{
- PkgDecoder: input,
-
- ctxt: ctxt,
- imports: imports,
-
- posBases: make([]*syntax.PosBase, input.NumElems(pkgbits.RelocPosBase)),
- pkgs: make([]*types2.Package, input.NumElems(pkgbits.RelocPkg)),
- typs: make([]types2.Type, input.NumElems(pkgbits.RelocType)),
- }
-
- r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
- pkg := r.pkg()
- r.Bool() // has init
-
- for i, n := 0, r.Len(); i < n; i++ {
- // As if r.obj(), but avoiding the Scope.Lookup call,
- // to avoid eager loading of imports.
- r.Sync(pkgbits.SyncObject)
- assert(!r.Bool())
- r.p.objIdx(r.Reloc(pkgbits.RelocObj))
- assert(r.Len() == 0)
- }
-
- r.Sync(pkgbits.SyncEOF)
-
- pkg.MarkComplete()
- return pkg
-}
-
-type reader2 struct {
- pkgbits.Decoder
-
- p *pkgReader2
-
- dict *reader2Dict
-}
-
-type reader2Dict struct {
- bounds []typeInfo
-
- tparams []*types2.TypeParam
-
- derived []derivedInfo
- derivedTypes []types2.Type
-}
-
-type reader2TypeBound struct {
- derived bool
- boundIdx int
-}
-
-func (pr *pkgReader2) newReader(k pkgbits.RelocKind, idx int, marker pkgbits.SyncMarker) *reader2 {
- return &reader2{
- Decoder: pr.NewDecoder(k, idx, marker),
- p: pr,
- }
-}
-
-// @@@ Positions
-
-func (r *reader2) pos() syntax.Pos {
- r.Sync(pkgbits.SyncPos)
- if !r.Bool() {
- return syntax.Pos{}
- }
-
- // TODO(mdempsky): Delta encoding.
- posBase := r.posBase()
- line := r.Uint()
- col := r.Uint()
- return syntax.MakePos(posBase, line, col)
-}
-
-func (r *reader2) posBase() *syntax.PosBase {
- return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase))
-}
-
-func (pr *pkgReader2) posBaseIdx(idx int) *syntax.PosBase {
- if b := pr.posBases[idx]; b != nil {
- return b
- }
-
- r := pr.newReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
- var b *syntax.PosBase
-
- filename := r.String()
-
- if r.Bool() {
- b = syntax.NewTrimmedFileBase(filename, true)
- } else {
- pos := r.pos()
- line := r.Uint()
- col := r.Uint()
- b = syntax.NewLineBase(pos, filename, true, line, col)
- }
-
- pr.posBases[idx] = b
- return b
-}
-
-// @@@ Packages
-
-func (r *reader2) pkg() *types2.Package {
- r.Sync(pkgbits.SyncPkg)
- return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
-}
-
-func (pr *pkgReader2) pkgIdx(idx int) *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 {
- return pkg
- }
-
- pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg()
- pr.pkgs[idx] = pkg
- return pkg
-}
-
-func (r *reader2) doPkg() *types2.Package {
- path := r.String()
- if path == "builtin" {
- return nil // universe
- }
- if path == "" {
- path = r.p.PkgPath()
- }
-
- if pkg := r.p.imports[path]; pkg != nil {
- return pkg
- }
-
- name := r.String()
- height := r.Len()
-
- pkg := types2.NewPackageHeight(path, name, height)
- r.p.imports[path] = pkg
-
- // TODO(mdempsky): The list of imported packages is important for
- // go/types, but we could probably skip populating it for types2.
- imports := make([]*types2.Package, r.Len())
- for i := range imports {
- imports[i] = r.pkg()
- }
- pkg.SetImports(imports)
-
- return pkg
-}
-
-// @@@ Types
-
-func (r *reader2) typ() types2.Type {
- return r.p.typIdx(r.typInfo(), r.dict)
-}
-
-func (r *reader2) typInfo() typeInfo {
- r.Sync(pkgbits.SyncType)
- if r.Bool() {
- return typeInfo{idx: r.Len(), derived: true}
- }
- return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
-}
-
-func (pr *pkgReader2) typIdx(info typeInfo, dict *reader2Dict) types2.Type {
- idx := info.idx
- var where *types2.Type
- if info.derived {
- where = &dict.derivedTypes[idx]
- idx = dict.derived[idx].idx
- } else {
- where = &pr.typs[idx]
- }
-
- if typ := *where; typ != nil {
- return typ
- }
-
- r := pr.newReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
- r.dict = dict
-
- typ := r.doTyp()
- assert(typ != nil)
-
- // See comment in pkgReader.typIdx explaining how this happens.
- if prev := *where; prev != nil {
- return prev
- }
-
- *where = typ
- return typ
-}
-
-func (r *reader2) doTyp() (res types2.Type) {
- switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
- default:
- base.FatalfAt(src.NoXPos, "unhandled type tag: %v", tag)
- panic("unreachable")
-
- case pkgbits.TypeBasic:
- return types2.Typ[r.Len()]
-
- case pkgbits.TypeNamed:
- obj, targs := r.obj()
- name := obj.(*types2.TypeName)
- if len(targs) != 0 {
- t, _ := types2.Instantiate(r.p.ctxt, name.Type(), targs, false)
- return t
- }
- return name.Type()
-
- case pkgbits.TypeTypeParam:
- return r.dict.tparams[r.Len()]
-
- case pkgbits.TypeArray:
- len := int64(r.Uint64())
- return types2.NewArray(r.typ(), len)
- case pkgbits.TypeChan:
- dir := types2.ChanDir(r.Len())
- return types2.NewChan(dir, r.typ())
- case pkgbits.TypeMap:
- return types2.NewMap(r.typ(), r.typ())
- case pkgbits.TypePointer:
- return types2.NewPointer(r.typ())
- case pkgbits.TypeSignature:
- return r.signature(nil, nil, nil)
- case pkgbits.TypeSlice:
- return types2.NewSlice(r.typ())
- case pkgbits.TypeStruct:
- return r.structType()
- case pkgbits.TypeInterface:
- return r.interfaceType()
- case pkgbits.TypeUnion:
- return r.unionType()
- }
-}
-
-func (r *reader2) structType() *types2.Struct {
- fields := make([]*types2.Var, r.Len())
- var tags []string
- for i := range fields {
- pos := r.pos()
- pkg, name := r.selector()
- ftyp := r.typ()
- tag := r.String()
- embedded := r.Bool()
-
- fields[i] = types2.NewField(pos, pkg, name, ftyp, embedded)
- if tag != "" {
- for len(tags) < i {
- tags = append(tags, "")
- }
- tags = append(tags, tag)
- }
- }
- return types2.NewStruct(fields, tags)
-}
-
-func (r *reader2) unionType() *types2.Union {
- terms := make([]*types2.Term, r.Len())
- for i := range terms {
- terms[i] = types2.NewTerm(r.Bool(), r.typ())
- }
- return types2.NewUnion(terms)
-}
-
-func (r *reader2) interfaceType() *types2.Interface {
- methods := make([]*types2.Func, r.Len())
- embeddeds := make([]types2.Type, r.Len())
- implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool()
-
- for i := range methods {
- pos := r.pos()
- pkg, name := r.selector()
- mtyp := r.signature(nil, nil, nil)
- methods[i] = types2.NewFunc(pos, pkg, name, mtyp)
- }
-
- for i := range embeddeds {
- embeddeds[i] = r.typ()
- }
-
- iface := types2.NewInterfaceType(methods, embeddeds)
- if implicit {
- iface.MarkImplicit()
- }
- return iface
-}
-
-func (r *reader2) signature(recv *types2.Var, rtparams, tparams []*types2.TypeParam) *types2.Signature {
- r.Sync(pkgbits.SyncSignature)
-
- params := r.params()
- results := r.params()
- variadic := r.Bool()
-
- return types2.NewSignatureType(recv, rtparams, tparams, params, results, variadic)
-}
-
-func (r *reader2) params() *types2.Tuple {
- r.Sync(pkgbits.SyncParams)
- params := make([]*types2.Var, r.Len())
- for i := range params {
- params[i] = r.param()
- }
- return types2.NewTuple(params...)
-}
-
-func (r *reader2) param() *types2.Var {
- r.Sync(pkgbits.SyncParam)
-
- pos := r.pos()
- pkg, name := r.localIdent()
- typ := r.typ()
-
- return types2.NewParam(pos, pkg, name, typ)
-}
-
-// @@@ Objects
-
-func (r *reader2) obj() (types2.Object, []types2.Type) {
- r.Sync(pkgbits.SyncObject)
-
- assert(!r.Bool())
-
- pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj))
- obj := pkg.Scope().Lookup(name)
-
- targs := make([]types2.Type, r.Len())
- for i := range targs {
- targs[i] = r.typ()
- }
-
- return obj, targs
-}
-
-func (pr *pkgReader2) objIdx(idx int) (*types2.Package, string) {
- rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
-
- objPkg, objName := rname.qualifiedIdent()
- assert(objName != "")
-
- tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
-
- if tag == pkgbits.ObjStub {
- assert(objPkg == nil || objPkg == types2.Unsafe)
- return objPkg, objName
- }
-
- dict := pr.objDictIdx(idx)
-
- r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
- r.dict = dict
-
- objPkg.Scope().InsertLazy(objName, func() types2.Object {
- switch tag {
- default:
- panic("weird")
-
- case pkgbits.ObjAlias:
- pos := r.pos()
- typ := r.typ()
- return types2.NewTypeName(pos, objPkg, objName, typ)
-
- case pkgbits.ObjConst:
- pos := r.pos()
- typ := r.typ()
- val := r.Value()
- return types2.NewConst(pos, objPkg, objName, typ, val)
-
- case pkgbits.ObjFunc:
- pos := r.pos()
- tparams := r.typeParamNames()
- sig := r.signature(nil, nil, tparams)
- return types2.NewFunc(pos, objPkg, objName, sig)
-
- case pkgbits.ObjType:
- pos := r.pos()
-
- return types2.NewTypeNameLazy(pos, objPkg, objName, func(named *types2.Named) (tparams []*types2.TypeParam, underlying types2.Type, methods []*types2.Func) {
- tparams = r.typeParamNames()
-
- // TODO(mdempsky): Rewrite receiver types to underlying is an
- // Interface? The go/types importer does this (I think because
- // unit tests expected that), but cmd/compile doesn't care
- // about it, so maybe we can avoid worrying about that here.
- underlying = r.typ().Underlying()
-
- methods = make([]*types2.Func, r.Len())
- for i := range methods {
- methods[i] = r.method()
- }
-
- return
- })
-
- case pkgbits.ObjVar:
- pos := r.pos()
- typ := r.typ()
- return types2.NewVar(pos, objPkg, objName, typ)
- }
- })
-
- return objPkg, objName
-}
-
-func (pr *pkgReader2) objDictIdx(idx int) *reader2Dict {
- r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
-
- var dict reader2Dict
-
- if implicits := r.Len(); implicits != 0 {
- base.Fatalf("unexpected object with %v implicit type parameter(s)", implicits)
- }
-
- dict.bounds = make([]typeInfo, r.Len())
- for i := range dict.bounds {
- dict.bounds[i] = r.typInfo()
- }
-
- dict.derived = make([]derivedInfo, r.Len())
- dict.derivedTypes = make([]types2.Type, len(dict.derived))
- for i := range dict.derived {
- dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
- }
-
- // function references follow, but reader2 doesn't need those
-
- return &dict
-}
-
-func (r *reader2) typeParamNames() []*types2.TypeParam {
- r.Sync(pkgbits.SyncTypeParamNames)
-
- // Note: This code assumes it only processes objects without
- // implement type parameters. This is currently fine, because
- // reader2 is only used to read in exported declarations, which are
- // always package scoped.
-
- if len(r.dict.bounds) == 0 {
- return nil
- }
-
- // Careful: Type parameter lists may have cycles. To allow for this,
- // we construct the type parameter list in two passes: first we
- // create all the TypeNames and TypeParams, then we construct and
- // set the bound type.
-
- r.dict.tparams = make([]*types2.TypeParam, len(r.dict.bounds))
- for i := range r.dict.bounds {
- pos := r.pos()
- pkg, name := r.localIdent()
-
- tname := types2.NewTypeName(pos, pkg, name, nil)
- r.dict.tparams[i] = types2.NewTypeParam(tname, nil)
- }
-
- for i, bound := range r.dict.bounds {
- r.dict.tparams[i].SetConstraint(r.p.typIdx(bound, r.dict))
- }
-
- return r.dict.tparams
-}
-
-func (r *reader2) method() *types2.Func {
- r.Sync(pkgbits.SyncMethod)
- pos := r.pos()
- pkg, name := r.selector()
-
- rtparams := r.typeParamNames()
- sig := r.signature(r.param(), rtparams, nil)
-
- _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go.
- return types2.NewFunc(pos, pkg, name, sig)
-}
-
-func (r *reader2) qualifiedIdent() (*types2.Package, string) { return r.ident(pkgbits.SyncSym) }
-func (r *reader2) localIdent() (*types2.Package, string) { return r.ident(pkgbits.SyncLocalIdent) }
-func (r *reader2) selector() (*types2.Package, string) { return r.ident(pkgbits.SyncSelector) }
-
-func (r *reader2) ident(marker pkgbits.SyncMarker) (*types2.Package, string) {
- r.Sync(marker)
- return r.pkg(), r.String()
-}