github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/cmd/compile/internal/gc/bexport.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 export.
     6  
     7  /*
     8  1) Export data encoding principles:
     9  
    10  The export data is a serialized description of the graph of exported
    11  "objects": constants, types, variables, and functions. Aliases may be
    12  directly reexported, and unaliased types may be indirectly reexported
    13  (as part of the type of a directly exported object). More generally,
    14  objects referred to from inlined function bodies can be reexported.
    15  We need to know which package declares these reexported objects, and
    16  therefore packages are also part of the export graph.
    17  
    18  The roots of the graph are two lists of objects. The 1st list (phase 1,
    19  see Export) contains all objects that are exported at the package level.
    20  These objects are the full representation of the package's API, and they
    21  are the only information a platform-independent tool (e.g., go/types)
    22  needs to know to type-check against a package.
    23  
    24  The 2nd list of objects contains all objects referred to from exported
    25  inlined function bodies. These objects are needed by the compiler to
    26  make sense of the function bodies; the exact list contents are compiler-
    27  specific.
    28  
    29  Finally, the export data contains a list of representations for inlined
    30  function bodies. The format of this representation is compiler specific.
    31  
    32  The graph is serialized in in-order fashion, starting with the roots.
    33  Each object in the graph is serialized by writing its fields sequentially.
    34  If the field is a pointer to another object, that object is serialized in
    35  place, recursively. Otherwise the field is written in place. Non-pointer
    36  fields are all encoded as integer or string values.
    37  
    38  Some objects (packages, types) may be referred to more than once. When
    39  reaching an object that was not serialized before, an integer _index_
    40  is assigned to it, starting at 0. In this case, the encoding starts
    41  with an integer _tag_ < 0. The tag value indicates the kind of object
    42  that follows and that this is the first time that we see this object.
    43  If the object was already serialized, the encoding is simply the object
    44  index >= 0. An importer can trivially determine if an object needs to
    45  be read in for the first time (tag < 0) and entered into the respective
    46  object table, or if the object was seen already (index >= 0), in which
    47  case the index is used to look up the object in the respective table.
    48  
    49  Before exporting or importing, the type tables are populated with the
    50  predeclared types (int, string, error, unsafe.Pointer, etc.). This way
    51  they are automatically encoded with a known and fixed type index.
    52  
    53  2) Encoding format:
    54  
    55  The export data starts with two newline-terminated strings: a version
    56  string and either an empty string, or "debug", when emitting the debug
    57  format. These strings are followed by version-specific encoding options.
    58  
    59  (The Go1.7 version starts with a couple of bytes specifying the format.
    60  That format encoding is no longer used but is supported to avoid spurious
    61  errors when importing old installed package files.)
    62  
    63  This header is followed by the package object for the exported package,
    64  two lists of objects, and the list of inlined function bodies.
    65  
    66  The encoding of objects is straight-forward: Constants, variables, and
    67  functions start with their name, type, and possibly a value. Named types
    68  record their name and package so that they can be canonicalized: If the
    69  same type was imported before via another import, the importer must use
    70  the previously imported type pointer so that we have exactly one version
    71  (i.e., one pointer) for each named type (and read but discard the current
    72  type encoding). Unnamed types simply encode their respective fields.
    73  Aliases are encoded starting with their name followed by the qualified
    74  identifier denoting the original (aliased) object, which was exported
    75  earlier.
    76  
    77  In the encoding, some lists start with the list length. Some lists are
    78  terminated with an end marker (usually for lists where we may not know
    79  the length a priori).
    80  
    81  Integers use variable-length encoding for compact representation.
    82  
    83  Strings are canonicalized similar to objects that may occur multiple times:
    84  If the string was exported already, it is represented by its index only.
    85  Otherwise, the export data starts with the negative string length (negative,
    86  so we can distinguish from string index), followed by the string bytes.
    87  The empty string is mapped to index 0. (The initial format string is an
    88  exception; it is encoded as the string bytes followed by a newline).
    89  
    90  The exporter and importer are completely symmetric in implementation: For
    91  each encoding routine there is a matching and symmetric decoding routine.
    92  This symmetry makes it very easy to change or extend the format: If a new
    93  field needs to be encoded, a symmetric change can be made to exporter and
    94  importer.
    95  
    96  3) Making changes to the encoding format:
    97  
    98  Any change to the encoding format requires a respective change in the
    99  exporter below and a corresponding symmetric change to the importer in
   100  bimport.go.
   101  
   102  Furthermore, it requires a corresponding change to go/internal/gcimporter
   103  and golang.org/x/tools/go/gcimporter15. Changes to the latter must preserve
   104  compatibility with both the last release of the compiler, and with the
   105  corresponding compiler at tip. That change is necessarily more involved,
   106  as it must switch based on the version number in the export data file.
   107  
   108  It is recommended to turn on debugFormat temporarily when working on format
   109  changes as it will help finding encoding/decoding inconsistencies quickly.
   110  */
   111  
   112  package gc
   113  
   114  import (
   115  	"bufio"
   116  	"bytes"
   117  	"encoding/binary"
   118  	"fmt"
   119  	"math/big"
   120  	"sort"
   121  	"strings"
   122  )
   123  
   124  // If debugFormat is set, each integer and string value is preceded by a marker
   125  // and position information in the encoding. This mechanism permits an importer
   126  // to recognize immediately when it is out of sync. The importer recognizes this
   127  // mode automatically (i.e., it can import export data produced with debugging
   128  // support even if debugFormat is not set at the time of import). This mode will
   129  // lead to massively larger export data (by a factor of 2 to 3) and should only
   130  // be enabled during development and debugging.
   131  //
   132  // NOTE: This flag is the first flag to enable if importing dies because of
   133  // (suspected) format errors, and whenever a change is made to the format.
   134  const debugFormat = false // default: false
   135  
   136  // forceObjFileStability enforces additional constraints in export data
   137  // and other parts of the compiler to eliminate object file differences
   138  // only due to the choice of export format.
   139  // TODO(gri) disable and remove once there is only one export format again
   140  const forceObjFileStability = true
   141  
   142  // Current export format version. Increase with each format change.
   143  // 3: added aliasTag and export of aliases
   144  // 2: removed unused bool in ODCL export
   145  // 1: header format change (more regular), export package for _ struct fields
   146  // 0: Go1.7 encoding
   147  const exportVersion = 3
   148  
   149  // exportInlined enables the export of inlined function bodies and related
   150  // dependencies. The compiler should work w/o any loss of functionality with
   151  // the flag disabled, but the generated code will lose access to inlined
   152  // function bodies across packages, leading to performance bugs.
   153  // Leave for debugging.
   154  const exportInlined = true // default: true
   155  
   156  // trackAllTypes enables cycle tracking for all types, not just named
   157  // types. The existing compiler invariants assume that unnamed types
   158  // that are not completely set up are not used, or else there are spurious
   159  // errors.
   160  // If disabled, only named types are tracked, possibly leading to slightly
   161  // less efficient encoding in rare cases. It also prevents the export of
   162  // some corner-case type declarations (but those were not handled correctly
   163  // with the former textual export format either).
   164  // TODO(gri) enable and remove once issues caused by it are fixed
   165  const trackAllTypes = false
   166  
   167  type exporter struct {
   168  	out *bufio.Writer
   169  
   170  	// object -> index maps, indexed in order of serialization
   171  	strIndex map[string]int
   172  	pkgIndex map[*Pkg]int
   173  	typIndex map[*Type]int
   174  	funcList []*Func
   175  
   176  	// position encoding
   177  	posInfoFormat bool
   178  	prevFile      string
   179  	prevLine      int
   180  
   181  	// debugging support
   182  	written int // bytes written
   183  	indent  int // for p.trace
   184  	trace   bool
   185  
   186  	// work-around for issue #16369 only
   187  	nesting int // amount of "nesting" of interface types
   188  }
   189  
   190  // export writes the exportlist for localpkg to out and returns the number of bytes written.
   191  func export(out *bufio.Writer, trace bool) int {
   192  	p := exporter{
   193  		out:           out,
   194  		strIndex:      map[string]int{"": 0}, // empty string is mapped to 0
   195  		pkgIndex:      make(map[*Pkg]int),
   196  		typIndex:      make(map[*Type]int),
   197  		posInfoFormat: true,
   198  		trace:         trace,
   199  	}
   200  
   201  	// write version info
   202  	// The version string must start with "version %d" where %d is the version
   203  	// number. Additional debugging information may follow after a blank; that
   204  	// text is ignored by the importer.
   205  	p.rawStringln(fmt.Sprintf("version %d", exportVersion))
   206  	var debug string
   207  	if debugFormat {
   208  		debug = "debug"
   209  	}
   210  	p.rawStringln(debug) // cannot use p.bool since it's affected by debugFormat; also want to see this clearly
   211  	p.bool(trackAllTypes)
   212  	p.bool(p.posInfoFormat)
   213  
   214  	// --- generic export data ---
   215  
   216  	// populate type map with predeclared "known" types
   217  	predecl := predeclared()
   218  	for index, typ := range predecl {
   219  		p.typIndex[typ] = index
   220  	}
   221  	if len(p.typIndex) != len(predecl) {
   222  		Fatalf("exporter: duplicate entries in type map?")
   223  	}
   224  
   225  	// write package data
   226  	if localpkg.Path != "" {
   227  		Fatalf("exporter: local package path not empty: %q", localpkg.Path)
   228  	}
   229  	p.pkg(localpkg)
   230  	if p.trace {
   231  		p.tracef("\n")
   232  	}
   233  
   234  	// export objects
   235  	//
   236  	// First, export all exported (package-level) objects; i.e., all objects
   237  	// in the current exportlist. These objects represent all information
   238  	// required to import this package and type-check against it; i.e., this
   239  	// is the platform-independent export data. The format is generic in the
   240  	// sense that different compilers can use the same representation.
   241  	//
   242  	// During this first phase, more objects may be added to the exportlist
   243  	// (due to inlined function bodies and their dependencies). Export those
   244  	// objects in a second phase. That data is platform-specific as it depends
   245  	// on the inlining decisions of the compiler and the representation of the
   246  	// inlined function bodies.
   247  
   248  	// remember initial exportlist length
   249  	var numglobals = len(exportlist)
   250  
   251  	// Phase 1: Export objects in _current_ exportlist; exported objects at
   252  	//          package level.
   253  	// Use range since we want to ignore objects added to exportlist during
   254  	// this phase.
   255  	objcount := 0
   256  	for _, n := range exportlist {
   257  		sym := n.Sym
   258  
   259  		if sym.Flags&SymExported != 0 {
   260  			continue
   261  		}
   262  		sym.Flags |= SymExported
   263  
   264  		// TODO(gri) Closures have dots in their names;
   265  		// e.g., TestFloatZeroValue.func1 in math/big tests.
   266  		if strings.Contains(sym.Name, ".") {
   267  			Fatalf("exporter: unexpected symbol: %v", sym)
   268  		}
   269  
   270  		// TODO(gri) Should we do this check?
   271  		// if sym.Flags&SymExport == 0 {
   272  		// 	continue
   273  		// }
   274  
   275  		if sym.Def == nil {
   276  			Fatalf("exporter: unknown export symbol: %v", sym)
   277  		}
   278  
   279  		// TODO(gri) Optimization: Probably worthwhile collecting
   280  		// long runs of constants and export them "in bulk" (saving
   281  		// tags and types, and making import faster).
   282  
   283  		if p.trace {
   284  			p.tracef("\n")
   285  		}
   286  		p.obj(sym)
   287  		objcount++
   288  	}
   289  
   290  	// indicate end of list
   291  	if p.trace {
   292  		p.tracef("\n")
   293  	}
   294  	p.tag(endTag)
   295  
   296  	// for self-verification only (redundant)
   297  	p.int(objcount)
   298  
   299  	// --- compiler-specific export data ---
   300  
   301  	if p.trace {
   302  		p.tracef("\n--- compiler-specific export data ---\n[ ")
   303  		if p.indent != 0 {
   304  			Fatalf("exporter: incorrect indentation")
   305  		}
   306  	}
   307  
   308  	// write compiler-specific flags
   309  	if p.trace {
   310  		p.tracef("\n")
   311  	}
   312  
   313  	// Phase 2: Export objects added to exportlist during phase 1.
   314  	// Don't use range since exportlist may grow during this phase
   315  	// and we want to export all remaining objects.
   316  	objcount = 0
   317  	for i := numglobals; exportInlined && i < len(exportlist); i++ {
   318  		n := exportlist[i]
   319  		sym := n.Sym
   320  
   321  		// TODO(gri) The rest of this loop body is identical with
   322  		// the loop body above. Leave alone for now since there
   323  		// are different optimization opportunities, but factor
   324  		// eventually.
   325  
   326  		if sym.Flags&SymExported != 0 {
   327  			continue
   328  		}
   329  		sym.Flags |= SymExported
   330  
   331  		// TODO(gri) Closures have dots in their names;
   332  		// e.g., TestFloatZeroValue.func1 in math/big tests.
   333  		if strings.Contains(sym.Name, ".") {
   334  			Fatalf("exporter: unexpected symbol: %v", sym)
   335  		}
   336  
   337  		// TODO(gri) Should we do this check?
   338  		// if sym.Flags&SymExport == 0 {
   339  		// 	continue
   340  		// }
   341  
   342  		if sym.Def == nil {
   343  			Fatalf("exporter: unknown export symbol: %v", sym)
   344  		}
   345  
   346  		// TODO(gri) Optimization: Probably worthwhile collecting
   347  		// long runs of constants and export them "in bulk" (saving
   348  		// tags and types, and making import faster).
   349  
   350  		if p.trace {
   351  			p.tracef("\n")
   352  		}
   353  
   354  		if sym.Flags&SymAlias != 0 {
   355  			Fatalf("exporter: unexpected alias %v in inlined function body", sym)
   356  		}
   357  
   358  		p.obj(sym)
   359  		objcount++
   360  	}
   361  
   362  	// indicate end of list
   363  	if p.trace {
   364  		p.tracef("\n")
   365  	}
   366  	p.tag(endTag)
   367  
   368  	// for self-verification only (redundant)
   369  	p.int(objcount)
   370  
   371  	// --- inlined function bodies ---
   372  
   373  	if p.trace {
   374  		p.tracef("\n--- inlined function bodies ---\n")
   375  		if p.indent != 0 {
   376  			Fatalf("exporter: incorrect indentation")
   377  		}
   378  	}
   379  
   380  	// write inlineable function bodies
   381  	objcount = 0
   382  	for i, f := range p.funcList {
   383  		if f != nil {
   384  			// function has inlineable body:
   385  			// write index and body
   386  			if p.trace {
   387  				p.tracef("\n----\nfunc { %#v }\n", f.Inl)
   388  			}
   389  			p.int(i)
   390  			p.stmtList(f.Inl)
   391  			if p.trace {
   392  				p.tracef("\n")
   393  			}
   394  			objcount++
   395  		}
   396  	}
   397  
   398  	// indicate end of list
   399  	if p.trace {
   400  		p.tracef("\n")
   401  	}
   402  	p.int(-1) // invalid index terminates list
   403  
   404  	// for self-verification only (redundant)
   405  	p.int(objcount)
   406  
   407  	if p.trace {
   408  		p.tracef("\n--- end ---\n")
   409  	}
   410  
   411  	// --- end of export data ---
   412  
   413  	return p.written
   414  }
   415  
   416  func (p *exporter) pkg(pkg *Pkg) {
   417  	if pkg == nil {
   418  		Fatalf("exporter: unexpected nil pkg")
   419  	}
   420  
   421  	// if we saw the package before, write its index (>= 0)
   422  	if i, ok := p.pkgIndex[pkg]; ok {
   423  		p.index('P', i)
   424  		return
   425  	}
   426  
   427  	// otherwise, remember the package, write the package tag (< 0) and package data
   428  	if p.trace {
   429  		p.tracef("P%d = { ", len(p.pkgIndex))
   430  		defer p.tracef("} ")
   431  	}
   432  	p.pkgIndex[pkg] = len(p.pkgIndex)
   433  
   434  	p.tag(packageTag)
   435  	p.string(pkg.Name)
   436  	p.string(pkg.Path)
   437  }
   438  
   439  func unidealType(typ *Type, val Val) *Type {
   440  	// Untyped (ideal) constants get their own type. This decouples
   441  	// the constant type from the encoding of the constant value.
   442  	if typ == nil || typ.IsUntyped() {
   443  		typ = untype(val.Ctype())
   444  	}
   445  	return typ
   446  }
   447  
   448  func (p *exporter) obj(sym *Sym) {
   449  	if sym.Flags&SymAlias != 0 {
   450  		p.tag(aliasTag)
   451  		p.pos(nil) // TODO(gri) fix position information
   452  		// Aliases can only be exported from the package that
   453  		// declares them (aliases to aliases are resolved to the
   454  		// original object, and so are uses of aliases in inlined
   455  		// exported function bodies). Thus, we only need the alias
   456  		// name without package qualification.
   457  		if sym.Pkg != localpkg {
   458  			Fatalf("exporter: export of non-local alias: %v", sym)
   459  		}
   460  		p.string(sym.Name)
   461  		orig := sym.Def.Sym
   462  		if orig.Flags&SymAlias != 0 {
   463  			Fatalf("exporter: original object %v marked as alias", sym)
   464  		}
   465  		p.qualifiedName(orig)
   466  		return
   467  	}
   468  
   469  	if sym != sym.Def.Sym {
   470  		Fatalf("exporter: exported object %v is not original %v", sym, sym.Def.Sym)
   471  	}
   472  
   473  	// Exported objects may be from different packages because they
   474  	// may be re-exported via an exported alias or as dependencies in
   475  	// exported inlined function bodies. Thus, exported object names
   476  	// must be fully qualified.
   477  	//
   478  	// (This can only happen for aliased objects or during phase 2
   479  	// (exportInlined enabled) of object export. Unaliased Objects
   480  	// exported in phase 1 (compiler-indendepent objects) are by
   481  	// definition only the objects from the current package and not
   482  	// pulled in via inlined function bodies. In that case the package
   483  	// qualifier is not needed. Possible space optimization.)
   484  
   485  	n := sym.Def
   486  	switch n.Op {
   487  	case OLITERAL:
   488  		// constant
   489  		// TODO(gri) determine if we need the typecheck call here
   490  		n = typecheck(n, Erv)
   491  		if n == nil || n.Op != OLITERAL {
   492  			Fatalf("exporter: dumpexportconst: oconst nil: %v", sym)
   493  		}
   494  
   495  		p.tag(constTag)
   496  		p.pos(n)
   497  		// TODO(gri) In inlined functions, constants are used directly
   498  		// so they should never occur as re-exported objects. We may
   499  		// not need the qualified name here. See also comment above.
   500  		// Possible space optimization.
   501  		p.qualifiedName(sym)
   502  		p.typ(unidealType(n.Type, n.Val()))
   503  		p.value(n.Val())
   504  
   505  	case OTYPE:
   506  		// named type
   507  		t := n.Type
   508  		if t.Etype == TFORW {
   509  			Fatalf("exporter: export of incomplete type %v", sym)
   510  		}
   511  
   512  		p.tag(typeTag)
   513  		p.typ(t)
   514  
   515  	case ONAME:
   516  		// variable or function
   517  		n = typecheck(n, Erv|Ecall)
   518  		if n == nil || n.Type == nil {
   519  			Fatalf("exporter: variable/function exported but not defined: %v", sym)
   520  		}
   521  
   522  		if n.Type.Etype == TFUNC && n.Class == PFUNC {
   523  			// function
   524  			p.tag(funcTag)
   525  			p.pos(n)
   526  			p.qualifiedName(sym)
   527  
   528  			sig := sym.Def.Type
   529  			inlineable := isInlineable(sym.Def)
   530  
   531  			p.paramList(sig.Params(), inlineable)
   532  			p.paramList(sig.Results(), inlineable)
   533  
   534  			var f *Func
   535  			if inlineable {
   536  				f = sym.Def.Func
   537  				// TODO(gri) re-examine reexportdeplist:
   538  				// Because we can trivially export types
   539  				// in-place, we don't need to collect types
   540  				// inside function bodies in the exportlist.
   541  				// With an adjusted reexportdeplist used only
   542  				// by the binary exporter, we can also avoid
   543  				// the global exportlist.
   544  				reexportdeplist(f.Inl)
   545  			}
   546  			p.funcList = append(p.funcList, f)
   547  		} else {
   548  			// variable
   549  			p.tag(varTag)
   550  			p.pos(n)
   551  			p.qualifiedName(sym)
   552  			p.typ(sym.Def.Type)
   553  		}
   554  
   555  	default:
   556  		Fatalf("exporter: unexpected export symbol: %v %v", n.Op, sym)
   557  	}
   558  }
   559  
   560  func (p *exporter) pos(n *Node) {
   561  	if !p.posInfoFormat {
   562  		return
   563  	}
   564  
   565  	file, line := fileLine(n)
   566  	if file == p.prevFile {
   567  		// common case: write line delta
   568  		// delta == 0 means different file or no line change
   569  		delta := line - p.prevLine
   570  		p.int(delta)
   571  		if delta == 0 {
   572  			p.int(-1) // -1 means no file change
   573  		}
   574  	} else {
   575  		// different file
   576  		p.int(0)
   577  		// Encode filename as length of common prefix with previous
   578  		// filename, followed by (possibly empty) suffix. Filenames
   579  		// frequently share path prefixes, so this can save a lot
   580  		// of space and make export data size less dependent on file
   581  		// path length. The suffix is unlikely to be empty because
   582  		// file names tend to end in ".go".
   583  		n := commonPrefixLen(p.prevFile, file)
   584  		p.int(n)           // n >= 0
   585  		p.string(file[n:]) // write suffix only
   586  		p.prevFile = file
   587  		p.int(line)
   588  	}
   589  	p.prevLine = line
   590  }
   591  
   592  func fileLine(n *Node) (file string, line int) {
   593  	if n != nil {
   594  		file, line = Ctxt.LineHist.AbsFileLine(int(n.Lineno))
   595  	}
   596  	return
   597  }
   598  
   599  func commonPrefixLen(a, b string) int {
   600  	if len(a) > len(b) {
   601  		a, b = b, a
   602  	}
   603  	// len(a) <= len(b)
   604  	i := 0
   605  	for i < len(a) && a[i] == b[i] {
   606  		i++
   607  	}
   608  	return i
   609  }
   610  
   611  func isInlineable(n *Node) bool {
   612  	if exportInlined && n != nil && n.Func != nil && n.Func.Inl.Len() != 0 {
   613  		// when lazily typechecking inlined bodies, some re-exported ones may not have been typechecked yet.
   614  		// currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package
   615  		if Debug['l'] < 2 {
   616  			typecheckinl(n)
   617  		}
   618  		return true
   619  	}
   620  	return false
   621  }
   622  
   623  var errorInterface *Type // lazily initialized
   624  
   625  func (p *exporter) typ(t *Type) {
   626  	if t == nil {
   627  		Fatalf("exporter: nil type")
   628  	}
   629  
   630  	// Possible optimization: Anonymous pointer types *T where
   631  	// T is a named type are common. We could canonicalize all
   632  	// such types *T to a single type PT = *T. This would lead
   633  	// to at most one *T entry in typIndex, and all future *T's
   634  	// would be encoded as the respective index directly. Would
   635  	// save 1 byte (pointerTag) per *T and reduce the typIndex
   636  	// size (at the cost of a canonicalization map). We can do
   637  	// this later, without encoding format change.
   638  
   639  	// if we saw the type before, write its index (>= 0)
   640  	if i, ok := p.typIndex[t]; ok {
   641  		p.index('T', i)
   642  		return
   643  	}
   644  
   645  	// otherwise, remember the type, write the type tag (< 0) and type data
   646  	if trackAllTypes {
   647  		if p.trace {
   648  			p.tracef("T%d = {>\n", len(p.typIndex))
   649  			defer p.tracef("<\n} ")
   650  		}
   651  		p.typIndex[t] = len(p.typIndex)
   652  	}
   653  
   654  	// pick off named types
   655  	if tsym := t.Sym; tsym != nil {
   656  		if !trackAllTypes {
   657  			// if we don't track all types, track named types now
   658  			p.typIndex[t] = len(p.typIndex)
   659  		}
   660  
   661  		// Predeclared types should have been found in the type map.
   662  		if t.Orig == t {
   663  			Fatalf("exporter: predeclared type missing from type map?")
   664  		}
   665  
   666  		n := typenod(t)
   667  		if n.Type != t {
   668  			Fatalf("exporter: named type definition incorrectly set up")
   669  		}
   670  
   671  		p.tag(namedTag)
   672  		p.pos(n)
   673  		p.qualifiedName(tsym)
   674  
   675  		// write underlying type
   676  		orig := t.Orig
   677  		if orig == errortype {
   678  			// The error type is the only predeclared type which has
   679  			// a composite underlying type. When we encode that type,
   680  			// make sure to encode the underlying interface rather than
   681  			// the named type again. See also the comment in universe.go
   682  			// regarding the errortype and issue #15920.
   683  			if errorInterface == nil {
   684  				errorInterface = makeErrorInterface()
   685  			}
   686  			orig = errorInterface
   687  		}
   688  		p.typ(orig)
   689  
   690  		// interfaces don't have associated methods
   691  		if t.Orig.IsInterface() {
   692  			return
   693  		}
   694  
   695  		// sort methods for reproducible export format
   696  		// TODO(gri) Determine if they are already sorted
   697  		// in which case we can drop this step.
   698  		var methods []*Field
   699  		for _, m := range t.Methods().Slice() {
   700  			methods = append(methods, m)
   701  		}
   702  		sort.Sort(methodbyname(methods))
   703  		p.int(len(methods))
   704  
   705  		if p.trace && len(methods) > 0 {
   706  			p.tracef("associated methods {>")
   707  		}
   708  
   709  		for _, m := range methods {
   710  			if p.trace {
   711  				p.tracef("\n")
   712  			}
   713  			if strings.Contains(m.Sym.Name, ".") {
   714  				Fatalf("invalid symbol name: %s (%v)", m.Sym.Name, m.Sym)
   715  			}
   716  
   717  			p.pos(m.Nname)
   718  			p.fieldSym(m.Sym, false)
   719  
   720  			sig := m.Type
   721  			mfn := sig.Nname()
   722  			inlineable := isInlineable(mfn)
   723  
   724  			p.paramList(sig.Recvs(), inlineable)
   725  			p.paramList(sig.Params(), inlineable)
   726  			p.paramList(sig.Results(), inlineable)
   727  			p.bool(m.Nointerface) // record go:nointerface pragma value (see also #16243)
   728  
   729  			var f *Func
   730  			if inlineable {
   731  				f = mfn.Func
   732  				reexportdeplist(mfn.Func.Inl)
   733  			}
   734  			p.funcList = append(p.funcList, f)
   735  		}
   736  
   737  		if p.trace && len(methods) > 0 {
   738  			p.tracef("<\n} ")
   739  		}
   740  
   741  		return
   742  	}
   743  
   744  	// otherwise we have a type literal
   745  	switch t.Etype {
   746  	case TARRAY:
   747  		if t.isDDDArray() {
   748  			Fatalf("array bounds should be known at export time: %v", t)
   749  		}
   750  		p.tag(arrayTag)
   751  		p.int64(t.NumElem())
   752  		p.typ(t.Elem())
   753  
   754  	case TSLICE:
   755  		p.tag(sliceTag)
   756  		p.typ(t.Elem())
   757  
   758  	case TDDDFIELD:
   759  		// see p.param use of TDDDFIELD
   760  		p.tag(dddTag)
   761  		p.typ(t.DDDField())
   762  
   763  	case TSTRUCT:
   764  		p.tag(structTag)
   765  		p.fieldList(t)
   766  
   767  	case TPTR32, TPTR64: // could use Tptr but these are constants
   768  		p.tag(pointerTag)
   769  		p.typ(t.Elem())
   770  
   771  	case TFUNC:
   772  		p.tag(signatureTag)
   773  		p.paramList(t.Params(), false)
   774  		p.paramList(t.Results(), false)
   775  
   776  	case TINTER:
   777  		p.tag(interfaceTag)
   778  		// gc doesn't separate between embedded interfaces
   779  		// and methods declared explicitly with an interface
   780  		p.int(0) // no embedded interfaces
   781  
   782  		// Because the compiler flattens interfaces containing
   783  		// embedded interfaces, it is possible to create interface
   784  		// types that recur through an unnamed type.
   785  		// If trackAllTypes is disabled, such recursion is not
   786  		// detected, leading to a stack overflow during export
   787  		// (issue #16369).
   788  		// As a crude work-around we terminate deep recursion
   789  		// through interface types with an empty interface and
   790  		// report an error.
   791  		// This will catch endless recursion, but is unlikely
   792  		// to trigger for valid, deeply nested types given the
   793  		// high threshold.
   794  		// It would be ok to continue without reporting an error
   795  		// since the export format is valid. But a subsequent
   796  		// import would import an incorrect type. The textual
   797  		// exporter does not report an error but importing the
   798  		// resulting package will lead to a syntax error during
   799  		// import.
   800  		// TODO(gri) remove this once we have a permanent fix
   801  		// for the issue.
   802  		if p.nesting > 100 {
   803  			p.int(0) // 0 methods to indicate empty interface
   804  			yyerrorl(t.Lineno, "cannot export unnamed recursive interface")
   805  			break
   806  		}
   807  
   808  		p.nesting++
   809  		p.methodList(t)
   810  		p.nesting--
   811  
   812  	case TMAP:
   813  		p.tag(mapTag)
   814  		p.typ(t.Key())
   815  		p.typ(t.Val())
   816  
   817  	case TCHAN:
   818  		p.tag(chanTag)
   819  		p.int(int(t.ChanDir()))
   820  		p.typ(t.Elem())
   821  
   822  	default:
   823  		Fatalf("exporter: unexpected type: %v (Etype = %d)", t, t.Etype)
   824  	}
   825  }
   826  
   827  func (p *exporter) qualifiedName(sym *Sym) {
   828  	p.string(sym.Name)
   829  	p.pkg(sym.Pkg)
   830  }
   831  
   832  func (p *exporter) fieldList(t *Type) {
   833  	if p.trace && t.NumFields() > 0 {
   834  		p.tracef("fields {>")
   835  		defer p.tracef("<\n} ")
   836  	}
   837  
   838  	p.int(t.NumFields())
   839  	for _, f := range t.Fields().Slice() {
   840  		if p.trace {
   841  			p.tracef("\n")
   842  		}
   843  		p.field(f)
   844  	}
   845  }
   846  
   847  func (p *exporter) field(f *Field) {
   848  	p.pos(f.Nname)
   849  	p.fieldName(f)
   850  	p.typ(f.Type)
   851  	p.string(f.Note)
   852  }
   853  
   854  func (p *exporter) methodList(t *Type) {
   855  	if p.trace && t.NumFields() > 0 {
   856  		p.tracef("methods {>")
   857  		defer p.tracef("<\n} ")
   858  	}
   859  
   860  	p.int(t.NumFields())
   861  	for _, m := range t.Fields().Slice() {
   862  		if p.trace {
   863  			p.tracef("\n")
   864  		}
   865  		p.method(m)
   866  	}
   867  }
   868  
   869  func (p *exporter) method(m *Field) {
   870  	p.pos(m.Nname)
   871  	p.fieldName(m)
   872  	p.paramList(m.Type.Params(), false)
   873  	p.paramList(m.Type.Results(), false)
   874  }
   875  
   876  // fieldName is like qualifiedName but it doesn't record the package for exported names.
   877  func (p *exporter) fieldName(t *Field) {
   878  	name := t.Sym.Name
   879  	if t.Embedded != 0 {
   880  		name = "" // anonymous field
   881  		if bname := basetypeName(t.Type); bname != "" && !exportname(bname) {
   882  			// anonymous field with unexported base type name
   883  			name = "?" // unexported name to force export of package
   884  		}
   885  	}
   886  	p.string(name)
   887  	if name != "" && !exportname(name) {
   888  		p.pkg(t.Sym.Pkg)
   889  	}
   890  }
   891  
   892  func basetypeName(t *Type) string {
   893  	s := t.Sym
   894  	if s == nil && t.IsPtr() {
   895  		s = t.Elem().Sym // deref
   896  	}
   897  	// s should exist, but be conservative
   898  	if s != nil {
   899  		return s.Name
   900  	}
   901  	return ""
   902  }
   903  
   904  func (p *exporter) paramList(params *Type, numbered bool) {
   905  	if !params.IsFuncArgStruct() {
   906  		Fatalf("exporter: parameter list expected")
   907  	}
   908  
   909  	// use negative length to indicate unnamed parameters
   910  	// (look at the first parameter only since either all
   911  	// names are present or all are absent)
   912  	//
   913  	// TODO(gri) If we don't have an exported function
   914  	// body, the parameter names are irrelevant for the
   915  	// compiler (though they may be of use for other tools).
   916  	// Possible space optimization.
   917  	n := params.NumFields()
   918  	if n > 0 && parName(params.Field(0), numbered) == "" {
   919  		n = -n
   920  	}
   921  	p.int(n)
   922  	for _, q := range params.Fields().Slice() {
   923  		p.param(q, n, numbered)
   924  	}
   925  }
   926  
   927  func (p *exporter) param(q *Field, n int, numbered bool) {
   928  	t := q.Type
   929  	if q.Isddd {
   930  		// create a fake type to encode ... just for the p.typ call
   931  		t = typDDDField(t.Elem())
   932  	}
   933  	p.typ(t)
   934  	if n > 0 {
   935  		name := parName(q, numbered)
   936  		if name == "" {
   937  			// Sometimes we see an empty name even for n > 0.
   938  			// This appears to happen for interface methods
   939  			// with _ (blank) parameter names. Make sure we
   940  			// have a proper name and package so we don't crash
   941  			// during import (see also issue #15470).
   942  			// (parName uses "" instead of "?" as in fmt.go)
   943  			// TODO(gri) review parameter name encoding
   944  			name = "_"
   945  		}
   946  		p.string(name)
   947  		if name != "_" {
   948  			// Because of (re-)exported inlined functions
   949  			// the importpkg may not be the package to which this
   950  			// function (and thus its parameter) belongs. We need to
   951  			// supply the parameter package here. We need the package
   952  			// when the function is inlined so we can properly resolve
   953  			// the name. The _ (blank) parameter cannot be accessed, so
   954  			// we don't need to export a package.
   955  			//
   956  			// TODO(gri) This is compiler-specific. Try using importpkg
   957  			// here and then update the symbols if we find an inlined
   958  			// body only. Otherwise, the parameter name is ignored and
   959  			// the package doesn't matter. This would remove an int
   960  			// (likely 1 byte) for each named parameter.
   961  			p.pkg(q.Sym.Pkg)
   962  		}
   963  	}
   964  	// TODO(gri) This is compiler-specific (escape info).
   965  	// Move into compiler-specific section eventually?
   966  	// (Not having escape info causes tests to fail, e.g. runtime GCInfoTest)
   967  	p.string(q.Note)
   968  }
   969  
   970  func parName(f *Field, numbered bool) string {
   971  	s := f.Sym
   972  	if s == nil {
   973  		return ""
   974  	}
   975  
   976  	// Take the name from the original, lest we substituted it with ~r%d or ~b%d.
   977  	// ~r%d is a (formerly) unnamed result.
   978  	if f.Nname != nil {
   979  		if f.Nname.Orig != nil {
   980  			s = f.Nname.Orig.Sym
   981  			if s != nil && s.Name[0] == '~' {
   982  				if s.Name[1] == 'r' { // originally an unnamed result
   983  					return "" // s = nil
   984  				} else if s.Name[1] == 'b' { // originally the blank identifier _
   985  					return "_" // belongs to localpkg
   986  				}
   987  			}
   988  		} else {
   989  			return "" // s = nil
   990  		}
   991  	}
   992  
   993  	if s == nil {
   994  		return ""
   995  	}
   996  
   997  	// print symbol with Vargen number or not as desired
   998  	name := s.Name
   999  	if strings.Contains(name, ".") {
  1000  		Fatalf("invalid symbol name: %s", name)
  1001  	}
  1002  
  1003  	// Functions that can be inlined use numbered parameters so we can distinguish them
  1004  	// from other names in their context after inlining (i.e., the parameter numbering
  1005  	// is a form of parameter rewriting). See issue 4326 for an example and test case.
  1006  	if forceObjFileStability || numbered {
  1007  		if !strings.Contains(name, "·") && f.Nname != nil && f.Nname.Name != nil && f.Nname.Name.Vargen > 0 {
  1008  			name = fmt.Sprintf("%s·%d", name, f.Nname.Name.Vargen) // append Vargen
  1009  		}
  1010  	} else {
  1011  		if i := strings.Index(name, "·"); i > 0 {
  1012  			name = name[:i] // cut off Vargen
  1013  		}
  1014  	}
  1015  	return name
  1016  }
  1017  
  1018  func (p *exporter) value(x Val) {
  1019  	if p.trace {
  1020  		p.tracef("= ")
  1021  	}
  1022  
  1023  	switch x := x.U.(type) {
  1024  	case bool:
  1025  		tag := falseTag
  1026  		if x {
  1027  			tag = trueTag
  1028  		}
  1029  		p.tag(tag)
  1030  
  1031  	case *Mpint:
  1032  		if minintval[TINT64].Cmp(x) <= 0 && x.Cmp(maxintval[TINT64]) <= 0 {
  1033  			// common case: x fits into an int64 - use compact encoding
  1034  			p.tag(int64Tag)
  1035  			p.int64(x.Int64())
  1036  			return
  1037  		}
  1038  		// uncommon case: large x - use float encoding
  1039  		// (powers of 2 will be encoded efficiently with exponent)
  1040  		f := newMpflt()
  1041  		f.SetInt(x)
  1042  		p.tag(floatTag)
  1043  		p.float(f)
  1044  
  1045  	case *Mpflt:
  1046  		p.tag(floatTag)
  1047  		p.float(x)
  1048  
  1049  	case *Mpcplx:
  1050  		p.tag(complexTag)
  1051  		p.float(&x.Real)
  1052  		p.float(&x.Imag)
  1053  
  1054  	case string:
  1055  		p.tag(stringTag)
  1056  		p.string(x)
  1057  
  1058  	case *NilVal:
  1059  		// not a constant but used in exported function bodies
  1060  		p.tag(nilTag)
  1061  
  1062  	default:
  1063  		Fatalf("exporter: unexpected value %v (%T)", x, x)
  1064  	}
  1065  }
  1066  
  1067  func (p *exporter) float(x *Mpflt) {
  1068  	// extract sign (there is no -0)
  1069  	f := &x.Val
  1070  	sign := f.Sign()
  1071  	if sign == 0 {
  1072  		// x == 0
  1073  		p.int(0)
  1074  		return
  1075  	}
  1076  	// x != 0
  1077  
  1078  	// extract exponent such that 0.5 <= m < 1.0
  1079  	var m big.Float
  1080  	exp := f.MantExp(&m)
  1081  
  1082  	// extract mantissa as *big.Int
  1083  	// - set exponent large enough so mant satisfies mant.IsInt()
  1084  	// - get *big.Int from mant
  1085  	m.SetMantExp(&m, int(m.MinPrec()))
  1086  	mant, acc := m.Int(nil)
  1087  	if acc != big.Exact {
  1088  		Fatalf("exporter: internal error")
  1089  	}
  1090  
  1091  	p.int(sign)
  1092  	p.int(exp)
  1093  	p.string(string(mant.Bytes()))
  1094  }
  1095  
  1096  // ----------------------------------------------------------------------------
  1097  // Inlined function bodies
  1098  
  1099  // Approach: More or less closely follow what fmt.go is doing for FExp mode
  1100  // but instead of emitting the information textually, emit the node tree in
  1101  // binary form.
  1102  
  1103  // TODO(gri) Improve tracing output. The current format is difficult to read.
  1104  
  1105  // stmtList may emit more (or fewer) than len(list) nodes.
  1106  func (p *exporter) stmtList(list Nodes) {
  1107  	if p.trace {
  1108  		if list.Len() == 0 {
  1109  			p.tracef("{}")
  1110  		} else {
  1111  			p.tracef("{>")
  1112  			defer p.tracef("<\n}")
  1113  		}
  1114  	}
  1115  
  1116  	for _, n := range list.Slice() {
  1117  		if p.trace {
  1118  			p.tracef("\n")
  1119  		}
  1120  		// TODO inlining produces expressions with ninits. we can't export these yet.
  1121  		// (from fmt.go:1461ff)
  1122  		if opprec[n.Op] < 0 {
  1123  			p.stmt(n)
  1124  		} else {
  1125  			p.expr(n)
  1126  		}
  1127  	}
  1128  
  1129  	p.op(OEND)
  1130  }
  1131  
  1132  func (p *exporter) exprList(list Nodes) {
  1133  	if p.trace {
  1134  		if list.Len() == 0 {
  1135  			p.tracef("{}")
  1136  		} else {
  1137  			p.tracef("{>")
  1138  			defer p.tracef("<\n}")
  1139  		}
  1140  	}
  1141  
  1142  	for _, n := range list.Slice() {
  1143  		if p.trace {
  1144  			p.tracef("\n")
  1145  		}
  1146  		p.expr(n)
  1147  	}
  1148  
  1149  	p.op(OEND)
  1150  }
  1151  
  1152  func (p *exporter) elemList(list Nodes) {
  1153  	if p.trace {
  1154  		p.tracef("[ ")
  1155  	}
  1156  	p.int(list.Len())
  1157  	if p.trace {
  1158  		if list.Len() == 0 {
  1159  			p.tracef("] {}")
  1160  		} else {
  1161  			p.tracef("] {>")
  1162  			defer p.tracef("<\n}")
  1163  		}
  1164  	}
  1165  
  1166  	for _, n := range list.Slice() {
  1167  		if p.trace {
  1168  			p.tracef("\n")
  1169  		}
  1170  		p.fieldSym(n.Sym, false)
  1171  		p.expr(n.Left)
  1172  	}
  1173  }
  1174  
  1175  func (p *exporter) expr(n *Node) {
  1176  	if p.trace {
  1177  		p.tracef("( ")
  1178  		defer p.tracef(") ")
  1179  	}
  1180  
  1181  	// from nodefmt (fmt.go)
  1182  	//
  1183  	// nodefmt reverts nodes back to their original - we don't need to do
  1184  	// it because we are not bound to produce valid Go syntax when exporting
  1185  	//
  1186  	// if (fmtmode != FExp || n.Op != OLITERAL) && n.Orig != nil {
  1187  	// 	n = n.Orig
  1188  	// }
  1189  
  1190  	// from exprfmt (fmt.go)
  1191  	for n != nil && n.Implicit && (n.Op == OIND || n.Op == OADDR) {
  1192  		n = n.Left
  1193  	}
  1194  
  1195  	switch op := n.Op; op {
  1196  	// expressions
  1197  	// (somewhat closely following the structure of exprfmt in fmt.go)
  1198  	case OPAREN:
  1199  		p.expr(n.Left) // unparen
  1200  
  1201  	// case ODDDARG:
  1202  	//	unimplemented - handled by default case
  1203  
  1204  	case OLITERAL:
  1205  		if n.Val().Ctype() == CTNIL && n.Orig != nil && n.Orig != n {
  1206  			p.expr(n.Orig)
  1207  			break
  1208  		}
  1209  		p.op(OLITERAL)
  1210  		p.typ(unidealType(n.Type, n.Val()))
  1211  		p.value(n.Val())
  1212  
  1213  	case ONAME:
  1214  		// Special case: name used as local variable in export.
  1215  		// _ becomes ~b%d internally; print as _ for export
  1216  		if n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
  1217  			p.op(ONAME)
  1218  			p.string("_") // inlined and customized version of p.sym(n)
  1219  			break
  1220  		}
  1221  
  1222  		if n.Sym != nil && !isblank(n) && n.Name.Vargen > 0 {
  1223  			p.op(ONAME)
  1224  			p.sym(n)
  1225  			break
  1226  		}
  1227  
  1228  		// Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method,
  1229  		// but for export, this should be rendered as (*pkg.T).meth.
  1230  		// These nodes have the special property that they are names with a left OTYPE and a right ONAME.
  1231  		if n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME {
  1232  			p.op(OXDOT)
  1233  			p.expr(n.Left) // n.Left.Op == OTYPE
  1234  			p.fieldSym(n.Right.Sym, true)
  1235  			break
  1236  		}
  1237  
  1238  		p.op(ONAME)
  1239  		p.sym(n)
  1240  
  1241  	// case OPACK, ONONAME:
  1242  	// 	should have been resolved by typechecking - handled by default case
  1243  
  1244  	case OTYPE:
  1245  		p.op(OTYPE)
  1246  		if p.bool(n.Type == nil) {
  1247  			p.sym(n)
  1248  		} else {
  1249  			p.typ(n.Type)
  1250  		}
  1251  
  1252  	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
  1253  	// 	should have been resolved by typechecking - handled by default case
  1254  
  1255  	// case OCLOSURE:
  1256  	//	unimplemented - handled by default case
  1257  
  1258  	// case OCOMPLIT:
  1259  	// 	should have been resolved by typechecking - handled by default case
  1260  
  1261  	case OPTRLIT:
  1262  		p.op(OPTRLIT)
  1263  		p.expr(n.Left)
  1264  		p.bool(n.Implicit)
  1265  
  1266  	case OSTRUCTLIT:
  1267  		p.op(OSTRUCTLIT)
  1268  		p.typ(n.Type)
  1269  		p.elemList(n.List) // special handling of field names
  1270  
  1271  	case OARRAYLIT, OSLICELIT, OMAPLIT:
  1272  		p.op(OCOMPLIT)
  1273  		p.typ(n.Type)
  1274  		p.exprList(n.List)
  1275  
  1276  	case OKEY:
  1277  		p.op(OKEY)
  1278  		p.exprsOrNil(n.Left, n.Right)
  1279  
  1280  	// case OSTRUCTKEY:
  1281  	//	unreachable - handled in case OSTRUCTLIT by elemList
  1282  
  1283  	// case OCALLPART:
  1284  	//	unimplemented - handled by default case
  1285  
  1286  	case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
  1287  		p.op(OXDOT)
  1288  		p.expr(n.Left)
  1289  		p.fieldSym(n.Sym, true)
  1290  
  1291  	case ODOTTYPE, ODOTTYPE2:
  1292  		p.op(ODOTTYPE)
  1293  		p.expr(n.Left)
  1294  		if p.bool(n.Right != nil) {
  1295  			p.expr(n.Right)
  1296  		} else {
  1297  			p.typ(n.Type)
  1298  		}
  1299  
  1300  	case OINDEX, OINDEXMAP:
  1301  		p.op(OINDEX)
  1302  		p.expr(n.Left)
  1303  		p.expr(n.Right)
  1304  
  1305  	case OSLICE, OSLICESTR, OSLICEARR:
  1306  		p.op(OSLICE)
  1307  		p.expr(n.Left)
  1308  		low, high, _ := n.SliceBounds()
  1309  		p.exprsOrNil(low, high)
  1310  
  1311  	case OSLICE3, OSLICE3ARR:
  1312  		p.op(OSLICE3)
  1313  		p.expr(n.Left)
  1314  		low, high, max := n.SliceBounds()
  1315  		p.exprsOrNil(low, high)
  1316  		p.expr(max)
  1317  
  1318  	case OCOPY, OCOMPLEX:
  1319  		// treated like other builtin calls (see e.g., OREAL)
  1320  		p.op(op)
  1321  		p.expr(n.Left)
  1322  		p.expr(n.Right)
  1323  		p.op(OEND)
  1324  
  1325  	case OCONV, OCONVIFACE, OCONVNOP, OARRAYBYTESTR, OARRAYRUNESTR, OSTRARRAYBYTE, OSTRARRAYRUNE, ORUNESTR:
  1326  		p.op(OCONV)
  1327  		p.typ(n.Type)
  1328  		if n.Left != nil {
  1329  			p.expr(n.Left)
  1330  			p.op(OEND)
  1331  		} else {
  1332  			p.exprList(n.List) // emits terminating OEND
  1333  		}
  1334  
  1335  	case OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
  1336  		p.op(op)
  1337  		if n.Left != nil {
  1338  			p.expr(n.Left)
  1339  			p.op(OEND)
  1340  		} else {
  1341  			p.exprList(n.List) // emits terminating OEND
  1342  		}
  1343  		// only append() calls may contain '...' arguments
  1344  		if op == OAPPEND {
  1345  			p.bool(n.Isddd)
  1346  		} else if n.Isddd {
  1347  			Fatalf("exporter: unexpected '...' with %s call", opnames[op])
  1348  		}
  1349  
  1350  	case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
  1351  		p.op(OCALL)
  1352  		p.expr(n.Left)
  1353  		p.exprList(n.List)
  1354  		p.bool(n.Isddd)
  1355  
  1356  	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
  1357  		p.op(op) // must keep separate from OMAKE for importer
  1358  		p.typ(n.Type)
  1359  		switch {
  1360  		default:
  1361  			// empty list
  1362  			p.op(OEND)
  1363  		case n.List.Len() != 0: // pre-typecheck
  1364  			p.exprList(n.List) // emits terminating OEND
  1365  		case n.Right != nil:
  1366  			p.expr(n.Left)
  1367  			p.expr(n.Right)
  1368  			p.op(OEND)
  1369  		case n.Left != nil && (n.Op == OMAKESLICE || !n.Left.Type.IsUntyped()):
  1370  			p.expr(n.Left)
  1371  			p.op(OEND)
  1372  		}
  1373  
  1374  	// unary expressions
  1375  	case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV:
  1376  		p.op(op)
  1377  		p.expr(n.Left)
  1378  
  1379  	// binary expressions
  1380  	case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
  1381  		OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
  1382  		p.op(op)
  1383  		p.expr(n.Left)
  1384  		p.expr(n.Right)
  1385  
  1386  	case OADDSTR:
  1387  		p.op(OADDSTR)
  1388  		p.exprList(n.List)
  1389  
  1390  	case OCMPSTR, OCMPIFACE:
  1391  		p.op(Op(n.Etype))
  1392  		p.expr(n.Left)
  1393  		p.expr(n.Right)
  1394  
  1395  	case ODCLCONST:
  1396  		// if exporting, DCLCONST should just be removed as its usage
  1397  		// has already been replaced with literals
  1398  		// TODO(gri) these should not be exported in the first place
  1399  		// TODO(gri) why is this considered an expression in fmt.go?
  1400  		p.op(ODCLCONST)
  1401  
  1402  	default:
  1403  		Fatalf("cannot export %v (%d) node\n"+
  1404  			"==> please file an issue and assign to gri@\n", n.Op, int(n.Op))
  1405  	}
  1406  }
  1407  
  1408  // Caution: stmt will emit more than one node for statement nodes n that have a non-empty
  1409  // n.Ninit and where n cannot have a natural init section (such as in "if", "for", etc.).
  1410  func (p *exporter) stmt(n *Node) {
  1411  	if p.trace {
  1412  		p.tracef("( ")
  1413  		defer p.tracef(") ")
  1414  	}
  1415  
  1416  	if n.Ninit.Len() > 0 && !stmtwithinit(n.Op) {
  1417  		if p.trace {
  1418  			p.tracef("( /* Ninits */ ")
  1419  		}
  1420  
  1421  		// can't use stmtList here since we don't want the final OEND
  1422  		for _, n := range n.Ninit.Slice() {
  1423  			p.stmt(n)
  1424  		}
  1425  
  1426  		if p.trace {
  1427  			p.tracef(") ")
  1428  		}
  1429  	}
  1430  
  1431  	switch op := n.Op; op {
  1432  	case ODCL:
  1433  		p.op(ODCL)
  1434  		p.sym(n.Left)
  1435  		p.typ(n.Left.Type)
  1436  
  1437  	// case ODCLFIELD:
  1438  	//	unimplemented - handled by default case
  1439  
  1440  	case OAS, OASWB:
  1441  		// Don't export "v = <N>" initializing statements, hope they're always
  1442  		// preceded by the DCL which will be re-parsed and typecheck to reproduce
  1443  		// the "v = <N>" again.
  1444  		if n.Right != nil {
  1445  			p.op(OAS)
  1446  			p.expr(n.Left)
  1447  			p.expr(n.Right)
  1448  		}
  1449  
  1450  	case OASOP:
  1451  		p.op(OASOP)
  1452  		p.int(int(n.Etype))
  1453  		p.expr(n.Left)
  1454  		if p.bool(!n.Implicit) {
  1455  			p.expr(n.Right)
  1456  		}
  1457  
  1458  	case OAS2, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
  1459  		p.op(OAS2)
  1460  		p.exprList(n.List)
  1461  		p.exprList(n.Rlist)
  1462  
  1463  	case ORETURN:
  1464  		p.op(ORETURN)
  1465  		p.exprList(n.List)
  1466  
  1467  	// case ORETJMP:
  1468  	// 	unreachable - generated by compiler for trampolin routines
  1469  
  1470  	case OPROC, ODEFER:
  1471  		p.op(op)
  1472  		p.expr(n.Left)
  1473  
  1474  	case OIF:
  1475  		p.op(OIF)
  1476  		p.stmtList(n.Ninit)
  1477  		p.expr(n.Left)
  1478  		p.stmtList(n.Nbody)
  1479  		p.stmtList(n.Rlist)
  1480  
  1481  	case OFOR:
  1482  		p.op(OFOR)
  1483  		p.stmtList(n.Ninit)
  1484  		p.exprsOrNil(n.Left, n.Right)
  1485  		p.stmtList(n.Nbody)
  1486  
  1487  	case ORANGE:
  1488  		p.op(ORANGE)
  1489  		p.stmtList(n.List)
  1490  		p.expr(n.Right)
  1491  		p.stmtList(n.Nbody)
  1492  
  1493  	case OSELECT, OSWITCH:
  1494  		p.op(op)
  1495  		p.stmtList(n.Ninit)
  1496  		p.exprsOrNil(n.Left, nil)
  1497  		p.stmtList(n.List)
  1498  
  1499  	case OCASE, OXCASE:
  1500  		p.op(OXCASE)
  1501  		p.stmtList(n.List)
  1502  		p.stmtList(n.Nbody)
  1503  
  1504  	case OFALL, OXFALL:
  1505  		p.op(OXFALL)
  1506  
  1507  	case OBREAK, OCONTINUE:
  1508  		p.op(op)
  1509  		p.exprsOrNil(n.Left, nil)
  1510  
  1511  	case OEMPTY:
  1512  		// nothing to emit
  1513  
  1514  	case OGOTO, OLABEL:
  1515  		p.op(op)
  1516  		p.expr(n.Left)
  1517  
  1518  	default:
  1519  		Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op)
  1520  	}
  1521  }
  1522  
  1523  func (p *exporter) exprsOrNil(a, b *Node) {
  1524  	ab := 0
  1525  	if a != nil {
  1526  		ab |= 1
  1527  	}
  1528  	if b != nil {
  1529  		ab |= 2
  1530  	}
  1531  	p.int(ab)
  1532  	if ab&1 != 0 {
  1533  		p.expr(a)
  1534  	}
  1535  	if ab&2 != 0 {
  1536  		p.expr(b)
  1537  	}
  1538  }
  1539  
  1540  func (p *exporter) fieldSym(s *Sym, short bool) {
  1541  	name := s.Name
  1542  
  1543  	// remove leading "type." in method names ("(T).m" -> "m")
  1544  	if short {
  1545  		if i := strings.LastIndex(name, "."); i >= 0 {
  1546  			name = name[i+1:]
  1547  		}
  1548  	}
  1549  
  1550  	// we should never see a _ (blank) here - these are accessible ("read") fields
  1551  	// TODO(gri) can we assert this with an explicit check?
  1552  	p.string(name)
  1553  	if !exportname(name) {
  1554  		p.pkg(s.Pkg)
  1555  	}
  1556  }
  1557  
  1558  // sym must encode the _ (blank) identifier as a single string "_" since
  1559  // encoding for some nodes is based on this assumption (e.g. ONAME nodes).
  1560  func (p *exporter) sym(n *Node) {
  1561  	s := n.Sym
  1562  	if s.Pkg != nil {
  1563  		if len(s.Name) > 0 && s.Name[0] == '.' {
  1564  			Fatalf("exporter: exporting synthetic symbol %s", s.Name)
  1565  		}
  1566  	}
  1567  
  1568  	if p.trace {
  1569  		p.tracef("{ SYM ")
  1570  		defer p.tracef("} ")
  1571  	}
  1572  
  1573  	name := s.Name
  1574  
  1575  	// remove leading "type." in method names ("(T).m" -> "m")
  1576  	if i := strings.LastIndex(name, "."); i >= 0 {
  1577  		name = name[i+1:]
  1578  	}
  1579  
  1580  	if strings.Contains(name, "·") && n.Name.Vargen > 0 {
  1581  		Fatalf("exporter: unexpected · in symbol name")
  1582  	}
  1583  
  1584  	if i := n.Name.Vargen; i > 0 {
  1585  		name = fmt.Sprintf("%s·%d", name, i)
  1586  	}
  1587  
  1588  	p.string(name)
  1589  	if name != "_" {
  1590  		p.pkg(s.Pkg)
  1591  	}
  1592  }
  1593  
  1594  func (p *exporter) bool(b bool) bool {
  1595  	if p.trace {
  1596  		p.tracef("[")
  1597  		defer p.tracef("= %v] ", b)
  1598  	}
  1599  
  1600  	x := 0
  1601  	if b {
  1602  		x = 1
  1603  	}
  1604  	p.int(x)
  1605  	return b
  1606  }
  1607  
  1608  func (p *exporter) op(op Op) {
  1609  	if p.trace {
  1610  		p.tracef("[")
  1611  		defer p.tracef("= %v] ", op)
  1612  	}
  1613  
  1614  	p.int(int(op))
  1615  }
  1616  
  1617  // ----------------------------------------------------------------------------
  1618  // Low-level encoders
  1619  
  1620  func (p *exporter) index(marker byte, index int) {
  1621  	if index < 0 {
  1622  		Fatalf("exporter: invalid index < 0")
  1623  	}
  1624  	if debugFormat {
  1625  		p.marker('t')
  1626  	}
  1627  	if p.trace {
  1628  		p.tracef("%c%d ", marker, index)
  1629  	}
  1630  	p.rawInt64(int64(index))
  1631  }
  1632  
  1633  func (p *exporter) tag(tag int) {
  1634  	if tag >= 0 {
  1635  		Fatalf("exporter: invalid tag >= 0")
  1636  	}
  1637  	if debugFormat {
  1638  		p.marker('t')
  1639  	}
  1640  	if p.trace {
  1641  		p.tracef("%s ", tagString[-tag])
  1642  	}
  1643  	p.rawInt64(int64(tag))
  1644  }
  1645  
  1646  func (p *exporter) int(x int) {
  1647  	p.int64(int64(x))
  1648  }
  1649  
  1650  func (p *exporter) int64(x int64) {
  1651  	if debugFormat {
  1652  		p.marker('i')
  1653  	}
  1654  	if p.trace {
  1655  		p.tracef("%d ", x)
  1656  	}
  1657  	p.rawInt64(x)
  1658  }
  1659  
  1660  func (p *exporter) string(s string) {
  1661  	if debugFormat {
  1662  		p.marker('s')
  1663  	}
  1664  	if p.trace {
  1665  		p.tracef("%q ", s)
  1666  	}
  1667  	// if we saw the string before, write its index (>= 0)
  1668  	// (the empty string is mapped to 0)
  1669  	if i, ok := p.strIndex[s]; ok {
  1670  		p.rawInt64(int64(i))
  1671  		return
  1672  	}
  1673  	// otherwise, remember string and write its negative length and bytes
  1674  	p.strIndex[s] = len(p.strIndex)
  1675  	p.rawInt64(-int64(len(s)))
  1676  	for i := 0; i < len(s); i++ {
  1677  		p.rawByte(s[i])
  1678  	}
  1679  }
  1680  
  1681  // marker emits a marker byte and position information which makes
  1682  // it easy for a reader to detect if it is "out of sync". Used only
  1683  // if debugFormat is set.
  1684  func (p *exporter) marker(m byte) {
  1685  	p.rawByte(m)
  1686  	// Uncomment this for help tracking down the location
  1687  	// of an incorrect marker when running in debugFormat.
  1688  	// if p.trace {
  1689  	// 	p.tracef("#%d ", p.written)
  1690  	// }
  1691  	p.rawInt64(int64(p.written))
  1692  }
  1693  
  1694  // rawInt64 should only be used by low-level encoders.
  1695  func (p *exporter) rawInt64(x int64) {
  1696  	var tmp [binary.MaxVarintLen64]byte
  1697  	n := binary.PutVarint(tmp[:], x)
  1698  	for i := 0; i < n; i++ {
  1699  		p.rawByte(tmp[i])
  1700  	}
  1701  }
  1702  
  1703  // rawStringln should only be used to emit the initial version string.
  1704  func (p *exporter) rawStringln(s string) {
  1705  	for i := 0; i < len(s); i++ {
  1706  		p.rawByte(s[i])
  1707  	}
  1708  	p.rawByte('\n')
  1709  }
  1710  
  1711  // rawByte is the bottleneck interface to write to p.out.
  1712  // rawByte escapes b as follows (any encoding does that
  1713  // hides '$'):
  1714  //
  1715  //	'$'  => '|' 'S'
  1716  //	'|'  => '|' '|'
  1717  //
  1718  // Necessary so other tools can find the end of the
  1719  // export data by searching for "$$".
  1720  // rawByte should only be used by low-level encoders.
  1721  func (p *exporter) rawByte(b byte) {
  1722  	switch b {
  1723  	case '$':
  1724  		// write '$' as '|' 'S'
  1725  		b = 'S'
  1726  		fallthrough
  1727  	case '|':
  1728  		// write '|' as '|' '|'
  1729  		p.out.WriteByte('|')
  1730  		p.written++
  1731  	}
  1732  	p.out.WriteByte(b)
  1733  	p.written++
  1734  }
  1735  
  1736  // tracef is like fmt.Printf but it rewrites the format string
  1737  // to take care of indentation.
  1738  func (p *exporter) tracef(format string, args ...interface{}) {
  1739  	if strings.ContainsAny(format, "<>\n") {
  1740  		var buf bytes.Buffer
  1741  		for i := 0; i < len(format); i++ {
  1742  			// no need to deal with runes
  1743  			ch := format[i]
  1744  			switch ch {
  1745  			case '>':
  1746  				p.indent++
  1747  				continue
  1748  			case '<':
  1749  				p.indent--
  1750  				continue
  1751  			}
  1752  			buf.WriteByte(ch)
  1753  			if ch == '\n' {
  1754  				for j := p.indent; j > 0; j-- {
  1755  					buf.WriteString(".  ")
  1756  				}
  1757  			}
  1758  		}
  1759  		format = buf.String()
  1760  	}
  1761  	fmt.Printf(format, args...)
  1762  }
  1763  
  1764  // ----------------------------------------------------------------------------
  1765  // Export format
  1766  
  1767  // Tags. Must be < 0.
  1768  const (
  1769  	// Objects
  1770  	packageTag = -(iota + 1)
  1771  	constTag
  1772  	typeTag
  1773  	varTag
  1774  	funcTag
  1775  	endTag
  1776  
  1777  	// Types
  1778  	namedTag
  1779  	arrayTag
  1780  	sliceTag
  1781  	dddTag
  1782  	structTag
  1783  	pointerTag
  1784  	signatureTag
  1785  	interfaceTag
  1786  	mapTag
  1787  	chanTag
  1788  
  1789  	// Values
  1790  	falseTag
  1791  	trueTag
  1792  	int64Tag
  1793  	floatTag
  1794  	fractionTag // not used by gc
  1795  	complexTag
  1796  	stringTag
  1797  	nilTag
  1798  	unknownTag // not used by gc (only appears in packages with errors)
  1799  
  1800  	// Aliases
  1801  	aliasTag
  1802  )
  1803  
  1804  // Debugging support.
  1805  // (tagString is only used when tracing is enabled)
  1806  var tagString = [...]string{
  1807  	// Objects
  1808  	-packageTag: "package",
  1809  	-constTag:   "const",
  1810  	-typeTag:    "type",
  1811  	-varTag:     "var",
  1812  	-funcTag:    "func",
  1813  	-endTag:     "end",
  1814  
  1815  	// Types
  1816  	-namedTag:     "named type",
  1817  	-arrayTag:     "array",
  1818  	-sliceTag:     "slice",
  1819  	-dddTag:       "ddd",
  1820  	-structTag:    "struct",
  1821  	-pointerTag:   "pointer",
  1822  	-signatureTag: "signature",
  1823  	-interfaceTag: "interface",
  1824  	-mapTag:       "map",
  1825  	-chanTag:      "chan",
  1826  
  1827  	// Values
  1828  	-falseTag:    "false",
  1829  	-trueTag:     "true",
  1830  	-int64Tag:    "int64",
  1831  	-floatTag:    "float",
  1832  	-fractionTag: "fraction",
  1833  	-complexTag:  "complex",
  1834  	-stringTag:   "string",
  1835  	-nilTag:      "nil",
  1836  	-unknownTag:  "unknown",
  1837  
  1838  	// Aliases
  1839  	-aliasTag: "alias",
  1840  }
  1841  
  1842  // untype returns the "pseudo" untyped type for a Ctype (import/export use only).
  1843  // (we can't use an pre-initialized array because we must be sure all types are
  1844  // set up)
  1845  func untype(ctype Ctype) *Type {
  1846  	switch ctype {
  1847  	case CTINT:
  1848  		return idealint
  1849  	case CTRUNE:
  1850  		return idealrune
  1851  	case CTFLT:
  1852  		return idealfloat
  1853  	case CTCPLX:
  1854  		return idealcomplex
  1855  	case CTSTR:
  1856  		return idealstring
  1857  	case CTBOOL:
  1858  		return idealbool
  1859  	case CTNIL:
  1860  		return Types[TNIL]
  1861  	}
  1862  	Fatalf("exporter: unknown Ctype")
  1863  	return nil
  1864  }
  1865  
  1866  var predecl []*Type // initialized lazily
  1867  
  1868  func predeclared() []*Type {
  1869  	if predecl == nil {
  1870  		// initialize lazily to be sure that all
  1871  		// elements have been initialized before
  1872  		predecl = []*Type{
  1873  			// basic types
  1874  			Types[TBOOL],
  1875  			Types[TINT],
  1876  			Types[TINT8],
  1877  			Types[TINT16],
  1878  			Types[TINT32],
  1879  			Types[TINT64],
  1880  			Types[TUINT],
  1881  			Types[TUINT8],
  1882  			Types[TUINT16],
  1883  			Types[TUINT32],
  1884  			Types[TUINT64],
  1885  			Types[TUINTPTR],
  1886  			Types[TFLOAT32],
  1887  			Types[TFLOAT64],
  1888  			Types[TCOMPLEX64],
  1889  			Types[TCOMPLEX128],
  1890  			Types[TSTRING],
  1891  
  1892  			// aliases
  1893  			bytetype,
  1894  			runetype,
  1895  
  1896  			// error
  1897  			errortype,
  1898  
  1899  			// untyped types
  1900  			untype(CTBOOL),
  1901  			untype(CTINT),
  1902  			untype(CTRUNE),
  1903  			untype(CTFLT),
  1904  			untype(CTCPLX),
  1905  			untype(CTSTR),
  1906  			untype(CTNIL),
  1907  
  1908  			// package unsafe
  1909  			Types[TUNSAFEPTR],
  1910  
  1911  			// invalid type (package contains errors)
  1912  			Types[Txxx],
  1913  
  1914  			// any type, for builtin export data
  1915  			Types[TANY],
  1916  		}
  1917  	}
  1918  	return predecl
  1919  }