go/gcimporter15: update to match std lib gcimporter (fix build)

TBR=adonovan

Change-Id: Ib2464def48932e0d0fc24f67c76a10e8918acb9d
Reviewed-on: https://go-review.googlesource.com/27235
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Robert Griesemer 2016-08-17 10:41:00 -07:00
parent 8ea9d46069
commit 2bbdb4568e
2 changed files with 57 additions and 55 deletions

View File

@ -40,10 +40,9 @@ const debugFormat = false // default: false
// If trace is set, debugging output is printed to std out. // If trace is set, debugging output is printed to std out.
const trace = false // default: false const trace = false // default: false
// This version doesn't write the nointerface flag for exported methods. // Current export format version.
// The corresponding importer handles both "v0" and "v1". // Must not start with 'c' or 'd' (initials of prior format).
// See also issues #16243, #16244. const exportVersion = "version 1"
const exportVersion = "v0"
// trackAllTypes enables cycle tracking for all types, not just named // trackAllTypes enables cycle tracking for all types, not just named
// types. The existing compiler invariants assume that unnamed types // types. The existing compiler invariants assume that unnamed types
@ -86,39 +85,18 @@ func BExportData(fset *token.FileSet, pkg *types.Package) []byte {
posInfoFormat: true, // TODO(gri) might become a flag, eventually posInfoFormat: true, // TODO(gri) might become a flag, eventually
} }
// first byte indicates low-level encoding format // write version info
var format byte = 'c' // compact p.rawStringln(exportVersion)
var debug string
if debugFormat { if debugFormat {
format = 'd' debug = "debug"
} }
p.rawByte(format) p.rawStringln(debug) // cannot use p.bool since it's affected by debugFormat; also want to see this clearly
p.bool(trackAllTypes)
format = 'n' // track named types only
if trackAllTypes {
format = 'a'
}
p.rawByte(format)
// posInfo exported or not?
p.bool(p.posInfoFormat) p.bool(p.posInfoFormat)
// --- generic export data --- // --- generic export data ---
if trace {
p.tracef("\n--- generic export data ---\n")
if p.indent != 0 {
log.Fatalf("gcimporter: incorrect indentation %d", p.indent)
}
}
if trace {
p.tracef("version = ")
}
p.string(exportVersion)
if trace {
p.tracef("\n")
}
// populate type map with predeclared "known" types // populate type map with predeclared "known" types
for index, typ := range predeclared { for index, typ := range predeclared {
p.typIndex[typ] = index p.typIndex[typ] = index
@ -401,6 +379,7 @@ func (p *exporter) assocMethods(named *types.Named) {
p.paramList(types.NewTuple(sig.Recv()), false) p.paramList(types.NewTuple(sig.Recv()), false)
p.paramList(sig.Params(), sig.Variadic()) p.paramList(sig.Params(), sig.Variadic())
p.paramList(sig.Results(), false) p.paramList(sig.Results(), false)
p.int(0) // dummy value for go:nointerface pragma - ignored by importer
} }
if trace && methods != nil { if trace && methods != nil {
@ -719,7 +698,7 @@ func (p *exporter) marker(m byte) {
p.rawInt64(int64(p.written)) p.rawInt64(int64(p.written))
} }
// rawInt64 should only be used by low-level encoders // rawInt64 should only be used by low-level encoders.
func (p *exporter) rawInt64(x int64) { func (p *exporter) rawInt64(x int64) {
var tmp [binary.MaxVarintLen64]byte var tmp [binary.MaxVarintLen64]byte
n := binary.PutVarint(tmp[:], x) n := binary.PutVarint(tmp[:], x)
@ -728,6 +707,14 @@ func (p *exporter) rawInt64(x int64) {
} }
} }
// rawStringln should only be used to emit the initial version string.
func (p *exporter) rawStringln(s string) {
for i := 0; i < len(s); i++ {
p.rawByte(s[i])
}
p.rawByte('\n')
}
// rawByte is the bottleneck interface to write to p.out. // rawByte is the bottleneck interface to write to p.out.
// rawByte escapes b as follows (any encoding does that // rawByte escapes b as follows (any encoding does that
// hides '$'): // hides '$'):

View File

@ -26,7 +26,6 @@ type importer struct {
data []byte data []byte
path string path string
buf []byte // for reading strings buf []byte // for reading strings
version string
// object lists // object lists
strList []string // in order of appearance strList []string // in order of appearance
@ -60,27 +59,36 @@ func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []
files: make(map[string]*token.File), files: make(map[string]*token.File),
} }
// read low-level encoding format // read version info
switch format := p.rawByte(); format { if b := p.rawByte(); b == 'c' || b == 'd' {
case 'c': // Go1.7 encoding; first byte encodes low-level
// compact format - nothing to do // encoding format (compact vs debug).
case 'd': // For backward-compatibility only (avoid problems with
p.debugFormat = true // old installed packages). Newly compiled packages use
default: // the extensible format string.
return p.read, nil, fmt.Errorf("invalid encoding format in export data: got %q; want 'c' or 'd'", format) // TODO(gri) Remove this support eventually; after Go1.8.
if b == 'd' {
p.debugFormat = true
}
p.trackAllTypes = p.rawByte() == 'a'
p.posInfoFormat = p.int() != 0
const go17version = "v1"
if s := p.string(); s != go17version {
return p.read, nil, fmt.Errorf("importer: unknown export data format: %s (imported package compiled with old compiler?)", s)
}
} else {
// Go1.8 extensible encoding
const exportVersion = "version 1"
if s := p.rawStringln(b); s != exportVersion {
return p.read, nil, fmt.Errorf("importer: unknown export data format: %s (imported package compiled with old compiler?)", s)
}
p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
p.trackAllTypes = p.int() != 0
p.posInfoFormat = p.int() != 0
} }
p.trackAllTypes = p.rawByte() == 'a'
p.posInfoFormat = p.int() != 0
// --- generic export data --- // --- generic export data ---
p.version = p.string()
if p.version != "v0" && p.version != "v1" {
return p.read, nil, fmt.Errorf("unknown export data version: %s", p.version)
}
// populate typList with predeclared "known" types // populate typList with predeclared "known" types
p.typList = append(p.typList, predeclared...) p.typList = append(p.typList, predeclared...)
@ -345,10 +353,7 @@ func (p *importer) typ(parent *types.Package) types.Type {
recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver? recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
params, isddd := p.paramList() params, isddd := p.paramList()
result, _ := p.paramList() result, _ := p.paramList()
p.int() // go:nointerface pragma - discarded
if p.version == "v1" {
p.int() // nointerface flag - discarded
}
sig := types.NewSignature(recv.At(0), params, result, isddd) sig := types.NewSignature(recv.At(0), params, result, isddd)
t0.AddMethod(types.NewFunc(pos, parent, name, sig)) t0.AddMethod(types.NewFunc(pos, parent, name, sig))
@ -729,7 +734,7 @@ func (p *importer) marker(want byte) {
} }
} }
// rawInt64 should only be used by low-level decoders // rawInt64 should only be used by low-level decoders.
func (p *importer) rawInt64() int64 { func (p *importer) rawInt64() int64 {
i, err := binary.ReadVarint(p) i, err := binary.ReadVarint(p)
if err != nil { if err != nil {
@ -738,6 +743,16 @@ func (p *importer) rawInt64() int64 {
return i return i
} }
// rawStringln should only be used to read the initial version string.
func (p *importer) rawStringln(b byte) string {
p.buf = p.buf[:0]
for b != '\n' {
p.buf = append(p.buf, b)
b = p.rawByte()
}
return string(p.buf)
}
// needed for binary.ReadVarint in rawInt64 // needed for binary.ReadVarint in rawInt64
func (p *importer) ReadByte() (byte, error) { func (p *importer) ReadByte() (byte, error) {
return p.rawByte(), nil return p.rawByte(), nil