// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Indexed package export.
//
// The indexed export data format is an evolution of the previous
// binary export data format. Its chief contribution is introducing an
// index table, which allows efficient random access of individual
// declarations and inline function bodies. In turn, this allows
// avoiding unnecessary work for compilation units that import large
// packages.
//
//
// The top-level data format is structured as:
//
//     Header struct {
//         Tag        byte   // 'i'
//         Version    uvarint
//         StringSize uvarint
//         DataSize   uvarint
//     }
//
//     Strings [StringSize]byte
//     Data    [DataSize]byte
//
//     MainIndex []struct{
//         PkgPath   stringOff
//         PkgName   stringOff
//         PkgHeight uvarint
//
//         Decls []struct{
//             Name   stringOff
//             Offset declOff
//         }
//     }
//
// uvarint means a uint64 written out using uvarint encoding.
//
// []T means a uvarint followed by that many T objects. In other
// words:
//
//     Len   uvarint
//     Elems [Len]T
//
// stringOff means a uvarint that indicates an offset within the
// Strings section. At that offset is another uvarint, followed by
// that many bytes, which form the string value.
//
// declOff means a uvarint that indicates an offset within the Data
// section where the associated declaration can be found.
//
//
// There are five kinds of declarations, distinguished by their first
// byte:
//
//     type Var struct {
//         Tag  byte // 'V'
//         Pos  Pos
//         Type typeOff
//     }
//
//     type Func struct {
//         Tag       byte // 'F'
//         Pos       Pos
//         Signature Signature
//     }
//
//     type Const struct {
//         Tag   byte // 'C'
//         Pos   Pos
//         Value Value
//     }
//
//     type Type struct {
//         Tag        byte // 'T'
//         Pos        Pos
//         Underlying typeOff
//
//         Methods []struct{  // omitted if Underlying is an interface type
//             Pos       Pos
//             Name      stringOff
//             Recv      Param
//             Signature Signature
//         }
//     }
//
//     type Alias struct {
//         Tag  byte // 'A'
//         Pos  Pos
//         Type typeOff
//     }
//
//
// typeOff means a uvarint that either indicates a predeclared type,
// or an offset into the Data section. If the uvarint is less than
// predeclReserved, then it indicates the index into the predeclared
// types list (see predeclared in bexport.go for order). Otherwise,
// subtracting predeclReserved yields the offset of a type descriptor.
//
// Value means a type and type-specific value. See
// (*exportWriter).value for details.
//
//
// There are nine kinds of type descriptors, distinguished by an itag:
//
//     type DefinedType struct {
//         Tag     itag // definedType
//         Name    stringOff
//         PkgPath stringOff
//     }
//
//     type PointerType struct {
//         Tag  itag // pointerType
//         Elem typeOff
//     }
//
//     type SliceType struct {
//         Tag  itag // sliceType
//         Elem typeOff
//     }
//
//     type ArrayType struct {
//         Tag  itag // arrayType
//         Len  uint64
//         Elem typeOff
//     }
//
//     type ChanType struct {
//         Tag  itag   // chanType
//         Dir  uint64 // 1 RecvOnly; 2 SendOnly; 3 SendRecv
//         Elem typeOff
//     }
//
//     type MapType struct {
//         Tag  itag // mapType
//         Key  typeOff
//         Elem typeOff
//     }
//
//     type FuncType struct {
//         Tag       itag // signatureType
//         PkgPath   stringOff
//         Signature Signature
//     }
//
//     type StructType struct {
//         Tag     itag // structType
//         PkgPath stringOff
//         Fields []struct {
//             Pos      Pos
//             Name     stringOff
//             Type     typeOff
//             Embedded bool
//             Note     stringOff
//         }
//     }
//
//     type InterfaceType struct {
//         Tag     itag // interfaceType
//         PkgPath stringOff
//         Embeddeds []struct {
//             Pos  Pos
//             Type typeOff
//         }
//         Methods []struct {
//             Pos       Pos
//             Name      stringOff
//             Signature Signature
//         }
//     }
//
//
//     type Signature struct {
//         Params   []Param
//         Results  []Param
//         Variadic bool  // omitted if Results is empty
//     }
//
//     type Param struct {
//         Pos  Pos
//         Name stringOff
//         Type typOff
//     }
//
//
// Pos encodes a file:line pair, incorporating a simple delta encoding
// scheme within a data object. See exportWriter.pos for details.
//
//
// Compiler-specific details.
//
// cmd/compile writes out a second index for inline bodies and also
// appends additional compiler-specific details after declarations.
// Third-party tools are not expected to depend on these details and
// they're expected to change much more rapidly, so they're omitted
// here. See exportWriter's varExt/funcExt/etc methods for details.

package gc

