github.com/euank/go@v0.0.0-20160829210321-495514729181/src/go/internal/gcimporter/bimport.go (about)

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