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