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)
18
19type importer struct {
20	imports    map[string]*types.Package
21	data       []byte
22	importpath string
23	buf        []byte // for reading strings
24	version    int    // export format version
25
26	// object lists
27	strList       []string           // in order of appearance
28	pathList      []string           // in order of appearance
29	pkgList       []*types.Package   // in order of appearance
30	typList       []types.Type       // in order of appearance
31	interfaceList []*types.Interface // for delayed completion only
32	trackAllTypes bool
33
34	// position encoding
35	posInfoFormat bool
36	prevFile      string
37	prevLine      int
38	fake          fakeFileSet
39
40	// debugging support
41	debugFormat bool
42	read        int // bytes read
43}
44
45// BImportData imports a package from the serialized package data
46// and returns the number of bytes consumed and a reference to the package.
47// If the export data version is not recognized or the format is otherwise
48// compromised, an error is returned.
49func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
50	// catch panics and return them as errors
51	const currentVersion = 6
52	version := -1 // unknown version
53	defer func() {
54		if e := recover(); e != nil {
55			// Return a (possibly nil or incomplete) package unchanged (see #16088).
56			if version > currentVersion {
57				err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
58			} else {
59				err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
60			}
61		}
62	}()
63
64	p := importer{
65		imports:    imports,
66		data:       data,
67		importpath: path,
68		version:    version,
69		strList:    []string{""}, // empty string is mapped to 0
70		pathList:   []string{""}, // empty string is mapped to 0
71		fake: fakeFileSet{
72			fset:  fset,
73			files: make(map[string]*token.File),
74		},
75	}
76
77	// read version info
78	var versionstr string
79	if b := p.rawByte(); b == 'c' || b == 'd' {
80		// Go1.7 encoding; first byte encodes low-level
81		// encoding format (compact vs debug).
82		// For backward-compatibility only (avoid problems with
83		// old installed packages). Newly compiled packages use
84		// the extensible format string.
85		// TODO(gri) Remove this support eventually; after Go1.8.
86		if b == 'd' {
87			p.debugFormat = true
88		}
89		p.trackAllTypes = p.rawByte() == 'a'
90		p.posInfoFormat = p.int() != 0
91		versionstr = p.string()
92		if versionstr == "v1" {
93			version = 0
94		}
95	} else {
96		// Go1.8 extensible encoding
97		// read version string and extract version number (ignore anything after the version number)
98		versionstr = p.rawStringln(b)
99		if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" {
100			if v, err := strconv.Atoi(s[1]); err == nil && v > 0 {
101				version = v
102			}
103		}
104	}
105	p.version = version
106
107	// read version specific flags - extend as necessary
108	switch p.version {
109	// case currentVersion:
110	// 	...
111	//	fallthrough
112	case currentVersion, 5, 4, 3, 2, 1:
113		p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
114		p.trackAllTypes = p.int() != 0
115		p.posInfoFormat = p.int() != 0
116	case 0:
117		// Go1.7 encoding format - nothing to do here
118	default:
119		errorf("unknown bexport format version %d (%q)", p.version, versionstr)
120	}
121
122	// --- generic export data ---
123
124	// populate typList with predeclared "known" types
125	p.typList = append(p.typList, predeclared...)
126
127	// read package data
128	pkg = p.pkg()
129
130	// read objects of phase 1 only (see cmd/compile/internal/gc/bexport.go)
131	objcount := 0
132	for {
133		tag := p.tagOrIndex()
134		if tag == endTag {
135			break
136		}
137		p.obj(tag)
138		objcount++
139	}
140
141	// self-verification
142	if count := p.int(); count != objcount {
143		errorf("got %d objects; want %d", objcount, count)
144	}
145
146	// ignore compiler-specific import data
147
148	// complete interfaces
149	// TODO(gri) re-investigate if we still need to do this in a delayed fashion
150	for _, typ := range p.interfaceList {
151		typ.Complete()
152	}
153
154	// record all referenced packages as imports
155	list := append(([]*types.Package)(nil), p.pkgList[1:]...)
156	sort.Sort(byPath(list))
157	pkg.SetImports(list)
158
159	// package was imported completely and without errors
160	pkg.MarkComplete()
161
162	return p.read, pkg, nil
163}
164
165func errorf(format string, args ...interface{}) {
166	panic(fmt.Sprintf(format, args...))
167}
168
169func (p *importer) pkg() *types.Package {
170	// if the package was seen before, i is its index (>= 0)
171	i := p.tagOrIndex()
172	if i >= 0 {
173		return p.pkgList[i]
174	}
175
176	// otherwise, i is the package tag (< 0)
177	if i != packageTag {
178		errorf("unexpected package tag %d version %d", i, p.version)
179	}
180
181	// read package data
182	name := p.string()
183	var path string
184	if p.version >= 5 {
185		path = p.path()
186	} else {
187		path = p.string()
188	}
189	if p.version >= 6 {
190		p.int() // package height; unused by go/types
191	}
192
193	// we should never see an empty package name
194	if name == "" {
195		errorf("empty package name in import")
196	}
197
198	// an empty path denotes the package we are currently importing;
199	// it must be the first package we see
200	if (path == "") != (len(p.pkgList) == 0) {
201		errorf("package path %q for pkg index %d", path, len(p.pkgList))
202	}
203
204	// if the package was imported before, use that one; otherwise create a new one
205	if path == "" {
206		path = p.importpath
207	}
208	pkg := p.imports[path]
209	if pkg == nil {
210		pkg = types.NewPackage(path, name)
211		p.imports[path] = pkg
212	} else if pkg.Name() != name {
213		errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path)
214	}
215	p.pkgList = append(p.pkgList, pkg)
216
217	return pkg
218}
219
220// objTag returns the tag value for each object kind.
221func objTag(obj types.Object) int {
222	switch obj.(type) {
223	case *types.Const:
224		return constTag
225	case *types.TypeName:
226		return typeTag
227	case *types.Var:
228		return varTag
229	case *types.Func:
230		return funcTag
231	default:
232		errorf("unexpected object: %v (%T)", obj, obj) // panics
233		panic("unreachable")
234	}
235}
236
237func sameObj(a, b types.Object) bool {
238	// Because unnamed types are not canonicalized, we cannot simply compare types for
239	// (pointer) identity.
240	// Ideally we'd check equality of constant values as well, but this is good enough.
241	return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type())
242}
243
244func (p *importer) declare(obj types.Object) {
245	pkg := obj.Pkg()
246	if alt := pkg.Scope().Insert(obj); alt != nil {
247		// This can only trigger if we import a (non-type) object a second time.
248		// Excluding type aliases, this cannot happen because 1) we only import a package
249		// once; and b) we ignore compiler-specific export data which may contain
250		// functions whose inlined function bodies refer to other functions that
251		// were already imported.
252		// However, type aliases require reexporting the original type, so we need
253		// to allow it (see also the comment in cmd/compile/internal/gc/bimport.go,
254		// method importer.obj, switch case importing functions).
255		// TODO(gri) review/update this comment once the gc compiler handles type aliases.
256		if !sameObj(obj, alt) {
257			errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt)
258		}
259	}
260}
261
262func (p *importer) obj(tag int) {
263	switch tag {
264	case constTag:
265		pos := p.pos()
266		pkg, name := p.qualifiedName()
267		typ := p.typ(nil, nil)
268		val := p.value()
269		p.declare(types.NewConst(pos, pkg, name, typ, val))
270
271	case aliasTag:
272		// TODO(gri) verify type alias hookup is correct
273		pos := p.pos()
274		pkg, name := p.qualifiedName()
275		typ := p.typ(nil, nil)
276		p.declare(types.NewTypeName(pos, pkg, name, typ))
277
278	case typeTag:
279		p.typ(nil, nil)
280
281	case varTag:
282		pos := p.pos()
283		pkg, name := p.qualifiedName()
284		typ := p.typ(nil, nil)
285		p.declare(types.NewVar(pos, pkg, name, typ))
286
287	case funcTag:
288		pos := p.pos()
289		pkg, name := p.qualifiedName()
290		params, isddd := p.paramList()
291		result, _ := p.paramList()
292		sig := types.NewSignature(nil, params, result, isddd)
293		p.declare(types.NewFunc(pos, pkg, name, sig))
294
295	default:
296		errorf("unexpected object tag %d", tag)
297	}
298}
299
300const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
301
302func (p *importer) pos() token.Pos {
303	if !p.posInfoFormat {
304		return token.NoPos
305	}
306
307	file := p.prevFile
308	line := p.prevLine
309	delta := p.int()
310	line += delta
311	if p.version >= 5 {
312		if delta == deltaNewFile {
313			if n := p.int(); n >= 0 {
314				// file changed
315				file = p.path()
316				line = n
317			}
318		}
319	} else {
320		if delta == 0 {
321			if n := p.int(); n >= 0 {
322				// file changed
323				file = p.prevFile[:n] + p.string()
324				line = p.int()
325			}
326		}
327	}
328	p.prevFile = file
329	p.prevLine = line
330
331	return p.fake.pos(file, line, 0)
332}
333
334// Synthesize a token.Pos
335type fakeFileSet struct {
336	fset  *token.FileSet
337	files map[string]*token.File
338}
339
340func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
341	// TODO(mdempsky): Make use of column.
342
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 !token.IsExported(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 !token.IsExported(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 (p *importer) value() constant.Value {
734	switch tag := p.tagOrIndex(); tag {
735	case falseTag:
736		return constant.MakeBool(false)
737	case trueTag:
738		return constant.MakeBool(true)
739	case int64Tag:
740		return constant.MakeInt64(p.int64())
741	case floatTag:
742		return p.float()
743	case complexTag:
744		re := p.float()
745		im := p.float()
746		return constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
747	case stringTag:
748		return constant.MakeString(p.string())
749	case unknownTag:
750		return constant.MakeUnknown()
751	default:
752		errorf("unexpected value tag %d", tag) // panics
753		panic("unreachable")
754	}
755}
756
757func (p *importer) float() constant.Value {
758	sign := p.int()
759	if sign == 0 {
760		return constant.MakeInt64(0)
761	}
762
763	exp := p.int()
764	mant := []byte(p.string()) // big endian
765
766	// remove leading 0's if any
767	for len(mant) > 0 && mant[0] == 0 {
768		mant = mant[1:]
769	}
770
771	// convert to little endian
772	// TODO(gri) go/constant should have a more direct conversion function
773	//           (e.g., once it supports a big.Float based implementation)
774	for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 {
775		mant[i], mant[j] = mant[j], mant[i]
776	}
777
778	// adjust exponent (constant.MakeFromBytes creates an integer value,
779	// but mant represents the mantissa bits such that 0.5 <= mant < 1.0)
780	exp -= len(mant) << 3
781	if len(mant) > 0 {
782		for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 {
783			exp++
784		}
785	}
786
787	x := constant.MakeFromBytes(mant)
788	switch {
789	case exp < 0:
790		d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
791		x = constant.BinaryOp(x, token.QUO, d)
792	case exp > 0:
793		x = constant.Shift(x, token.SHL, uint(exp))
794	}
795
796	if sign < 0 {
797		x = constant.UnaryOp(token.SUB, x, 0)
798	}
799	return x
800}
801
802// ----------------------------------------------------------------------------
803// Low-level decoders
804
805func (p *importer) tagOrIndex() int {
806	if p.debugFormat {
807		p.marker('t')
808	}
809
810	return int(p.rawInt64())
811}
812
813func (p *importer) int() int {
814	x := p.int64()
815	if int64(int(x)) != x {
816		errorf("exported integer too large")
817	}
818	return int(x)
819}
820
821func (p *importer) int64() int64 {
822	if p.debugFormat {
823		p.marker('i')
824	}
825
826	return p.rawInt64()
827}
828
829func (p *importer) path() string {
830	if p.debugFormat {
831		p.marker('p')
832	}
833	// if the path was seen before, i is its index (>= 0)
834	// (the empty string is at index 0)
835	i := p.rawInt64()
836	if i >= 0 {
837		return p.pathList[i]
838	}
839	// otherwise, i is the negative path length (< 0)
840	a := make([]string, -i)
841	for n := range a {
842		a[n] = p.string()
843	}
844	s := strings.Join(a, "/")
845	p.pathList = append(p.pathList, s)
846	return s
847}
848
849func (p *importer) string() string {
850	if p.debugFormat {
851		p.marker('s')
852	}
853	// if the string was seen before, i is its index (>= 0)
854	// (the empty string is at index 0)
855	i := p.rawInt64()
856	if i >= 0 {
857		return p.strList[i]
858	}
859	// otherwise, i is the negative string length (< 0)
860	if n := int(-i); n <= cap(p.buf) {
861		p.buf = p.buf[:n]
862	} else {
863		p.buf = make([]byte, n)
864	}
865	for i := range p.buf {
866		p.buf[i] = p.rawByte()
867	}
868	s := string(p.buf)
869	p.strList = append(p.strList, s)
870	return s
871}
872
873func (p *importer) marker(want byte) {
874	if got := p.rawByte(); got != want {
875		errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
876	}
877
878	pos := p.read
879	if n := int(p.rawInt64()); n != pos {
880		errorf("incorrect position: got %d; want %d", n, pos)
881	}
882}
883
884// rawInt64 should only be used by low-level decoders.
885func (p *importer) rawInt64() int64 {
886	i, err := binary.ReadVarint(p)
887	if err != nil {
888		errorf("read error: %v", err)
889	}
890	return i
891}
892
893// rawStringln should only be used to read the initial version string.
894func (p *importer) rawStringln(b byte) string {
895	p.buf = p.buf[:0]
896	for b != '\n' {
897		p.buf = append(p.buf, b)
898		b = p.rawByte()
899	}
900	return string(p.buf)
901}
902
903// needed for binary.ReadVarint in rawInt64
904func (p *importer) ReadByte() (byte, error) {
905	return p.rawByte(), nil
906}
907
908// byte is the bottleneck interface for reading p.data.
909// It unescapes '|' 'S' to '$' and '|' '|' to '|'.
910// rawByte should only be used by low-level decoders.
911func (p *importer) rawByte() byte {
912	b := p.data[0]
913	r := 1
914	if b == '|' {
915		b = p.data[1]
916		r = 2
917		switch b {
918		case 'S':
919			b = '$'
920		case '|':
921			// nothing to do
922		default:
923			errorf("unexpected escape sequence in export data")
924		}
925	}
926	p.data = p.data[r:]
927	p.read += r
928	return b
929
930}
931
932// ----------------------------------------------------------------------------
933// Export format
934
935// Tags. Must be < 0.
936const (
937	// Objects
938	packageTag = -(iota + 1)
939	constTag
940	typeTag
941	varTag
942	funcTag
943	endTag
944
945	// Types
946	namedTag
947	arrayTag
948	sliceTag
949	dddTag
950	structTag
951	pointerTag
952	signatureTag
953	interfaceTag
954	mapTag
955	chanTag
956
957	// Values
958	falseTag
959	trueTag
960	int64Tag
961	floatTag
962	fractionTag // not used by gc
963	complexTag
964	stringTag
965	nilTag     // only used by gc (appears in exported inlined function bodies)
966	unknownTag // not used by gc (only appears in packages with errors)
967
968	// Type aliases
969	aliasTag
970)
971
972var predeclared = []types.Type{
973	// basic types
974	types.Typ[types.Bool],
975	types.Typ[types.Int],
976	types.Typ[types.Int8],
977	types.Typ[types.Int16],
978	types.Typ[types.Int32],
979	types.Typ[types.Int64],
980	types.Typ[types.Uint],
981	types.Typ[types.Uint8],
982	types.Typ[types.Uint16],
983	types.Typ[types.Uint32],
984	types.Typ[types.Uint64],
985	types.Typ[types.Uintptr],
986	types.Typ[types.Float32],
987	types.Typ[types.Float64],
988	types.Typ[types.Complex64],
989	types.Typ[types.Complex128],
990	types.Typ[types.String],
991
992	// basic type aliases
993	types.Universe.Lookup("byte").Type(),
994	types.Universe.Lookup("rune").Type(),
995
996	// error
997	types.Universe.Lookup("error").Type(),
998
999	// untyped types
1000	types.Typ[types.UntypedBool],
1001	types.Typ[types.UntypedInt],
1002	types.Typ[types.UntypedRune],
1003	types.Typ[types.UntypedFloat],
1004	types.Typ[types.UntypedComplex],
1005	types.Typ[types.UntypedString],
1006	types.Typ[types.UntypedNil],
1007
1008	// package unsafe
1009	types.Typ[types.UnsafePointer],
1010
1011	// invalid type
1012	types.Typ[types.Invalid], // only appears in packages with errors
1013
1014	// used internally by gc; never used by this package or in .a files
1015	anyType{},
1016}
1017
1018type anyType struct{}
1019
1020func (t anyType) Underlying() types.Type { return t }
1021func (t anyType) String() string         { return "any" }
1022