import (
	"bufio"
	"bytes"
	"cmd/compile/internal/types"
	"cmd/internal/obj"
	"cmd/internal/src"
	"encoding/binary"
	"fmt"
	"go/ast"
	"io"
	"math/big"
	"strings"
)

// Current indexed export format version. Increase with each format change.
// 0: Go1.11 encoding
const iexportVersion = 0

// predeclReserved is the number of type offsets reserved for types
// implicitly declared in the universe block.
const predeclReserved = 32

// An itag distinguishes the kind of type that was written into the
// indexed export format.
type itag uint64

const (
	// Types
	definedType itag = iota
	pointerType
	sliceType
	arrayType
	chanType
	mapType
	signatureType
	structType
	interfaceType
)

func iexport(out *bufio.Writer) {
	// Mark inline bodies that are reachable through exported types.
	// (Phase 0 of bexport.go.)
	{
		// TODO(mdempsky): Separate from bexport logic.
		p := &exporter{marked: make(map[*types.Type]bool)}
		for _, n := range exportlist {
			sym := n.Sym
			p.markType(asNode(sym.Def).Type)
		}
	}

	p := iexporter{
		allPkgs:     map[*types.Pkg]bool{},
		stringIndex: map[string]uint64{},
		declIndex:   map[*Node]uint64{},
		inlineIndex: map[*Node]uint64{},
		typIndex:    map[*types.Type]uint64{},
	}

	for i, pt := range predeclared() {
		p.typIndex[pt] = uint64(i)
	}
	if len(p.typIndex) > predeclReserved {
		Fatalf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)
	}

	// Initialize work queue with exported declarations.
	for _, n := range exportlist {
		p.pushDecl(n)
	}

	// Loop until no more work. We use a queue because while
	// writing out inline bodies, we may discover additional
	// declarations that are needed.
	for !p.declTodo.empty() {
		p.doDecl(p.declTodo.popLeft())
	}

	// Append indices to data0 section.
	dataLen := uint64(p.data0.Len())
	w := p.newWriter()
	w.writeIndex(p.declIndex, true)
	w.writeIndex(p.inlineIndex, false)
	w.flush()

	// Assemble header.
	var hdr intWriter
	hdr.WriteByte('i')
	hdr.uint64(iexportVersion)
	hdr.uint64(uint64(p.strings.Len()))
	hdr.uint64(dataLen)

	// Flush output.
	io.Copy(out, &hdr)
	io.Copy(out, &p.strings)
	io.Copy(out, &p.data0)
}

// writeIndex writes out an object index. mainIndex indicates whether
// we're writing out the main index, which is also read by
// non-compiler tools and includes a complete package description
// (i.e., name and height).
func (w *exportWriter) writeIndex(index map[*Node]uint64, mainIndex bool) {
	// Build a map from packages to objects from that package.
	pkgObjs := map[*types.Pkg][]*Node{}

	// For the main index, make sure to include every package that
	// we reference, even if we're not exporting (or reexporting)
	// any symbols from it.
	if mainIndex {
		pkgObjs[localpkg] = nil
		for pkg := range w.p.allPkgs {
			pkgObjs[pkg] = nil
		}
	}

	for n := range index {
		pkgObjs[n.Sym.Pkg] = append(pkgObjs[n.Sym.Pkg], n)
	}

	var pkgs []*types.Pkg
	for pkg, objs := range pkgObjs {
		pkgs = append(pkgs, pkg)

		obj.SortSlice(objs, func(i, j int) bool {
			return objs[i].Sym.Name < objs[j].Sym.Name
		})
	}

	obj.SortSlice(pkgs, func(i, j int) bool {
		return pkgs[i].Path < pkgs[j].Path
	})

	w.uint64(uint64(len(pkgs)))
	for _, pkg := range pkgs {
		w.string(pkg.Path)
		if mainIndex {
			w.string(pkg.Name)
			w.uint64(uint64(pkg.Height))
		}

		objs := pkgObjs[pkg]
		w.uint64(uint64(len(objs)))
		for _, n := range objs {
			w.string(n.Sym.Name)
			w.uint64(index[n])
		}
	}
}

type iexporter struct {
	// allPkgs tracks all packages that have been referenced by
	// the export data, so we can ensure to include them in the
	// main index.
	allPkgs map[*types.Pkg]bool

	declTodo nodeQueue

	strings     intWriter
	stringIndex map[string]uint64

	data0       intWriter
	declIndex   map[*Node]uint64
	inlineIndex map[*Node]uint64
	typIndex    map[*types.Type]uint64
}

// stringOff returns the offset of s within the string section.
// If not already present, it's added to the end.
func (p *iexporter) stringOff(s string) uint64 {
	off, ok := p.stringIndex[s]
	if !ok {
		off = uint64(p.strings.Len())
		p.stringIndex[s] = off

		p.strings.uint64(uint64(len(s)))
		p.strings.WriteString(s)
	}
	return off
}

