]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: clean up encoding of export version info
authorRobert Griesemer <gri@golang.org>
Sat, 20 Aug 2016 01:10:00 +0000 (18:10 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 22 Aug 2016 22:28:52 +0000 (22:28 +0000)
Replace ad-hoc encoding of export version info with a
more systematic approach.

Continue to read (but not write) the Go1.7 format for backward-
compatibility. This will avoid spurious errors with old installed
packages.

Fixes #16244.

Change-Id: I945e79ffd5e22b883250f6f9fac218370c2505a2
Reviewed-on: https://go-review.googlesource.com/27452
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/bexport.go
src/cmd/compile/internal/gc/bimport.go
src/cmd/compile/internal/gc/builtin.go
src/go/internal/gcimporter/bimport.go

index 7915bce8c6195b26a1a4bb0ffebd238600a1b19f..a55493854fe2c00c507286065165c664c73f4bfa 100644 (file)
@@ -51,13 +51,16 @@ they are automatically encoded with a known and fixed type index.
 
 2) Encoding format:
 
-The export data starts with a single byte indicating the encoding format
-(compact, or with debugging information), followed by a version string
-(so we can evolve the encoding if need be), and then the package object
-for the exported package (with an empty path).
+The export data starts with two newline-terminated strings: a version
+string and either an empty string, or "debug", when emitting the debug
+format. These strings are followed by version-specific encoding options.
 
-After this header, two lists of objects and the list of inlined function
-bodies follows.
+(The Go1.7 version starts with a couple of bytes specifying the format.
+That format encoding is no longer used but is supported to avoid spurious
+errors when importing old installed package files.)
+
+The header is followed by the package object for the exported package,
+two lists of objects, and the list of inlined function bodies.
 
 The encoding of objects is straight-forward: Constants, variables, and
 functions start with their name, type, and possibly a value. Named types
@@ -77,7 +80,8 @@ Strings are canonicalized similar to objects that may occur multiple times:
 If the string was exported already, it is represented by its index only.
 Otherwise, the export data starts with the negative string length (negative,
 so we can distinguish from string index), followed by the string bytes.
-The empty string is mapped to index 0.
+The empty string is mapped to index 0. (The initial format string is an
+exception; it is encoded as the string bytes followed by a newline).
 
 The exporter and importer are completely symmetric in implementation: For
 each encoding routine there is a matching and symmetric decoding routine.
@@ -154,8 +158,8 @@ const debugFormat = false // default: false
 const forceObjFileStability = true
 
 // Current export format version.
-// TODO(gri) Make this more systematic (issue #16244).
-const exportVersion = "v1"
+// Must not start with 'c' or 'd' (initials of prior format).
+const exportVersion = "version 1"
 
 // exportInlined enables the export of inlined function bodies and related
 // dependencies. The compiler should work w/o any loss of functionality with
@@ -212,43 +216,18 @@ func export(out *bufio.Writer, trace bool) int {
                trace:         trace,
        }
 
-       // TODO(gri) clean up the ad-hoc encoding of the file format below
-       // (we need this so we can read the builtin package export data
-       // easily w/o being affected by format changes)
-
-       // first byte indicates low-level encoding format
-       var format byte = 'c' // compact
+       // write version info
+       p.rawStringln(exportVersion)
+       var debug string
        if debugFormat {
-               format = 'd'
-       }
-       p.rawByte(format)
-
-       format = 'n' // track named types only
-       if trackAllTypes {
-               format = 'a'
+               debug = "debug"
        }
-       p.rawByte(format)
-
-       // posInfo exported or not?
+       p.rawStringln(debug) // cannot use p.bool since it's affected by debugFormat; also want to see this clearly
+       p.bool(trackAllTypes)
        p.bool(p.posInfoFormat)
 
        // --- generic export data ---
 
