Home | History | Annotate | Download | only in gc
      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 4:
     90 	// 	...
     91 	//	fallthrough
     92 	case 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 typeTag:
    321 		p.typ()
    322 
    323 	case varTag:
    324 		p.pos()
    325 		sym := p.qualifiedName()
    326 		typ := p.typ()
    327 		importvar(sym, typ)
    328 
    329 	case funcTag:
    330 		p.pos()
    331 		sym := p.qualifiedName()
    332 		params := p.paramList()
    333 		result := p.paramList()
    334 
    335 		sig := functypefield(nil, params, result)
    336 		importsym(sym, ONAME)
    337 		if sym.Def != nil && sym.Def.Op == ONAME {
    338 			// function was imported before (via another import)
    339 			if !eqtype(sig, sym.Def.Type) {
    340 				formatErrorf("inconsistent definition for func %v during import\n\t%v\n\t%v", sym, sym.Def.Type, sig)
    341 			}
    342 			p.funcList = append(p.funcList, nil)
    343 			break
    344 		}
    345 
    346 		n := newfuncname(sym)
    347 		n.Type = sig
    348 		declare(n, PFUNC)
    349 		p.funcList = append(p.funcList, n)
    350 		importlist = append(importlist, n)
    351 
    352 		if Debug['E'] > 0 {
    353 			fmt.Printf("import [%q] func %v \n", importpkg.Path, n)
    354 			if Debug['m'] > 2 && n.Func.Inl.Len() != 0 {
    355 				fmt.Printf("inl body: %v\n", n.Func.Inl)
    356 			}
    357 		}
    358 
    359 	case aliasTag:
    360 		p.pos()
    361 		alias := importpkg.Lookup(p.string())
    362 		orig := p.qualifiedName()
    363 
    364 		// Although the protocol allows the alias to precede the original,
    365 		// this never happens in files produced by gc.
    366 		alias.Flags |= SymAlias
    367 		alias.Def = orig.Def
    368 		importsym(alias, orig.Def.Op)
    369 
    370 	default:
    371 		formatErrorf("unexpected object (tag = %d)", tag)
    372 	}
    373 }
    374 
    375 func (p *importer) pos() {
    376 	if !p.posInfoFormat {
    377 		return
    378 	}
    379 
    380 	file := p.prevFile
    381 	line := p.prevLine
    382 	if delta := p.int(); delta != 0 {
    383 		// line changed
    384 		line += delta
    385 	} else if n := p.int(); n >= 0 {
    386 		// file changed
    387 		file = p.prevFile[:n] + p.string()
    388 		p.prevFile = file
    389 		line = p.int()
    390 	}
    391 	p.prevLine = line
    392 
    393 	// TODO(gri) register new position
    394 }
    395 
    396 func (p *importer) newtyp(etype EType) *Type {
    397 	t := typ(etype)
    398 	if p.trackAllTypes {
    399 		p.typList = append(p.typList, t)
    400 	}
    401 	return t
    402 }
    403 
    404 // importtype declares that pt, an imported named type, has underlying type t.
    405 func (p *importer) importtype(pt, t *Type) {
    406 	if pt.Etype == TFORW {
    407 		n := pt.nod
    408 		copytype(pt.nod, t)
    409 		pt.nod = n // unzero nod
    410 		pt.Sym.Importdef = importpkg
    411 		pt.Sym.Lastlineno = lineno
    412 		declare(n, PEXTERN)
    413 		checkwidth(pt)
    414 	} else {
    415 		// pt.Orig and t must be identical.
    416 		if p.trackAllTypes {
    417 			// If we track all types, t may not be fully set up yet.
    418 			// Collect the types and verify identity later.
    419 			p.cmpList = append(p.cmpList, struct{ pt, t *Type }{pt, t})
    420 		} else if !eqtype(pt.Orig, t) {
    421 			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)
    422 		}
    423 	}
    424 
    425 	if Debug['E'] != 0 {
    426 		fmt.Printf("import type %v %L\n", pt, t)
    427 	}
    428 }
    429 
    430 func (p *importer) typ() *Type {
    431 	// if the type was seen before, i is its index (>= 0)
    432 	i := p.tagOrIndex()
    433 	if i >= 0 {
    434 		return p.typList[i]
    435 	}
    436 
    437 	// otherwise, i is the type tag (< 0)
    438 	var t *Type
    439 	switch i {
    440 	case namedTag:
    441 		p.pos()
    442 		tsym := p.qualifiedName()
    443 
    444 		t = pkgtype(tsym)
    445 		p.typList = append(p.typList, t)
    446 
    447 		// read underlying type
    448 		t0 := p.typ()
    449 		p.importtype(t, t0)
    450 
    451 		// interfaces don't have associated methods
    452 		if t0.IsInterface() {
    453 			break
    454 		}
    455 
    456 		// set correct import context (since p.typ() may be called
    457 		// while importing the body of an inlined function)
    458 		savedContext := dclcontext
    459 		dclcontext = PEXTERN
    460 
    461 		// read associated methods
    462 		for i := p.int(); i > 0; i-- {
    463 			p.pos()
    464 			sym := p.fieldSym()
    465 
    466 			// during import unexported method names should be in the type's package
    467 			if !exportname(sym.Name) && sym.Pkg != tsym.Pkg {
    468 				Fatalf("imported method name %+v in wrong package %s\n", sym, tsym.Pkg.Name)
    469 			}
    470 
    471 			recv := p.paramList() // TODO(gri) do we need a full param list for the receiver?
    472 			params := p.paramList()
    473 			result := p.paramList()
    474 			nointerface := p.bool()
    475 
    476 			base := recv[0].Type
    477 			star := false
    478 			if base.IsPtr() {
    479 				base = base.Elem()
    480 				star = true
    481 			}
    482 
    483 			n := methodname0(sym, star, base.Sym)
    484 			n.Type = functypefield(recv[0], params, result)
    485 			checkwidth(n.Type)
    486 			addmethod(sym, n.Type, false, nointerface)
    487 			p.funcList = append(p.funcList, n)
    488 			importlist = append(importlist, n)
    489 
    490 			// (comment from parser.go)
    491 			// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
    492 			// (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled
    493 			// out by typecheck's lookdot as this $$.ttype. So by providing
    494 			// this back link here we avoid special casing there.
    495 			n.Type.SetNname(n)
    496 
    497 			if Debug['E'] > 0 {
    498 				fmt.Printf("import [%q] meth %v \n", importpkg.Path, n)
    499 				if Debug['m'] > 2 && n.Func.Inl.Len() != 0 {
    500 					fmt.Printf("inl body: %v\n", n.Func.Inl)
    501 				}
    502 			}
    503 		}
    504 
    505 		dclcontext = savedContext
    506 
    507 	case arrayTag:
    508 		t = p.newtyp(TARRAY)
    509 		bound := p.int64()
    510 		elem := p.typ()
    511 		t.Extra = &ArrayType{Elem: elem, Bound: bound}
    512 
    513 	case sliceTag:
    514 		t = p.newtyp(TSLICE)
    515 		elem := p.typ()
    516 		t.Extra = SliceType{Elem: elem}
    517 
    518 	case dddTag:
    519 		t = p.newtyp(TDDDFIELD)
    520 		t.Extra = DDDFieldType{T: p.typ()}
    521 
    522 	case structTag:
    523 		t = p.newtyp(TSTRUCT)
    524 		t.SetFields(p.fieldList())
    525 		checkwidth(t)
    526 
    527 	case pointerTag:
    528 		t = p.newtyp(Tptr)
    529 		t.Extra = PtrType{Elem: p.typ()}
    530 
    531 	case signatureTag:
    532 		t = p.newtyp(TFUNC)
    533 		params := p.paramList()
    534 		result := p.paramList()
    535 		functypefield0(t, nil, params, result)
    536 
    537 	case interfaceTag:
    538 		t = p.newtyp(TINTER)
    539 		if p.int() != 0 {
    540 			formatErrorf("unexpected embedded interface")
    541 		}
    542 		t.SetFields(p.methodList())
    543 		checkwidth(t)
    544 
    545 	case mapTag:
    546 		t = p.newtyp(TMAP)
    547 		mt := t.MapType()
    548 		mt.Key = p.typ()
    549 		mt.Val = p.typ()
    550 
    551 	case chanTag:
    552 		t = p.newtyp(TCHAN)
    553 		ct := t.ChanType()
    554 		ct.Dir = ChanDir(p.int())
    555 		ct.Elem = p.typ()
    556 
    557 	default:
    558 		formatErrorf("unexpected type (tag = %d)", i)
    559 	}
    560 
    561 	if t == nil {
    562 		formatErrorf("nil type (type tag = %d)", i)
    563 	}
    564 
    565 	return t
    566 }
    567 
    568 func (p *importer) qualifiedName() *Sym {
    569 	name := p.string()
    570 	pkg := p.pkg()
    571 	return pkg.Lookup(name)
    572 }
    573 
    574 func (p *importer) fieldList() (fields []*Field) {
    575 	if n := p.int(); n > 0 {
    576 		fields = make([]*Field, n)
    577 		for i := range fields {
    578 			fields[i] = p.field()
    579 		}
    580 	}
    581 	return
    582 }
    583 
    584 func (p *importer) field() *Field {
    585 	p.pos()
    586 	sym := p.fieldName()
    587 	typ := p.typ()
    588 	note := p.string()
    589 
    590 	f := newField()
    591 	if sym.Name == "" {
    592 		// anonymous field - typ must be T or *T and T must be a type name
    593 		s := typ.Sym
    594 		if s == nil && typ.IsPtr() {
    595 			s = typ.Elem().Sym // deref
    596 		}
    597 		sym = sym.Pkg.Lookup(s.Name)
    598 		f.Embedded = 1
    599 	}
    600 
    601 	f.Sym = sym
    602 	f.Nname = newname(sym)
    603 	f.Type = typ
    604 	f.Note = note
    605 
    606 	return f
    607 }
    608 
    609 func (p *importer) methodList() (methods []*Field) {
    610 	if n := p.int(); n > 0 {
    611 		methods = make([]*Field, n)
    612 		for i := range methods {
    613 			methods[i] = p.method()
    614 		}
    615 	}
    616 	return
    617 }
    618 
    619 func (p *importer) method() *Field {
    620 	p.pos()
    621 	sym := p.fieldName()
    622 	params := p.paramList()
    623 	result := p.paramList()
    624 
    625 	f := newField()
    626 	f.Sym = sym
    627 	f.Nname = newname(sym)
    628 	f.Type = functypefield(fakethisfield(), params, result)
    629 	return f
    630 }
    631 
    632 func (p *importer) fieldName() *Sym {
    633 	name := p.string()
    634 	if p.version == 0 && name == "_" {
    635 		// version 0 didn't export a package for _ fields
    636 		// but used the builtin package instead
    637 		return builtinpkg.Lookup(name)
    638 	}
    639 	pkg := localpkg
    640 	if name != "" && !exportname(name) {
    641 		if name == "?" {
    642 			name = ""
    643 		}
    644 		pkg = p.pkg()
    645 	}
    646 	return pkg.Lookup(name)
    647 }
    648 
    649 func (p *importer) paramList() []*Field {
    650 	i := p.int()
    651 	if i == 0 {
    652 		return nil
    653 	}
    654 	// negative length indicates unnamed parameters
    655 	named := true
    656 	if i < 0 {
    657 		i = -i
    658 		named = false
    659 	}
    660 	// i > 0
    661 	fs := make([]*Field, i)
    662 	for i := range fs {
    663 		fs[i] = p.param(named)
    664 	}
    665 	return fs
    666 }
    667 
    668 func (p *importer) param(named bool) *Field {
    669 	f := newField()
    670 	f.Type = p.typ()
    671 	if f.Type.Etype == TDDDFIELD {
    672 		// TDDDFIELD indicates wrapped ... slice type
    673 		f.Type = typSlice(f.Type.DDDField())
    674 		f.Isddd = true
    675 	}
    676 
    677 	if named {
    678 		name := p.string()
    679 		if name == "" {
    680 			formatErrorf("expected named parameter")
    681 		}
    682 		// TODO(gri) Supply function/method package rather than
    683 		// encoding the package for each parameter repeatedly.
    684 		pkg := localpkg
    685 		if name != "_" {
    686 			pkg = p.pkg()
    687 		}
    688 		f.Sym = pkg.Lookup(name)
    689 		f.Nname = newname(f.Sym)
    690 	}
    691 
    692 	// TODO(gri) This is compiler-specific (escape info).
    693 	// Move into compiler-specific section eventually?
    694 	f.Note = p.string()
    695 
    696 	return f
    697 }
    698 
    699 func (p *importer) value(typ *Type) (x Val) {
    700 	switch tag := p.tagOrIndex(); tag {
    701 	case falseTag:
    702 		x.U = false
    703 
    704 	case trueTag:
    705 		x.U = true
    706 
    707 	case int64Tag:
    708 		u := new(Mpint)
    709 		u.SetInt64(p.int64())
    710 		u.Rune = typ == idealrune
    711 		x.U = u
    712 
    713 	case floatTag:
    714 		f := newMpflt()
    715 		p.float(f)
    716 		if typ == idealint || typ.IsInteger() {
    717 			// uncommon case: large int encoded as float
    718 			u := new(Mpint)
    719 			u.SetFloat(f)
    720 			x.U = u
    721 			break
    722 		}
    723 		x.U = f
    724 
    725 	case complexTag:
    726 		u := new(Mpcplx)
    727 		p.float(&u.Real)
    728 		p.float(&u.Imag)
    729 		x.U = u
    730 
    731 	case stringTag:
    732 		x.U = p.string()
    733 
    734 	case unknownTag:
    735 		formatErrorf("unknown constant (importing package with errors)")
    736 
    737 	case nilTag:
    738 		x.U = new(NilVal)
    739 
    740 	default:
    741 		formatErrorf("unexpected value tag %d", tag)
    742 	}
    743 
    744 	// verify ideal type
    745 	if typ.IsUntyped() && untype(x.Ctype()) != typ {
    746 		formatErrorf("value %v and type %v don't match", x, typ)
    747 	}
    748 
    749 	return
    750 }
    751 
    752 func (p *importer) float(x *Mpflt) {
    753 	sign := p.int()
    754 	if sign == 0 {
    755 		x.SetFloat64(0)
    756 		return
    757 	}
    758 
    759 	exp := p.int()
    760 	mant := new(big.Int).SetBytes([]byte(p.string()))
    761 
    762 	m := x.Val.SetInt(mant)
    763 	m.SetMantExp(m, exp-mant.BitLen())
    764 	if sign < 0 {
    765 		m.Neg(m)
    766 	}
    767 }
    768 
    769 // ----------------------------------------------------------------------------
    770 // Inlined function bodies
    771 
    772 // Approach: Read nodes and use them to create/declare the same data structures
    773 // as done originally by the (hidden) parser by closely following the parser's
    774 // original code. In other words, "parsing" the import data (which happens to
    775 // be encoded in binary rather textual form) is the best way at the moment to
    776 // re-establish the syntax tree's invariants. At some future point we might be
    777 // able to avoid this round-about way and create the rewritten nodes directly,
    778 // possibly avoiding a lot of duplicate work (name resolution, type checking).
    779 //
    780 // Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their
    781 // unrefined nodes (since this is what the importer uses). The respective case
    782 // entries are unreachable in the importer.
    783 
    784 func (p *importer) stmtList() []*Node {
    785 	var list []*Node
    786 	for {
    787 		n := p.node()
    788 		if n == nil {
    789 			break
    790 		}
    791 		// OBLOCK nodes may be created when importing ODCL nodes - unpack them
    792 		if n.Op == OBLOCK {
    793 			list = append(list, n.List.Slice()...)
    794 		} else {
    795 			list = append(list, n)
    796 		}
    797 	}
    798 	return list
    799 }
    800 
    801 func (p *importer) exprList() []*Node {
    802 	var list []*Node
    803 	for {
    804 		n := p.expr()
    805 		if n == nil {
    806 			break
    807 		}
    808 		list = append(list, n)
    809 	}
    810 	return list
    811 }
    812 
    813 func (p *importer) elemList() []*Node {
    814 	c := p.int()
    815 	list := make([]*Node, c)
    816 	for i := range list {
    817 		s := p.fieldSym()
    818 		list[i] = nodSym(OSTRUCTKEY, p.expr(), s)
    819 	}
    820 	return list
    821 }
    822 
    823 func (p *importer) expr() *Node {
    824 	n := p.node()
    825 	if n != nil && n.Op == OBLOCK {
    826 		Fatalf("unexpected block node: %v", n)
    827 	}
    828 	return n
    829 }
    830 
    831 // TODO(gri) split into expr and stmt
    832 func (p *importer) node() *Node {
    833 	switch op := p.op(); op {
    834 	// expressions
    835 	// case OPAREN:
    836 	// 	unreachable - unpacked by exporter
    837 
    838 	// case ODDDARG:
    839 	//	unimplemented
    840 
    841 	case OLITERAL:
    842 		typ := p.typ()
    843 		n := nodlit(p.value(typ))
    844 		if !typ.IsUntyped() {
    845 			// Type-checking simplifies unsafe.Pointer(uintptr(c))
    846 			// to unsafe.Pointer(c) which then cannot type-checked
    847 			// again. Re-introduce explicit uintptr(c) conversion.
    848 			// (issue 16317).
    849 			if typ.IsUnsafePtr() {
    850 				conv := nod(OCALL, typenod(Types[TUINTPTR]), nil)
    851 				conv.List.Set1(n)
    852 				n = conv
    853 			}
    854 			conv := nod(OCALL, typenod(typ), nil)
    855 			conv.List.Set1(n)
    856 			n = conv
    857 		}
    858 		return n
    859 
    860 	case ONAME:
    861 		return mkname(p.sym())
    862 
    863 	// case OPACK, ONONAME:
    864 	// 	unreachable - should have been resolved by typechecking
    865 
    866 	case OTYPE:
    867 		if p.bool() {
    868 			return mkname(p.sym())
    869 		}
    870 		return typenod(p.typ())
    871 
    872 	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
    873 	//      unreachable - should have been resolved by typechecking
    874 
    875 	// case OCLOSURE:
    876 	//	unimplemented
    877 
    878 	case OPTRLIT:
    879 		n := p.expr()
    880 		if !p.bool() /* !implicit, i.e. '&' operator */ {
    881 			if n.Op == OCOMPLIT {
    882 				// Special case for &T{...}: turn into (*T){...}.
    883 				n.Right = nod(OIND, n.Right, nil)
    884 				n.Right.Implicit = true
    885 			} else {
    886 				n = nod(OADDR, n, nil)
    887 			}
    888 		}
    889 		return n
    890 
    891 	case OSTRUCTLIT:
    892 		n := nod(OCOMPLIT, nil, typenod(p.typ()))
    893 		n.List.Set(p.elemList()) // special handling of field names
    894 		return n
    895 
    896 	// case OARRAYLIT, OSLICELIT, OMAPLIT:
    897 	// 	unreachable - mapped to case OCOMPLIT below by exporter
    898 
    899 	case OCOMPLIT:
    900 		n := nod(OCOMPLIT, nil, typenod(p.typ()))
    901 		n.List.Set(p.exprList())
    902 		return n
    903 
    904 	case OKEY:
    905 		left, right := p.exprsOrNil()
    906 		return nod(OKEY, left, right)
    907 
    908 	// case OSTRUCTKEY:
    909 	//	unreachable - handled in case OSTRUCTLIT by elemList
    910 
    911 	// case OCALLPART:
    912 	//	unimplemented
    913 
    914 	// case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
    915 	// 	unreachable - mapped to case OXDOT below by exporter
    916 
    917 	case OXDOT:
    918 		// see parser.new_dotname
    919 		return nodSym(OXDOT, p.expr(), p.fieldSym())
    920 
    921 	// case ODOTTYPE, ODOTTYPE2:
    922 	// 	unreachable - mapped to case ODOTTYPE below by exporter
    923 
    924 	case ODOTTYPE:
    925 		n := nod(ODOTTYPE, p.expr(), nil)
    926 		if p.bool() {
    927 			n.Right = p.expr()
    928 		} else {
    929 			n.Right = typenod(p.typ())
    930 		}
    931 		return n
    932 
    933 	// case OINDEX, OINDEXMAP, OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
    934 	// 	unreachable - mapped to cases below by exporter
    935 
    936 	case OINDEX:
    937 		return nod(op, p.expr(), p.expr())
    938 
    939 	case OSLICE, OSLICE3:
    940 		n := nod(op, p.expr(), nil)
    941 		low, high := p.exprsOrNil()
    942 		var max *Node
    943 		if n.Op.IsSlice3() {
    944 			max = p.expr()
    945 		}
    946 		n.SetSliceBounds(low, high, max)
    947 		return n
    948 
    949 	// case OCONV, OCONVIFACE, OCONVNOP, OARRAYBYTESTR, OARRAYRUNESTR, OSTRARRAYBYTE, OSTRARRAYRUNE, ORUNESTR:
    950 	// 	unreachable - mapped to OCONV case below by exporter
    951 
    952 	case OCONV:
    953 		n := nod(OCALL, typenod(p.typ()), nil)
    954 		n.List.Set(p.exprList())
    955 		return n
    956 
    957 	case OCOPY, OCOMPLEX, OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
    958 		n := builtinCall(op)
    959 		n.List.Set(p.exprList())
    960 		if op == OAPPEND {
    961 			n.Isddd = p.bool()
    962 		}
    963 		return n
    964 
    965 	// case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
    966 	// 	unreachable - mapped to OCALL case below by exporter
    967 
    968 	case OCALL:
    969 		n := nod(OCALL, p.expr(), nil)
    970 		n.List.Set(p.exprList())
    971 		n.Isddd = p.bool()
    972 		return n
    973 
    974 	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
    975 		n := builtinCall(OMAKE)
    976 		n.List.Append(typenod(p.typ()))
    977 		n.List.Append(p.exprList()...)
    978 		return n
    979 
    980 	// unary expressions
    981 	case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV:
    982 		return nod(op, p.expr(), nil)
    983 
    984 	// binary expressions
    985 	case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
    986 		OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
    987 		return nod(op, p.expr(), p.expr())
    988 
    989 	case OADDSTR:
    990 		list := p.exprList()
    991 		x := list[0]
    992 		for _, y := range list[1:] {
    993 			x = nod(OADD, x, y)
    994 		}
    995 		return x
    996 
    997 	// case OCMPSTR, OCMPIFACE:
    998 	// 	unreachable - mapped to std comparison operators by exporter
    999 
   1000 	case ODCLCONST:
   1001 		// TODO(gri) these should not be exported in the first place
   1002 		return nod(OEMPTY, nil, nil)
   1003 
   1004 	// --------------------------------------------------------------------
   1005 	// statements
   1006 	case ODCL:
   1007 		if p.version < 2 {
   1008 			// versions 0 and 1 exported a bool here but it
   1009 			// was always false - simply ignore in this case
   1010 			p.bool()
   1011 		}
   1012 		lhs := dclname(p.sym())
   1013 		typ := typenod(p.typ())
   1014 		return liststmt(variter([]*Node{lhs}, typ, nil)) // TODO(gri) avoid list creation
   1015 
   1016 	// case ODCLFIELD:
   1017 	//	unimplemented
   1018 
   1019 	// case OAS, OASWB:
   1020 	// 	unreachable - mapped to OAS case below by exporter
   1021 
   1022 	case OAS:
   1023 		return nod(OAS, p.expr(), p.expr())
   1024 
   1025 	case OASOP:
   1026 		n := nod(OASOP, nil, nil)
   1027 		n.Etype = EType(p.int())
   1028 		n.Left = p.expr()
   1029 		if !p.bool() {
   1030 			n.Right = nodintconst(1)
   1031 			n.Implicit = true
   1032 		} else {
   1033 			n.Right = p.expr()
   1034 		}
   1035 		return n
   1036 
   1037 	// case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
   1038 	// 	unreachable - mapped to OAS2 case below by exporter
   1039 
   1040 	case OAS2:
   1041 		n := nod(OAS2, nil, nil)
   1042 		n.List.Set(p.exprList())
   1043 		n.Rlist.Set(p.exprList())
   1044 		return n
   1045 
   1046 	case ORETURN:
   1047 		n := nod(ORETURN, nil, nil)
   1048 		n.List.Set(p.exprList())
   1049 		return n
   1050 
   1051 	// case ORETJMP:
   1052 	// 	unreachable - generated by compiler for trampolin routines (not exported)
   1053 
   1054 	case OPROC, ODEFER:
   1055 		return nod(op, p.expr(), nil)
   1056 
   1057 	case OIF:
   1058 		markdcl()
   1059 		n := nod(OIF, nil, nil)
   1060 		n.Ninit.Set(p.stmtList())
   1061 		n.Left = p.expr()
   1062 		n.Nbody.Set(p.stmtList())
   1063 		n.Rlist.Set(p.stmtList())
   1064 		popdcl()
   1065 		return n
   1066 
   1067 	case OFOR:
   1068 		markdcl()
   1069 		n := nod(OFOR, nil, nil)
   1070 		n.Ninit.Set(p.stmtList())
   1071 		n.Left, n.Right = p.exprsOrNil()
   1072 		n.Nbody.Set(p.stmtList())
   1073 		popdcl()
   1074 		return n
   1075 
   1076 	case ORANGE:
   1077 		markdcl()
   1078 		n := nod(ORANGE, nil, nil)
   1079 		n.List.Set(p.stmtList())
   1080 		n.Right = p.expr()
   1081 		n.Nbody.Set(p.stmtList())
   1082 		popdcl()
   1083 		return n
   1084 
   1085 	case OSELECT, OSWITCH:
   1086 		markdcl()
   1087 		n := nod(op, nil, nil)
   1088 		n.Ninit.Set(p.stmtList())
   1089 		n.Left, _ = p.exprsOrNil()
   1090 		n.List.Set(p.stmtList())
   1091 		popdcl()
   1092 		return n
   1093 
   1094 	// case OCASE, OXCASE:
   1095 	// 	unreachable - mapped to OXCASE case below by exporter
   1096 
   1097 	case OXCASE:
   1098 		markdcl()
   1099 		n := nod(OXCASE, nil, nil)
   1100 		n.Xoffset = int64(block)
   1101 		n.List.Set(p.exprList())
   1102 		// TODO(gri) eventually we must declare variables for type switch
   1103 		// statements (type switch statements are not yet exported)
   1104 		n.Nbody.Set(p.stmtList())
   1105 		popdcl()
   1106 		return n
   1107 
   1108 	// case OFALL:
   1109 	// 	unreachable - mapped to OXFALL case below by exporter
   1110 
   1111 	case OXFALL:
   1112 		n := nod(OXFALL, nil, nil)
   1113 		n.Xoffset = int64(block)
   1114 		return n
   1115 
   1116 	case OBREAK, OCONTINUE:
   1117 		left, _ := p.exprsOrNil()
   1118 		if left != nil {
   1119 			left = newname(left.Sym)
   1120 		}
   1121 		return nod(op, left, nil)
   1122 
   1123 	// case OEMPTY:
   1124 	// 	unreachable - not emitted by exporter
   1125 
   1126 	case OGOTO, OLABEL:
   1127 		n := nod(op, newname(p.expr().Sym), nil)
   1128 		n.Sym = dclstack // context, for goto restrictions
   1129 		return n
   1130 
   1131 	case OEND:
   1132 		return nil
   1133 
   1134 	default:
   1135 		Fatalf("cannot import %v (%d) node\n"+
   1136 			"==> please file an issue and assign to gri@\n", op, int(op))
   1137 		panic("unreachable") // satisfy compiler
   1138 	}
   1139 }
   1140 
   1141 func builtinCall(op Op) *Node {
   1142 	return nod(OCALL, mkname(builtinpkg.Lookup(goopnames[op])), nil)
   1143 }
   1144 
   1145 func (p *importer) exprsOrNil() (a, b *Node) {
   1146 	ab := p.int()
   1147 	if ab&1 != 0 {
   1148 		a = p.expr()
   1149 	}
   1150 	if ab&2 != 0 {
   1151 		b = p.expr()
   1152 	}
   1153 	return
   1154 }
   1155 
   1156 func (p *importer) fieldSym() *Sym {
   1157 	name := p.string()
   1158 	pkg := localpkg
   1159 	if !exportname(name) {
   1160 		pkg = p.pkg()
   1161 	}
   1162 	return pkg.Lookup(name)
   1163 }
   1164 
   1165 func (p *importer) sym() *Sym {
   1166 	name := p.string()
   1167 	pkg := localpkg
   1168 	if name != "_" {
   1169 		pkg = p.pkg()
   1170 	}
   1171 	return pkg.Lookup(name)
   1172 }
   1173 
   1174 func (p *importer) bool() bool {
   1175 	return p.int() != 0
   1176 }
   1177 
   1178 func (p *importer) op() Op {
   1179 	return Op(p.int())
   1180 }
   1181 
   1182 // ----------------------------------------------------------------------------
   1183 // Low-level decoders
   1184 
   1185 func (p *importer) tagOrIndex() int {
   1186 	if p.debugFormat {
   1187 		p.marker('t')
   1188 	}
   1189 
   1190 	return int(p.rawInt64())
   1191 }
   1192 
   1193 func (p *importer) int() int {
   1194 	x := p.int64()
   1195 	if int64(int(x)) != x {
   1196 		formatErrorf("exported integer too large")
   1197 	}
   1198 	return int(x)
   1199 }
   1200 
   1201 func (p *importer) int64() int64 {
   1202 	if p.debugFormat {
   1203 		p.marker('i')
   1204 	}
   1205 
   1206 	return p.rawInt64()
   1207 }
   1208 
   1209 func (p *importer) string() string {
   1210 	if p.debugFormat {
   1211 		p.marker('s')
   1212 	}
   1213 	// if the string was seen before, i is its index (>= 0)
   1214 	// (the empty string is at index 0)
   1215 	i := p.rawInt64()
   1216 	if i >= 0 {
   1217 		return p.strList[i]
   1218 	}
   1219 	// otherwise, i is the negative string length (< 0)
   1220 	if n := int(-i); n <= cap(p.buf) {
   1221 		p.buf = p.buf[:n]
   1222 	} else {
   1223 		p.buf = make([]byte, n)
   1224 	}
   1225 	for i := range p.buf {
   1226 		p.buf[i] = p.rawByte()
   1227 	}
   1228 	s := string(p.buf)
   1229 	p.strList = append(p.strList, s)
   1230 	return s
   1231 }
   1232 
   1233 func (p *importer) marker(want byte) {
   1234 	if got := p.rawByte(); got != want {
   1235 		formatErrorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
   1236 	}
   1237 
   1238 	pos := p.read
   1239 	if n := int(p.rawInt64()); n != pos {
   1240 		formatErrorf("incorrect position: got %d; want %d", n, pos)
   1241 	}
   1242 }
   1243 
   1244 // rawInt64 should only be used by low-level decoders.
   1245 func (p *importer) rawInt64() int64 {
   1246 	i, err := binary.ReadVarint(p)
   1247 	if err != nil {
   1248 		formatErrorf("read error: %v", err)
   1249 	}
   1250 	return i
   1251 }
   1252 
   1253 // rawStringln should only be used to read the initial version string.
   1254 func (p *importer) rawStringln(b byte) string {
   1255 	p.buf = p.buf[:0]
   1256 	for b != '\n' {
   1257 		p.buf = append(p.buf, b)
   1258 		b = p.rawByte()
   1259 	}
   1260 	return string(p.buf)
   1261 }
   1262 
   1263 // needed for binary.ReadVarint in rawInt64
   1264 func (p *importer) ReadByte() (byte, error) {
   1265 	return p.rawByte(), nil
   1266 }
   1267 
   1268 // rawByte is the bottleneck interface for reading from p.in.
   1269 // It unescapes '|' 'S' to '$' and '|' '|' to '|'.
   1270 // rawByte should only be used by low-level decoders.
   1271 func (p *importer) rawByte() byte {
   1272 	c, err := p.in.ReadByte()
   1273 	p.read++
   1274 	if err != nil {
   1275 		formatErrorf("read error: %v", err)
   1276 	}
   1277 	if c == '|' {
   1278 		c, err = p.in.ReadByte()
   1279 		p.read++
   1280 		if err != nil {
   1281 			formatErrorf("read error: %v", err)
   1282 		}
   1283 		switch c {
   1284 		case 'S':
   1285 			c = '$'
   1286 		case '|':
   1287 			// nothing to do
   1288 		default:
   1289 			formatErrorf("unexpected escape sequence in export data")
   1290 		}
   1291 	}
   1292 	return c
   1293 }
   1294