// pushDecl adds n to the declaration work queue, if not already present.
func (p *iexporter) pushDecl(n *Node) {
	if n.Sym == nil || asNode(n.Sym.Def) != n && n.Op != OTYPE {
		Fatalf("weird Sym: %v, %v", n, n.Sym)
	}

	// Don't export predeclared declarations.
	if n.Sym.Pkg == builtinpkg || n.Sym.Pkg == unsafepkg {
		return
	}

	if _, ok := p.declIndex[n]; ok {
		return
	}

	p.declIndex[n] = ^uint64(0) // mark n present in work queue
	p.declTodo.pushRight(n)
}

// exportWriter handles writing out individual data section chunks.
type exportWriter struct {
	p *iexporter

	data     intWriter
	currPkg  *types.Pkg
	prevFile string
	prevLine int64
}

func (p *iexporter) doDecl(n *Node) {
	w := p.newWriter()
	w.setPkg(n.Sym.Pkg, false)

	switch n.Op {
	case ONAME:
		switch n.Class() {
		case PEXTERN:
			// Variable.
			w.tag('V')
			w.pos(n.Pos)
			w.typ(n.Type)
			w.varExt(n)

		case PFUNC:
			if n.IsMethod() {
				Fatalf("unexpected method: %v", n)
			}

			// Function.
			w.tag('F')
			w.pos(n.Pos)
			w.signature(n.Type)
			w.funcExt(n)

		default:
			Fatalf("unexpected class: %v, %v", n, n.Class())
		}

	case OLITERAL:
		// Constant.
		n = typecheck(n, Erv)
		w.tag('C')
		w.pos(n.Pos)
		w.value(n.Type, n.Val())

	case OTYPE:
		if IsAlias(n.Sym) {
			// Alias.
			w.tag('A')
			w.pos(n.Pos)
			w.typ(n.Type)
			break
		}

		// Defined type.
		w.tag('T')
		w.pos(n.Pos)

		underlying := n.Type.Orig
		if underlying == types.Errortype.Orig {
			// For "type T error", use error as the
			// underlying type instead of error's own
			// underlying anonymous interface. This
			// ensures consistency with how importers may
			// declare error (e.g., go/types uses nil Pkg
			// for predeclared objects).
			underlying = types.Errortype
		}
		w.typ(underlying)

		t := n.Type
		if t.IsInterface() {
			break
		}

		ms := t.Methods()
		w.uint64(uint64(ms.Len()))
		for _, m := range ms.Slice() {
			w.pos(m.Pos)
			w.selector(m.Sym)
			w.param(m.Type.Recv())
			w.signature(m.Type)
		}

		for _, m := range ms.Slice() {
			w.methExt(m)
		}

	default:
		Fatalf("unexpected node: %v", n)
	}

	p.declIndex[n] = w.flush()
}

func (w *exportWriter) tag(tag byte) {
	w.data.WriteByte(tag)
}

func (p *iexporter) doInline(f *Node) {
	w := p.newWriter()
	w.setPkg(fnpkg(f), false)

	w.stmtList(asNodes(f.Func.Inl.Body))

	p.inlineIndex[f] = w.flush()
}

func (w *exportWriter) pos(pos src.XPos) {
	p := Ctxt.PosTable.Pos(pos)
	file := p.Base().AbsFilename()
	line := int64(p.RelLine())

	// When file is the same as the last position (common case),
	// we can save a few bytes by delta encoding just the line
	// number.
	//
	// Note: Because data objects may be read out of order (or not
	// at all), we can only apply delta encoding within a single
	// object. This is handled implicitly by tracking prevFile and
	// prevLine as fields of exportWriter.

	if file == w.prevFile {
		delta := line - w.prevLine
		w.int64(delta)
		if delta == deltaNewFile {
			w.int64(-1)
		}
	} else {
		w.int64(deltaNewFile)
		w.int64(line) // line >= 0
		w.string(file)
		w.prevFile = file
	}
	w.prevLine = line
}

func (w *exportWriter) pkg(pkg *types.Pkg) {
	// Ensure any referenced packages are declared in the main index.
	w.p.allPkgs[pkg] = true

	w.string(pkg.Path)
}

func (w *exportWriter) qualifiedIdent(n *Node) {
	// Ensure any referenced declarations are written out too.
	w.p.pushDecl(n)

	s := n.Sym
	w.string(s.Name)
	w.pkg(s.Pkg)
}

