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