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