func (w *exportWriter) selector(s *types.Sym) {
	if w.currPkg == nil {
		Fatalf("missing currPkg")
	}

	// Method selectors are rewritten into method symbols (of the
	// form T.M) during typechecking, but we want to write out
	// just the bare method name.
	name := s.Name
	if i := strings.LastIndex(name, "."); i >= 0 {
		name = name[i+1:]
	} else {
		pkg := w.currPkg
		if types.IsExported(name) {
			pkg = localpkg
		}
		if s.Pkg != pkg {
			Fatalf("package mismatch in selector: %v in package %q, but want %q", s, s.Pkg.Path, pkg.Path)
		}
	}

	w.string(name)
}

func (w *exportWriter) typ(t *types.Type) {
	w.data.uint64(w.p.typOff(t))
}

func (p *iexporter) newWriter() *exportWriter {
	return &exportWriter{p: p}
}

func (w *exportWriter) flush() uint64 {
	off := uint64(w.p.data0.Len())
	io.Copy(&w.p.data0, &w.data)
	return off
}

func (p *iexporter) typOff(t *types.Type) uint64 {
	off, ok := p.typIndex[t]
	if !ok {
		w := p.newWriter()
		w.doTyp(t)
		off = predeclReserved + w.flush()
		p.typIndex[t] = off
	}
	return off
}

func (w *exportWriter) startType(k itag) {
	w.data.uint64(uint64(k))
}

func (w *exportWriter) doTyp(t *types.Type) {
	if t.Sym != nil {
		if t.Sym.Pkg == builtinpkg || t.Sym.Pkg == unsafepkg {
			Fatalf("builtin type missing from typIndex: %v", t)
		}

		w.startType(definedType)
		w.qualifiedIdent(typenod(t))
		return
	}

	switch t.Etype {
	case TPTR32, TPTR64:
		w.startType(pointerType)
		w.typ(t.Elem())

	case TSLICE:
		w.startType(sliceType)
		w.typ(t.Elem())

	case TARRAY:
		w.startType(arrayType)
		w.uint64(uint64(t.NumElem()))
		w.typ(t.Elem())

	case TCHAN:
		w.startType(chanType)
		w.uint64(uint64(t.ChanDir()))
		w.typ(t.Elem())

	case TMAP:
		w.startType(mapType)
		w.typ(t.Key())
		w.typ(t.Elem())

	case TFUNC:
		w.startType(signatureType)
		w.setPkg(t.Pkg(), true)
		w.signature(t)

	case TSTRUCT:
		w.startType(structType)
		w.setPkg(t.Pkg(), true)

		w.uint64(uint64(t.NumFields()))
		for _, f := range t.FieldSlice() {
			w.pos(f.Pos)
			w.selector(f.Sym)
			w.typ(f.Type)
			w.bool(f.Embedded != 0)
			w.string(f.Note)
		}

	case TINTER:
		var embeddeds, methods []*types.Field
		for _, m := range t.Methods().Slice() {
			if m.Sym != nil {
				methods = append(methods, m)
			} else {
				embeddeds = append(embeddeds, m)
			}
		}

		w.startType(interfaceType)
		w.setPkg(t.Pkg(), true)

		w.uint64(uint64(len(embeddeds)))
		for _, f := range embeddeds {
			w.pos(f.Pos)
			w.typ(f.Type)
		}

		w.uint64(uint64(len(methods)))
		for _, f := range methods {
			w.pos(f.Pos)
			w.selector(f.Sym)
			w.signature(f.Type)
		}

	default:
		Fatalf("unexpected type: %v", t)
	}
}

func (w *exportWriter) setPkg(pkg *types.Pkg, write bool) {
	if pkg == nil {
		// TODO(mdempsky): Proactively set Pkg for types and
		// remove this fallback logic.
		pkg = localpkg
	}

	if write {
		w.pkg(pkg)
	}

	w.currPkg = pkg
}

func (w *exportWriter) signature(t *types.Type) {
	w.paramList(t.Params().FieldSlice())
	w.paramList(t.Results().FieldSlice())
	if n := t.Params().NumFields(); n > 0 {
		w.bool(t.Params().Field(n - 1).Isddd())
	}
}

func (w *exportWriter) paramList(fs []*types.Field) {
	w.uint64(uint64(len(fs)))
	for _, f := range fs {
		w.param(f)
	}
}

func (w *exportWriter) param(f *types.Field) {
	w.pos(f.Pos)
	w.localIdent(origSym(f.Sym), 0)
	w.typ(f.Type)
}

func constTypeOf(typ *types.Type) Ctype {
	switch typ {
	case types.Idealint, types.Idealrune:
		return CTINT
	case types.Idealfloat:
		return CTFLT
	case types.Idealcomplex:
		return CTCPLX
	}

	switch typ.Etype {
	case TCHAN, TFUNC, TMAP, TNIL, TINTER, TSLICE:
		return CTNIL
	case TBOOL:
		return CTBOOL
	case TSTRING:
		return CTSTR
	case TINT, TINT8, TINT16, TINT32, TINT64,
		TUINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINTPTR,
		TPTR32, TPTR64, TUNSAFEPTR:
		return CTINT
	case TFLOAT32, TFLOAT64:
		return CTFLT
	case TCOMPLEX64, TCOMPLEX128:
		return CTCPLX
	}

	Fatalf("unexpected constant type: %v", typ)
	return 0
}

