github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/src/cmd/compile/internal/gc/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  // Binary package import.
     6  // See bexport.go for the export data format and how
     7  // to make a format change.
     8  
     9  package gc
    10  
    11  import (
    12  	"bufio"
    13  	"encoding/binary"
    14  	"fmt"
    15  	"math/big"
    16  	"strconv"
    17  	"strings"
    18  )
    19  
    20  // The overall structure of Import is symmetric to Export: For each
    21  // export method in bexport.go there is a matching and symmetric method
    22  // in bimport.go. Changing the export format requires making symmetric
    23  // changes to bimport.go and bexport.go.
    24  
    25  type importer struct {
    26  	in      *bufio.Reader
    27  	buf     []byte // reused for reading strings
    28  	version int    // export format version
    29  
    30  	// object lists, in order of deserialization
    31  	strList       []string
    32  	pkgList       []*Pkg
    33  	typList       []*Type
    34  	funcList      []*Node // nil entry means already declared
    35  	trackAllTypes bool
    36  
    37  	// for delayed type verification
    38  	cmpList []struct{ pt, t *Type }
    39  
    40  	// position encoding
    41  	posInfoFormat bool
    42  	prevFile      string
    43  	prevLine      int
    44  
    45  	// debugging support
    46  	debugFormat bool
    47  	read        int // bytes read
    48  }
    49  
    50  // Import populates importpkg from the serialized package data.
    51  func Import(in *bufio.Reader) {
    52  	p := importer{
    53  		in:      in,
    54  		version: -1,           // unknown version
    55  		strList: []string{""}, // empty string is mapped to 0
    56  	}
    57  
    58  	// read version info
    59  	var versionstr string
    60  	if b := p.rawByte(); b == 'c' || b == 'd' {
    61  		// Go1.7 encoding; first byte encodes low-level
    62  		// encoding format (compact vs debug).
    63  		// For backward-compatibility only (avoid problems with
    64  		// old installed packages). Newly compiled packages use
    65  		// the extensible format string.
    66  		// TODO(gri) Remove this support eventually; after Go1.8.
    67  		if b == 'd' {
    68  			p.debugFormat = true
    69  		}
    70  		p.trackAllTypes = p.rawByte() == 'a'
    71  		p.posInfoFormat = p.bool()
    72  		versionstr = p.string()
    73  		if versionstr == "v1" {
    74  			p.version = 0
    75  		}
    76  	} else {
    77  		// Go1.8 extensible encoding
    78  		// read version string and extract version number (ignore anything after the version number)
    79  		versionstr = p.rawStringln(b)
    80  		if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" {
    81  			if v, err := strconv.Atoi(s[1]); err == nil && v > 0 {
    82  				p.version = v
    83  			}
    84  		}
    85  	}
    86  
    87  	// read version specific flags - extend as necessary
    88  	switch p.version {
    89  	// case 5:
    90  	// 	...
    91  	//	fallthrough
    92  	case 4, 3, 2, 1:
    93  		p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
    94  		p.trackAllTypes = p.bool()
    95  		p.posInfoFormat = p.bool()
    96  	case 0:
    97  		// Go1.7 encoding format - nothing to do here
    98  	default:
    99  		formatErrorf("unknown export format version %d (%q)", p.version, versionstr)
   100  	}
   101  
   102  	// --- generic export data ---
   103  
   104  	// populate typList with predeclared "known" types
   105  	p.typList = append(p.typList, predeclared()...)
   106  
   107  	// read package data
   108  	p.pkg()
   109  
   110  	// defer some type-checking until all types are read in completely
   111  	tcok := typecheckok
   112  	typecheckok = true
   113  	defercheckwidth()
   114  
   115  	// read objects
   116  
   117  	// phase 1
   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  		formatErrorf("got %d objects; want %d", objcount, count)
   131  	}
   132  
   133  	// --- compiler-specific export data ---
   134  
   135  	// read compiler-specific flags
   136  
   137  	// phase 2
   138  	objcount = 0
   139  	for {
   140  		tag := p.tagOrIndex()
   141  		if tag == endTag {
   142  			break
   143  		}
   144  		p.obj(tag)
   145  		objcount++
   146  	}
   147  
   148  	// self-verification
   149  	if count := p.int(); count != objcount {
   150  		formatErrorf("got %d objects; want %d", objcount, count)
   151  	}
   152  
   153  	// read inlineable functions bodies
   154  	if dclcontext != PEXTERN {
   155  		formatErrorf("unexpected context %d", dclcontext)
   156  	}
   157  
   158  	objcount = 0
   159  	for i0 := -1; ; {
   160  		i := p.int() // index of function with inlineable body
   161  		if i < 0 {
   162  			break
   163  		}
   164  
   165  		// don't process the same function twice
   166  		if i <= i0 {
   167  			formatErrorf("index not increasing: %d <= %d", i, i0)
   168  		}
   169  		i0 = i
   170  
   171  		if funcdepth != 0 {
   172  			formatErrorf("unexpected Funcdepth %d", funcdepth)
   173  		}
   174  
   175  		// Note: In the original code, funchdr and funcbody are called for
   176  		// all functions (that were not yet imported). Now, we are calling
   177  		// them only for functions with inlineable bodies. funchdr does
   178  		// parameter renaming which doesn't matter if we don't have a body.
   179  
   180  		if f := p.funcList[i]; f != nil {
   181  			// function not yet imported - read body and set it
   182  			funchdr(f)
   183  			body := p.stmtList()
   184  			if body == nil {
   185  				// Make sure empty body is not interpreted as
   186  				// no inlineable body (see also parser.fnbody)
   187  				// (not doing so can cause significant performance
   188  				// degradation due to unnecessary calls to empty
   189  				// functions).
   190  				body = []*Node{nod(OEMPTY, nil, nil)}
   191  			}
   192  			f.Func.Inl.Set(body)
   193  			funcbody(f)
   194  		} else {
   195  			// function already imported - read body but discard declarations
   196  			dclcontext = PDISCARD // throw away any declarations
   197  			p.stmtList()
   198  			dclcontext = PEXTERN
   199  		}
   200  
   201  		objcount++
   202  	}
   203  
   204  	// self-verification
   205  	if count := p.int(); count != objcount {
   206  		formatErrorf("got %d functions; want %d", objcount, count)
   207  	}
   208  
   209  	if dclcontext != PEXTERN {
   210  		formatErrorf("unexpected context %d", dclcontext)
   211  	}
   212  
   213  	p.verifyTypes()
   214  
   215  	// --- end of export data ---
   216  
   217  	typecheckok = tcok
   218  	resumecheckwidth()
   219  
   220  	if debug_dclstack != 0 {
   221  		testdclstack()
   222  	}
   223  }
   224  
   225  func formatErrorf(format string, args ...interface{}) {
   226  	if debugFormat {
   227  		Fatalf(format, args...)
   228  	}
   229  
   230  	yyerror("cannot import %q due to version skew - reinstall package (%s)",
   231  		importpkg.Path, fmt.Sprintf(format, args...))
   232  	errorexit()
   233  }
   234  
   235  func (p *importer) verifyTypes() {
   236  	for _, pair := range p.cmpList {
   237  		pt := pair.pt
   238  		t := pair.t
   239  		if !eqtype(pt.Orig, t) {
   240  			formatErrorf("inconsistent definition for type %v during import\n\t%L (in %q)\n\t%L (in %q)", pt.Sym, pt, pt.Sym.Importdef.Path, t, importpkg.Path)
   241  		}
   242  	}
   243  }
   244  
   245  // numImport tracks how often a package with a given name is imported.
   246  // It is used to provide a better error message (by using the package
   247  // path to disambiguate) if a package that appears multiple times with
   248  // the same name appears in an error message.
   249  var numImport = make(map[string]int)
   250  
   251  func (p *importer) pkg() *Pkg {
   252  	// if the package was seen before, i is its index (>= 0)
   253  	i := p.tagOrIndex()
   254  	if i >= 0 {
   255  		return p.pkgList[i]
   256  	}
   257  
   258  	// otherwise, i is the package tag (< 0)
   259  	if i != packageTag {
   260  		formatErrorf("expected package tag, found tag = %d", i)
   261  	}
   262  
   263  	// read package data
   264  	name := p.string()
   265  	path := p.string()
   266  
   267  	// we should never see an empty package name
   268  	if name == "" {
   269  		formatErrorf("empty package name for path %q", path)
   270  	}
   271  
   272  	// we should never see a bad import path
   273  	if isbadimport(path) {
   274  		formatErrorf("bad package path %q for package %s", path, name)
   275  	}
   276  
   277  	// an empty path denotes the package we are currently importing;
   278  	// it must be the first package we see
   279  	if (path == "") != (len(p.pkgList) == 0) {
   280  		formatErrorf("package path %q for pkg index %d", path, len(p.pkgList))
   281  	}
   282  
   283  	// add package to pkgList
   284  	pkg := importpkg
   285  	if path != "" {
   286  		pkg = mkpkg(path)
   287  	}
   288  	if pkg.Name == "" {
   289  		pkg.Name = name
   290  		numImport[name]++
   291  	} else if pkg.Name != name {
   292  		yyerror("conflicting package names %s and %s for path %q", pkg.Name, name, path)
   293  	}
   294  	if myimportpath != "" && path == myimportpath {
   295  		yyerror("import %q: package depends on %q (import cycle)", importpkg.Path, path)
   296  		errorexit()
   297  	}
   298  	p.pkgList = append(p.pkgList, pkg)
   299  
   300  	return pkg
   301  }
   302  
   303  func idealType(typ *Type) *Type {
   304  	if typ.IsUntyped() {
   305  		// canonicalize ideal types
   306  		typ = Types[TIDEAL]
   307  	}
   308  	return typ
   309  }
   310  
   311  func (p *importer) obj(tag int) {
   312  	switch tag {
   313  	case constTag:
   314  		p.pos()
   315  		sym := p.qualifiedName()
   316  		typ := p.typ()
   317  		val := p.value(typ)
   318  		importconst(sym, idealType(typ), nodlit(val))
   319  
   320  	case aliasTag:
   321  		p.pos()
   322  		sym := p.qualifiedName()
   323  		typ := p.typ()
   324  		importalias(sym, typ)
   325  
   326  	case typeTag:
   327  		p.typ()
   328  
   329  	case varTag:
   330  		p.pos()
   331  		sym := p.qualifiedName()
   332  		typ := p.typ()
   333  		importvar(sym, typ)
   334  
   335  	case funcTag:
   336  		p.pos()
   337  		sym := p.qualifiedName()
   338  		params := p.paramList()
   339  		result := p.paramList()
   340  
   341  		sig := functypefield(nil, params, result)
   342  		importsym(sym, ONAME)
   343  		if sym.Def != nil && sym.Def.Op == ONAME {
   344  			// function was imported before (via another import)
   345  			if !eqtype(sig, sym.Def.Type) {
   346  				formatErrorf("inconsistent definition for func %v during import\n\t%v\n\t%v", sym, sym.Def.Type, sig)
   347  			}
   348  			p.funcList = append(p.funcList, nil)
   349  			break
   350  		}
   351  
   352  		n := newfuncname(sym)
   353  		n.Type = sig
   354  		declare(n, PFUNC)
   355  		p.funcList = append(p.funcList, n)
   356  		importlist = append(importlist, n)
   357  
   358  		if Debug['E'] > 0 {
   359  			fmt.Printf("import [%q] func %v \n", importpkg.Path, n)
   360  			if Debug['m'] > 2 && n.Func.Inl.Len() != 0 {
   361  				fmt.Printf("inl body: %v\n", n.Func.Inl)
   362  			}
   363  		}
   364  
   365  	default:
   366  		formatErrorf("unexpected object (tag = %d)", tag)
   367  	}
   368  }
   369  
   370  func (p *importer) pos() {
   371  	if !p.posInfoFormat {
   372  		return
   373  	}
   374  
   375  	file := p.prevFile
   376  	line := p.prevLine
   377  	if delta := p.int(); delta != 0 {
   378  		// line changed
   379  		line += delta
   380  	} else if n := p.int(); n >= 0 {
   381  		// file changed
   382  		file = p.prevFile[:n] + p.string()
   383  		p.prevFile = file
   384  		line = p.int()
   385  	}
   386  	p.prevLine = line
   387  
   388  	// TODO(gri) register new position
   389  }
   390  
   391  func (p *importer) newtyp(etype EType) *Type {
   392  	t := typ(etype)
   393  	if p.trackAllTypes {
   394  		p.typList = append(p.typList, t)
   395  	}
   396  	return t
   397  }
   398  
   399  // importtype declares that pt, an imported named type, has underlying type t.
   400  func (p *importer) importtype(pt, t *Type) {
   401  	if pt.Etype == TFORW {
   402  		n := pt.nod
   403  		copytype(pt.nod, t)
   404  		pt.nod = n // unzero nod
   405  		pt.Sym.Importdef = importpkg
   406  		pt.Sym.Lastlineno = lineno
   407  		declare(n, PEXTERN)
   408  		checkwidth(pt)
   409  	} else {
   410  		// pt.Orig and t must be identical.
   411  		if p.trackAllTypes {
   412  			// If we track all types, t may not be fully set up yet.
   413  			// Collect the types and verify identity later.
   414  			p.cmpList = append(p.cmpList, struct{ pt, t *Type }{pt, t})
   415  		} else if !eqtype(pt.Orig, t) {
   416  			yyerror("inconsistent definition for type %v during import\n\t%L (in %q)\n\t%L (in %q)", pt.Sym, pt, pt.Sym.Importdef.Path, t, importpkg.Path)
   417  		}
   418  	}
   419  
   420  	if Debug['E'] != 0 {
   421  		fmt.Printf("import type %v %L\n", pt, t)
   422  	}
   423  }
   424  
   425  func (p *importer) typ() *Type {
   426  	// if the type was seen before, i is its index (>= 0)
   427  	i := p.tagOrIndex()
   428  	if i >= 0 {
   429  		return p.typList[i]
   430  	}
   431  
   432  	// otherwise, i is the type tag (< 0)
   433  	var t *Type
   434  	switch i {
   435  	case namedTag:
   436  		p.pos()
   437  		tsym := p.qualifiedName()
   438  
   439  		t = pkgtype(tsym)
   440  		p.typList = append(p.typList, t)
   441  
   442  		// read underlying type
   443  		t0 := p.typ()
   444  		p.importtype(t, t0)
   445  
   446  		// interfaces don't have associated methods
   447  		if t0.IsInterface() {
   448  			break
   449  		}
   450  
   451  		// set correct import context (since p.typ() may be called
   452  		// while importing the body of an inlined function)
   453  		savedContext := dclcontext
   454  		dclcontext = PEXTERN
   455  
   456  		// read associated methods
   457  		for i := p.int(); i > 0; i-- {
   458  			p.pos()
   459  			sym := p.fieldSym()
   460  
   461  			// during import unexported method names should be in the type's package
   462  			if !exportname(sym.Name) && sym.Pkg != tsym.Pkg {
   463  				Fatalf("imported method name %+v in wrong package %s\n", sym, tsym.Pkg.Name)
   464  			}
   465  
   466  			recv := p.paramList() // TODO(gri) do we need a full param list for the receiver?
   467  			params := p.paramList()
   468  			result := p.paramList()
   469  			nointerface := p.bool()
   470  
   471  			n := newfuncname(methodname(sym, recv[0].Type))
   472  			n.Type = functypefield(recv[0], params, result)
   473  			checkwidth(n.Type)
   474  			addmethod(sym, n.Type, false, nointerface)
   475  			p.funcList = append(p.funcList, n)
   476  			importlist = append(importlist, n)
   477  
   478  			// (comment from parser.go)
   479  			// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
   480  			// (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled
   481  			// out by typecheck's lookdot as this $$.ttype. So by providing
   482  			// this back link here we avoid special casing there.
   483  			n.Type.SetNname(n)
   484  
   485  			if Debug['E'] > 0 {
   486  				fmt.Printf("import [%q] meth %v \n", importpkg.Path, n)
   487  				if Debug['m'] > 2 && n.Func.Inl.Len() != 0 {
   488  					fmt.Printf("inl body: %v\n", n.Func.Inl)
   489  				}
   490  			}
   491  		}
   492  
   493  		dclcontext = savedContext
   494  
   495  	case arrayTag:
   496  		t = p.newtyp(TARRAY)
   497  		bound := p.int64()
   498  		elem := p.typ()
   499  		t.Extra = &ArrayType{Elem: elem, Bound: bound}
   500  
   501  	case sliceTag:
   502  		t = p.newtyp(TSLICE)
   503  		elem := p.typ()
   504  		t.Extra = SliceType{Elem: elem}
   505  
   506  	case dddTag:
   507  		t = p.newtyp(TDDDFIELD)
   508  		t.Extra = DDDFieldType{T: p.typ()}
   509  
   510  	case structTag:
   511  		t = p.newtyp(TSTRUCT)
   512  		t.SetFields(p.fieldList())
   513  		checkwidth(t)
   514  
   515  	case pointerTag:
   516  		t = p.newtyp(Tptr)
   517  		t.Extra = PtrType{Elem: p.typ()}
   518  
   519  	case signatureTag:
   520  		t = p.newtyp(TFUNC)
   521  		params := p.paramList()
   522  		result := p.paramList()
   523  		functypefield0(t, nil, params, result)
   524  
   525  	case interfaceTag:
   526  		t = p.newtyp(TINTER)
   527  		if p.int() != 0 {
   528  			formatErrorf("unexpected embedded interface")
   529  		}
   530  		t.SetFields(p.methodList())
   531  		checkwidth(t)
   532  
   533  	case mapTag:
   534  		t = p.newtyp(TMAP)
   535  		mt := t.MapType()
   536  		mt.Key = p.typ()
   537  		mt.Val = p.typ()
   538  
   539  	case chanTag:
   540  		t = p.newtyp(TCHAN)
   541  		ct := t.ChanType()
   542  		ct.Dir = ChanDir(p.int())
   543  		ct.Elem = p.typ()
   544  
   545  	default:
   546  		formatErrorf("unexpected type (tag = %d)", i)
   547  	}
   548  
   549  	if t == nil {
   550  		formatErrorf("nil type (type tag = %d)", i)
   551  	}
   552  
   553  	return t
   554  }
   555  
   556  func (p *importer) qualifiedName() *Sym {
   557  	name := p.string()
   558  	pkg := p.pkg()
   559  	return pkg.Lookup(name)
   560  }
   561  
   562  func (p *importer) fieldList() (fields []*Field) {
   563  	if n := p.int(); n > 0 {
   564  		fields = make([]*Field, n)
   565  		for i := range fields {
   566  			fields[i] = p.field()
   567  		}
   568  	}
   569  	return
   570  }
   571  
   572  func (p *importer) field() *Field {
   573  	p.pos()
   574  	sym, alias := p.fieldName()
   575  	typ := p.typ()
   576  	note := p.string()
   577  
   578  	f := newField()
   579  	if sym.Name == "" {
   580  		// anonymous field: typ must be T or *T and T must be a type name
   581  		s := typ.Sym
   582  		if s == nil && typ.IsPtr() {
   583  			s = typ.Elem().Sym // deref
   584  		}
   585  		sym = sym.Pkg.Lookup(s.Name)
   586  		f.Embedded = 1
   587  	} else if alias {
   588  		// anonymous field: we have an explicit name because it's a type alias
   589  		f.Embedded = 1
   590  	}
   591  
   592  	f.Sym = sym
   593  	f.Nname = newname(sym)
   594  	f.Type = typ
   595  	f.Note = note
   596  
   597  	return f
   598  }
   599  
   600  func (p *importer) methodList() (methods []*Field) {
   601  	if n := p.int(); n > 0 {
   602  		methods = make([]*Field, n)
   603  		for i := range methods {
   604  			methods[i] = p.method()
   605  		}
   606  	}
   607  	return
   608  }
   609  
   610  func (p *importer) method() *Field {
   611  	p.pos()
   612  	sym := p.methodName()
   613  	params := p.paramList()
   614  	result := p.paramList()
   615  
   616  	f := newField()
   617  	f.Sym = sym
   618  	f.Nname = newname(sym)
   619  	f.Type = functypefield(fakethisfield(), params, result)
   620  	return f
   621  }
   622  
   623  func (p *importer) fieldName() (*Sym, bool) {
   624  	name := p.string()
   625  	if p.version == 0 && name == "_" {
   626  		// version 0 didn't export a package for _ field names
   627  		// but used the builtin package instead
   628  		return builtinpkg.Lookup(name), false
   629  	}
   630  	pkg := localpkg
   631  	alias := false
   632  	switch name {
   633  	case "":
   634  		// 1) field name matches base type name and is exported: nothing to do
   635  	case "?":
   636  		// 2) field name matches base type name and is not exported: need package
   637  		name = ""
   638  		pkg = p.pkg()
   639  	case "@":
   640  		// 3) field name doesn't match base type name (alias name): need name and possibly package
   641  		name = p.string()
   642  		alias = true
   643  		fallthrough
   644  	default:
   645  		if !exportname(name) {
   646  			pkg = p.pkg()
   647  		}
   648  	}
   649  	return pkg.Lookup(name), alias
   650  }
   651  
   652  func (p *importer) methodName() *Sym {
   653  	name := p.string()
   654  	if p.version == 0 && name == "_" {
   655  		// version 0 didn't export a package for _ method names
   656  		// but used the builtin package instead
   657  		return builtinpkg.Lookup(name)
   658  	}
   659  	pkg := localpkg
   660  	if !exportname(name) {
   661  		pkg = p.pkg()
   662  	}
   663  	return pkg.Lookup(name)
   664  }
   665  
   666  func (p *importer) paramList() []*Field {
   667  	i := p.int()
   668  	if i == 0 {
   669  		return nil
   670  	}
   671  	// negative length indicates unnamed parameters
   672  	named := true
   673  	if i < 0 {
   674  		i = -i
   675  		named = false
   676  	}
   677  	// i > 0
   678  	fs := make([]*Field, i)
   679  	for i := range fs {
   680  		fs[i] = p.param(named)
   681  	}
   682  	return fs
   683  }
   684  
   685  func (p *importer) param(named bool) *Field {
   686  	f := newField()
   687  	f.Type = p.typ()
   688  	if f.Type.Etype == TDDDFIELD {
   689  		// TDDDFIELD indicates wrapped ... slice type
   690  		f.Type = typSlice(f.Type.DDDField())
   691  		f.Isddd = true
   692  	}
   693  
   694  	if named {
   695  		name := p.string()
   696  		if name == "" {
   697  			formatErrorf("expected named parameter")
   698  		}
   699  		// TODO(gri) Supply function/method package rather than
   700  		// encoding the package for each parameter repeatedly.
   701  		pkg := localpkg
   702  		if name != "_" {
   703  			pkg = p.pkg()
   704  		}
   705  		f.Sym = pkg.Lookup(name)
   706  		f.Nname = newname(f.Sym)
   707  	}
   708  
   709  	// TODO(gri) This is compiler-specific (escape info).
   710  	// Move into compiler-specific section eventually?
   711  	f.Note = p.string()
   712  
   713  	return f
   714  }
   715  
   716  func (p *importer) value(typ *Type) (x Val) {
   717  	switch tag := p.tagOrIndex(); tag {
   718  	case falseTag:
   719  		x.U = false
   720  
   721  	case trueTag:
   722  		x.U = true
   723  
   724  	case int64Tag:
   725  		u := new(Mpint)
   726  		u.SetInt64(p.int64())
   727  		u.Rune = typ == idealrune
   728  		x.U = u
   729  
   730  	case floatTag:
   731  		f := newMpflt()
   732  		p.float(f)
   733  		if typ == idealint || typ.IsInteger() {
   734  			// uncommon case: large int encoded as float
   735  			u := new(Mpint)
   736  			u.SetFloat(f)
   737  			x.U = u
   738  			break
   739  		}
   740  		x.U = f
   741  
   742  	case complexTag:
   743  		u := new(Mpcplx)
   744  		p.float(&u.Real)
   745  		p.float(&u.Imag)
   746  		x.U = u
   747  
   748  	case stringTag:
   749  		x.U = p.string()
   750  
   751  	case unknownTag:
   752  		formatErrorf("unknown constant (importing package with errors)")
   753  
   754  	case nilTag:
   755  		x.U = new(NilVal)
   756  
   757  	default:
   758  		formatErrorf("unexpected value tag %d", tag)
   759  	}
   760  
   761  	// verify ideal type
   762  	if typ.IsUntyped() && untype(x.Ctype()) != typ {
   763  		formatErrorf("value %v and type %v don't match", x, typ)
   764  	}
   765  
   766  	return
   767  }
   768  
   769  func (p *importer) float(x *Mpflt) {
   770  	sign := p.int()
   771  	if sign == 0 {
   772  		x.SetFloat64(0)
   773  		return
   774  	}
   775  
   776  	exp := p.int()
   777  	mant := new(big.Int).SetBytes([]byte(p.string()))
   778  
   779  	m := x.Val.SetInt(mant)
   780  	m.SetMantExp(m, exp-mant.BitLen())
   781  	if sign < 0 {
   782  		m.Neg(m)
   783  	}
   784  }
   785  
   786  // ----------------------------------------------------------------------------
   787  // Inlined function bodies
   788  
   789  // Approach: Read nodes and use them to create/declare the same data structures
   790  // as done originally by the (hidden) parser by closely following the parser's
   791  // original code. In other words, "parsing" the import data (which happens to
   792  // be encoded in binary rather textual form) is the best way at the moment to
   793  // re-establish the syntax tree's invariants. At some future point we might be
   794  // able to avoid this round-about way and create the rewritten nodes directly,
   795  // possibly avoiding a lot of duplicate work (name resolution, type checking).
   796  //
   797  // Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their
   798  // unrefined nodes (since this is what the importer uses). The respective case
   799  // entries are unreachable in the importer.
   800  
   801  func (p *importer) stmtList() []*Node {
   802  	var list []*Node
   803  	for {
   804  		n := p.node()
   805  		if n == nil {
   806  			break
   807  		}
   808  		// OBLOCK nodes may be created when importing ODCL nodes - unpack them
   809  		if n.Op == OBLOCK {
   810  			list = append(list, n.List.Slice()...)
   811  		} else {
   812  			list = append(list, n)
   813  		}
   814  	}
   815  	return list
   816  }
   817  
   818  func (p *importer) exprList() []*Node {
   819  	var list []*Node
   820  	for {
   821  		n := p.expr()
   822  		if n == nil {
   823  			break
   824  		}
   825  		list = append(list, n)
   826  	}
   827  	return list
   828  }
   829  
   830  func (p *importer) elemList() []*Node {
   831  	c := p.int()
   832  	list := make([]*Node, c)
   833  	for i := range list {
   834  		s := p.fieldSym()
   835  		list[i] = nodSym(OSTRUCTKEY, p.expr(), s)
   836  	}
   837  	return list
   838  }
   839  
   840  func (p *importer) expr() *Node {
   841  	n := p.node()
   842  	if n != nil && n.Op == OBLOCK {
   843  		Fatalf("unexpected block node: %v", n)
   844  	}
   845  	return n
   846  }
   847  
   848  // TODO(gri) split into expr and stmt
   849  func (p *importer) node() *Node {
   850  	switch op := p.op(); op {
   851  	// expressions
   852  	// case OPAREN:
   853  	// 	unreachable - unpacked by exporter
   854  
   855  	// case ODDDARG:
   856  	//	unimplemented
   857  
   858  	case OLITERAL:
   859  		typ := p.typ()
   860  		n := nodlit(p.value(typ))
   861  		if !typ.IsUntyped() {
   862  			// Type-checking simplifies unsafe.Pointer(uintptr(c))
   863  			// to unsafe.Pointer(c) which then cannot type-checked
   864  			// again. Re-introduce explicit uintptr(c) conversion.
   865  			// (issue 16317).
   866  			if typ.IsUnsafePtr() {
   867  				conv := nod(OCALL, typenod(Types[TUINTPTR]), nil)
   868  				conv.List.Set1(n)
   869  				n = conv
   870  			}
   871  			conv := nod(OCALL, typenod(typ), nil)
   872  			conv.List.Set1(n)
   873  			n = conv
   874  		}
   875  		return n
   876  
   877  	case ONAME:
   878  		return mkname(p.sym())
   879  
   880  	// case OPACK, ONONAME:
   881  	// 	unreachable - should have been resolved by typechecking
   882  
   883  	case OTYPE:
   884  		if p.bool() {
   885  			return mkname(p.sym())
   886  		}
   887  		return typenod(p.typ())
   888  
   889  	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
   890  	//      unreachable - should have been resolved by typechecking
   891  
   892  	// case OCLOSURE:
   893  	//	unimplemented
   894  
   895  	case OPTRLIT:
   896  		n := p.expr()
   897  		if !p.bool() /* !implicit, i.e. '&' operator */ {
   898  			if n.Op == OCOMPLIT {
   899  				// Special case for &T{...}: turn into (*T){...}.
   900  				n.Right = nod(OIND, n.Right, nil)
   901  				n.Right.Implicit = true
   902  			} else {
   903  				n = nod(OADDR, n, nil)
   904  			}
   905  		}
   906  		return n
   907  
   908  	case OSTRUCTLIT:
   909  		n := nod(OCOMPLIT, nil, typenod(p.typ()))
   910  		n.List.Set(p.elemList()) // special handling of field names
   911  		return n
   912  
   913  	// case OARRAYLIT, OSLICELIT, OMAPLIT:
   914  	// 	unreachable - mapped to case OCOMPLIT below by exporter
   915  
   916  	case OCOMPLIT:
   917  		n := nod(OCOMPLIT, nil, typenod(p.typ()))
   918  		n.List.Set(p.exprList())
   919  		return n
   920  
   921  	case OKEY:
   922  		left, right := p.exprsOrNil()
   923  		return nod(OKEY, left, right)
   924  
   925  	// case OSTRUCTKEY:
   926  	//	unreachable - handled in case OSTRUCTLIT by elemList
   927  
   928  	// case OCALLPART:
   929  	//	unimplemented
   930  
   931  	// case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
   932  	// 	unreachable - mapped to case OXDOT below by exporter
   933  
   934  	case OXDOT:
   935  		// see parser.new_dotname
   936  		return nodSym(OXDOT, p.expr(), p.fieldSym())
   937  
   938  	// case ODOTTYPE, ODOTTYPE2:
   939  	// 	unreachable - mapped to case ODOTTYPE below by exporter
   940  
   941  	case ODOTTYPE:
   942  		n := nod(ODOTTYPE, p.expr(), nil)
   943  		if p.bool() {
   944  			n.Right = p.expr()
   945  		} else {
   946  			n.Right = typenod(p.typ())
   947  		}
   948  		return n
   949  
   950  	// case OINDEX, OINDEXMAP, OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
   951  	// 	unreachable - mapped to cases below by exporter
   952  
   953  	case OINDEX:
   954  		return nod(op, p.expr(), p.expr())
   955  
   956  	case OSLICE, OSLICE3:
   957  		n := nod(op, p.expr(), nil)
   958  		low, high := p.exprsOrNil()
   959  		var max *Node
   960  		if n.Op.IsSlice3() {
   961  			max = p.expr()
   962  		}
   963  		n.SetSliceBounds(low, high, max)
   964  		return n
   965  
   966  	// case OCONV, OCONVIFACE, OCONVNOP, OARRAYBYTESTR, OARRAYRUNESTR, OSTRARRAYBYTE, OSTRARRAYRUNE, ORUNESTR:
   967  	// 	unreachable - mapped to OCONV case below by exporter
   968  
   969  	case OCONV:
   970  		n := nod(OCALL, typenod(p.typ()), nil)
   971  		n.List.Set(p.exprList())
   972  		return n
   973  
   974  	case OCOPY, OCOMPLEX, OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
   975  		n := builtinCall(op)
   976  		n.List.Set(p.exprList())
   977  		if op == OAPPEND {
   978  			n.Isddd = p.bool()
   979  		}
   980  		return n
   981  
   982  	// case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
   983  	// 	unreachable - mapped to OCALL case below by exporter
   984  
   985  	case OCALL:
   986  		n := nod(OCALL, p.expr(), nil)
   987  		n.List.Set(p.exprList())
   988  		n.Isddd = p.bool()
   989  		return n
   990  
   991  	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
   992  		n := builtinCall(OMAKE)
   993  		n.List.Append(typenod(p.typ()))
   994  		n.List.Append(p.exprList()...)
   995  		return n
   996  
   997  	// unary expressions
   998  	case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV:
   999  		return nod(op, p.expr(), nil)
  1000  
  1001  	// binary expressions
  1002  	case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
  1003  		OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
  1004  		return nod(op, p.expr(), p.expr())
  1005  
  1006  	case OADDSTR:
  1007  		list := p.exprList()
  1008  		x := list[0]
  1009  		for _, y := range list[1:] {
  1010  			x = nod(OADD, x, y)
  1011  		}
  1012  		return x
  1013  
  1014  	// case OCMPSTR, OCMPIFACE:
  1015  	// 	unreachable - mapped to std comparison operators by exporter
  1016  
  1017  	case ODCLCONST:
  1018  		// TODO(gri) these should not be exported in the first place
  1019  		return nod(OEMPTY, nil, nil)
  1020  
  1021  	// --------------------------------------------------------------------
  1022  	// statements
  1023  	case ODCL:
  1024  		if p.version < 2 {
  1025  			// versions 0 and 1 exported a bool here but it
  1026  			// was always false - simply ignore in this case
  1027  			p.bool()
  1028  		}
  1029  		lhs := dclname(p.sym())
  1030  		typ := typenod(p.typ())
  1031  		return liststmt(variter([]*Node{lhs}, typ, nil)) // TODO(gri) avoid list creation
  1032  
  1033  	// case ODCLFIELD:
  1034  	//	unimplemented
  1035  
  1036  	// case OAS, OASWB:
  1037  	// 	unreachable - mapped to OAS case below by exporter
  1038  
  1039  	case OAS:
  1040  		return nod(OAS, p.expr(), p.expr())
  1041  
  1042  	case OASOP:
  1043  		n := nod(OASOP, nil, nil)
  1044  		n.Etype = EType(p.int())
  1045  		n.Left = p.expr()
  1046  		if !p.bool() {
  1047  			n.Right = nodintconst(1)
  1048  			n.Implicit = true
  1049  		} else {
  1050  			n.Right = p.expr()
  1051  		}
  1052  		return n
  1053  
  1054  	// case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
  1055  	// 	unreachable - mapped to OAS2 case below by exporter
  1056  
  1057  	case OAS2:
  1058  		n := nod(OAS2, nil, nil)
  1059  		n.List.Set(p.exprList())
  1060  		n.Rlist.Set(p.exprList())
  1061  		return n
  1062  
  1063  	case ORETURN:
  1064  		n := nod(ORETURN, nil, nil)
  1065  		n.List.Set(p.exprList())
  1066  		return n
  1067  
  1068  	// case ORETJMP:
  1069  	// 	unreachable - generated by compiler for trampolin routines (not exported)
  1070  
  1071  	case OPROC, ODEFER:
  1072  		return nod(op, p.expr(), nil)
  1073  
  1074  	case OIF:
  1075  		markdcl()
  1076  		n := nod(OIF, nil, nil)
  1077  		n.Ninit.Set(p.stmtList())
  1078  		n.Left = p.expr()
  1079  		n.Nbody.Set(p.stmtList())
  1080  		n.Rlist.Set(p.stmtList())
  1081  		popdcl()
  1082  		return n
  1083  
  1084  	case OFOR:
  1085  		markdcl()
  1086  		n := nod(OFOR, nil, nil)
  1087  		n.Ninit.Set(p.stmtList())
  1088  		n.Left, n.Right = p.exprsOrNil()
  1089  		n.Nbody.Set(p.stmtList())
  1090  		popdcl()
  1091  		return n
  1092  
  1093  	case ORANGE:
  1094  		markdcl()
  1095  		n := nod(ORANGE, nil, nil)
  1096  		n.List.Set(p.stmtList())
  1097  		n.Right = p.expr()
  1098  		n.Nbody.Set(p.stmtList())
  1099  		popdcl()
  1100  		return n
  1101  
  1102  	case OSELECT, OSWITCH:
  1103  		markdcl()
  1104  		n := nod(op, nil, nil)
  1105  		n.Ninit.Set(p.stmtList())
  1106  		n.Left, _ = p.exprsOrNil()
  1107  		n.List.Set(p.stmtList())
  1108  		popdcl()
  1109  		return n
  1110  
  1111  	// case OCASE, OXCASE:
  1112  	// 	unreachable - mapped to OXCASE case below by exporter
  1113  
  1114  	case OXCASE:
  1115  		markdcl()
  1116  		n := nod(OXCASE, nil, nil)
  1117  		n.Xoffset = int64(block)
  1118  		n.List.Set(p.exprList())
  1119  		// TODO(gri) eventually we must declare variables for type switch
  1120  		// statements (type switch statements are not yet exported)
  1121  		n.Nbody.Set(p.stmtList())
  1122  		popdcl()
  1123  		return n
  1124  
  1125  	// case OFALL:
  1126  	// 	unreachable - mapped to OXFALL case below by exporter
  1127  
  1128  	case OXFALL:
  1129  		n := nod(OXFALL, nil, nil)
  1130  		n.Xoffset = int64(block)
  1131  		return n
  1132  
  1133  	case OBREAK, OCONTINUE:
  1134  		left, _ := p.exprsOrNil()
  1135  		if left != nil {
  1136  			left = newname(left.Sym)
  1137  		}
  1138  		return nod(op, left, nil)
  1139  
  1140  	// case OEMPTY:
  1141  	// 	unreachable - not emitted by exporter
  1142  
  1143  	case OGOTO, OLABEL:
  1144  		n := nod(op, newname(p.expr().Sym), nil)
  1145  		n.Sym = dclstack // context, for goto restrictions
  1146  		return n
  1147  
  1148  	case OEND:
  1149  		return nil
  1150  
  1151  	default:
  1152  		Fatalf("cannot import %v (%d) node\n"+
  1153  			"==> please file an issue and assign to gri@\n", op, int(op))
  1154  		panic("unreachable") // satisfy compiler
  1155  	}
  1156  }
  1157  
  1158  func builtinCall(op Op) *Node {
  1159  	return nod(OCALL, mkname(builtinpkg.Lookup(goopnames[op])), nil)
  1160  }
  1161  
  1162  func (p *importer) exprsOrNil() (a, b *Node) {
  1163  	ab := p.int()
  1164  	if ab&1 != 0 {
  1165  		a = p.expr()
  1166  	}
  1167  	if ab&2 != 0 {
  1168  		b = p.expr()
  1169  	}
  1170  	return
  1171  }
  1172  
  1173  func (p *importer) fieldSym() *Sym {
  1174  	name := p.string()
  1175  	pkg := localpkg
  1176  	if !exportname(name) {
  1177  		pkg = p.pkg()
  1178  	}
  1179  	return pkg.Lookup(name)
  1180  }
  1181  
  1182  func (p *importer) sym() *Sym {
  1183  	name := p.string()
  1184  	pkg := localpkg
  1185  	if name != "_" {
  1186  		pkg = p.pkg()
  1187  	}
  1188  	linkname := p.string()
  1189  	sym := pkg.Lookup(name)
  1190  	sym.Linkname = linkname
  1191  	return sym
  1192  }
  1193  
  1194  func (p *importer) bool() bool {
  1195  	return p.int() != 0
  1196  }
  1197  
  1198  func (p *importer) op() Op {
  1199  	return Op(p.int())
  1200  }
  1201  
  1202  // ----------------------------------------------------------------------------
  1203  // Low-level decoders
  1204  
  1205  func (p *importer) tagOrIndex() int {
  1206  	if p.debugFormat {
  1207  		p.marker('t')
  1208  	}
  1209  
  1210  	return int(p.rawInt64())
  1211  }
  1212  
  1213  func (p *importer) int() int {
  1214  	x := p.int64()
  1215  	if int64(int(x)) != x {
  1216  		formatErrorf("exported integer too large")
  1217  	}
  1218  	return int(x)
  1219  }
  1220  
  1221  func (p *importer) int64() int64 {
  1222  	if p.debugFormat {
  1223  		p.marker('i')
  1224  	}
  1225  
  1226  	return p.rawInt64()
  1227  }
  1228  
  1229  func (p *importer) string() string {
  1230  	if p.debugFormat {
  1231  		p.marker('s')
  1232  	}
  1233  	// if the string was seen before, i is its index (>= 0)
  1234  	// (the empty string is at index 0)
  1235  	i := p.rawInt64()
  1236  	if i >= 0 {
  1237  		return p.strList[i]
  1238  	}
  1239  	// otherwise, i is the negative string length (< 0)
  1240  	if n := int(-i); n <= cap(p.buf) {
  1241  		p.buf = p.buf[:n]
  1242  	} else {
  1243  		p.buf = make([]byte, n)
  1244  	}
  1245  	for i := range p.buf {
  1246  		p.buf[i] = p.rawByte()
  1247  	}
  1248  	s := string(p.buf)
  1249  	p.strList = append(p.strList, s)
  1250  	return s
  1251  }
  1252  
  1253  func (p *importer) marker(want byte) {
  1254  	if got := p.rawByte(); got != want {
  1255  		formatErrorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
  1256  	}
  1257  
  1258  	pos := p.read
  1259  	if n := int(p.rawInt64()); n != pos {
  1260  		formatErrorf("incorrect position: got %d; want %d", n, pos)
  1261  	}
  1262  }
  1263  
  1264  // rawInt64 should only be used by low-level decoders.
  1265  func (p *importer) rawInt64() int64 {
  1266  	i, err := binary.ReadVarint(p)
  1267  	if err != nil {
  1268  		formatErrorf("read error: %v", err)
  1269  	}
  1270  	return i
  1271  }
  1272  
  1273  // rawStringln should only be used to read the initial version string.
  1274  func (p *importer) rawStringln(b byte) string {
  1275  	p.buf = p.buf[:0]
  1276  	for b != '\n' {
  1277  		p.buf = append(p.buf, b)
  1278  		b = p.rawByte()
  1279  	}
  1280  	return string(p.buf)
  1281  }
  1282  
  1283  // needed for binary.ReadVarint in rawInt64
  1284  func (p *importer) ReadByte() (byte, error) {
  1285  	return p.rawByte(), nil
  1286  }
  1287  
  1288  // rawByte is the bottleneck interface for reading from p.in.
  1289  // It unescapes '|' 'S' to '$' and '|' '|' to '|'.
  1290  // rawByte should only be used by low-level decoders.
  1291  func (p *importer) rawByte() byte {
  1292  	c, err := p.in.ReadByte()
  1293  	p.read++
  1294  	if err != nil {
  1295  		formatErrorf("read error: %v", err)
  1296  	}
  1297  	if c == '|' {
  1298  		c, err = p.in.ReadByte()
  1299  		p.read++
  1300  		if err != nil {
  1301  			formatErrorf("read error: %v", err)
  1302  		}
  1303  		switch c {
  1304  		case 'S':
  1305  			c = '$'
  1306  		case '|':
  1307  			// nothing to do
  1308  		default:
  1309  			formatErrorf("unexpected escape sequence in export data")
  1310  		}
  1311  	}
  1312  	return c
  1313  }