aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/compile/internal/noder/linker.go31
-rw-r--r--src/cmd/compile/internal/noder/reader.go79
-rw-r--r--src/cmd/compile/internal/noder/reader2.go43
-rw-r--r--src/cmd/compile/internal/noder/reloc.go1
-rw-r--r--src/cmd/compile/internal/noder/sync.go1
-rw-r--r--src/cmd/compile/internal/noder/unified.go4
-rw-r--r--src/cmd/compile/internal/noder/writer.go81
7 files changed, 124 insertions, 116 deletions
diff --git a/src/cmd/compile/internal/noder/linker.go b/src/cmd/compile/internal/noder/linker.go
index eefb5083e5..2bc7f7c608 100644
--- a/src/cmd/compile/internal/noder/linker.go
+++ b/src/cmd/compile/internal/noder/linker.go
@@ -110,7 +110,7 @@ func (l *linker) relocPkg(pr *pkgReader, idx int) int {
}
func (l *linker) relocObj(pr *pkgReader, idx int) int {
- path, name, tag, _ := pr.peekObj(idx)
+ path, name, tag := pr.peekObj(idx)
sym := types.NewPkg(path, "").Lookup(name)
if newidx, ok := l.decls[sym]; ok {
@@ -127,7 +127,7 @@ func (l *linker) relocObj(pr *pkgReader, idx int) int {
pr = pri.pr
idx = pri.idx
- path2, name2, tag2, _ := pr.peekObj(idx)
+ path2, name2, tag2 := pr.peekObj(idx)
sym2 := types.NewPkg(path2, "").Lookup(name2)
assert(sym == sym2)
assert(tag2 != objStub)
@@ -135,13 +135,16 @@ func (l *linker) relocObj(pr *pkgReader, idx int) int {
w := l.pw.newEncoderRaw(relocObj)
wext := l.pw.newEncoderRaw(relocObjExt)
+ wname := l.pw.newEncoderRaw(relocName)
wdict := l.pw.newEncoderRaw(relocObjDict)
l.decls[sym] = w.idx
assert(wext.idx == w.idx)
+ assert(wname.idx == w.idx)
assert(wdict.idx == w.idx)
l.relocCommon(pr, &w, relocObj, idx)
+ l.relocCommon(pr, &wname, relocName, idx)
l.relocCommon(pr, &wdict, relocObjDict, idx)
var obj *ir.Name
@@ -279,33 +282,15 @@ func (pr *pkgDecoder) peekPkgPath(idx int) string {
return path
}
-func (pr *pkgDecoder) peekObj(idx int) (string, string, codeObj, []int) {
- r := pr.newDecoder(relocObj, idx, syncObject1)
+func (pr *pkgDecoder) peekObj(idx int) (string, string, codeObj) {
+ r := pr.newDecoder(relocName, idx, syncObject1)
r.sync(syncSym)
r.sync(syncPkg)
path := pr.peekPkgPath(r.reloc(relocPkg))
name := r.string()
assert(name != "")
- r.sync(syncTypeParamBounds)
- r.len() // implicits
- bounds := make([]int, r.len())
- for i := range bounds {
- r.sync(syncType)
- if r.bool() {
- r.len()
- } else {
- r.reloc(relocType)
- }
-
- // TODO(mdempsky): This result now needs to include the 'derived'
- // bool too, but none of the callers currently depend on it
- // anyway. Either fix it to be meaningful, or just get rid of it
- // altogether.
- bounds[i] = -1
- }
-
tag := codeObj(r.code(syncCodeObj))
- return path, name, tag, bounds
+ return path, name, tag
}
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go
index de708769ba..44d1c4f28b 100644
--- a/src/cmd/compile/internal/noder/reader.go
+++ b/src/cmd/compile/internal/noder/reader.go
@@ -534,18 +534,10 @@ func (r *reader) obj() ir.Node {
}
func (pr *pkgReader) objIdx(idx int, implicits, explicits []*types.Type) ir.Node {
- r := pr.newReader(relocObj, idx, syncObject1)
- r.ext = pr.newReader(relocObjExt, idx, syncObject1)
-
- _, sym := r.qualifiedIdent()
-
- dict := &readerDict{}
- r.dict = dict
- r.ext.dict = dict
-
- r.typeParamBounds(sym, implicits, explicits)
+ rname := pr.newReader(relocName, idx, syncObject1)
+ _, sym := rname.qualifiedIdent()
+ tag := codeObj(rname.code(syncCodeObj))
- tag := codeObj(r.code(syncCodeObj))
if tag == objStub {
assert(!sym.IsBlank())
switch sym.Pkg {
@@ -556,30 +548,19 @@ func (pr *pkgReader) objIdx(idx int, implicits, explicits []*types.Type) ir.Node
return pri.pr.objIdx(pri.idx, nil, explicits)
}
if haveLegacyImports {
- assert(!r.hasTypeParams())
+ assert(len(explicits) == 0)
return typecheck.Resolve(ir.NewIdent(src.NoXPos, sym))
}
base.Fatalf("unresolved stub: %v", sym)
}
- {
- rdict := pr.newReader(relocObjDict, idx, syncObject1)
- r.dict.derived = make([]derivedInfo, rdict.len())
- r.dict.derivedTypes = make([]*types.Type, len(r.dict.derived))
- for i := range r.dict.derived {
- r.dict.derived[i] = derivedInfo{rdict.reloc(relocType), rdict.bool()}
- }
- r.dict.funcs = make([]objInfo, rdict.len())
- r.dict.funcsObj = make([]ir.Node, len(r.dict.funcs))
- for i := range r.dict.funcs {
- objIdx := rdict.reloc(relocObj)
- targs := make([]typeInfo, rdict.len())
- for j := range targs {
- targs[j] = rdict.typInfo()
- }
- r.dict.funcs[i] = objInfo{idx: objIdx, explicits: targs}
- }
- }
+ dict := pr.objDictIdx(sym, idx, implicits, explicits)
+
+ r := pr.newReader(relocObj, idx, syncObject1)
+ r.ext = pr.newReader(relocObjExt, idx, syncObject1)
+
+ r.dict = dict
+ r.ext.dict = dict
sym = r.mangle(sym)
if !sym.IsBlank() && sym.Def != nil {
@@ -692,8 +673,10 @@ func (r *reader) mangle(sym *types.Sym) *types.Sym {
return sym.Pkg.Lookup(buf.String())
}
-func (r *reader) typeParamBounds(sym *types.Sym, implicits, explicits []*types.Type) {
- r.sync(syncTypeParamBounds)
+func (pr *pkgReader) objDictIdx(sym *types.Sym, idx int, implicits, explicits []*types.Type) *readerDict {
+ r := pr.newReader(relocObjDict, idx, syncObject1)
+
+ var dict readerDict
nimplicits := r.len()
nexplicits := r.len()
@@ -702,12 +685,11 @@ func (r *reader) typeParamBounds(sym *types.Sym, implicits, explicits []*types.T
base.Fatalf("%v has %v+%v params, but instantiated with %v+%v args", sym, nimplicits, nexplicits, len(implicits), len(explicits))
}
- r.dict.targs = append(implicits[:nimplicits:nimplicits], explicits...)
- r.dict.implicits = nimplicits
+ dict.targs = append(implicits[:nimplicits:nimplicits], explicits...)
+ dict.implicits = nimplicits
// For stenciling, we can just skip over the type parameters.
-
- for range r.dict.targs[r.dict.implicits:] {
+ for range dict.targs[dict.implicits:] {
// Skip past bounds without actually evaluating them.
r.sync(syncType)
if r.bool() {
@@ -716,6 +698,25 @@ func (r *reader) typeParamBounds(sym *types.Sym, implicits, explicits []*types.T
r.reloc(relocType)
}
}
+
+ dict.derived = make([]derivedInfo, r.len())
+ dict.derivedTypes = make([]*types.Type, len(dict.derived))
+ for i := range dict.derived {
+ dict.derived[i] = derivedInfo{r.reloc(relocType), r.bool()}
+ }
+
+ dict.funcs = make([]objInfo, r.len())
+ dict.funcsObj = make([]ir.Node, len(dict.funcs))
+ for i := range dict.funcs {
+ objIdx := r.reloc(relocObj)
+ targs := make([]typeInfo, r.len())
+ for j := range targs {
+ targs[j] = r.typInfo()
+ }
+ dict.funcs[i] = objInfo{idx: objIdx, explicits: targs}
+ }
+
+ return &dict
}
func (r *reader) typeParamNames() {
@@ -790,7 +791,11 @@ func (r *reader) selector() (origPkg *types.Pkg, sym *types.Sym) {
}
func (r *reader) hasTypeParams() bool {
- return r.dict != nil && len(r.dict.targs) != 0
+ return r.dict.hasTypeParams()
+}
+
+func (dict *readerDict) hasTypeParams() bool {
+ return dict != nil && len(dict.targs) != 0
}
// @@@ Compiler extensions
diff --git a/src/cmd/compile/internal/noder/reader2.go b/src/cmd/compile/internal/noder/reader2.go
index a2339145fa..297fa59439 100644
--- a/src/cmd/compile/internal/noder/reader2.go
+++ b/src/cmd/compile/internal/noder/reader2.go
@@ -358,29 +358,22 @@ func (r *reader2) obj() (types2.Object, []types2.Type) {
}
func (pr *pkgReader2) objIdx(idx int) (*types2.Package, string) {
- r := pr.newReader(relocObj, idx, syncObject1)
- r.dict = &reader2Dict{}
+ rname := pr.newReader(relocName, idx, syncObject1)
- objPkg, objName := r.qualifiedIdent()
+ objPkg, objName := rname.qualifiedIdent()
assert(objName != "")
- r.typeParamBounds()
- tag := codeObj(r.code(syncCodeObj))
+ tag := codeObj(rname.code(syncCodeObj))
if tag == objStub {
assert(objPkg == nil)
return objPkg, objName
}
- {
- rdict := r.p.newReader(relocObjDict, idx, syncObject1)
- r.dict.derived = make([]derivedInfo, rdict.len())
- r.dict.derivedTypes = make([]types2.Type, len(r.dict.derived))
- for i := range r.dict.derived {
- r.dict.derived[i] = derivedInfo{rdict.reloc(relocType), rdict.bool()}
- }
- // function references follow, but reader2 doesn't need those
- }
+ dict := pr.objDictIdx(idx)
+
+ r := pr.newReader(relocObj, idx, syncObject1)
+ r.dict = dict
objPkg.Scope().InsertLazy(objName, func() types2.Object {
switch tag {
@@ -439,17 +432,29 @@ func (r *reader2) value() (types2.Type, constant.Value) {
return r.typ(), r.rawValue()
}
-func (r *reader2) typeParamBounds() {
- r.sync(syncTypeParamBounds)
+func (pr *pkgReader2) objDictIdx(idx int) *reader2Dict {
+ r := pr.newReader(relocObjDict, idx, syncObject1)
+
+ var dict reader2Dict
if implicits := r.len(); implicits != 0 {
base.Fatalf("unexpected object with %v implicit type parameter(s)", implicits)
}
- r.dict.bounds = make([]typeInfo, r.len())
- for i := range r.dict.bounds {
- r.dict.bounds[i] = r.typInfo()
+ 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(relocType), r.bool()}
}
+
+ // function references follow, but reader2 doesn't need those
+
+ return &dict
}
func (r *reader2) typeParamNames() []*types2.TypeName {
diff --git a/src/cmd/compile/internal/noder/reloc.go b/src/cmd/compile/internal/noder/reloc.go
index 4eb6bcdb1c..669a6182e6 100644
--- a/src/cmd/compile/internal/noder/reloc.go
+++ b/src/cmd/compile/internal/noder/reloc.go
@@ -31,6 +31,7 @@ const (
relocMeta
relocPosBase
relocPkg
+ relocName
relocType
relocObj
relocObjExt
diff --git a/src/cmd/compile/internal/noder/sync.go b/src/cmd/compile/internal/noder/sync.go
index aef98dbd78..7af558f8b2 100644
--- a/src/cmd/compile/internal/noder/sync.go
+++ b/src/cmd/compile/internal/noder/sync.go
@@ -183,4 +183,5 @@ const (
syncTypeParamNames
syncTypeParamBounds
syncImplicitTypes
+ syncObjectName
)
diff --git a/src/cmd/compile/internal/noder/unified.go b/src/cmd/compile/internal/noder/unified.go
index e8c203ae46..9f80ca000d 100644
--- a/src/cmd/compile/internal/noder/unified.go
+++ b/src/cmd/compile/internal/noder/unified.go
@@ -263,7 +263,7 @@ func readPackage(pr *pkgReader, importpkg *types.Pkg) {
idx := r.reloc(relocObj)
assert(r.len() == 0)
- path, name, code, _ := r.p.peekObj(idx)
+ path, name, code := r.p.peekObj(idx)
if code != objStub {
objReader[types.NewPkg(path, "").Lookup(name)] = pkgReaderIndex{pr, idx, nil}
}
@@ -298,7 +298,7 @@ func writeNewExport(out io.Writer) {
idx := r.reloc(relocObj)
assert(r.len() == 0)
- xpath, xname, xtag, _ := pr.peekObj(idx)
+ xpath, xname, xtag := pr.peekObj(idx)
assert(xpath == pr.pkgPath)
assert(xtag != objStub)
diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go
index 48884056f3..bf60246d64 100644
--- a/src/cmd/compile/internal/noder/writer.go
+++ b/src/cmd/compile/internal/noder/writer.go
@@ -505,60 +505,45 @@ func (pw *pkgWriter) objIdx(obj types2.Object) int {
w := pw.newWriter(relocObj, syncObject1)
w.ext = pw.newWriter(relocObjExt, syncObject1)
+ wname := pw.newWriter(relocName, syncObject1)
wdict := pw.newWriter(relocObjDict, syncObject1)
pw.globalsIdx[obj] = w.idx // break cycles
assert(w.ext.idx == w.idx)
+ assert(wname.idx == w.idx)
assert(wdict.idx == w.idx)
w.dict = dict
w.ext.dict = dict
- // Ident goes first so importer can avoid unnecessary work if
- // they've already resolved this object.
- w.qualifiedIdent(obj)
-
- w.typeParamBounds(objTypeParams(obj))
-
- w.doObj(obj)
-
+ code := w.doObj(obj)
w.flush()
w.ext.flush()
- // Done writing out the object description; write out the list of
- // derived types and instantiated functions found along the way.
- wdict.len(len(dict.derived))
- for _, typ := range dict.derived {
- wdict.reloc(relocType, typ.idx)
- wdict.bool(typ.needed)
- }
- wdict.len(len(dict.funcs))
- for _, fn := range dict.funcs {
- wdict.reloc(relocObj, fn.idx)
- wdict.len(len(fn.explicits))
- for _, targ := range fn.explicits {
- wdict.typInfo(targ)
- }
- }
+ wname.qualifiedIdent(obj)
+ wname.code(code)
+ wname.flush()
+
+ wdict.objDict(obj, w.dict)
wdict.flush()
return w.idx
}
-func (w *writer) doObj(obj types2.Object) {
+func (w *writer) doObj(obj types2.Object) codeObj {
if obj.Pkg() != w.p.curpkg {
- w.code(objStub)
- return
+ return objStub
}
switch obj := obj.(type) {
default:
w.p.unexpected("object", obj)
+ panic("unreachable")
case *types2.Const:
- w.code(objConst)
w.pos(obj)
w.value(obj.Type(), obj.Val())
+ return objConst
case *types2.Func:
decl, ok := w.p.funDecls[obj]
@@ -584,28 +569,26 @@ func (w *writer) doObj(obj types2.Object) {
sig = types2.NewSignature(nil, types2.NewTuple(params...), sig.Results(), sig.Variadic())
}
- w.code(objFunc)
w.pos(obj)
w.typeParamNames(sig.TParams())
w.signature(sig)
w.pos(decl)
w.ext.funcExt(obj)
+ return objFunc
case *types2.TypeName:
decl, ok := w.p.typDecls[obj]
assert(ok)
if obj.IsAlias() {
- w.code(objAlias)
w.pos(obj)
w.typ(obj.Type())
- break
+ return objAlias
}
named := obj.Type().(*types2.Named)
assert(named.TArgs() == nil)
- w.code(objType)
w.pos(obj)
w.typeParamNames(named.TParams())
w.ext.typeExt(obj)
@@ -616,11 +599,13 @@ func (w *writer) doObj(obj types2.Object) {
w.method(named.Method(i))
}
+ return objType
+
case *types2.Var:
- w.code(objVar)
w.pos(obj)
w.typ(obj.Type())
w.ext.varExt(obj)
+ return objVar
}
}
@@ -638,15 +623,41 @@ func (w *writer) value(typ types2.Type, val constant.Value) {
w.rawValue(val)
}
-func (w *writer) typeParamBounds(tparams []*types2.TypeName) {
- w.sync(syncTypeParamBounds)
+// objDict writes the dictionary needed for reading the given object.
+func (w *writer) objDict(obj types2.Object, dict *writerDict) {
+ // TODO(mdempsky): Split objDict into multiple entries? reader.go
+ // doesn't care about the type parameter bounds, and reader2.go
+ // doesn't care about referenced functions.
+
+ w.dict = dict // TODO(mdempsky): This is a bit sketchy.
- w.len(len(w.dict.implicits))
+ w.len(len(dict.implicits))
+ tparams := objTypeParams(obj)
w.len(len(tparams))
for _, tparam := range tparams {
w.typ(tparam.Type().(*types2.TypeParam).Bound())
}
+
+ nderived := len(dict.derived)
+ w.len(nderived)
+ for _, typ := range dict.derived {
+ w.reloc(relocType, typ.idx)
+ w.bool(typ.needed)
+ }
+
+ nfuncs := len(dict.funcs)
+ w.len(nfuncs)
+ for _, fn := range dict.funcs {
+ w.reloc(relocObj, fn.idx)
+ w.len(len(fn.explicits))
+ for _, targ := range fn.explicits {
+ w.typInfo(targ)
+ }
+ }
+
+ assert(len(dict.derived) == nderived)
+ assert(len(dict.funcs) == nfuncs)
}
func (w *writer) typeParamNames(tparams []*types2.TypeName) {