func (w *exportWriter) value(typ *types.Type, v Val) {
	if typ.IsUntyped() {
		typ = untype(v.Ctype())
	}
	w.typ(typ)

	// Each type has only one admissible constant representation,
	// so we could type switch directly on v.U here. However,
	// switching on the type increases symmetry with import logic
	// and provides a useful consistency check.

	switch constTypeOf(typ) {
	case CTNIL:
		// Only one value; nothing to encode.
		_ = v.U.(*NilVal)
	case CTBOOL:
		w.bool(v.U.(bool))
	case CTSTR:
		w.string(v.U.(string))
	case CTINT:
		w.mpint(&v.U.(*Mpint).Val, typ)
	case CTFLT:
		w.mpfloat(&v.U.(*Mpflt).Val, typ)
	case CTCPLX:
		x := v.U.(*Mpcplx)
		w.mpfloat(&x.Real.Val, typ)
		w.mpfloat(&x.Imag.Val, typ)
	}
}

func intSize(typ *types.Type) (signed bool, maxBytes uint) {
	if typ.IsUntyped() {
		return true, Mpprec / 8
	}

	switch typ.Etype {
	case TFLOAT32, TCOMPLEX64:
		return true, 3
	case TFLOAT64, TCOMPLEX128:
		return true, 7
	}

	signed = typ.IsSigned()
	maxBytes = uint(typ.Size())

	// The go/types API doesn't expose sizes to importers, so they
	// don't know how big these types are.
	switch typ.Etype {
	case TINT, TUINT, TUINTPTR:
		maxBytes = 8
	}

	return
}

// mpint exports a multi-precision integer.
//
// For unsigned types, small values are written out as a single
// byte. Larger values are written out as a length-prefixed big-endian
// byte string, where the length prefix is encoded as its complement.
// For example, bytes 0, 1, and 2 directly represent the integer
// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-,
// 2-, and 3-byte big-endian string follow.
//
// Encoding for signed types use the same general approach as for
// unsigned types, except small values use zig-zag encoding and the
// bottom bit of length prefix byte for large values is reserved as a
// sign bit.
//
// The exact boundary between small and large encodings varies
// according to the maximum number of bytes needed to encode a value
// of type typ. As a special case, 8-bit types are always encoded as a
// single byte.
//
// TODO(mdempsky): Is this level of complexity really worthwhile?
func (w *exportWriter) mpint(x *big.Int, typ *types.Type) {
	signed, maxBytes := intSize(typ)

	negative := x.Sign() < 0
	if !signed && negative {
		Fatalf("negative unsigned integer; type %v, value %v", typ, x)
	}

	b := x.Bytes()
	if len(b) > 0 && b[0] == 0 {
		Fatalf("leading zeros")
	}
	if uint(len(b)) > maxBytes {
		Fatalf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)
	}

	maxSmall := 256 - maxBytes
	if signed {
		maxSmall = 256 - 2*maxBytes
	}
	if maxBytes == 1 {
		maxSmall = 256
	}

	// Check if x can use small value encoding.
	if len(b) <= 1 {
		var ux uint
		if len(b) == 1 {
			ux = uint(b[0])
		}
		if signed {
			ux <<= 1
			if negative {
				ux--
			}
		}
		if ux < maxSmall {
			w.data.WriteByte(byte(ux))
			return
		}
	}

	n := 256 - uint(len(b))
	if signed {
		n = 256 - 2*uint(len(b))
		if negative {
			n |= 1
		}
	}
	if n < maxSmall || n >= 256 {
		Fatalf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)
	}

	w.data.WriteByte(byte(n))
	w.data.Write(b)
}

// mpfloat exports a multi-precision floating point number.
//
// The number's value is decomposed into mantissa × 2**exponent, where
// mantissa is an integer. The value is written out as mantissa (as a
// multi-precision integer) and then the exponent, except exponent is
// omitted if mantissa is zero.
func (w *exportWriter) mpfloat(f *big.Float, typ *types.Type) {
	if f.IsInf() {
		Fatalf("infinite constant")
	}

	// Break into f = mant × 2**exp, with 0.5 <= mant < 1.
	var mant big.Float
	exp := int64(f.MantExp(&mant))

	// Scale so that mant is an integer.
	prec := mant.MinPrec()
	mant.SetMantExp(&mant, int(prec))
	exp -= int64(prec)

	manti, acc := mant.Int(nil)
	if acc != big.Exact {
		Fatalf("exporter: internal error")
	}
	w.mpint(manti, typ)
	if manti.Sign() != 0 {
		w.int64(exp)
	}
}

