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