1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// This file is a copy of $GOROOT/src/go/internal/gcimporter/bimport.go.
6
7package gcimporter
8
9import (
10	"encoding/binary"
11	"fmt"
12	"go/constant"
13	"go/token"
14	"go/types"
15	"sort"
16	"strconv"
17	"strings"
18	"sync"
19	"unicode"
20	"unicode/utf8"
21)
22
23type importer struct {
24	imports    map[string]*types.Package
25	data       []byte
26	importpath string
27	buf        []byte // for reading strings
28	version    int    // export format version
29
30	// object lists
31	strList       []string           // in order of appearance
32	pathList      []string           // in order of appearance
33	pkgList       []*types.Package   // in order of appearance
34	typList       []types.Type       // in order of appearance
35	interfaceList []*types.Interface // for delayed completion only
36	trackAllTypes bool
37
38	// position encoding
39	posInfoFormat bool
40	prevFile      string
41	prevLine      int
42	fake          fakeFileSet
43
44	// debugging support
45	debugFormat bool
46	read        int // bytes read
47}
48
49// BImportData imports a package from the serialized package data
50// and returns the number of bytes consumed and a reference to the package.
51// If the export data version is not recognized or the format is otherwise
52// compromised, an error is returned.
53func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
54	// catch panics and return them as errors
55	const currentVersion = 6
56	version := -1 // unknown version
57	defer func() {
58		if e := recover(); e != nil {
59			// Return a (possibly nil or incomplete) package unchanged (see #16088).
60			if version > currentVersion {
61				err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
62			} else {
63				err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
64			}
65		}
66	}()
67
68	p := importer{
69		imports:    imports,
70		data:       data,
71		importpath: path,
72		version:    version,
73		strList:    []string{""}, // empty string is mapped to 0
74		pathList:   []string{""}, // empty string is mapped to 0
75		fake: fakeFileSet{
76			fset:  fset,
77			files: make(map[string]*token.File),
78		},
79	}
80
81	// read version info
82	var versionstr string
83	if b := p.rawByte(); b == 'c' || b == 'd' {
84		// Go1.7 encoding; first byte encodes low-level
85		// encoding format (compact vs debug).
86		// For backward-compatibility only (avoid problems with
87		// old installed packages). Newly compiled packages use
88		// the extensible format string.
89		// TODO(gri) Remove this support eventually; after Go1.8.
90		if b == 'd' {
91			p.debugFormat = true
92		}
93		p.trackAllTypes = p.rawByte() == 'a'
94		p.posInfoFormat = p.int() != 0
95		versionstr = p.string()
96		if versionstr == "v1" {
97			version = 0
98		}
99	} else {
100		// Go1.8 extensible encoding
101		// read version string and extract version number (ignore anything after the version number)
102		versionstr = p.rawStringln(b)
103		if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" {
104			if v, err := strconv.Atoi(s[1]); err == nil && v > 0 {
105				version = v
106			}
107		}
108	}
109	p.version = version
110
111	// read version specific flags - extend as necessary
112	switch p.version {
113	// case currentVersion:
114	// 	...
115	//	fallthrough
116	case currentVersion, 5, 4, 3, 2, 1:
117		p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
118		p.trackAllTypes = p.int() != 0
119		p.posInfoFormat = p.int() != 0
120	case 0:
121		// Go1.7 encoding format - nothing to do here
122	default:
123		errorf("unknown bexport format version %d (%q)", p.version, versionstr)
124	}
125
126	// --- generic export data ---
127
128	// populate typList with predeclared "known" types
129	p.typList = append(p.typList, predeclared()...)
130
131	// read package data
132	pkg = p.pkg()
133
134	// read objects of phase 1 only (see cmd/compile/internal/gc/bexport.go)
135	objcount := 0
136	for {
137		tag := p.tagOrIndex()
138		if tag == endTag {
139			break
140		}
141		p.obj(tag)
142		objcount++
143	}
144
145	// self-verification
146	if count := p.int(); count != objcount {
147		errorf("got %d objects; want %d", objcount, count)
148	}
149
150	// ignore compiler-specific import data
151
152	// complete interfaces
153	// TODO(gri) re-investigate if we still need to do this in a delayed fashion
154	for _, typ := range p.interfaceList {
155		typ.Complete()
156	}
157
158	// record all referenced packages as imports
159	list := append(([]*types.Package)(nil), p.pkgList[1:]...)
160	sort.Sort(byPath(list))
161	pkg.SetImports(list)
162
163	// package was imported completely and without errors
164	pkg.MarkComplete()
165
166	return p.read, pkg, nil
167}
168
169func errorf(format string, args ...interface{}) {
170	panic(fmt.Sprintf(format, args...))
171}
172
173func (p *importer) pkg() *types.Package {
174	// if the package was seen before, i is its index (>= 0)
175	i := p.tagOrIndex()
176	if i >= 0 {
177		return p.pkgList[i]
178	}
179
180	// otherwise, i is the package tag (< 0)
181	if i != packageTag {
182		errorf("unexpected package tag %d version %d", i, p.version)
183	}
184
185	// read package data
186	name := p.string()
187	var path string
188	if p.version >= 5 {
189		path = p.path()
190	} else {
191		path = p.string()
192	}
193	if p.version >= 6 {
194		p.int() // package height; unused by go/types
195	}
196
197	// we should never see an empty package name
198	if name == "" {
199		errorf("empty package name in import")
200	}
201
202	// an empty path denotes the package we are currently importing;
203	// it must be the first package we see
204	if (path == "") != (len(p.pkgList) == 0) {
205		errorf("package path %q for pkg index %d", path, len(p.pkgList))
206	}
207
208	// if the package was imported before, use that one; otherwise create a new one
209	if path == "" {
210		path = p.importpath
211	}
212	pkg := p.imports[path]
213	if pkg == nil {
214		pkg = types.NewPackage(path, name)
215		p.imports[path] = pkg
216	} else if pkg.Name() != name {
217		errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path)
218	}
219	p.pkgList = append(p.pkgList, pkg)
220
221	return pkg
222}
223
224// objTag returns the tag value for each object kind.
225func objTag(obj types.Object) int {
226	switch obj.(type) {
227	case *types.Const:
228		return constTag
229	case *types.TypeName:
230		return typeTag
231	case *types.Var:
232		return varTag
233	case *types.Func:
234		return funcTag
235	default:
236		errorf("unexpected object: %v (%T)", obj, obj) // panics
237		panic("unreachable")
238	}
239}
240
241func sameObj(a, b types.Object) bool {
242	// Because unnamed types are not canonicalized, we cannot simply compare types for
243	// (pointer) identity.
244	// Ideally we'd check equality of constant values as well, but this is good enough.
245	return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type())
246}
247
248func (p *importer) declare(obj types.Object) {
249	pkg := obj.Pkg()
250	if alt := pkg.Scope().Insert(obj); alt != nil {
251		// This can only trigger if we import a (non-type) object a second time.
252		// Excluding type aliases, this cannot happen because 1) we only import a package
253		// once; and b) we ignore compiler-specific export data which may contain
254		// functions whose inlined function bodies refer to other functions that
255		// were already imported.
256		// However, type aliases require reexporting the original type, so we need
257		// to allow it (see also the comment in cmd/compile/internal/gc/bimport.go,
258		// method importer.obj, switch case importing functions).
259		// TODO(gri) review/update this comment once the gc compiler handles type aliases.
260		if !sameObj(obj, alt) {
261			errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt)
262		}
263	}
264}
265
266func (p *importer) obj(tag int) {
267	switch tag {
268	case constTag:
269		pos := p.pos()
270		pkg, name := p.qualifiedName()
271		typ := p.typ(nil, nil)
272		val := p.value()
273		p.declare(types.NewConst(pos, pkg, name, typ, val))
274
275	case aliasTag:
276		// TODO(gri) verify type alias hookup is correct
277		pos := p.pos()
278		pkg, name := p.qualifiedName()
279		typ := p.typ(nil, nil)
280		p.declare(types.NewTypeName(pos, pkg, name, typ))
281
282	case typeTag:
283		p.typ(nil, nil)
284
285	case varTag:
286		pos := p.pos()
287		pkg, name := p.qualifiedName()
288		typ := p.typ(nil, nil)
289		p.declare(types.NewVar(pos, pkg, name, typ))
290
291	case funcTag:
292		pos := p.pos()
293		pkg, name := p.qualifiedName()
294		params, isddd := p.paramList()
295		result, _ := p.paramList()
296		sig := types.NewSignature(nil, params, result, isddd)
297		p.declare(types.NewFunc(pos, pkg, name, sig))
298
299	default:
300		errorf("unexpected object tag %d", tag)
301	}
302}
303
304const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
305
306func (p *importer) pos() token.Pos {
307	if !p.posInfoFormat {
308		return token.NoPos
309	}
310
311	file := p.prevFile
312	line := p.prevLine
313	delta := p.int()
314	line += delta
315	if p.version >= 5 {
316		if delta == deltaNewFile {
317			if n := p.int(); n >= 0 {
318				// file changed
319				file = p.path()
320				line = n
321			}
322		}
323	} else {
324		if delta == 0 {
325			if n := p.int(); n >= 0 {
326				// file changed
327				file = p.prevFile[:n] + p.string()
328				line = p.int()
329			}
330		}
331	}
332	p.prevFile = file
333	p.prevLine = line
334
335	return p.fake.pos(file, line, 0)
336}
337
338// Synthesize a token.Pos
339type fakeFileSet struct {
340	fset  *token.FileSet
341	files map[string]*token.File
342}
343
344func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
345	// TODO(mdempsky): Make use of column.
346
347	// Since we don't know the set of needed file positions, we
348	// reserve maxlines positions per file.
349	const maxlines = 64 * 1024
350	f := s.files[file]
351	if f == nil {
352		f = s.fset.AddFile(file, -1, maxlines)
353		s.files[file] = f
354		// Allocate the fake linebreak indices on first use.
355		// TODO(adonovan): opt: save ~512KB using a more complex scheme?
356		fakeLinesOnce.Do(func() {
357			fakeLines = make([]int, maxlines)
358			for i := range fakeLines {
359				fakeLines[i] = i
360			}
361		})
362		f.SetLines(fakeLines)
363	}
364
365	if line > maxlines {
366		line = 1
367	}
368
369	// Treat the file as if it contained only newlines
370	// and column=1: use the line number as the offset.
371	return f.Pos(line - 1)
372}
373
374var (
375	fakeLines     []int
376	fakeLinesOnce sync.Once
377)
378
379func (p *importer) qualifiedName() (pkg *types.Package, name string) {
380	name = p.string()
381	pkg = p.pkg()
382	return
383}
384
385func (p *importer) record(t types.Type) {
386	p.typList = append(p.typList, t)
387}
388
389// A dddSlice is a types.Type representing ...T parameters.
390// It only appears for parameter types and does not escape
391// the importer.
392type dddSlice struct {
393	elem types.Type
394}
395
396func (t *dddSlice) Underlying() types.Type { return t }
397func (t *dddSlice) String() string         { return "..." + t.elem.String() }
398
399// parent is the package which declared the type; parent == nil means
400// the package currently imported. The parent package is needed for
401// exported struct fields and interface methods which don't contain
402// explicit package information in the export data.
403//
404// A non-nil tname is used as the "owner" of the result type; i.e.,
405// the result type is the underlying type of tname. tname is used
406// to give interface methods a named receiver type where possible.
407func (p *importer) typ(parent *types.Package, tname *types.Named) types.Type {
408	// if the type was seen before, i is its index (>= 0)
409	i := p.tagOrIndex()
410	if i >= 0 {
411		return p.typList[i]
412	}
413
414	// otherwise, i is the type tag (< 0)
415	switch i {
416	case namedTag:
417		// read type object
418		pos := p.pos()
419		parent, name := p.qualifiedName()
420		scope := parent.Scope()
421		obj := scope.Lookup(name)
422
423		// if the object doesn't exist yet, create and insert it
424		if obj == nil {
425			obj = types.NewTypeName(pos, parent, name, nil)
426			scope.Insert(obj)
427		}
428
429		if _, ok := obj.(*types.TypeName); !ok {
430			errorf("pkg = %s, name = %s => %s", parent, name, obj)
431		}
432
433		// associate new named type with obj if it doesn't exist yet
434		t0 := types.NewNamed(obj.(*types.TypeName), nil, nil)
435
436		// but record the existing type, if any
437		tname := obj.Type().(*types.Named) // tname is either t0 or the existing type
438		p.record(tname)
439
440		// read underlying type
441		t0.SetUnderlying(p.typ(parent, t0))
442
443		// interfaces don't have associated methods
444		if types.IsInterface(t0) {
445			return tname
446		}
447
448		// read associated methods
449		for i := p.int(); i > 0; i-- {
450			// TODO(gri) replace this with something closer to fieldName
451			pos := p.pos()
452			name := p.string()
453			if !exported(name) {
454				p.pkg()
455			}
456
457			recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
458			params, isddd := p.paramList()
459			result, _ := p.paramList()
460			p.int() // go:nointerface pragma - discarded
461
462			sig := types.NewSignature(recv.At(0), params, result, isddd)
463			t0.AddMethod(types.NewFunc(pos, parent, name, sig))
464		}
465
466		return tname
467
468	case arrayTag:
469		t := new(types.Array)
470		if p.trackAllTypes {
471			p.record(t)
472		}
473
474		n := p.int64()
475		*t = *types.NewArray(p.typ(parent, nil), n)
476		return t
477
478	case sliceTag:
479		t := new(types.Slice)
480		if p.trackAllTypes {
481			p.record(t)
482		}
483
484		*t = *types.NewSlice(p.typ(parent, nil))
485		return t
486
487	case dddTag:
488		t := new(dddSlice)
489		if p.trackAllTypes {
490			p.record(t)
491		}
492
493		t.elem = p.typ(parent, nil)
494		return t
495
496	case structTag:
497		t := new(types.Struct)
498		if p.trackAllTypes {
499			p.record(t)
500		}
501
502		*t = *types.NewStruct(p.fieldList(parent))
503		return t
504
505	case pointerTag:
506		t := new(types.Pointer)
507		if p.trackAllTypes {
508			p.record(t)
509		}
510
511		*t = *types.NewPointer(p.typ(parent, nil))
512		return t
513
514	case signatureTag:
515		t := new(types.Signature)
516		if p.trackAllTypes {
517			p.record(t)
518		}
519
520		params, isddd := p.paramList()
521		result, _ := p.paramList()
522		*t = *types.NewSignature(nil, params, result, isddd)
523		return t
524
525	case interfaceTag:
526		// Create a dummy entry in the type list. This is safe because we
527		// cannot expect the interface type to appear in a cycle, as any
528		// such cycle must contain a named type which would have been
529		// first defined earlier.
530		// TODO(gri) Is this still true now that we have type aliases?
531		// See issue #23225.
532		n := len(p.typList)
533		if p.trackAllTypes {
534			p.record(nil)
535		}
536
537		var embeddeds []types.Type
538		for n := p.int(); n > 0; n-- {
539			p.pos()
540			embeddeds = append(embeddeds, p.typ(parent, nil))
541		}
542
543		t := newInterface(p.methodList(parent, tname), embeddeds)
544		p.interfaceList = append(p.interfaceList, t)
545		if p.trackAllTypes {
546			p.typList[n] = t
547		}
548		return t
549
550	case mapTag:
551		t := new(types.Map)
552		if p.trackAllTypes {
553			p.record(t)
554		}
555
556		key := p.typ(parent, nil)
557		val := p.typ(parent, nil)
558		*t = *types.NewMap(key, val)
559		return t
560
561	case chanTag:
562		t := new(types.Chan)
563		if p.trackAllTypes {
564			p.record(t)
565		}
566
567		dir := chanDir(p.int())
568		val := p.typ(parent, nil)
569		*t = *types.NewChan(dir, val)
570		return t
571
572	default:
573		errorf("unexpected type tag %d", i) // panics
574		panic("unreachable")
575	}
576}
577
578func chanDir(d int) types.ChanDir {
579	// tag values must match the constants in cmd/compile/internal/gc/go.go
580	switch d {
581	case 1 /* Crecv */ :
582		return types.RecvOnly
583	case 2 /* Csend */ :
584		return types.SendOnly
585	case 3 /* Cboth */ :
586		return types.SendRecv
587	default:
588		errorf("unexpected channel dir %d", d)
589		return 0
590	}
591}
592
593func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) {
594	if n := p.int(); n > 0 {
595		fields = make([]*types.Var, n)
596		tags = make([]string, n)
597		for i := range fields {
598			fields[i], tags[i] = p.field(parent)
599		}
600	}
601	return
602}
603
604func (p *importer) field(parent *types.Package) (*types.Var, string) {
605	pos := p.pos()
606	pkg, name, alias := p.fieldName(parent)
607	typ := p.typ(parent, nil)
608	tag := p.string()
609
610	anonymous := false
611	if name == "" {
612		// anonymous field - typ must be T or *T and T must be a type name
613		switch typ := deref(typ).(type) {
614		case *types.Basic: // basic types are named types
615			pkg = nil // // objects defined in Universe scope have no package
616			name = typ.Name()
617		case *types.Named:
618			name = typ.Obj().Name()
619		default:
620			errorf("named base type expected")
621		}
622		anonymous = true
623	} else if alias {
624		// anonymous field: we have an explicit name because it's an alias
625		anonymous = true
626	}
627
628	return types.NewField(pos, pkg, name, typ, anonymous), tag
629}
630
631func (p *importer) methodList(parent *types.Package, baseType *types.Named) (methods []*types.Func) {
632	if n := p.int(); n > 0 {
633		methods = make([]*types.Func, n)
634		for i := range methods {
635			methods[i] = p.method(parent, baseType)
636		}
637	}
638	return
639}
640
641func (p *importer) method(parent *types.Package, baseType *types.Named) *types.Func {
642	pos := p.pos()
643	pkg, name, _ := p.fieldName(parent)
644	// If we don't have a baseType, use a nil receiver.
645	// A receiver using the actual interface type (which
646	// we don't know yet) will be filled in when we call
647	// types.Interface.Complete.
648	var recv *types.Var
649	if baseType != nil {
650		recv = types.NewVar(token.NoPos, parent, "", baseType)
651	}
652	params, isddd := p.paramList()
653	result, _ := p.paramList()
654	sig := types.NewSignature(recv, params, result, isddd)
655	return types.NewFunc(pos, pkg, name, sig)
656}
657
658func (p *importer) fieldName(parent *types.Package) (pkg *types.Package, name string, alias bool) {
659	name = p.string()
660	pkg = parent
661	if pkg == nil {
662		// use the imported package instead
663		pkg = p.pkgList[0]
664	}
665	if p.version == 0 && name == "_" {
666		// version 0 didn't export a package for _ fields
667		return
668	}
669	switch name {
670	case "":
671		// 1) field name matches base type name and is exported: nothing to do
672	case "?":
673		// 2) field name matches base type name and is not exported: need package
674		name = ""
675		pkg = p.pkg()
676	case "@":
677		// 3) field name doesn't match type name (alias)
678		name = p.string()
679		alias = true
680		fallthrough
681	default:
682		if !exported(name) {
683			pkg = p.pkg()
684		}
685	}
686	return
687}
688
689func (p *importer) paramList() (*types.Tuple, bool) {
690	n := p.int()
691	if n == 0 {
692		return nil, false
693	}
694	// negative length indicates unnamed parameters
695	named := true
696	if n < 0 {
697		n = -n
698		named = false
699	}
700	// n > 0
701	params := make([]*types.Var, n)
702	isddd := false
703	for i := range params {
704		params[i], isddd = p.param(named)
705	}
706	return types.NewTuple(params...), isddd
707}
708
709func (p *importer) param(named bool) (*types.Var, bool) {
710	t := p.typ(nil, nil)
711	td, isddd := t.(*dddSlice)
712	if isddd {
713		t = types.NewSlice(td.elem)
714	}
715
716	var pkg *types.Package
717	var name string
718	if named {
719		name = p.string()
720		if name == "" {
721			errorf("expected named parameter")
722		}
723		if name != "_" {
724			pkg = p.pkg()
725		}
726		if i := strings.Index(name, "·"); i > 0 {
727			name = name[:i] // cut off gc-specific parameter numbering
728		}
729	}
730
731	// read and discard compiler-specific info
732	p.string()
733
734	return types.NewVar(token.NoPos, pkg, name, t), isddd
735}
736
737func exported(name string) bool {
738	ch, _ := utf8.DecodeRuneInString(name)
739	return unicode.IsUpper(ch)
740}
741
742func (p *importer) value() constant.Value {
743	switch tag := p.tagOrIndex(); tag {
744	case falseTag:
745		return constant.MakeBool(false)
746	case trueTag:
747		return constant.MakeBool(true)
748	case int64Tag:
749		return constant.MakeInt64(p.int64())
750	case floatTag:
751		return p.float()
752	case complexTag:
753		re := p.float()
754		im := p.float()
755		return constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
756	case stringTag:
757		return constant.MakeString(p.string())
758	case unknownTag:
759		return constant.MakeUnknown()
760	default:
761		errorf("unexpected value tag %d", tag) // panics
762		panic("unreachable")
763	}
764}
765
766func (p *importer) float() constant.Value {
767	sign := p.int()
768	if sign == 0 {
769		return constant.MakeInt64(0)
770	}
771
772	exp := p.int()
773	mant := []byte(p.string()) // big endian
774
775	// remove leading 0's if any
776	for len(mant) > 0 && mant[0] == 0 {
777		mant = mant[1:]
778	}
779
780	// convert to little endian
781	// TODO(gri) go/constant should have a more direct conversion function
782	//           (e.g., once it supports a big.Float based implementation)
783	for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 {
784		mant[i], mant[j] = mant[j], mant[i]
785	}
786
787	// adjust exponent (constant.MakeFromBytes creates an integer value,
788	// but mant represents the mantissa bits such that 0.5 <= mant < 1.0)
789	exp -= len(mant) << 3
790	if len(mant) > 0 {
791		for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 {
792			exp++
793		}
794	}
795
796	x := constant.MakeFromBytes(mant)
797	switch {
798	case exp < 0:
799		d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
800		x = constant.BinaryOp(x, token.QUO, d)
801	case exp > 0:
802		x = constant.Shift(x, token.SHL, uint(exp))
803	}
804
805	if sign < 0 {
806		x = constant.UnaryOp(token.SUB, x, 0)
807	}
808	return x
809}
810
811// ----------------------------------------------------------------------------
812// Low-level decoders
813
814func (p *importer) tagOrIndex() int {
815	if p.debugFormat {
816		p.marker('t')
817	}
818
819	return int(p.rawInt64())
820}
821
822func (p *importer) int() int {
823	x := p.int64()
824	if int64(int(x)) != x {
825		errorf("exported integer too large")
826	}
827	return int(x)
828}
829
830func (p *importer) int64() int64 {
831	if p.debugFormat {
832		p.marker('i')
833	}
834
835	return p.rawInt64()
836}
837
838func (p *importer) path() string {
839	if p.debugFormat {
840		p.marker('p')
841	}
842	// if the path was seen before, i is its index (>= 0)
843	// (the empty string is at index 0)
844	i := p.rawInt64()
845	if i >= 0 {
846		return p.pathList[i]
847	}
848	// otherwise, i is the negative path length (< 0)
849	a := make([]string, -i)
850	for n := range a {
851		a[n] = p.string()
852	}
853	s := strings.Join(a, "/")
854	p.pathList = append(p.pathList, s)
855	return s
856}
857
858func (p *importer) string() string {
859	if p.debugFormat {
860		p.marker('s')
861	}
862	// if the string was seen before, i is its index (>= 0)
863	// (the empty string is at index 0)
864	i := p.rawInt64()
865	if i >= 0 {
866		return p.strList[i]
867	}
868	// otherwise, i is the negative string length (< 0)
869	if n := int(-i); n <= cap(p.buf) {
870		p.buf = p.buf[:n]
871	} else {
872		p.buf = make([]byte, n)
873	}
874	for i := range p.buf {
875		p.buf[i] = p.rawByte()
876	}
877	s := string(p.buf)
878	p.strList = append(p.strList, s)
879	return s
880}
881
882func (p *importer) marker(want byte) {
883	if got := p.rawByte(); got != want {
884		errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
885	}
886
887	pos := p.read
888	if n := int(p.rawInt64()); n != pos {
889		errorf("incorrect position: got %d; want %d", n, pos)
890	}
891}
892
893// rawInt64 should only be used by low-level decoders.
894func (p *importer) rawInt64() int64 {
895	i, err := binary.ReadVarint(p)
896	if err != nil {
897		errorf("read error: %v", err)
898	}
899	return i
900}
901
902// rawStringln should only be used to read the initial version string.
903func (p *importer) rawStringln(b byte) string {
904	p.buf = p.buf[:0]
905	for b != '\n' {
906		p.buf = append(p.buf, b)
907		b = p.rawByte()
908	}
909	return string(p.buf)
910}
911
912// needed for binary.ReadVarint in rawInt64
913func (p *importer) ReadByte() (byte, error) {
914	return p.rawByte(), nil
915}
916
917// byte is the bottleneck interface for reading p.data.
918// It unescapes '|' 'S' to '$' and '|' '|' to '|'.
919// rawByte should only be used by low-level decoders.
920func (p *importer) rawByte() byte {
921	b := p.data[0]
922	r := 1
923	if b == '|' {
924		b = p.data[1]
925		r = 2
926		switch b {
927		case 'S':
928			b = '$'
929		case '|':
930			// nothing to do
931		default:
932			errorf("unexpected escape sequence in export data")
933		}
934	}
935	p.data = p.data[r:]
936	p.read += r
937	return b
938
939}
940
941// ----------------------------------------------------------------------------
942// Export format
943
944// Tags. Must be < 0.
945const (
946	// Objects
947	packageTag = -(iota + 1)
948	constTag
949	typeTag
950	varTag
951	funcTag
952	endTag
953
954	// Types
955	namedTag
956	arrayTag
957	sliceTag
958	dddTag
959	structTag
960	pointerTag
961	signatureTag
962	interfaceTag
963	mapTag
964	chanTag
965
966	// Values
967	falseTag
968	trueTag
969	int64Tag
970	floatTag
971	fractionTag // not used by gc
972	complexTag
973	stringTag
974	nilTag     // only used by gc (appears in exported inlined function bodies)
975	unknownTag // not used by gc (only appears in packages with errors)
976
977	// Type aliases
978	aliasTag
979)
980
981var predeclOnce sync.Once
982var predecl []types.Type // initialized lazily
983
984func predeclared() []types.Type {
985	predeclOnce.Do(func() {
986		// initialize lazily to be sure that all
987		// elements have been initialized before
988		predecl = []types.Type{ // basic types
989			types.Typ[types.Bool],
990			types.Typ[types.Int],
991			types.Typ[types.Int8],
992			types.Typ[types.Int16],
993			types.Typ[types.Int32],
994			types.Typ[types.Int64],
995			types.Typ[types.Uint],
996			types.Typ[types.Uint8],
997			types.Typ[types.Uint16],
998			types.Typ[types.Uint32],
999			types.Typ[types.Uint64],
1000			types.Typ[types.Uintptr],
1001			types.Typ[types.Float32],
1002			types.Typ[types.Float64],
1003			types.Typ[types.Complex64],
1004			types.Typ[types.Complex128],
1005			types.Typ[types.String],
1006
1007			// basic type aliases
1008			types.Universe.Lookup("byte").Type(),
1009			types.Universe.Lookup("rune").Type(),
1010
1011			// error
1012			types.Universe.Lookup("error").Type(),
1013
1014			// untyped types
1015			types.Typ[types.UntypedBool],
1016			types.Typ[types.UntypedInt],
1017			types.Typ[types.UntypedRune],
1018			types.Typ[types.UntypedFloat],
1019			types.Typ[types.UntypedComplex],
1020			types.Typ[types.UntypedString],
1021			types.Typ[types.UntypedNil],
1022
1023			// package unsafe
1024			types.Typ[types.UnsafePointer],
1025
1026			// invalid type
1027			types.Typ[types.Invalid], // only appears in packages with errors
1028
1029			// used internally by gc; never used by this package or in .a files
1030			anyType{},
1031		}
1032	})
1033	return predecl
1034}
1035
1036type anyType struct{}
1037
1038func (t anyType) Underlying() types.Type { return t }
1039func (t anyType) String() string         { return "any" }
1040