func (w *exportWriter) bool(b bool) bool {
	var x uint64
	if b {
		x = 1
	}
	w.uint64(x)
	return b
}

func (w *exportWriter) int64(x int64)   { w.data.int64(x) }
func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) }
func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }

// Compiler-specific extensions.

func (w *exportWriter) varExt(n *Node) {
	w.linkname(n.Sym)
}

func (w *exportWriter) funcExt(n *Node) {
	w.linkname(n.Sym)

	// Escape analysis.
	for _, fs := range types.RecvsParams {
		for _, f := range fs(n.Type).FieldSlice() {
			w.string(f.Note)
		}
	}

	// Inline body.
	if n.Func.Inl != nil {
		w.uint64(1 + uint64(n.Func.Inl.Cost))
		if n.Func.ExportInline() {
			w.p.doInline(n)
		}

		// Endlineno for inlined function.
		if n.Name.Defn != nil {
			w.pos(n.Name.Defn.Func.Endlineno)
		} else {
			// When the exported node was defined externally,
			// e.g. io exports atomic.(*Value).Load or bytes exports errors.New.
			// Keep it as we don't distinguish this case in iimport.go.
			w.pos(n.Func.Endlineno)
		}
	} else {
		w.uint64(0)
	}
}

func (w *exportWriter) methExt(m *types.Field) {
	w.bool(m.Nointerface())
	w.funcExt(asNode(m.Type.Nname()))
}

func (w *exportWriter) linkname(s *types.Sym) {
	w.string(s.Linkname)
}

// Inline bodies.

func (w *exportWriter) stmtList(list Nodes) {
	for _, n := range list.Slice() {
		w.node(n)
	}
	w.op(OEND)
}

func (w *exportWriter) node(n *Node) {
	if opprec[n.Op] < 0 {
		w.stmt(n)
	} else {
		w.expr(n)
	}
}

// Caution: stmt will emit more than one node for statement nodes n that have a non-empty
// n.Ninit and where n cannot have a natural init section (such as in "if", "for", etc.).
func (w *exportWriter) stmt(n *Node) {
	if n.Ninit.Len() > 0 && !stmtwithinit(n.Op) {
		// can't use stmtList here since we don't want the final OEND
		for _, n := range n.Ninit.Slice() {
			w.stmt(n)
		}
	}

	switch op := n.Op; op {
	case ODCL:
		w.op(ODCL)
		w.pos(n.Left.Pos)
		w.localName(n.Left)
		w.typ(n.Left.Type)

	// case ODCLFIELD:
	//	unimplemented - handled by default case

	case OAS:
		// Don't export "v = <N>" initializing statements, hope they're always
		// preceded by the DCL which will be re-parsed and typecheck to reproduce
		// the "v = <N>" again.
		if n.Right != nil {
			w.op(OAS)
			w.pos(n.Pos)
			w.expr(n.Left)
			w.expr(n.Right)
		}

	case OASOP:
		w.op(OASOP)
		w.pos(n.Pos)
		w.op(n.SubOp())
		w.expr(n.Left)
		if w.bool(!n.Implicit()) {
			w.expr(n.Right)
		}

	case OAS2, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
		w.op(OAS2)
		w.pos(n.Pos)
		w.exprList(n.List)
		w.exprList(n.Rlist)

	case ORETURN:
		w.op(ORETURN)
		w.pos(n.Pos)
		w.exprList(n.List)

	// case ORETJMP:
	// 	unreachable - generated by compiler for trampolin routines

	case OPROC, ODEFER:
		w.op(op)
		w.pos(n.Pos)
		w.expr(n.Left)

	case OIF:
		w.op(OIF)
		w.pos(n.Pos)
		w.stmtList(n.Ninit)
		w.expr(n.Left)
		w.stmtList(n.Nbody)
		w.stmtList(n.Rlist)

	case OFOR:
		w.op(OFOR)
		w.pos(n.Pos)
		w.stmtList(n.Ninit)
		w.exprsOrNil(n.Left, n.Right)
		w.stmtList(n.Nbody)

	case ORANGE:
		w.op(ORANGE)
		w.pos(n.Pos)
		w.stmtList(n.List)
		w.expr(n.Right)
		w.stmtList(n.Nbody)

	case OSELECT, OSWITCH:
		w.op(op)
		w.pos(n.Pos)
		w.stmtList(n.Ninit)
		w.exprsOrNil(n.Left, nil)
		w.stmtList(n.List)

	case OCASE, OXCASE:
		w.op(OXCASE)
		w.pos(n.Pos)
		w.stmtList(n.List)
		w.stmtList(n.Nbody)

	case OFALL:
		w.op(OFALL)
		w.pos(n.Pos)

	case OBREAK, OCONTINUE:
		w.op(op)
		w.pos(n.Pos)
		w.exprsOrNil(n.Left, nil)

	case OEMPTY:
		// nothing to emit

	case OGOTO, OLABEL:
		w.op(op)
		w.pos(n.Pos)
		w.expr(n.Left)

	default:
		Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op)
	}
}