-       if p.trace {
-               p.tracef("\n--- package ---\n")
-               if p.indent != 0 {
-                       Fatalf("exporter: incorrect indentation %d", p.indent)
-               }
-       }
-
-       if p.trace {
-               p.tracef("version = ")
-       }
-       p.string(exportVersion)
-       if p.trace {
-               p.tracef("\n")
-       }
-
        // populate type map with predeclared "known" types
        predecl := predeclared()
        for index, typ := range predecl {
@@ -1725,7 +1704,7 @@ func (p *exporter) marker(m byte) {
        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) {
        var tmp [binary.MaxVarintLen64]byte
        n := binary.PutVarint(tmp[:], x)
@@ -1734,6 +1713,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 escapes b as follows (any encoding does that
 // hides '$'):
index b0c1f5c698cc1a879940c64144e9d711b83e54a0..2f724861f602d8c0c72ec29bd501233074672aed 100644 (file)
@@ -51,26 +51,35 @@ func Import(in *bufio.Reader) {
                strList: []string{""}, // empty string is mapped to 0
        }
 
-       // read low-level encoding format
-       switch format := p.rawByte(); format {
-       case 'c':
-               // compact format - nothing to do
-       case 'd':
-               p.debugFormat = true
-       default:
-               Fatalf("importer: invalid encoding format in export data: got %q; want 'c' or 'd'", format)
+       // read version info
+       if b := p.rawByte(); b == 'c' || b == 'd' {
+               // Go1.7 encoding; first byte encodes low-level
+               // encoding format (compact vs debug).
+               // For backward-compatibility only (avoid problems with
+               // old installed packages). Newly compiled packages use
+               // the extensible format string.
+               // TODO(gri) Remove this support eventually; after Go1.8.
+               if b == 'd' {
+                       p.debugFormat = true
+               }
+               p.trackAllTypes = p.rawByte() == 'a'
+               p.posInfoFormat = p.bool()
+               const go17version = "v1"
+               if s := p.string(); s != go17version {
+                       Fatalf("importer: unknown export data format: %s (imported package compiled with old compiler?)", s)
+               }
+       } else {
+               // Go1.8 extensible encoding
+               if s := p.rawStringln(b); s != exportVersion {
+                       Fatalf("importer: unknown export data format: %s (imported package compiled with old compiler?)", s)
+               }
+               p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
+               p.trackAllTypes = p.bool()
+               p.posInfoFormat = p.bool()
        }
 
-       p.trackAllTypes = p.rawByte() == 'a'
-
-       p.posInfoFormat = p.bool()
-
        // --- generic export data ---
 
-       if v := p.string(); v != exportVersion {
-               Fatalf("importer: unknown export data version: %s", v)
-       }
-
        // populate typList with predeclared "known" types
        p.typList = append(p.typList, predeclared()...)
 
@@ -1185,7 +1194,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 {
        i, err := binary.ReadVarint(p)
        if err != nil {
@@ -1194,6 +1203,16 @@ func (p *importer) rawInt64() int64 {
        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
 func (p *importer) ReadByte() (byte, error) {
        return p.rawByte(), nil
index 28fbf1719e73e06523d1bedcef4750662ec6cd43..e49224b4a4d50a6980f7f05aaa272817683bf292 100644 (file)
 package gc
 
 const runtimeimport = "" +
-       "cn\x00\x03v1\x01\rruntime\x00\t\x11newobject\x00\x02\x17\"\vtyp·2\x00\x00" +
-       "\x01\x17:\x00\t\x13panicindex\x00\x00\x00\t\x13panicslice\x00\x00\x00\t\x15pani" +
-       "cdivide\x00\x00\x00\t\x15throwreturn\x00\x00\x00\t\x11throwinit\x00\x00\x00" +
-       "\t\x11panicwrap\x00\x05 \x00 \x00 \x00\x00\t\rgopanic\x00\x01\x1b\x00\x00\x00\x00\t\x11go" +
-       "recover\x00\x01\x17\b\x00\x01\x1b\x00\x00\x00\t\x11printbool\x00\x01\x00\x00\x00\t\x13print" +
-       "float\x00\x01\x1a\x00\x00\t\x0fprintint\x00\x01\n\x00\x00\t\x0fprinthex\x00\x01\x14\x00\x00" +
-       "\t\x11printuint\x00\x01\x14\x00\x00\t\x17printcomplex\x00\x01\x1e\x00\x00\t\x15pri" +
-       "ntstring\x00\x01 \x00\x00\t\x17printpointer\x00\x01:\x00\x00\t\x13printi" +
-       "face\x00\x01:\x00\x00\t\x13printeface\x00\x01:\x00\x00\t\x13printslice\x00\x01" +
-       ":\x00\x00\t\rprintnl\x00\x00\x00\t\rprintsp\x00\x00\x00\t\x11printlock\x00\x00" +
-       "\x00\t\x15printunlock\x00\x00\x00\t\x19concatstring2\x00\x05\x17\x0f@\"\x00 " +
-       "\x00 \x00\x01 \x00\t\x19concatstring3\x00\a\x17\x0f@\"\x00 \x00 \x00 \x00\x01 \x00\t\x19c" +
-       "oncatstring4\x00\t\x17\x0f@\"\x00 \x00 \x00 \x00 \x00\x01 \x00\t\x19concatst" +
-       "ring5\x00\v\x17\x0f@\"\x00 \x00 \x00 \x00 \x00 \x00\x01 \x00\t\x19concatstrings" +
-       "\x00\x03\x17\x0f@\"\x00\x11 \x00\x01 \x00\t\x11cmpstring\x00\x03 \x00 \x00\x01\x02\x00\t\x0feqstr" +
-       "ing\x00\x03 \x00 \x00\x01\x00\x00\t\x11intstring\x00\x03\x17\x0f\b\"\x00\n\x00\x01 \x00\t!sli" +
-       "cebytetostring\x00\x03\x17\x0f@\"\x00\x11\"\x00\x01 \x00\t'slicebyteto" +
-       "stringtmp\x00\x01\x11\"\x00\x01 \x00\t!slicerunetostring\x00\x03\x17\x0f" +
-       "@\"\x00\x11|S\x00\x01 \x00\t!stringtoslicebyte\x00\x03\x17\x0f@\"\x00 \x00\x01\x11" +
-       "\"\x00\t'stringtoslicebytetmp\x00\x01 \x00\x01\x11\"\x00\t!string" +
-       "toslicerune\x00\x03\x17\x0f@|S\x00 \x00\x01\x11|S\x00\t\x13stringiter\x00\x03" +
-       " \x00\x02\x00\x01\x02\x00\t\x15stringiter2\x00\x03 \x00\x02\x00\x04\x02\rretk·1\x00\x00|S" +
-       "\rretv·2\x00\x00\t\x11slicecopy\x00\x06:\tto·2\x00\x00:\tfr·3\x00" +
-       "\x00\x16\vwid·4\x00\x1bunsafe-uintptr\x01\x02\x00\t\x1dslicestrin" +
-       "gcopy\x00\x04:^\x00\x00:`\x00\x00\x01\x02\x00\t\rconvI2E\x00\x02:\relem·2\x00\x00" +
-       "\x02:\vret·1\x00\x00\t\rconvI2I\x00\x04\x17\"\b\x00\x00:\relem·3\x00\x00\x02:" +
-       "l\x00\x00\t\rconvT2E\x00\x06\x17\"\b\x00\x00\x17:p\x00\x00\x17:\vbuf·4\x00\x00\x02:l\x00\x00" +
-       "\t\rconvT2I\x00\x06\x17\"\vtab·2\x00\x00\x17:p\x00\x00\x17:t\x00\x00\x02:l\x00\x00\t\x11a" +
-       "ssertE2E\x00\x06\x17\"\vtyp·1\x00\x00:\x0fiface·2\x00\x00\x17:\vret\xc2" +
-       "\xb73\x00\x00\x00\t\x13assertE2E2\x00\x06\x17\"\b\x00\x00:\x0fiface·3\x00\x00\x17:\vr" +
-       "et·4\x00\x00\x01\x00\x00\t\x11assertE2I\x00\x06\x17\"||\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x00" +
-       "\t\x13assertE2I2\x00\x06\x17\"\b\x00\x00:\x84\x01\x00\x00\x17:\x86\x01\x00\x00\x01\x00\x00\t\x11asser" +
-       "tE2T\x00\x06\x17\"||\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x00\t\x13assertE2T2\x00\x06\x17\"\b" +
-       "\x00\x00:\x84\x01\x00\x00\x17:\x86\x01\x00\x00\x01\x00\x00\t\x11assertI2E\x00\x06\x17\"||\x00\x00:~\x00\x00\x17" +
-       ":\x80\x01\x00\x00\x00\t\x13assertI2E2\x00\x06\x17\"\b\x00\x00:\x84\x01\x00\x00\x17:\x86\x01\x00\x00\x01\x00\x00\t" +
-       "\x11assertI2I\x00\x06\x17\"||\x00\x00:~\x00\x00\x17:\x80\x01\x00\x00\x00\t\x13assertI2I" +
-       "2\x00\x06\x17\"\b\x00\x00:\x84\x01\x00\x00\x17:\x86\x01\x00\x00\x01\x00\x00\t\x11assertI2T\x00\x06\x17\"||\x00" +
-       "\x00:~\x00\x00\x17:\x80\x01\x00\x00\x00\t\x13assertI2T2\x00\x06\x17\"\b\x00\x00:\x84\x01\x00\x00\x17:\x86\x01" +
-       "\x00\x00\x01\x00\x00\t\x17panicdottype\x00\x06\x17\"\rhave·1\x00\x00\x17\"\rwant" +
-       "·2\x00\x00\x17\"\x84\x01\x00\x00\x00\t\rifaceeq\x00\x04:\ti1·2\x00\x00:\ti2·3\x00" +
-       "\x00\x02\x00l\x00\x00\t\refaceeq\x00\x04:\xa4\x01\x00\x00:\xa6\x01\x00\x00\x02\x00l\x00\x00\t\rmakema" +
-       "p\x00\b\x17\"\x13mapType·2\x00\x00\n\rhint·3\x00\x00\x17:\x11mapbuf·" +
-       "4\x00\x00\x17:\x17bucketbuf·5\x00\x00\x02\x1d::\rhmap·1\x00\x00\t\x13mapa" +
-       "ccess1\x00\x06\x17\"\xac\x01\x00\x00\x1d::\rhmap·3\x00\x00\x17:\vkey·4\x00\x00\x02\x17" +
-       ":\vval·1\x00\x00\t!mapaccess1_fast32\x00\x06\x17\"\xac\x01\x00\x00\x1d::" +
-       "\xb8\x01\x00\x00:\xba\x01\x00\x00\x02\x17:\xbc\x01\x00\x00\t!mapaccess1_fast64\x00\x06\x17\"\xac" +
-       "\x01\x00\x00\x1d::\xb8\x01\x00\x00:\xba\x01\x00\x00\x02\x17:\xbc\x01\x00\x00\t#mapaccess1_fasts" +
-       "tr\x00\x06\x17\"\xac\x01\x00\x00\x1d::\xb8\x01\x00\x00:\xba\x01\x00\x00\x02\x17:\xbc\x01\x00\x00\t\x1bmapaccess" +
-       "1_fat\x00\b\x17\"\xac\x01\x00\x00\x1d::\xb8\x01\x00\x00\x17:\xba\x01\x00\x00\x17\"\rzero·5\x00\x00\x02\x17" +
-       ":\xbc\x01\x00\x00\t\x13mapaccess2\x00\x06\x17\"\x13mapType·3\x00\x00\x1d::\rhm" +
-       "ap·4\x00\x00\x17:\vkey·5\x00\x00\x04\x17:\xbc\x01\x00\x00\x00\rpres·2\x00\x00\t!ma" +
-       "paccess2_fast32\x00\x06\x17\"\xca\x01\x00\x00\x1d::\xcc\x01\x00\x00:\xce\x01\x00\x00\x04\x17:\xbc\x01" +
-       "\x00\x00\x00\xd0\x01\x00\x00\t!mapaccess2_fast64\x00\x06\x17\"\xca\x01\x00\x00\x1d::\xcc\x01\x00" +
-       "\x00:\xce\x01\x00\x00\x04\x17:\xbc\x01\x00\x00\x00\xd0\x01\x00\x00\t#mapaccess2_faststr\x00\x06" +
-       "\x17\"\xca\x01\x00\x00\x1d::\xcc\x01\x00\x00:\xce\x01\x00\x00\x04\x17:\xbc\x01\x00\x00\x00\xd0\x01\x00\x00\t\x1bmapacces" +
-       "s2_fat\x00\b\x17\"\xca\x01\x00\x00\x1d::\xcc\x01\x00\x00\x17:\xce\x01\x00\x00\x17\"\rzero·6\x00\x00\x04" +
-       "\x17:\xbc\x01\x00\x00\x00\xd0\x01\x00\x00\t\x13mapassign1\x00\b\x17\"\x13mapType·1\x00\x00" +
-       "\x1d::\rhmap·2\x00\x00\x17:\vkey·3\x00\x00\x17:\vval·4\x00\x00\x00\t\x15ma" +
-       "piterinit\x00\x06\x17\"\xde\x01\x00\x00\x1d::\xe0\x01\x00\x00\x17:\x0fhiter·3\x00\x00\x00\t\x11" +
-       "mapdelete\x00\x06\x17\"\xde\x01\x00\x00\x1d::\xe0\x01\x00\x00\x17:\xe2\x01\x00\x00\x00\t\x15mapiter" +
-       "next\x00\x02\x17:\x0fhiter·1\x00\x00\x00\t\x0fmakechan\x00\x04\x17\"\x15chanT" +
-       "ype·2\x00\x00\n\xae\x01\x00\x00\x02\x1f\x06:\x0fhchan·1\x00\x00\t\x11chanrecv1\x00" +
-       "\x06\x17\"\x15chanType·1\x00\x00\x1f\x02:\x0fhchan·2\x00\x00\x17:p\x00\x00\x00\t\x11c" +
-       "hanrecv2\x00\x06\x17\"\xf2\x01\x00\x00\x1f\x02:\x0fhchan·3\x00\x00\x17:\relem·4" +
-       "\x00\x00\x01\x00\x00\t\x11chansend1\x00\x06\x17\"\xf8\x01\x00\x00\x1f\x04:\xfa\x01\x00\x00\x17:p\x00\x00\x00\t\x11c" +
-       "losechan\x00\x02:\xf4\x01\x00\x00\x00\a\x17writeBarrier\x00\x15\x06\renable" +
-       "d\x00\x00\x00\vneeded\x00\x00\x00\x05cgo\x00\x00\x00\t\x1dwritebarrierptr\x00\x04" +
-       "\x17:\vdst·1\x00\x00:\vsrc·2\x00\x00\x00\t\x17typedmemmove\x00\x06\x17\"" +
-       "||\x00\x00\x17:\vdst·2\x00\x00\x17:\vsrc·3\x00\x00\x00\t\x1btypedslicec" +
-       "opy\x00\x06\x17\"\b\x00\x00:\vdst·3\x00\x00:\vsrc·4\x00\x00\x01\x02\x00\t\x17selec" +
-       "tnbsend\x00\x06\x17\"\xf2\x01\x00\x00\x1f\x04:\xfe\x01\x00\x00\x17:\x80\x02\x00\x00\x01\x00\x00\t\x17selectn" +
-       "brecv\x00\x06\x17\"\xf2\x01\x00\x00\x17:p\x00\x00\x1f\x02:\x0fhchan·4\x00\x00\x01\x00\x00\t\x19sel" +
-       "ectnbrecv2\x00\b\x17\"\xf2\x01\x00\x00\x17:p\x00\x00\x17\x00\x15received·4\x00\x00\x1f" +
-       "\x02:\x0fhchan·5\x00\x00\x01\x00\x00\t\x11newselect\x00\x06\x17\"\vsel·1\x00\x00" +
-       "\n\x13selsize·2\x00\x00\b\rsize·3\x00\x00\x00\t\x13selectsend\x00\x06" +
-       "\x17\"\vsel·2\x00\x00\x1f\x04:\xfe\x01\x00\x00\x17:\x80\x02\x00\x00\x02\x00\x15selected·1\x00\x00" +
-       "\t\x13selectrecv\x00\x06\x17\"\xb6\x02\x00\x00\x1f\x02:\xfe\x01\x00\x00\x17:\x80\x02\x00\x00\x02\x00\xb8\x02\x00\x00\t" +
-       "\x15selectrecv2\x00\b\x17\"\xb6\x02\x00\x00\x1f\x02:\xfe\x01\x00\x00\x17:\x80\x02\x00\x00\x17\x00\x15rece" +
-       "ived·5\x00\x00\x02\x00\xb8\x02\x00\x00\t\x19selectdefault\x00\x02\x17\"\xb6\x02\x00\x00\x02\x00" +
-       "\xb8\x02\x00\x00\t\x0fselectgo\x00\x02\x17\"\xae\x02\x00\x00\x00\t\tblock\x00\x00\x00\t\x11makes" +
-       "lice\x00\x06\x17\"\b\x00\x00\n\vnel·3\x00\x00\n\vcap·4\x00\x00\x02\x11:\vary·" +
-       "1\x00\x00\t\x11growslice\x00\x06\x17\"\b\x00\x00\x11:\vold·3\x00\x00\x02\xca\x02\x00\x00\x02\x11:" +
-       "\xcc\x02\x00\x00\t\rmemmove\x00\x06\x17:\tto·1\x00\x00\x17:\vfrm·2\x00\x00\x16\x11le" +
-       "ngth·3\x00d\x00\t\vmemclr\x00\x04\x17\"\vptr·1\x00\x00\x16\x11length\xc2" +
-       "\xb72\x00d\x00\t\x0fmemequal\x00\x06\x17:\ax·2\x00\x00\x17:\ay·3\x00\x00\x16\rsiz" +
-       "e·4\x00d\x01\x00\x00\t\x11memequal8\x00\x04\x17:\xe2\x02\x00\x00\x17:\xe4\x02\x00\x00\x01\x00\x00\t\x13m" +
-       "emequal16\x00\x04\x17:\xe2\x02\x00\x00\x17:\xe4\x02\x00\x00\x01\x00\x00\t\x13memequal32\x00\x04" +
-       "\x17:\xe2\x02\x00\x00\x17:\xe4\x02\x00\x00\x01\x00\x00\t\x13memequal64\x00\x04\x17:\xe2\x02\x00\x00\x17:\xe4\x02\x00" +
-       "\x00\x01\x00\x00\t\x15memequal128\x00\x04\x17:\xe2\x02\x00\x00\x17:\xe4\x02\x00\x00\x01\x00\x00\t\x0fint6" +
-       "4div\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64div\x00\x03\x14\x00\x14\x00\x01\x14\x00\t\x0fint64" +
-       "mod\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64mod\x00\x03\x14\x00\x14\x00\x01\x14\x00\t\x1bfloat6" +
-       "4toint64\x00\x01\x1a\x00\x01\n\x00\t\x1dfloat64touint64\x00\x01\x1a\x00\x01\x14\x00\t" +
-       "\x1dfloat64touint32\x00\x01\x1a\x00\x01\x12\x00\t\x1bint64tofloat64\x00" +
-       "\x01\n\x00\x01\x1a\x00\t\x1duint64tofloat64\x00\x01\x14\x00\x01\x1a\x00\t\x1duint32to" +
-       "float64\x00\x01\x12\x00\x01\x1a\x00\t\x19complex128div\x00\x04\x1e\vnum·2\x00" +
-       "\x00\x1e\vden·3\x00\x00\x02\x1e\vquo·1\x00\x00\t\x19racefuncenter\x00\x01\x16" +
-       "d\x00\t\x17racefuncexit\x00\x00\x00\t\x0fraceread\x00\x01\x16d\x00\t\x11race" +
-       "write\x00\x01\x16d\x00\t\x19racereadrange\x00\x04\x16\raddr·1\x00d\x16\r" +
-       "size·2\x00d\x00\t\x1bracewriterange\x00\x04\x16\x98\x03\x00d\x16\x9a\x03\x00d\x00\t" +
-       "\x0fmsanread\x00\x04\x16\x98\x03\x00d\x16\x9a\x03\x00d\x00\t\x11msanwrite\x00\x04\x16\x98\x03\x00d" +
-       "\x16\x9a\x03\x00d\x00\v\xf8\x01\v\x00\x01\x00\n$$\n"
+       "version 1\n\n\x00\x00\x01\rruntime\x00\t\x11newobject\x00\x02\x17\"\vt" +
+       "yp·2\x00\x00\x01\x17:\x00\t\x13panicindex\x00\x00\x00\t\x13panicslice\x00\x00" +
+       "\x00\t\x15panicdivide\x00\x00\x00\t\x15throwreturn\x00\x00\x00\t\x11throw" +
+       "init\x00\x00\x00\t\x11panicwrap\x00\x05 \x00 \x00 \x00\x00\t\rgopanic\x00\x01\x1b\x00" +
+       "\x00\x00\x00\t\x11gorecover\x00\x01\x17\b\x00\x01\x1b\x00\x00\x00\t\x11printbool\x00\x01\x00\x00\x00" +
+       "\t\x13printfloat\x00\x01\x1a\x00\x00\t\x0fprintint\x00\x01\n\x00\x00\t\x0fprinth" +
+       "ex\x00\x01\x14\x00\x00\t\x11printuint\x00\x01\x14\x00\x00\t\x17printcomplex\x00\x01\x1e" +
+       "\x00\x00\t\x15printstring\x00\x01 \x00\x00\t\x17printpointer\x00\x01:\x00\x00\t" +
+       "\x13printiface\x00\x01:\x00\x00\t\x13printeface\x00\x01:\x00\x00\t\x13print" +
+       "slice\x00\x01:\x00\x00\t\rprintnl\x00\x00\x00\t\rprintsp\x00\x00\x00\t\x11prin" +
+       "tlock\x00\x00\x00\t\x15printunlock\x00\x00\x00\t\x19concatstring2\x00" +
+       "\x05\x17\x0f@\"\x00 \x00 \x00\x01 \x00\t\x19concatstring3\x00\a\x17\x0f@\"\x00 \x00 \x00 " +
+       "\x00\x01 \x00\t\x19concatstring4\x00\t\x17\x0f@\"\x00 \x00 \x00 \x00 \x00\x01 \x00\t\x19c" +
+       "oncatstring5\x00\v\x17\x0f@\"\x00 \x00 \x00 \x00 \x00 \x00\x01 \x00\t\x19concat" +
+       "strings\x00\x03\x17\x0f@\"\x00\x11 \x00\x01 \x00\t\x11cmpstring\x00\x03 \x00 \x00\x01\x02\x00" +
+       "\t\x0feqstring\x00\x03 \x00 \x00\x01\x00\x00\t\x11intstring\x00\x03\x17\x0f\b\"\x00\n\x00\x01" +
+       " \x00\t!slicebytetostring\x00\x03\x17\x0f@\"\x00\x11\"\x00\x01 \x00\t'slic" +
+       "ebytetostringtmp\x00\x01\x11\"\x00\x01 \x00\t!slicerunetostr" +
+       "ing\x00\x03\x17\x0f@\"\x00\x11|S\x00\x01 \x00\t!stringtoslicebyte\x00\x03\x17\x0f" +
+       "@\"\x00 \x00\x01\x11\"\x00\t'stringtoslicebytetmp\x00\x01 \x00\x01\x11\"\x00\t" +
+       "!stringtoslicerune\x00\x03\x17\x0f@|S\x00 \x00\x01\x11|S\x00\t\x13strin" +
+       "giter\x00\x03 \x00\x02\x00\x01\x02\x00\t\x15stringiter2\x00\x03 \x00\x02\x00\x04\x02\rretk" +
+       "·1\x00\x00|S\rretv·2\x00\x00\t\x11slicecopy\x00\x06:\tto·2\x00\x00:" +
+       "\tfr·3\x00\x00\x16\vwid·4\x00\x1bunsafe-uintptr\x01\x02\x00\t\x1dsli" +
+       "cestringcopy\x00\x04:\\\x00\x00:^\x00\x00\x01\x02\x00\t\rconvI2E\x00\x02:\rel" +
+       "em·2\x00\x00\x02:\vret·1\x00\x00\t\rconvI2I\x00\x04\x17\"\x06\x00\x00:\relem" +
+       "·3\x00\x00\x02:j\x00\x00\t\rconvT2E\x00\x06\x17\"\x06\x00\x00\x17:n\x00\x00\x17:\vbuf·4" +
+       "\x00\x00\x02:j\x00\x00\t\rconvT2I\x00\x06\x17\"\vtab·2\x00\x00\x17:n\x00\x00\x17:r\x00\x00\x02" +
+       ":j\x00\x00\t\x11assertE2E\x00\x06\x17\"\vtyp·1\x00\x00:\x0fiface·2\x00\x00" +
+       "\x17:\vret·3\x00\x00\x00\t\x13assertE2E2\x00\x06\x17\"\x06\x00\x00:\x0fiface·" +
+       "3\x00\x00\x17:\vret·4\x00\x00\x01\x00\x00\t\x11assertE2I\x00\x06\x17\"z\x00\x00:||\x00\x00" +
+       "\x17:~\x00\x00\x00\t\x13assertE2I2\x00\x06\x17\"\x06\x00\x00:\x82\x01\x00\x00\x17:\x84\x01\x00\x00\x01\x00\x00\t" +
+       "\x11assertE2T\x00\x06\x17\"z\x00\x00:||\x00\x00\x17:~\x00\x00\x00\t\x13assertE2T2" +
+       "\x00\x06\x17\"\x06\x00\x00:\x82\x01\x00\x00\x17:\x84\x01\x00\x00\x01\x00\x00\t\x11assertI2E\x00\x06\x17\"z\x00\x00:" +
+       "||\x00\x00\x17:~\x00\x00\x00\t\x13assertI2E2\x00\x06\x17\"\x06\x00\x00:\x82\x01\x00\x00\x17:\x84\x01\x00\x00" +
+       "\x01\x00\x00\t\x11assertI2I\x00\x06\x17\"z\x00\x00:||\x00\x00\x17:~\x00\x00\x00\t\x13assert" +
+       "I2I2\x00\x06\x17\"\x06\x00\x00:\x82\x01\x00\x00\x17:\x84\x01\x00\x00\x01\x00\x00\t\x11assertI2T\x00\x06\x17\"" +
+       "z\x00\x00:||\x00\x00\x17:~\x00\x00\x00\t\x13assertI2T2\x00\x06\x17\"\x06\x00\x00:\x82\x01\x00\x00\x17:" +
+       "\x84\x01\x00\x00\x01\x00\x00\t\x17panicdottype\x00\x06\x17\"\rhave·1\x00\x00\x17\"\rwa" +
+       "nt·2\x00\x00\x17\"\x82\x01\x00\x00\x00\t\rifaceeq\x00\x04:\ti1·2\x00\x00:\ti2·" +
+       "3\x00\x00\x02\x00j\x00\x00\t\refaceeq\x00\x04:\xa2\x01\x00\x00:\xa4\x01\x00\x00\x02\x00j\x00\x00\t\rmake" +
+       "map\x00\b\x17\"\x13mapType·2\x00\x00\n\rhint·3\x00\x00\x17:\x11mapbuf" +
+       "·4\x00\x00\x17:\x17bucketbuf·5\x00\x00\x02\x1d::\rhmap·1\x00\x00\t\x13ma" +
+       "paccess1\x00\x06\x17\"\xaa\x01\x00\x00\x1d::\rhmap·3\x00\x00\x17:\vkey·4\x00\x00" +
+       "\x02\x17:\vval·1\x00\x00\t!mapaccess1_fast32\x00\x06\x17\"\xaa\x01\x00\x00\x1d" +
+       "::\xb6\x01\x00\x00:\xb8\x01\x00\x00\x02\x17:\xba\x01\x00\x00\t!mapaccess1_fast64\x00\x06\x17" +
+       "\"\xaa\x01\x00\x00\x1d::\xb6\x01\x00\x00:\xb8\x01\x00\x00\x02\x17:\xba\x01\x00\x00\t#mapaccess1_fas" +
+       "tstr\x00\x06\x17\"\xaa\x01\x00\x00\x1d::\xb6\x01\x00\x00:\xb8\x01\x00\x00\x02\x17:\xba\x01\x00\x00\t\x1bmapacce" +
+       "ss1_fat\x00\b\x17\"\xaa\x01\x00\x00\x1d::\xb6\x01\x00\x00\x17:\xb8\x01\x00\x00\x17\"\rzero·5\x00\x00" +
+       "\x02\x17:\xba\x01\x00\x00\t\x13mapaccess2\x00\x06\x17\"\x13mapType·3\x00\x00\x1d::\r" +
+       "hmap·4\x00\x00\x17:\vkey·5\x00\x00\x04\x17:\xba\x01\x00\x00\x00\rpres·2\x00\x00\t!" +
+       "mapaccess2_fast32\x00\x06\x17\"\xc8\x01\x00\x00\x1d::\xca\x01\x00\x00:\xcc\x01\x00\x00\x04\x17:" +
+       "\xba\x01\x00\x00\x00\xce\x01\x00\x00\t!mapaccess2_fast64\x00\x06\x17\"\xc8\x01\x00\x00\x1d::\xca" +
+       "\x01\x00\x00:\xcc\x01\x00\x00\x04\x17:\xba\x01\x00\x00\x00\xce\x01\x00\x00\t#mapaccess2_faststr" +
+       "\x00\x06\x17\"\xc8\x01\x00\x00\x1d::\xca\x01\x00\x00:\xcc\x01\x00\x00\x04\x17:\xba\x01\x00\x00\x00\xce\x01\x00\x00\t\x1bmapacc" +
+       "ess2_fat\x00\b\x17\"\xc8\x01\x00\x00\x1d::\xca\x01\x00\x00\x17:\xcc\x01\x00\x00\x17\"\rzero·6\x00" +
+       "\x00\x04\x17:\xba\x01\x00\x00\x00\xce\x01\x00\x00\t\x13mapassign1\x00\b\x17\"\x13mapType·1" +
+       "\x00\x00\x1d::\rhmap·2\x00\x00\x17:\vkey·3\x00\x00\x17:\vval·4\x00\x00\x00\t\x15" +
+       "mapiterinit\x00\x06\x17\"\xdc\x01\x00\x00\x1d::\xde\x01\x00\x00\x17:\x0fhiter·3\x00\x00\x00" +
+       "\t\x11mapdelete\x00\x06\x17\"\xdc\x01\x00\x00\x1d::\xde\x01\x00\x00\x17:\xe0\x01\x00\x00\x00\t\x15mapit" +
+       "ernext\x00\x02\x17:\x0fhiter·1\x00\x00\x00\t\x0fmakechan\x00\x04\x17\"\x15cha" +
+       "nType·2\x00\x00\n\xac\x01\x00\x00\x02\x1f\x06:\x0fhchan·1\x00\x00\t\x11chanrecv" +
+       "1\x00\x06\x17\"\x15chanType·1\x00\x00\x1f\x02:\x0fhchan·2\x00\x00\x17:n\x00\x00\x00\t" +
+       "\x11chanrecv2\x00\x06\x17\"\xf0\x01\x00\x00\x1f\x02:\x0fhchan·3\x00\x00\x17:\relem\xc2" +
+       "\xb74\x00\x00\x01\x00\x00\t\x11chansend1\x00\x06\x17\"\xf6\x01\x00\x00\x1f\x04:\xf8\x01\x00\x00\x17:n\x00\x00\x00\t" +
+       "\x11closechan\x00\x02:\xf2\x01\x00\x00\x00\a\x17writeBarrier\x00\x15\x06\renab" +
+       "led\x00\x00\x00\vneeded\x00\x00\x00\x05cgo\x00\x00\x00\t\x1dwritebarrierptr" +
+       "\x00\x04\x17:\vdst·1\x00\x00:\vsrc·2\x00\x00\x00\t\x17typedmemmove\x00\x06" +
+       "\x17\"z\x00\x00\x17:\vdst·2\x00\x00\x17:\vsrc·3\x00\x00\x00\t\x1btypedslice" +
+       "copy\x00\x06\x17\"\x06\x00\x00:\vdst·3\x00\x00:\vsrc·4\x00\x00\x01\x02\x00\t\x17sele" +
+       "ctnbsend\x00\x06\x17\"\xf0\x01\x00\x00\x1f\x04:\xfc\x01\x00\x00\x17:\xfe\x01\x00\x00\x01\x00\x00\t\x17select" +
+       "nbrecv\x00\x06\x17\"\xf0\x01\x00\x00\x17:n\x00\x00\x1f\x02:\x0fhchan·4\x00\x00\x01\x00\x00\t\x19se" +
+       "lectnbrecv2\x00\b\x17\"\xf0\x01\x00\x00\x17:n\x00\x00\x17\x00\x15received·4\x00\x00" +
+       "\x1f\x02:\x0fhchan·5\x00\x00\x01\x00\x00\t\x11newselect\x00\x06\x17\"\vsel·1\x00" +
+       "\x00\n\x13selsize·2\x00\x00\b\rsize·3\x00\x00\x00\t\x13selectsend\x00" +
+       "\x06\x17\"\vsel·2\x00\x00\x1f\x04:\xfc\x01\x00\x00\x17:\xfe\x01\x00\x00\x02\x00\x15selected·1\x00" +
+       "\x00\t\x13selectrecv\x00\x06\x17\"\xb4\x02\x00\x00\x1f\x02:\xfc\x01\x00\x00\x17:\xfe\x01\x00\x00\x02\x00\xb6\x02\x00\x00" +
+       "\t\x15selectrecv2\x00\b\x17\"\xb4\x02\x00\x00\x1f\x02:\xfc\x01\x00\x00\x17:\xfe\x01\x00\x00\x17\x00\x15rec" +
+       "eived·5\x00\x00\x02\x00\xb6\x02\x00\x00\t\x19selectdefault\x00\x02\x17\"\xb4\x02\x00\x00\x02" +
+       "\x00\xb6\x02\x00\x00\t\x0fselectgo\x00\x02\x17\"\xac\x02\x00\x00\x00\t\tblock\x00\x00\x00\t\x11make" +
+       "slice\x00\x06\x17\"\x06\x00\x00\n\vnel·3\x00\x00\n\vcap·4\x00\x00\x02\x11:\vary\xc2" +
+       "\xb71\x00\x00\t\x11growslice\x00\x06\x17\"\x06\x00\x00\x11:\vold·3\x00\x00\x02\xc8\x02\x00\x00\x02\x11" +
+       ":\xca\x02\x00\x00\t\rmemmove\x00\x06\x17:\tto·1\x00\x00\x17:\vfrm·2\x00\x00\x16\x11l" +
+       "ength·3\x00b\x00\t\vmemclr\x00\x04\x17\"\vptr·1\x00\x00\x16\x11length" +
+       "·2\x00b\x00\t\x0fmemequal\x00\x06\x17:\ax·2\x00\x00\x17:\ay·3\x00\x00\x16\rsi" +
+       "ze·4\x00b\x01\x00\x00\t\x11memequal8\x00\x04\x17:\xe0\x02\x00\x00\x17:\xe2\x02\x00\x00\x01\x00\x00\t\x13" +
+       "memequal16\x00\x04\x17:\xe0\x02\x00\x00\x17:\xe2\x02\x00\x00\x01\x00\x00\t\x13memequal32\x00" +
+       "\x04\x17:\xe0\x02\x00\x00\x17:\xe2\x02\x00\x00\x01\x00\x00\t\x13memequal64\x00\x04\x17:\xe0\x02\x00\x00\x17:\xe2\x02" +
+       "\x00\x00\x01\x00\x00\t\x15memequal128\x00\x04\x17:\xe0\x02\x00\x00\x17:\xe2\x02\x00\x00\x01\x00\x00\t\x0fint" +
+       "64div\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64div\x00\x03\x14\x00\x14\x00\x01\x14\x00\t\x0fint6" +
+       "4mod\x00\x03\n\x00\n\x00\x01\n\x00\t\x11uint64mod\x00\x03\x14\x00\x14\x00\x01\x14\x00\t\x1bfloat" +
+       "64toint64\x00\x01\x1a\x00\x01\n\x00\t\x1dfloat64touint64\x00\x01\x1a\x00\x01\x14\x00" +
+       "\t\x1dfloat64touint32\x00\x01\x1a\x00\x01\x12\x00\t\x1bint64tofloat64" +
+       "\x00\x01\n\x00\x01\x1a\x00\t\x1duint64tofloat64\x00\x01\x14\x00\x01\x1a\x00\t\x1duint32t" +
+       "ofloat64\x00\x01\x12\x00\x01\x1a\x00\t\x19complex128div\x00\x04\x1e\vnum·2" +
+       "\x00\x00\x1e\vden·3\x00\x00\x02\x1e\vquo·1\x00\x00\t\x19racefuncenter\x00\x01" +
+       "\x16b\x00\t\x17racefuncexit\x00\x00\x00\t\x0fraceread\x00\x01\x16b\x00\t\x11rac" +
+       "ewrite\x00\x01\x16b\x00\t\x19racereadrange\x00\x04\x16\raddr·1\x00b\x16" +
+       "\rsize·2\x00b\x00\t\x1bracewriterange\x00\x04\x16\x96\x03\x00b\x16\x98\x03\x00b\x00" +
+       "\t\x0fmsanread\x00\x04\x16\x96\x03\x00b\x16\x98\x03\x00b\x00\t\x11msanwrite\x00\x04\x16\x96\x03\x00" +
+       "b\x16\x98\x03\x00b\x00\v\xf8\x01\v\x00\x01\x00\n$$\n"
 
 const unsafeimport = "" +
-       "cn\x00\x03v1\x01\vunsafe\x00\x05\r\rPointer\x00\x16\x00\t\x0fOffsetof\x00\x01" +
-       ":\x00\x01\x16\x00\t\vSizeof\x00\x01:\x00\x01\x16\x00\t\rAlignof\x00\x01:\x00\x01\x16\x00\v\b\v\x00" +
-       "\x01\x00\n$$\n"
+       "version 1\n\n\x00\x00\x01\vunsafe\x00\x05\r\rPointer\x00\x16\x00\t\x0fOff" +
+       "setof\x00\x01:\x00\x01\x16\x00\t\vSizeof\x00\x01:\x00\x01\x16\x00\t\rAlignof\x00\x01:\x00" +
+       "\x01\x16\x00\v\b\v\x00\x01\x00\n$$\n"
index dc09e6574673788adbcfc80b9884a7fa5de15eec..87701f99deb44d7227d613d029b016d67be4405b 100644 (file)
@@ -50,26 +50,36 @@ func BImportData(imports map[string]*types.Package, data []byte, path string) (i
                strList: []string{""}, // empty string is mapped to 0
        }
 
-       // read low-level encoding format
-       switch format := p.rawByte(); format {
-       case 'c':
-               // compact format - nothing to do
-       case 'd':
-               p.debugFormat = true
-       default:
-               return p.read, nil, fmt.Errorf("invalid encoding format in export data: got %q; want 'c' or 'd'", format)
+       // read version info
+       if b := p.rawByte(); b == 'c' || b == 'd' {
+               // Go1.7 encoding; first byte encodes low-level
+               // encoding format (compact vs debug).
+               // For backward-compatibility only (avoid problems with
+               // old installed packages). Newly compiled packages use
+               // the extensible format string.
+               // 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 ---
 
-       if v := p.string(); v != "v1" {
-               return p.read, nil, fmt.Errorf("unknown export data version: %s", v)
-       }
-
        // populate typList with predeclared "known" types
        p.typList = append(p.typList, predeclared...)
 
@@ -682,7 +692,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 {
        i, err := binary.ReadVarint(p)
        if err != nil {
@@ -691,6 +701,16 @@ func (p *importer) rawInt64() int64 {
        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
 func (p *importer) ReadByte() (byte, error) {
        return p.rawByte(), nil