func (w *exportWriter) exprList(list Nodes) {
	for _, n := range list.Slice() {
		w.expr(n)
	}
	w.op(OEND)
}

func (w *exportWriter) expr(n *Node) {
	// from nodefmt (fmt.go)
	//
	// nodefmt reverts nodes back to their original - we don't need to do
	// it because we are not bound to produce valid Go syntax when exporting
	//
	// if (fmtmode != FExp || n.Op != OLITERAL) && n.Orig != nil {
	// 	n = n.Orig
	// }

	// from exprfmt (fmt.go)
	for n.Op == OPAREN || n.Implicit() && (n.Op == OIND || n.Op == OADDR || n.Op == ODOT || n.Op == ODOTPTR) {
		n = n.Left
	}

	switch op := n.Op; op {
	// expressions
	// (somewhat closely following the structure of exprfmt in fmt.go)
	case OLITERAL:
		if n.Val().Ctype() == CTNIL && n.Orig != nil && n.Orig != n {
			w.expr(n.Orig)
			break
		}
		w.op(OLITERAL)
		w.pos(n.Pos)
		w.value(n.Type, n.Val())

	case ONAME:
		// Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method,
		// but for export, this should be rendered as (*pkg.T).meth.
		// These nodes have the special property that they are names with a left OTYPE and a right ONAME.
		if n.isMethodExpression() {
			w.op(OXDOT)
			w.pos(n.Pos)
			w.expr(n.Left) // n.Left.Op == OTYPE
			w.selector(n.Right.Sym)
			break
		}

		// Package scope name.
		if (n.Class() == PEXTERN || n.Class() == PFUNC) && !n.isBlank() {
			w.op(ONONAME)
			w.qualifiedIdent(n)
			break
		}

		// Function scope name.
		w.op(ONAME)
		w.localName(n)

	// case OPACK, ONONAME:
	// 	should have been resolved by typechecking - handled by default case

	case OTYPE:
		w.op(OTYPE)
		w.typ(n.Type)

	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
	// 	should have been resolved by typechecking - handled by default case

	// case OCLOSURE:
	//	unimplemented - handled by default case

	// case OCOMPLIT:
	// 	should have been resolved by typechecking - handled by default case

	case OPTRLIT:
		w.op(OPTRLIT)
		w.pos(n.Pos)
		w.expr(n.Left)
		w.bool(n.Implicit())

	case OSTRUCTLIT:
		w.op(OSTRUCTLIT)
		w.pos(n.Pos)
		w.typ(n.Type)
		w.elemList(n.List) // special handling of field names

	case OARRAYLIT, OSLICELIT, OMAPLIT:
		w.op(OCOMPLIT)
		w.pos(n.Pos)
		w.typ(n.Type)
		w.exprList(n.List)

	case OKEY:
		w.op(OKEY)
		w.pos(n.Pos)
		w.exprsOrNil(n.Left, n.Right)

	// case OSTRUCTKEY:
	//	unreachable - handled in case OSTRUCTLIT by elemList

	// case OCALLPART:
	//	unimplemented - handled by default case

	case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
		w.op(OXDOT)
		w.pos(n.Pos)
		w.expr(n.Left)
		w.selector(n.Sym)

	case ODOTTYPE, ODOTTYPE2:
		w.op(ODOTTYPE)
		w.pos(n.Pos)
		w.expr(n.Left)
		w.typ(n.Type)

	case OINDEX, OINDEXMAP:
		w.op(OINDEX)
		w.pos(n.Pos)
		w.expr(n.Left)
		w.expr(n.Right)

	case OSLICE, OSLICESTR, OSLICEARR:
		w.op(OSLICE)
		w.pos(n.Pos)
		w.expr(n.Left)
		low, high, _ := n.SliceBounds()
		w.exprsOrNil(low, high)

	case OSLICE3, OSLICE3ARR:
		w.op(OSLICE3)
		w.pos(n.Pos)
		w.expr(n.Left)
		low, high, max := n.SliceBounds()
		w.exprsOrNil(low, high)
		w.expr(max)

	case OCOPY, OCOMPLEX:
		// treated like other builtin calls (see e.g., OREAL)
		w.op(op)
		w.pos(n.Pos)
		w.expr(n.Left)
		w.expr(n.Right)
		w.op(OEND)

	case OCONV, OCONVIFACE, OCONVNOP, OARRAYBYTESTR, OARRAYRUNESTR, OSTRARRAYBYTE, OSTRARRAYRUNE, ORUNESTR:
		w.op(OCONV)
		w.pos(n.Pos)
		w.expr(n.Left)
		w.typ(n.Type)

	case OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
		w.op(op)
		w.pos(n.Pos)
		if n.Left != nil {
			w.expr(n.Left)
			w.op(OEND)
		} else {
			w.exprList(n.List) // emits terminating OEND
		}
		// only append() calls may contain '...' arguments
		if op == OAPPEND {
			w.bool(n.Isddd())
		} else if n.Isddd() {
			Fatalf("exporter: unexpected '...' with %v call", op)
		}

	case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
		w.op(OCALL)
		w.pos(n.Pos)
		w.expr(n.Left)
		w.exprList(n.List)
		w.bool(n.Isddd())

	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
		w.op(op) // must keep separate from OMAKE for importer
		w.pos(n.Pos)
		w.typ(n.Type)
		switch {
		default:
			// empty list
			w.op(OEND)
		case n.List.Len() != 0: // pre-typecheck
			w.exprList(n.List) // emits terminating OEND
		case n.Right != nil:
			w.expr(n.Left)
			w.expr(n.Right)
			w.op(OEND)
		case n.Left != nil && (n.Op == OMAKESLICE || !n.Left.Type.IsUntyped()):
			w.expr(n.Left)
			w.op(OEND)
		}

	// unary expressions
	case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV:
		w.op(op)
		w.pos(n.Pos)
		w.expr(n.Left)

	// binary expressions
	case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
		OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
		w.op(op)
		w.pos(n.Pos)
		w.expr(n.Left)
		w.expr(n.Right)

	case OADDSTR:
		w.op(OADDSTR)
		w.pos(n.Pos)
		w.exprList(n.List)

	case OCMPSTR, OCMPIFACE:
		w.op(n.SubOp())
		w.pos(n.Pos)
		w.expr(n.Left)
		w.expr(n.Right)

	case ODCLCONST:
		// if exporting, DCLCONST should just be removed as its usage
		// has already been replaced with literals

	default:
		Fatalf("cannot export %v (%d) node\n"+
			"==> please file an issue and assign to gri@\n", n.Op, int(n.Op))
	}
}

func (w *exportWriter) op(op Op) {
	w.uint64(uint64(op))
}

func (w *exportWriter) exprsOrNil(a, b *Node) {
	ab := 0
	if a != nil {
		ab |= 1
	}
	if b != nil {
		ab |= 2
	}
	w.uint64(uint64(ab))
	if ab&1 != 0 {
		w.expr(a)
	}
	if ab&2 != 0 {
		w.node(b)
	}
}

func (w *exportWriter) elemList(list Nodes) {
	w.uint64(uint64(list.Len()))
	for _, n := range list.Slice() {
		w.selector(n.Sym)
		w.expr(n.Left)
	}
}

func (w *exportWriter) localName(n *Node) {
	// Escape analysis happens after inline bodies are saved, but
	// we're using the same ONAME nodes, so we might still see
	// PAUTOHEAP here.
	//
	// Check for Stackcopy to identify PAUTOHEAP that came from
	// PPARAM/PPARAMOUT, because we only want to include vargen in
	// non-param names.
	var v int32
	if n.Class() == PAUTO || (n.Class() == PAUTOHEAP && n.Name.Param.Stackcopy == nil) {
		v = n.Name.Vargen
	}

	w.localIdent(n.Sym, v)
}

func (w *exportWriter) localIdent(s *types.Sym, v int32) {
	// Anonymous parameters.
	if s == nil {
		w.string("")
		return
	}

	name := s.Name
	if name == "_" {
		w.string("_")
		return
	}

	if i := strings.LastIndex(name, "."); i >= 0 {
		Fatalf("unexpected dot in identifier: %v", name)
	}

	if v > 0 {
		if strings.Contains(name, "·") {
			Fatalf("exporter: unexpected · in symbol name")
		}
		name = fmt.Sprintf("%s·%d", name, v)
	}

	if !ast.IsExported(name) && s.Pkg != w.currPkg {
		Fatalf("weird package in name: %v => %v, not %q", s, name, w.currPkg.Path)
	}

	w.string(name)
}

type intWriter struct {
	bytes.Buffer
}

func (w *intWriter) int64(x int64) {
	var buf [binary.MaxVarintLen64]byte
	n := binary.PutVarint(buf[:], x)
	w.Write(buf[:n])
}

func (w *intWriter) uint64(x uint64) {
	var buf [binary.MaxVarintLen64]byte
	n := binary.PutUvarint(buf[:], x)
	w.Write(buf[:n])
}
