Source file src/cmd/compile/internal/noder/reader.go

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package noder
     6  
     7  import (
     8  	"encoding/hex"
     9  	"fmt"
    10  	"go/constant"
    11  	"internal/buildcfg"
    12  	"internal/pkgbits"
    13  	"path/filepath"
    14  	"slices"
    15  	"strings"
    16  
    17  	"cmd/compile/internal/base"
    18  	"cmd/compile/internal/dwarfgen"
    19  	"cmd/compile/internal/inline"
    20  	"cmd/compile/internal/inline/interleaved"
    21  	"cmd/compile/internal/ir"
    22  	"cmd/compile/internal/objw"
    23  	"cmd/compile/internal/pgoir"
    24  	"cmd/compile/internal/reflectdata"
    25  	"cmd/compile/internal/staticinit"
    26  	"cmd/compile/internal/typecheck"
    27  	"cmd/compile/internal/types"
    28  	"cmd/internal/hash"
    29  	"cmd/internal/obj"
    30  	"cmd/internal/objabi"
    31  	"cmd/internal/src"
    32  )
    33  
    34  // This file implements cmd/compile backend's reader for the Unified
    35  // IR export data.
    36  
    37  // A pkgReader reads Unified IR export data.
    38  type pkgReader struct {
    39  	pkgbits.PkgDecoder
    40  
    41  	// Indices for encoded things; lazily populated as needed.
    42  	//
    43  	// Note: Objects (i.e., ir.Names) are lazily instantiated by
    44  	// populating their types.Sym.Def; see objReader below.
    45  
    46  	posBases []*src.PosBase
    47  	pkgs     []*types.Pkg
    48  	typs     []*types.Type
    49  
    50  	// offset for rewriting the given (absolute!) index into the output,
    51  	// but bitwise inverted so we can detect if we're missing the entry
    52  	// or not.
    53  	newindex []index
    54  }
    55  
    56  func newPkgReader(pr pkgbits.PkgDecoder) *pkgReader {
    57  	return &pkgReader{
    58  		PkgDecoder: pr,
    59  
    60  		posBases: make([]*src.PosBase, pr.NumElems(pkgbits.SectionPosBase)),
    61  		pkgs:     make([]*types.Pkg, pr.NumElems(pkgbits.SectionPkg)),
    62  		typs:     make([]*types.Type, pr.NumElems(pkgbits.SectionType)),
    63  
    64  		newindex: make([]index, pr.TotalElems()),
    65  	}
    66  }
    67  
    68  // A pkgReaderIndex compactly identifies an index (and its
    69  // corresponding dictionary) within a package's export data.
    70  type pkgReaderIndex struct {
    71  	pr        *pkgReader
    72  	idx       index
    73  	dict      *readerDict
    74  	methodSym *types.Sym
    75  
    76  	synthetic func(pos src.XPos, r *reader)
    77  }
    78  
    79  func (pri pkgReaderIndex) asReader(k pkgbits.SectionKind, marker pkgbits.SyncMarker) *reader {
    80  	if pri.synthetic != nil {
    81  		return &reader{synthetic: pri.synthetic}
    82  	}
    83  
    84  	r := pri.pr.newReader(k, pri.idx, marker)
    85  	r.dict = pri.dict
    86  	r.methodSym = pri.methodSym
    87  	return r
    88  }
    89  
    90  func (pr *pkgReader) newReader(k pkgbits.SectionKind, idx index, marker pkgbits.SyncMarker) *reader {
    91  	return &reader{
    92  		Decoder: pr.NewDecoder(k, idx, marker),
    93  		p:       pr,
    94  	}
    95  }
    96  
    97  // A reader provides APIs for reading an individual element.
    98  type reader struct {
    99  	pkgbits.Decoder
   100  
   101  	p *pkgReader
   102  
   103  	dict *readerDict
   104  
   105  	// funcLitGen is a counter for closure names.
   106  	funcLitGen int
   107  	// rangeLitGen is a counter for range func closure names.
   108  	rangeLitGen int
   109  
   110  	// TODO(mdempsky): The state below is all specific to reading
   111  	// function bodies. It probably makes sense to split it out
   112  	// separately so that it doesn't take up space in every reader
   113  	// instance.
   114  
   115  	curfn       *ir.Func
   116  	locals      []*ir.Name
   117  	closureVars []*ir.Name
   118  
   119  	// funarghack is used during inlining to suppress setting
   120  	// Field.Nname to the inlined copies of the parameters. This is
   121  	// necessary because we reuse the same types.Type as the original
   122  	// function, and most of the compiler still relies on field.Nname to
   123  	// find parameters/results.
   124  	funarghack bool
   125  
   126  	// methodSym is the name of method's name, if reading a method.
   127  	// It's nil if reading a normal function or closure body.
   128  	methodSym *types.Sym
   129  
   130  	// dictParam is the .dict param, if any.
   131  	dictParam *ir.Name
   132  
   133  	// synthetic is a callback function to construct a synthetic
   134  	// function body. It's used for creating the bodies of function
   135  	// literals used to curry arguments to shaped functions.
   136  	synthetic func(pos src.XPos, r *reader)
   137  
   138  	// scopeVars is a stack tracking the number of variables declared in
   139  	// the current function at the moment each open scope was opened.
   140  	scopeVars         []int
   141  	marker            dwarfgen.ScopeMarker
   142  	lastCloseScopePos src.XPos
   143  
   144  	// === details for handling inline body expansion ===
   145  
   146  	// If we're reading in a function body because of inlining, this is
   147  	// the call that we're inlining for.
   148  	inlCaller    *ir.Func
   149  	inlCall      *ir.CallExpr
   150  	inlFunc      *ir.Func
   151  	inlTreeIndex int
   152  	inlPosBases  map[*src.PosBase]*src.PosBase
   153  
   154  	// suppressInlPos tracks whether position base rewriting for
   155  	// inlining should be suppressed. See funcLit.
   156  	suppressInlPos int
   157  
   158  	delayResults bool
   159  
   160  	// Label to return to.
   161  	retlabel *types.Sym
   162  }
   163  
   164  // A readerDict represents an instantiated "compile-time dictionary,"
   165  // used for resolving any derived types needed for instantiating a
   166  // generic object.
   167  //
   168  // A compile-time dictionary can either be "shaped" or "non-shaped."
   169  // Shaped compile-time dictionaries are only used for instantiating
   170  // shaped type definitions and function bodies, while non-shaped
   171  // compile-time dictionaries are used for instantiating runtime
   172  // dictionaries.
   173  type readerDict struct {
   174  	shaped bool // whether this is a shaped dictionary
   175  
   176  	// baseSym is the symbol for the object this dictionary belongs to.
   177  	// If the object is an instantiated function or defined type, then
   178  	// baseSym is the mangled symbol, including any type arguments.
   179  	baseSym *types.Sym
   180  
   181  	// For non-shaped dictionaries, shapedObj is a reference to the
   182  	// corresponding shaped object (always a function or defined type).
   183  	shapedObj *ir.Name
   184  
   185  	// targs holds the implicit and explicit type arguments in use for
   186  	// reading the current object. For example:
   187  	//
   188  	//	func F[T any]() {
   189  	//		type X[U any] struct { t T; u U }
   190  	//		var _ X[string]
   191  	//	}
   192  	//
   193  	//	var _ = F[int]
   194  	//
   195  	// While instantiating F[int], we need to in turn instantiate
   196  	// X[string]. [int] and [string] are explicit type arguments for F
   197  	// and X, respectively; but [int] is also the implicit type
   198  	// arguments for X.
   199  	//
   200  	// (As an analogy to function literals, explicits are the function
   201  	// literal's formal parameters, while implicits are variables
   202  	// captured by the function literal.)
   203  	targs []*types.Type
   204  
   205  	// implicits counts how many of types within targs are implicit type
   206  	// arguments; the rest are explicit.
   207  	implicits int
   208  	// receivers counts how many of types within targs are receiver type
   209  	// arguments; they are explicit.
   210  	receivers int
   211  
   212  	derived      []derivedInfo // reloc index of the derived type's descriptor
   213  	derivedTypes []*types.Type // slice of previously computed derived types
   214  
   215  	// These slices correspond to entries in the runtime dictionary.
   216  	typeParamMethodExprs []readerMethodExprInfo
   217  	subdicts             []objInfo
   218  	rtypes               []typeInfo
   219  	itabs                []itabInfo
   220  }
   221  
   222  type readerMethodExprInfo struct {
   223  	typeParamIdx int
   224  	method       *types.Sym
   225  }
   226  
   227  func setType(n ir.Node, typ *types.Type) {
   228  	n.SetType(typ)
   229  	n.SetTypecheck(1)
   230  }
   231  
   232  func setValue(name *ir.Name, val constant.Value) {
   233  	name.SetVal(val)
   234  	name.Defn = nil
   235  }
   236  
   237  // @@@ Positions
   238  
   239  // pos reads a position from the bitstream.
   240  func (r *reader) pos() src.XPos {
   241  	return base.Ctxt.PosTable.XPos(r.pos0())
   242  }
   243  
   244  // origPos reads a position from the bitstream, and returns both the
   245  // original raw position and an inlining-adjusted position.
   246  func (r *reader) origPos() (origPos, inlPos src.XPos) {
   247  	r.suppressInlPos++
   248  	origPos = r.pos()
   249  	r.suppressInlPos--
   250  	inlPos = r.inlPos(origPos)
   251  	return
   252  }
   253  
   254  func (r *reader) pos0() src.Pos {
   255  	r.Sync(pkgbits.SyncPos)
   256  	if !r.Bool() {
   257  		return src.NoPos
   258  	}
   259  
   260  	posBase := r.posBase()
   261  	line := r.Uint()
   262  	col := r.Uint()
   263  	return src.MakePos(posBase, line, col)
   264  }
   265  
   266  // posBase reads a position base from the bitstream.
   267  func (r *reader) posBase() *src.PosBase {
   268  	return r.inlPosBase(r.p.posBaseIdx(r.Reloc(pkgbits.SectionPosBase)))
   269  }
   270  
   271  // posBaseIdx returns the specified position base, reading it first if
   272  // needed.
   273  func (pr *pkgReader) posBaseIdx(idx index) *src.PosBase {
   274  	if b := pr.posBases[idx]; b != nil {
   275  		return b
   276  	}
   277  
   278  	r := pr.newReader(pkgbits.SectionPosBase, idx, pkgbits.SyncPosBase)
   279  	var b *src.PosBase
   280  
   281  	absFilename := r.String()
   282  	filename := absFilename
   283  
   284  	// For build artifact stability, the export data format only
   285  	// contains the "absolute" filename as returned by objabi.AbsFile.
   286  	// However, some tests (e.g., test/run.go's asmcheck tests) expect
   287  	// to see the full, original filename printed out. Re-expanding
   288  	// "$GOROOT" to buildcfg.GOROOT is a close-enough approximation to
   289  	// satisfy this.
   290  	//
   291  	// The export data format only ever uses slash paths
   292  	// (for cross-operating-system reproducible builds),
   293  	// but error messages need to use native paths (backslash on Windows)
   294  	// as if they had been specified on the command line.
   295  	// (The go command always passes native paths to the compiler.)
   296  	const dollarGOROOT = "$GOROOT"
   297  	if buildcfg.GOROOT != "" && strings.HasPrefix(filename, dollarGOROOT) {
   298  		filename = filepath.FromSlash(buildcfg.GOROOT + filename[len(dollarGOROOT):])
   299  	}
   300  
   301  	if r.Bool() {
   302  		b = src.NewFileBase(filename, absFilename)
   303  	} else {
   304  		pos := r.pos0()
   305  		line := r.Uint()
   306  		col := r.Uint()
   307  		b = src.NewLinePragmaBase(pos, filename, absFilename, line, col)
   308  	}
   309  
   310  	pr.posBases[idx] = b
   311  	return b
   312  }
   313  
   314  // inlPosBase returns the inlining-adjusted src.PosBase corresponding
   315  // to oldBase, which must be a non-inlined position. When not
   316  // inlining, this is just oldBase.
   317  func (r *reader) inlPosBase(oldBase *src.PosBase) *src.PosBase {
   318  	if index := oldBase.InliningIndex(); index >= 0 {
   319  		base.Fatalf("oldBase %v already has inlining index %v", oldBase, index)
   320  	}
   321  
   322  	if r.inlCall == nil || r.suppressInlPos != 0 {
   323  		return oldBase
   324  	}
   325  
   326  	if newBase, ok := r.inlPosBases[oldBase]; ok {
   327  		return newBase
   328  	}
   329  
   330  	newBase := src.NewInliningBase(oldBase, r.inlTreeIndex)
   331  	r.inlPosBases[oldBase] = newBase
   332  	return newBase
   333  }
   334  
   335  // inlPos returns the inlining-adjusted src.XPos corresponding to
   336  // xpos, which must be a non-inlined position. When not inlining, this
   337  // is just xpos.
   338  func (r *reader) inlPos(xpos src.XPos) src.XPos {
   339  	pos := base.Ctxt.PosTable.Pos(xpos)
   340  	pos.SetBase(r.inlPosBase(pos.Base()))
   341  	return base.Ctxt.PosTable.XPos(pos)
   342  }
   343  
   344  // @@@ Packages
   345  
   346  // pkg reads a package reference from the bitstream.
   347  func (r *reader) pkg() *types.Pkg {
   348  	r.Sync(pkgbits.SyncPkg)
   349  	return r.p.pkgIdx(r.Reloc(pkgbits.SectionPkg))
   350  }
   351  
   352  // pkgIdx returns the specified package from the export data, reading
   353  // it first if needed.
   354  func (pr *pkgReader) pkgIdx(idx index) *types.Pkg {
   355  	if pkg := pr.pkgs[idx]; pkg != nil {
   356  		return pkg
   357  	}
   358  
   359  	pkg := pr.newReader(pkgbits.SectionPkg, idx, pkgbits.SyncPkgDef).doPkg()
   360  	pr.pkgs[idx] = pkg
   361  	return pkg
   362  }
   363  
   364  // doPkg reads a package definition from the bitstream.
   365  func (r *reader) doPkg() *types.Pkg {
   366  	path := r.String()
   367  	switch path {
   368  	case "":
   369  		path = r.p.PkgPath()
   370  	case "builtin":
   371  		return types.BuiltinPkg
   372  	case "unsafe":
   373  		return types.UnsafePkg
   374  	}
   375  
   376  	name := r.String()
   377  
   378  	pkg := types.NewPkg(path, "")
   379  
   380  	if pkg.Name == "" {
   381  		pkg.Name = name
   382  	} else {
   383  		base.Assertf(pkg.Name == name, "package %q has name %q, but want %q", pkg.Path, pkg.Name, name)
   384  	}
   385  
   386  	return pkg
   387  }
   388  
   389  // @@@ Types
   390  
   391  func (r *reader) typ() *types.Type {
   392  	return r.typWrapped(true)
   393  }
   394  
   395  // typWrapped is like typ, but allows suppressing generation of
   396  // unnecessary wrappers as a compile-time optimization.
   397  func (r *reader) typWrapped(wrapped bool) *types.Type {
   398  	return r.p.typIdx(r.typInfo(), r.dict, wrapped)
   399  }
   400  
   401  func (r *reader) typInfo() typeInfo {
   402  	r.Sync(pkgbits.SyncType)
   403  	if r.Bool() {
   404  		return typeInfo{idx: index(r.Len()), derived: true}
   405  	}
   406  	return typeInfo{idx: r.Reloc(pkgbits.SectionType), derived: false}
   407  }
   408  
   409  // typListIdx returns a list of the specified types, resolving derived
   410  // types within the given dictionary.
   411  func (pr *pkgReader) typListIdx(infos []typeInfo, dict *readerDict) []*types.Type {
   412  	typs := make([]*types.Type, len(infos))
   413  	for i, info := range infos {
   414  		typs[i] = pr.typIdx(info, dict, true)
   415  	}
   416  	return typs
   417  }
   418  
   419  // typIdx returns the specified type. If info specifies a derived
   420  // type, it's resolved within the given dictionary. If wrapped is
   421  // true, then method wrappers will be generated, if appropriate.
   422  func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict, wrapped bool) *types.Type {
   423  	idx := info.idx
   424  	var where **types.Type
   425  	if info.derived {
   426  		where = &dict.derivedTypes[idx]
   427  		idx = dict.derived[idx].idx
   428  	} else {
   429  		where = &pr.typs[idx]
   430  	}
   431  
   432  	if typ := *where; typ != nil {
   433  		return typ
   434  	}
   435  
   436  	r := pr.newReader(pkgbits.SectionType, idx, pkgbits.SyncTypeIdx)
   437  	r.dict = dict
   438  
   439  	typ := r.doTyp()
   440  	if typ == nil {
   441  		base.Fatalf("doTyp returned nil for info=%v", info)
   442  	}
   443  
   444  	// For recursive type declarations involving interfaces and aliases,
   445  	// above r.doTyp() call may have already set pr.typs[idx], so just
   446  	// double check and return the type.
   447  	//
   448  	// Example:
   449  	//
   450  	//     type F = func(I)
   451  	//
   452  	//     type I interface {
   453  	//         m(F)
   454  	//     }
   455  	//
   456  	// The writer writes data types in following index order:
   457  	//
   458  	//     0: func(I)
   459  	//     1: I
   460  	//     2: interface{m(func(I))}
   461  	//
   462  	// The reader resolves it in following index order:
   463  	//
   464  	//     0 -> 1 -> 2 -> 0 -> 1
   465  	//
   466  	// and can divide in logically 2 steps:
   467  	//
   468  	//  - 0 -> 1     : first time the reader reach type I,
   469  	//                 it creates new named type with symbol I.
   470  	//
   471  	//  - 2 -> 0 -> 1: the reader ends up reaching symbol I again,
   472  	//                 now the symbol I was setup in above step, so
   473  	//                 the reader just return the named type.
   474  	//
   475  	// Now, the functions called return, the pr.typs looks like below:
   476  	//
   477  	//  - 0 -> 1 -> 2 -> 0 : [<T> I <T>]
   478  	//  - 0 -> 1 -> 2      : [func(I) I <T>]
   479  	//  - 0 -> 1           : [func(I) I interface { "".m(func("".I)) }]
   480  	//
   481  	// The idx 1, corresponding with type I was resolved successfully
   482  	// after r.doTyp() call.
   483  
   484  	if prev := *where; prev != nil {
   485  		return prev
   486  	}
   487  
   488  	if wrapped {
   489  		// Only cache if we're adding wrappers, so that other callers that
   490  		// find a cached type know it was wrapped.
   491  		*where = typ
   492  
   493  		r.needWrapper(typ)
   494  	}
   495  
   496  	if !typ.IsUntyped() {
   497  		types.CheckSize(typ)
   498  	}
   499  
   500  	return typ
   501  }
   502  
   503  func (r *reader) doTyp() *types.Type {
   504  	switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
   505  	default:
   506  		panic(fmt.Sprintf("unexpected type: %v", tag))
   507  
   508  	case pkgbits.TypeBasic:
   509  		return *basics[r.Len()]
   510  
   511  	case pkgbits.TypeNamed:
   512  		obj := r.obj()
   513  		assert(obj.Op() == ir.OTYPE)
   514  		return obj.Type()
   515  
   516  	case pkgbits.TypeTypeParam:
   517  		return r.dict.targs[r.Len()]
   518  
   519  	case pkgbits.TypeArray:
   520  		len := int64(r.Uint64())
   521  		return types.NewArray(r.typ(), len)
   522  	case pkgbits.TypeChan:
   523  		dir := dirs[r.Len()]
   524  		return types.NewChan(r.typ(), dir)
   525  	case pkgbits.TypeMap:
   526  		return types.NewMap(r.typ(), r.typ())
   527  	case pkgbits.TypePointer:
   528  		return types.NewPtr(r.typ())
   529  	case pkgbits.TypeSignature:
   530  		return r.signature(nil)
   531  	case pkgbits.TypeSlice:
   532  		return types.NewSlice(r.typ())
   533  	case pkgbits.TypeStruct:
   534  		return r.structType()
   535  	case pkgbits.TypeInterface:
   536  		return r.interfaceType()
   537  	case pkgbits.TypeUnion:
   538  		return r.unionType()
   539  	}
   540  }
   541  
   542  func (r *reader) unionType() *types.Type {
   543  	// In the types1 universe, we only need to handle value types.
   544  	// Impure interfaces (i.e., interfaces with non-trivial type sets
   545  	// like "int | string") can only appear as type parameter bounds,
   546  	// and this is enforced by the types2 type checker.
   547  	//
   548  	// However, type unions can still appear in pure interfaces if the
   549  	// type union is equivalent to "any". E.g., typeparam/issue52124.go
   550  	// declares variables with the type "interface { any | int }".
   551  	//
   552  	// To avoid needing to represent type unions in types1 (since we
   553  	// don't have any uses for that today anyway), we simply fold them
   554  	// to "any".
   555  
   556  	// TODO(mdempsky): Restore consistency check to make sure folding to
   557  	// "any" is safe. This is unfortunately tricky, because a pure
   558  	// interface can reference impure interfaces too, including
   559  	// cyclically (#60117).
   560  	if false {
   561  		pure := false
   562  		for i, n := 0, r.Len(); i < n; i++ {
   563  			_ = r.Bool() // tilde
   564  			term := r.typ()
   565  			if term.IsEmptyInterface() {
   566  				pure = true
   567  			}
   568  		}
   569  		if !pure {
   570  			base.Fatalf("impure type set used in value type")
   571  		}
   572  	}
   573  
   574  	return types.Types[types.TINTER]
   575  }
   576  
   577  func (r *reader) interfaceType() *types.Type {
   578  	nmethods, nembeddeds := r.Len(), r.Len()
   579  	implicit := nmethods == 0 && nembeddeds == 1 && r.Bool()
   580  	assert(!implicit) // implicit interfaces only appear in constraints
   581  
   582  	fields := make([]*types.Field, nmethods+nembeddeds)
   583  	methods, embeddeds := fields[:nmethods], fields[nmethods:]
   584  
   585  	for i := range methods {
   586  		methods[i] = types.NewField(r.pos(), r.selector(), r.signature(types.FakeRecv()))
   587  	}
   588  	for i := range embeddeds {
   589  		embeddeds[i] = types.NewField(src.NoXPos, nil, r.typ())
   590  	}
   591  
   592  	if len(fields) == 0 {
   593  		return types.Types[types.TINTER] // empty interface
   594  	}
   595  	return types.NewInterface(fields)
   596  }
   597  
   598  func (r *reader) structType() *types.Type {
   599  	fields := make([]*types.Field, r.Len())
   600  	for i := range fields {
   601  		field := types.NewField(r.pos(), r.selector(), r.typ())
   602  		field.Note = r.String()
   603  		if r.Bool() {
   604  			field.Embedded = 1
   605  		}
   606  		fields[i] = field
   607  	}
   608  	return types.NewStruct(fields)
   609  }
   610  
   611  func (r *reader) signature(recv *types.Field) *types.Type {
   612  	r.Sync(pkgbits.SyncSignature)
   613  
   614  	params := r.params()
   615  	results := r.params()
   616  	if r.Bool() { // variadic
   617  		params[len(params)-1].SetIsDDD(true)
   618  	}
   619  
   620  	return types.NewSignature(recv, params, results)
   621  }
   622  
   623  func (r *reader) params() []*types.Field {
   624  	r.Sync(pkgbits.SyncParams)
   625  	params := make([]*types.Field, r.Len())
   626  	for i := range params {
   627  		params[i] = r.param()
   628  	}
   629  	return params
   630  }
   631  
   632  func (r *reader) param() *types.Field {
   633  	r.Sync(pkgbits.SyncParam)
   634  	return types.NewField(r.pos(), r.localIdent(), r.typ())
   635  }
   636  
   637  // @@@ Objects
   638  
   639  // objReader maps qualified identifiers (represented as *types.Sym) to
   640  // a pkgReader and corresponding index that can be used for reading
   641  // that object's definition.
   642  var objReader = map[*types.Sym]pkgReaderIndex{}
   643  
   644  // obj reads an instantiated object reference from the bitstream.
   645  func (r *reader) obj() ir.Node {
   646  	return r.p.objInstIdx(r.objInfo(), r.dict, false)
   647  }
   648  
   649  // objInfo reads an instantiated object reference from the bitstream
   650  // and returns the encoded reference to it, without instantiating it.
   651  func (r *reader) objInfo() objInfo {
   652  	r.Sync(pkgbits.SyncObject)
   653  	if r.Version().Has(pkgbits.DerivedFuncInstance) {
   654  		assert(!r.Bool())
   655  	}
   656  	idx := r.Reloc(pkgbits.SectionObj)
   657  
   658  	explicits := make([]typeInfo, r.Len())
   659  	for i := range explicits {
   660  		explicits[i] = r.typInfo()
   661  	}
   662  
   663  	return objInfo{idx, explicits}
   664  }
   665  
   666  // objInstIdx returns the encoded, instantiated object. If shaped is
   667  // true, then the shaped variant of the object is returned instead.
   668  func (pr *pkgReader) objInstIdx(info objInfo, dict *readerDict, shaped bool) ir.Node {
   669  	explicits := pr.typListIdx(info.explicits, dict)
   670  
   671  	var implicits []*types.Type
   672  	if dict != nil {
   673  		implicits = dict.targs
   674  	}
   675  
   676  	return pr.objIdx(info.idx, implicits, explicits, shaped)
   677  }
   678  
   679  // objIdx returns the specified object, instantiated with the given
   680  // type arguments, if any.
   681  // If shaped is true, then the shaped variant of the object is returned
   682  // instead.
   683  func (pr *pkgReader) objIdx(idx index, implicits, explicits []*types.Type, shaped bool) ir.Node {
   684  	n, err := pr.objIdxMayFail(idx, implicits, explicits, shaped)
   685  	if err != nil {
   686  		base.Fatalf("%v", err)
   687  	}
   688  	return n
   689  }
   690  
   691  // objIdxMayFail is equivalent to objIdx, but returns an error rather than
   692  // failing the build if this object requires type arguments and the incorrect
   693  // number of type arguments were passed.
   694  //
   695  // Other sources of internal failure (such as duplicate definitions) still fail
   696  // the build.
   697  func (pr *pkgReader) objIdxMayFail(idx index, implicits, explicits []*types.Type, shaped bool) (ir.Node, error) {
   698  	rname := pr.newReader(pkgbits.SectionName, idx, pkgbits.SyncObject1)
   699  	_, sym := rname.qualifiedIdent()
   700  	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
   701  
   702  	if tag == pkgbits.ObjStub {
   703  		assert(!sym.IsBlank())
   704  		switch sym.Pkg {
   705  		case types.BuiltinPkg, types.UnsafePkg:
   706  			return sym.Def.(ir.Node), nil
   707  		}
   708  		if pri, ok := objReader[sym]; ok {
   709  			return pri.pr.objIdxMayFail(pri.idx, nil, explicits, shaped)
   710  		}
   711  		if sym.Pkg.Path == "runtime" {
   712  			return typecheck.LookupRuntime(sym.Name), nil
   713  		}
   714  		base.Fatalf("unresolved stub: %v", sym)
   715  	}
   716  
   717  	dict, err := pr.objDictIdx(sym, idx, implicits, explicits, shaped)
   718  	if err != nil {
   719  		return nil, err
   720  	}
   721  
   722  	sym = dict.baseSym
   723  	if !sym.IsBlank() && sym.Def != nil {
   724  		return sym.Def.(*ir.Name), nil
   725  	}
   726  
   727  	r := pr.newReader(pkgbits.SectionObj, idx, pkgbits.SyncObject1)
   728  	rext := pr.newReader(pkgbits.SectionObjExt, idx, pkgbits.SyncObject1)
   729  
   730  	r.dict = dict
   731  	rext.dict = dict
   732  
   733  	do := func(op ir.Op, hasTParams bool) *ir.Name {
   734  		pos := r.pos()
   735  		setBasePos(pos)
   736  		if hasTParams {
   737  			r.typeParamNames()
   738  		}
   739  
   740  		name := ir.NewDeclNameAt(pos, op, sym)
   741  		name.Class = ir.PEXTERN // may be overridden later
   742  		if !sym.IsBlank() {
   743  			if sym.Def != nil {
   744  				base.FatalfAt(name.Pos(), "already have a definition for %v", name)
   745  			}
   746  			assert(sym.Def == nil)
   747  			sym.Def = name
   748  		}
   749  		return name
   750  	}
   751  
   752  	switch tag {
   753  	default:
   754  		panic("unexpected object")
   755  
   756  	case pkgbits.ObjAlias:
   757  		name := do(ir.OTYPE, false)
   758  
   759  		if r.Version().Has(pkgbits.AliasTypeParamNames) {
   760  			r.typeParamNames()
   761  		}
   762  
   763  		// Clumsy dance: the r.typ() call here might recursively find this
   764  		// type alias name, before we've set its type (#66873). So we
   765  		// temporarily clear sym.Def and then restore it later, if still
   766  		// unset.
   767  		hack := sym.Def == name
   768  		if hack {
   769  			sym.Def = nil
   770  		}
   771  		typ := r.typ()
   772  		if hack {
   773  			if sym.Def != nil {
   774  				name = sym.Def.(*ir.Name)
   775  				assert(types.IdenticalStrict(name.Type(), typ))
   776  				return name, nil
   777  			}
   778  			sym.Def = name
   779  		}
   780  
   781  		setType(name, typ)
   782  		name.SetAlias(true)
   783  		return name, nil
   784  
   785  	case pkgbits.ObjConst:
   786  		name := do(ir.OLITERAL, false)
   787  		typ := r.typ()
   788  		val := FixValue(typ, r.Value())
   789  		setType(name, typ)
   790  		setValue(name, val)
   791  		return name, nil
   792  
   793  	case pkgbits.ObjFunc:
   794  		npos := r.pos()
   795  		setBasePos(npos)
   796  
   797  		var sel *types.Sym
   798  		var recv *types.Field
   799  		if r.Version().Has(pkgbits.GenericMethods) && r.Bool() {
   800  			sel = r.selector()
   801  			r.recvTypeParamNames()
   802  			recv = r.param()
   803  			if r.Version().Has(pkgbits.PreserveMethodOrder) {
   804  				_ = r.Len() // method index not needed in compiler
   805  			}
   806  		} else {
   807  			if sym.Name == "init" {
   808  				sym = Renameinit()
   809  			}
   810  		}
   811  		r.typeParamNames()
   812  		typ := r.signature(recv)
   813  		fpos := r.pos()
   814  
   815  		fn := ir.NewFunc(fpos, npos, sym, typ)
   816  		if r.hasTypeParams() && r.dict.shaped {
   817  			typ.SetHasShape(true)
   818  		}
   819  
   820  		name := fn.Nname
   821  		if !sym.IsBlank() {
   822  			if sym.Def != nil {
   823  				base.FatalfAt(name.Pos(), "already have a definition for %v", name)
   824  			}
   825  			assert(sym.Def == nil)
   826  			sym.Def = name
   827  		}
   828  
   829  		if r.hasTypeParams() {
   830  			name.Func.SetDupok(true)
   831  			if r.dict.shaped {
   832  				setType(name, shapeSig(name.Func, r.dict))
   833  			} else {
   834  				todoDicts = append(todoDicts, func() {
   835  					r.dict.shapedObj = pr.objIdx(idx, implicits, explicits, true).(*ir.Name)
   836  				})
   837  			}
   838  		}
   839  
   840  		rext.funcExt(name, sel)
   841  		return name, nil
   842  
   843  	case pkgbits.ObjType:
   844  		name := do(ir.OTYPE, true)
   845  		typ := types.NewNamed(name)
   846  		setType(name, typ)
   847  		if r.hasTypeParams() && r.dict.shaped {
   848  			typ.SetHasShape(true)
   849  		}
   850  
   851  		// Important: We need to do this before SetUnderlying.
   852  		rext.typeExt(name)
   853  
   854  		// We need to defer CheckSize until we've called SetUnderlying to
   855  		// handle recursive types.
   856  		types.DeferCheckSize()
   857  		typ.SetUnderlying(r.typWrapped(false))
   858  		types.ResumeCheckSize()
   859  
   860  		if r.hasTypeParams() && !r.dict.shaped {
   861  			todoDicts = append(todoDicts, func() {
   862  				r.dict.shapedObj = pr.objIdx(idx, implicits, explicits, true).(*ir.Name)
   863  			})
   864  		}
   865  
   866  		methods := make([]*types.Field, r.Len())
   867  		for i := range methods {
   868  			methods[i] = r.method(rext)
   869  		}
   870  		if len(methods) != 0 {
   871  			typ.SetMethods(methods)
   872  		}
   873  
   874  		if !r.dict.shaped {
   875  			r.needWrapper(typ)
   876  		}
   877  
   878  		return name, nil
   879  
   880  	case pkgbits.ObjVar:
   881  		name := do(ir.ONAME, false)
   882  		setType(name, r.typ())
   883  		rext.varExt(name)
   884  		return name, nil
   885  	}
   886  }
   887  
   888  // mangle shapes the non-shaped symbol sym under the current dictionary.
   889  func (dict *readerDict) mangle(sym *types.Sym) *types.Sym {
   890  	if !dict.hasTypeParams() {
   891  		return sym
   892  	}
   893  
   894  	var buf strings.Builder
   895  	// If sym is a locally defined generic type, we need the suffix to
   896  	// stay at the end after mangling so that types/fmt.go can strip it
   897  	// out again when writing the type's runtime descriptor (#54456).
   898  	n0, vsuff := types.SplitVargenSuffix(sym.Name)
   899  	n1, msuff := types.SplitMethSuffix(sym.Name)
   900  
   901  	// Methods are never locally defined.
   902  	var n string
   903  	assert(vsuff == "" || msuff == "")
   904  	if vsuff != "" {
   905  		n = n0
   906  	} else {
   907  		n = n1
   908  	}
   909  
   910  	var j int
   911  	assert(dict.implicits == 0 || dict.receivers == 0)
   912  	if msuff != "" {
   913  		j = dict.receivers // consume receiver type arguments
   914  	} else {
   915  		j = len(dict.targs) // consume all type arguments
   916  	}
   917  
   918  	// put type arguments inside parenthesis; (*T)[int] -> (*T[int])
   919  	n, ok := strings.CutSuffix(n, ")")
   920  
   921  	// type arguments, if any
   922  	buf.WriteString(n)
   923  	if j > 0 {
   924  		buf.WriteByte('[')
   925  		for i := 0; i < j; i++ {
   926  			if i > 0 {
   927  				if i == dict.implicits {
   928  					buf.WriteByte(';')
   929  				} else {
   930  					buf.WriteByte(',')
   931  				}
   932  			}
   933  			buf.WriteString(dict.targs[i].LinkString())
   934  		}
   935  		buf.WriteByte(']')
   936  	}
   937  
   938  	if ok {
   939  		buf.WriteString(")")
   940  	}
   941  
   942  	buf.WriteString(vsuff)
   943  	buf.WriteString(msuff)
   944  
   945  	// method arguments, if any
   946  	if msuff != "" {
   947  		buf.WriteByte('[')
   948  		for i := j; i < len(dict.targs); i++ {
   949  			if i > j {
   950  				buf.WriteByte(',')
   951  			}
   952  			buf.WriteString(dict.targs[i].LinkString())
   953  		}
   954  		buf.WriteByte(']')
   955  	}
   956  
   957  	return sym.Pkg.Lookup(buf.String())
   958  }
   959  
   960  // Shapify returns the shape type for targ.
   961  //
   962  // If basic is true, then the type argument is used to instantiate a
   963  // type parameter whose constraint is a basic interface.
   964  func Shapify(targ *types.Type, basic bool) *types.Type {
   965  	if targ.Kind() == types.TFORW {
   966  		if targ.IsFullyInstantiated() {
   967  			// For recursive instantiated type argument, it may  still be a TFORW
   968  			// when shapifying happens. If we don't have targ's underlying type,
   969  			// shapify won't work. The worst case is we end up not reusing code
   970  			// optimally in some tricky cases.
   971  			if base.Debug.Shapify != 0 {
   972  				base.Warn("skipping shaping of recursive type %v", targ)
   973  			}
   974  			if targ.HasShape() {
   975  				return targ
   976  			}
   977  		} else {
   978  			base.Fatalf("%v is missing its underlying type", targ)
   979  		}
   980  	}
   981  	// For fully instantiated shape interface type, use it as-is. Otherwise, the instantiation
   982  	// involved recursive generic interface may cause mismatching in function signature, see issue #65362.
   983  	if targ.Kind() == types.TINTER && targ.IsFullyInstantiated() && targ.HasShape() {
   984  		return targ
   985  	}
   986  
   987  	// When a pointer type is used to instantiate a type parameter
   988  	// constrained by a basic interface, we know the pointer's element
   989  	// type can't matter to the generated code. In this case, we can use
   990  	// an arbitrary pointer type as the shape type. (To match the
   991  	// non-unified frontend, we use `*byte`.)
   992  	//
   993  	// Otherwise, we simply use the type's underlying type as its shape.
   994  	//
   995  	// TODO(mdempsky): It should be possible to do much more aggressive
   996  	// shaping still; e.g., collapsing all pointer-shaped types into a
   997  	// common type, collapsing scalars of the same size/alignment into a
   998  	// common type, recursively shaping the element types of composite
   999  	// types, and discarding struct field names and tags. However, we'll
  1000  	// need to start tracking how type parameters are actually used to
  1001  	// implement some of these optimizations.
  1002  	under := targ.Underlying()
  1003  	if basic && targ.IsPtr() && !targ.Elem().NotInHeap() {
  1004  		under = types.NewPtr(types.Types[types.TUINT8])
  1005  	}
  1006  
  1007  	// Bound the length of the shape name seen by users. Shape names are
  1008  	// embedded in the names of every function and method instantiated with
  1009  	// them, so a single unwieldy type argument (a large protobuf struct
  1010  	// (#65030), or an interface with many methods (#71535)) makes a mess of
  1011  	// nm output, stack traces and pprof graphs.
  1012  	//
  1013  	// The name is only ever used as a unique key for under; nothing parses
  1014  	// it. So anything that tells distinct shapes apart will do, and we can
  1015  	// pick whichever one reads best.
  1016  	//
  1017  	// Whatever we pick has to keep Shapify idempotent, that is
  1018  	// Shapify(Shapify(T)) == Shapify(T). An instantiation's shaped object is
  1019  	// found by shapifying its type arguments again, and a generic function
  1020  	// instantiated with a shape passes that shape on when it calls another
  1021  	// generic function, so Shapify is routinely applied to a type that is
  1022  	// already a shape. Without shortening that holds for free: the key is
  1023  	// under.LinkString(), and a shape has the same underlying type as the
  1024  	// type it was made from. Shortening derives the name from targ instead,
  1025  	// so the first case below has to recognize a shape and hand back the
  1026  	// name it already has.
  1027  	uls := under.LinkString()
  1028  	if base.Debug.MaxShapeLen != 0 && len(uls) > base.Debug.MaxShapeLen {
  1029  		switch targLS := targ.LinkString(); {
  1030  		case targ.IsShape():
  1031  			// targ is a shape this function already named. Reuse that name
  1032  			// verbatim.
  1033  			//
  1034  			// This is not subsumed by the case below. A shape is a named
  1035  			// type, so targ.Sym() != nil holds there too, but the two cases
  1036  			// use different strings: Sym().Name is unqualified, say
  1037  			// "main.Big", while LinkString is qualified by the shape
  1038  			// package, "go.shape.main.Big". The lookup below adds that
  1039  			// qualifier back, so falling through would name the shape of a
  1040  			// shape "go.shape.go.shape.main.Big" - or, if that is too long
  1041  			// in turn, hash it over the underlying type and merge it with
  1042  			// every other shape sharing that underlying type. Either way
  1043  			// the second Shapify lands on a different type than the first.
  1044  			uls = targ.Sym().Name
  1045  
  1046  		case targ.Sym() != nil && len(targLS) <= base.Debug.MaxShapeLen:
  1047  			// LinkString is what makes this safe to use as the shape's
  1048  			// identity: it is unique for each distinct type, qualified by
  1049  			// package path, and it keeps the ·N suffix that distinguishes
  1050  			// function-scope types. An unqualified name would collide.
  1051  			//
  1052  			// Naming a shape after the type argument means two named types
  1053  			// that share an underlying type no longer share a shape. That
  1054  			// only applies to underlying types over the length limit, where
  1055  			// having two copies is a fair price for a legible name.
  1056  			uls = targLS
  1057  
  1058  		default:
  1059  			// Nothing to borrow: the type argument has no name of its own,
  1060  			// or its name is too long as well, thus fall back to a hash.
  1061  			h := hash.Sum32([]byte(uls))
  1062  			uls = hex.EncodeToString(h[:])
  1063  		}
  1064  	}
  1065  
  1066  	sym := types.ShapePkg.Lookup(uls)
  1067  	if sym.Def == nil {
  1068  		name := ir.NewDeclNameAt(under.Pos(), ir.OTYPE, sym)
  1069  		typ := types.NewNamed(name)
  1070  		typ.SetUnderlying(under)
  1071  		sym.Def = typed(typ, name)
  1072  	}
  1073  	res := sym.Def.Type()
  1074  	assert(res.IsShape())
  1075  	assert(res.HasShape())
  1076  	return res
  1077  }
  1078  
  1079  // objDictIdx reads and returns the specified object dictionary.
  1080  func (pr *pkgReader) objDictIdx(sym *types.Sym, idx index, implicits, explicits []*types.Type, shaped bool) (*readerDict, error) {
  1081  	r := pr.newReader(pkgbits.SectionObjDict, idx, pkgbits.SyncObject1)
  1082  
  1083  	dict := readerDict{
  1084  		shaped: shaped,
  1085  	}
  1086  
  1087  	nimplicits := r.Len()
  1088  	nreceivers := 0
  1089  	if r.Version().Has(pkgbits.GenericMethods) {
  1090  		nreceivers = r.Len()
  1091  	}
  1092  	nexplicits := r.Len() + nreceivers
  1093  
  1094  	if nimplicits > len(implicits) || nexplicits != len(explicits) {
  1095  		return nil, fmt.Errorf("%v has %v+%v params, but instantiated with %v+%v args", sym, nimplicits, nexplicits, len(implicits), len(explicits))
  1096  	}
  1097  
  1098  	dict.targs = append(implicits[:nimplicits:nimplicits], explicits...)
  1099  	dict.implicits = nimplicits
  1100  	dict.receivers = nreceivers
  1101  
  1102  	// Within the compiler, we can just skip over the type parameters.
  1103  	for range dict.targs[dict.implicits:] {
  1104  		// Skip past bounds without actually evaluating them.
  1105  		r.typInfo()
  1106  	}
  1107  
  1108  	dict.derived = make([]derivedInfo, r.Len())
  1109  	dict.derivedTypes = make([]*types.Type, len(dict.derived))
  1110  	for i := range dict.derived {
  1111  		dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.SectionType)}
  1112  		if r.Version().Has(pkgbits.DerivedInfoNeeded) {
  1113  			assert(!r.Bool())
  1114  		}
  1115  	}
  1116  
  1117  	// Runtime dictionary information; private to the compiler.
  1118  
  1119  	// If any type argument is already shaped, then we're constructing a
  1120  	// shaped object, even if not explicitly requested (i.e., calling
  1121  	// objIdx with shaped==true). This can happen with instantiating
  1122  	// types that are referenced within a function body.
  1123  	for _, targ := range dict.targs {
  1124  		if targ.HasShape() {
  1125  			dict.shaped = true
  1126  			break
  1127  		}
  1128  	}
  1129  
  1130  	// And if we're constructing a shaped object, then shapify all type
  1131  	// arguments.
  1132  	for i, targ := range dict.targs {
  1133  		basic := r.Bool()
  1134  		if dict.shaped {
  1135  			dict.targs[i] = Shapify(targ, basic)
  1136  		}
  1137  	}
  1138  
  1139  	dict.baseSym = dict.mangle(sym)
  1140  
  1141  	dict.typeParamMethodExprs = make([]readerMethodExprInfo, r.Len())
  1142  	for i := range dict.typeParamMethodExprs {
  1143  		typeParamIdx := r.Len()
  1144  		method := r.selector()
  1145  
  1146  		dict.typeParamMethodExprs[i] = readerMethodExprInfo{typeParamIdx, method}
  1147  	}
  1148  
  1149  	dict.subdicts = make([]objInfo, r.Len())
  1150  	for i := range dict.subdicts {
  1151  		dict.subdicts[i] = r.objInfo()
  1152  	}
  1153  
  1154  	dict.rtypes = make([]typeInfo, r.Len())
  1155  	for i := range dict.rtypes {
  1156  		dict.rtypes[i] = r.typInfo()
  1157  	}
  1158  
  1159  	dict.itabs = make([]itabInfo, r.Len())
  1160  	for i := range dict.itabs {
  1161  		dict.itabs[i] = itabInfo{typ: r.typInfo(), iface: r.typInfo()}
  1162  	}
  1163  
  1164  	return &dict, nil
  1165  }
  1166  
  1167  func (r *reader) recvTypeParamNames() {
  1168  	r.Sync(pkgbits.SyncTypeParamNames)
  1169  
  1170  	for range r.dict.targs[r.dict.implicits : r.dict.implicits+r.dict.receivers] {
  1171  		r.pos()
  1172  		r.localIdent()
  1173  	}
  1174  }
  1175  
  1176  func (r *reader) typeParamNames() {
  1177  	r.Sync(pkgbits.SyncTypeParamNames)
  1178  
  1179  	for range r.dict.targs[r.dict.implicits+r.dict.receivers:] {
  1180  		r.pos()
  1181  		r.localIdent()
  1182  	}
  1183  }
  1184  
  1185  func (r *reader) method(rext *reader) *types.Field {
  1186  	r.Sync(pkgbits.SyncMethod)
  1187  	if r.Version().Has(pkgbits.PreserveMethodOrder) {
  1188  		_ = r.Len() // method index not needed in compiler
  1189  	}
  1190  	npos := r.pos()
  1191  	sym := r.selector()
  1192  	r.typeParamNames()
  1193  	recv := r.param()
  1194  	typ := r.signature(recv)
  1195  
  1196  	fpos := r.pos()
  1197  	fn := ir.NewFunc(fpos, npos, ir.ReceiverMethodSym(recv.Type, sym), typ)
  1198  	name := fn.Nname
  1199  
  1200  	if r.hasTypeParams() {
  1201  		name.Func.SetDupok(true)
  1202  		if r.dict.shaped {
  1203  			typ = shapeSig(name.Func, r.dict)
  1204  			setType(name, typ)
  1205  		}
  1206  	}
  1207  
  1208  	rext.funcExt(name, sym)
  1209  
  1210  	meth := types.NewField(name.Func.Pos(), sym, typ)
  1211  	meth.Nname = name
  1212  	meth.SetNointerface(name.Func.Pragma&ir.Nointerface != 0)
  1213  
  1214  	return meth
  1215  }
  1216  
  1217  func (r *reader) qualifiedIdent() (pkg *types.Pkg, sym *types.Sym) {
  1218  	r.Sync(pkgbits.SyncSym)
  1219  	pkg = r.pkg()
  1220  	if name := r.String(); name != "" {
  1221  		sym = pkg.Lookup(name)
  1222  	}
  1223  	return
  1224  }
  1225  
  1226  func (r *reader) localIdent() *types.Sym {
  1227  	r.Sync(pkgbits.SyncLocalIdent)
  1228  	pkg := r.pkg()
  1229  	if name := r.String(); name != "" {
  1230  		return pkg.Lookup(name)
  1231  	}
  1232  	return nil
  1233  }
  1234  
  1235  func (r *reader) selector() *types.Sym {
  1236  	r.Sync(pkgbits.SyncSelector)
  1237  	pkg := r.pkg()
  1238  	name := r.String()
  1239  	if types.IsExported(name) {
  1240  		pkg = types.LocalPkg
  1241  	}
  1242  	return pkg.Lookup(name)
  1243  }
  1244  
  1245  func (r *reader) hasTypeParams() bool {
  1246  	return r.dict.hasTypeParams()
  1247  }
  1248  
  1249  func (dict *readerDict) hasTypeParams() bool {
  1250  	return dict != nil && len(dict.targs) != 0
  1251  }
  1252  
  1253  // @@@ Compiler extensions
  1254  
  1255  func (r *reader) funcExt(name *ir.Name, method *types.Sym) {
  1256  	r.Sync(pkgbits.SyncFuncExt)
  1257  
  1258  	fn := name.Func
  1259  
  1260  	// XXX: Workaround because linker doesn't know how to copy Pos.
  1261  	if !fn.Pos().IsKnown() {
  1262  		fn.SetPos(name.Pos())
  1263  	}
  1264  
  1265  	// Normally, we only compile local functions, which saves redundant compilation work.
  1266  	// n.Defn is not nil for local functions, and is nil for imported function. But for
  1267  	// generic functions, we might have an instantiation that no other package has seen before.
  1268  	// So we need to be conservative and compile it again.
  1269  	//
  1270  	// That's why name.Defn is set here, so ir.VisitFuncsBottomUp can analyze function.
  1271  	// TODO(mdempsky,cuonglm): find a cleaner way to handle this.
  1272  	if name.Sym().Pkg == types.LocalPkg || r.hasTypeParams() {
  1273  		name.Defn = fn
  1274  	}
  1275  
  1276  	fn.Pragma = r.pragmaFlag()
  1277  	r.linkname(name)
  1278  
  1279  	if buildcfg.GOARCH == "wasm" {
  1280  		importmod := r.String()
  1281  		importname := r.String()
  1282  		exportname := r.String()
  1283  
  1284  		if importmod != "" && importname != "" {
  1285  			fn.WasmImport = &ir.WasmImport{
  1286  				Module: importmod,
  1287  				Name:   importname,
  1288  			}
  1289  		}
  1290  		if exportname != "" {
  1291  			if method != nil {
  1292  				base.ErrorfAt(fn.Pos(), 0, "cannot use //go:wasmexport on a method")
  1293  			}
  1294  			fn.WasmExport = &ir.WasmExport{Name: exportname}
  1295  		}
  1296  	}
  1297  
  1298  	if r.Bool() {
  1299  		assert(name.Defn == nil)
  1300  
  1301  		fn.ABI = obj.ABI(r.Uint64())
  1302  
  1303  		// Escape analysis.
  1304  		for _, f := range name.Type().RecvParams() {
  1305  			f.Note = r.String()
  1306  		}
  1307  
  1308  		if r.Bool() {
  1309  			fn.Inl = &ir.Inline{
  1310  				Cost:            int32(r.Len()),
  1311  				CanDelayResults: r.Bool(),
  1312  			}
  1313  			if buildcfg.Experiment.NewInliner {
  1314  				fn.Inl.Properties = r.String()
  1315  			}
  1316  		}
  1317  	} else {
  1318  		r.addBody(name.Func, method)
  1319  	}
  1320  	r.Sync(pkgbits.SyncEOF)
  1321  }
  1322  
  1323  func (r *reader) typeExt(name *ir.Name) {
  1324  	r.Sync(pkgbits.SyncTypeExt)
  1325  
  1326  	typ := name.Type()
  1327  
  1328  	if r.hasTypeParams() {
  1329  		// Mark type as fully instantiated to ensure the type descriptor is written
  1330  		// out as DUPOK and method wrappers are generated even for imported types.
  1331  		typ.SetIsFullyInstantiated(true)
  1332  		// HasShape should be set if any type argument is or has a shape type.
  1333  		for _, targ := range r.dict.targs {
  1334  			if targ.HasShape() {
  1335  				typ.SetHasShape(true)
  1336  				break
  1337  			}
  1338  		}
  1339  	}
  1340  
  1341  	name.SetPragma(r.pragmaFlag())
  1342  
  1343  	typecheck.SetBaseTypeIndex(typ, r.Int64(), r.Int64())
  1344  }
  1345  
  1346  func (r *reader) varExt(name *ir.Name) {
  1347  	r.Sync(pkgbits.SyncVarExt)
  1348  	r.linkname(name)
  1349  }
  1350  
  1351  func (r *reader) linkname(name *ir.Name) {
  1352  	assert(name.Op() == ir.ONAME)
  1353  	r.Sync(pkgbits.SyncLinkname)
  1354  
  1355  	if idx := r.Int64(); idx >= 0 {
  1356  		lsym := name.Linksym()
  1357  		lsym.SymIdx = int32(idx)
  1358  		lsym.Set(obj.AttrIndexed, true)
  1359  	} else {
  1360  		linkname := r.String()
  1361  		std := r.Bool()
  1362  		sym := name.Sym()
  1363  		sym.Linkname = linkname
  1364  		if sym.Pkg == types.LocalPkg && linkname != "" {
  1365  			// Mark linkname in the current package. We don't mark the
  1366  			// ones that are imported and propagated (e.g. through
  1367  			// inlining or instantiation, which are marked in their
  1368  			// corresponding packages). So we can tell in which package
  1369  			// the linkname is used (pulled), and the linker can
  1370  			// make a decision for allowing or disallowing it.
  1371  			if std {
  1372  				sym.Linksym().Set(obj.AttrLinknameStd, true)
  1373  			} else {
  1374  				sym.Linksym().Set(obj.AttrLinkname, true)
  1375  			}
  1376  		}
  1377  	}
  1378  }
  1379  
  1380  func (r *reader) pragmaFlag() ir.PragmaFlag {
  1381  	r.Sync(pkgbits.SyncPragma)
  1382  	return ir.PragmaFlag(r.Int())
  1383  }
  1384  
  1385  // @@@ Function bodies
  1386  
  1387  // bodyReader tracks where the serialized IR for a local or imported,
  1388  // generic function's body can be found.
  1389  var bodyReader = map[*ir.Func]pkgReaderIndex{}
  1390  
  1391  // importBodyReader tracks where the serialized IR for an imported,
  1392  // static (i.e., non-generic) function body can be read.
  1393  var importBodyReader = map[*types.Sym]pkgReaderIndex{}
  1394  
  1395  // bodyReaderFor returns the pkgReaderIndex for reading fn's
  1396  // serialized IR, and whether one was found.
  1397  func bodyReaderFor(fn *ir.Func) (pri pkgReaderIndex, ok bool) {
  1398  	if fn.Nname.Defn != nil {
  1399  		pri, ok = bodyReader[fn]
  1400  		base.AssertfAt(ok, base.Pos, "must have bodyReader for %v", fn) // must always be available
  1401  	} else {
  1402  		pri, ok = importBodyReader[fn.Sym()]
  1403  	}
  1404  	return
  1405  }
  1406  
  1407  // todoDicts holds the list of dictionaries that still need their
  1408  // runtime dictionary objects constructed.
  1409  var todoDicts []func()
  1410  
  1411  // todoBodies holds the list of function bodies that still need to be
  1412  // constructed.
  1413  var todoBodies []*ir.Func
  1414  
  1415  // addBody reads a function body reference from the element bitstream,
  1416  // and associates it with fn.
  1417  func (r *reader) addBody(fn *ir.Func, method *types.Sym) {
  1418  	// addBody should only be called for local functions or imported
  1419  	// generic functions; see comment in funcExt.
  1420  	assert(fn.Nname.Defn != nil)
  1421  
  1422  	idx := r.Reloc(pkgbits.SectionBody)
  1423  
  1424  	pri := pkgReaderIndex{r.p, idx, r.dict, method, nil}
  1425  	bodyReader[fn] = pri
  1426  
  1427  	if r.curfn == nil {
  1428  		todoBodies = append(todoBodies, fn)
  1429  		return
  1430  	}
  1431  
  1432  	pri.funcBody(fn)
  1433  }
  1434  
  1435  func (pri pkgReaderIndex) funcBody(fn *ir.Func) {
  1436  	r := pri.asReader(pkgbits.SectionBody, pkgbits.SyncFuncBody)
  1437  	panicking := true
  1438  	defer func() {
  1439  		if panicking {
  1440  			// TODO not sure what the best way to print in this context is.
  1441  			// If code panics in unified IR reading, you want *something* like this.
  1442  			// Whoever ends up debugging the next unified IR failure, please
  1443  			// improve this (base.Warnf?) if you can figure out how.
  1444  			fmt.Printf("****** panic traversed funcBody of %v\n", fn)
  1445  		}
  1446  	}()
  1447  	r.funcBody(fn)
  1448  	panicking = false
  1449  
  1450  }
  1451  
  1452  // funcBody reads a function body definition from the element
  1453  // bitstream, and populates fn with it.
  1454  func (r *reader) funcBody(fn *ir.Func) {
  1455  	r.curfn = fn
  1456  	r.closureVars = fn.ClosureVars
  1457  	if len(r.closureVars) != 0 && r.hasTypeParams() {
  1458  		r.dictParam = r.closureVars[len(r.closureVars)-1] // dictParam is last; see reader.funcLit
  1459  	}
  1460  
  1461  	ir.WithPos(fn, func() {
  1462  		r.declareParams()
  1463  
  1464  		if r.syntheticBody(fn.Pos()) {
  1465  			return
  1466  		}
  1467  
  1468  		if !r.Bool() {
  1469  			return
  1470  		}
  1471  
  1472  		body := r.stmts()
  1473  		if body == nil {
  1474  			body = []ir.Node{typecheck.Stmt(r.curfn, ir.NewBlockStmt(src.NoXPos, nil))}
  1475  		}
  1476  		fn.Body = body
  1477  		fn.Endlineno = r.pos()
  1478  	})
  1479  
  1480  	r.marker.WriteTo(fn)
  1481  }
  1482  
  1483  // syntheticBody adds a synthetic body to r.curfn if appropriate, and
  1484  // reports whether it did.
  1485  func (r *reader) syntheticBody(pos src.XPos) bool {
  1486  	if r.synthetic != nil {
  1487  		r.synthetic(pos, r)
  1488  		return true
  1489  	}
  1490  
  1491  	// If this function has type parameters and isn't shaped, then we
  1492  	// just tail call its corresponding shaped variant.
  1493  	if r.hasTypeParams() && !r.dict.shaped {
  1494  		r.callShaped(pos)
  1495  		return true
  1496  	}
  1497  
  1498  	return false
  1499  }
  1500  
  1501  // callShaped emits a tail call to r.shapedFn, passing along the
  1502  // arguments to the current function.
  1503  func (r *reader) callShaped(pos src.XPos) {
  1504  	shapedObj := r.dict.shapedObj
  1505  	assert(shapedObj != nil)
  1506  
  1507  	var shapedFn ir.Node
  1508  	if r.methodSym == nil {
  1509  		// Instantiating a generic function; shapedObj is the shaped function itself.
  1510  		assert(shapedObj.Op() == ir.ONAME && shapedObj.Class == ir.PFUNC)
  1511  		shapedFn = shapedObj
  1512  	} else {
  1513  		// Instantiating a generic type's method; shapedObj is the shaped method itself
  1514  		// if the method is generic — else, it is the shaped type declaring the method.
  1515  		shapedFn = shapedMethodExpr(pos, shapedObj, r.methodSym)
  1516  	}
  1517  
  1518  	params := r.syntheticArgs()
  1519  
  1520  	// Construct the arguments list: receiver (if any), then runtime
  1521  	// dictionary, and finally normal parameters.
  1522  	//
  1523  	// Note: For simplicity, shaped methods are added as normal methods
  1524  	// on their shaped types. So existing code (e.g., packages ir and
  1525  	// typecheck) expects the shaped type to appear as the receiver
  1526  	// parameter (or first parameter, as a method expression). Hence
  1527  	// putting the dictionary parameter after that is the least invasive
  1528  	// solution at the moment.
  1529  	var args ir.Nodes
  1530  	if r.methodSym != nil {
  1531  		args.Append(params[0])
  1532  		params = params[1:]
  1533  	}
  1534  	args.Append(typecheck.Expr(r.curfn, ir.NewAddrExpr(pos, r.p.dictNameOf(r.dict))))
  1535  	args.Append(params...)
  1536  
  1537  	r.syntheticTailCall(pos, shapedFn, args)
  1538  }
  1539  
  1540  // syntheticArgs returns the recvs and params arguments passed to the
  1541  // current function.
  1542  func (r *reader) syntheticArgs() ir.Nodes {
  1543  	sig := r.curfn.Nname.Type()
  1544  	return ir.ToNodes(r.curfn.Dcl[:sig.NumRecvs()+sig.NumParams()])
  1545  }
  1546  
  1547  // syntheticTailCall emits a tail call to fn, passing the given
  1548  // arguments list.
  1549  func (r *reader) syntheticTailCall(pos src.XPos, fn ir.Node, args ir.Nodes) {
  1550  	// Mark the function as a wrapper so it doesn't show up in stack
  1551  	// traces.
  1552  	r.curfn.SetWrapper(true)
  1553  
  1554  	call := typecheck.Call(r.curfn, pos, fn, args, fn.Type().IsVariadic()).(*ir.CallExpr)
  1555  
  1556  	var stmt ir.Node
  1557  	if fn.Type().NumResults() != 0 {
  1558  		stmt = typecheck.Stmt(r.curfn, ir.NewReturnStmt(pos, []ir.Node{call}))
  1559  	} else {
  1560  		stmt = call
  1561  	}
  1562  	r.curfn.Body.Append(stmt)
  1563  }
  1564  
  1565  // dictNameOf returns the runtime dictionary corresponding to dict.
  1566  func (pr *pkgReader) dictNameOf(dict *readerDict) *ir.Name {
  1567  	pos := base.AutogeneratedPos
  1568  
  1569  	// Check that we only instantiate runtime dictionaries with real types.
  1570  	base.AssertfAt(!dict.shaped, pos, "runtime dictionary of shaped object %v", dict.baseSym)
  1571  
  1572  	sym := dict.baseSym.Pkg.Lookup(objabi.GlobalDictPrefix + "." + dict.baseSym.Name)
  1573  	if sym.Def != nil {
  1574  		return sym.Def.(*ir.Name)
  1575  	}
  1576  
  1577  	name := ir.NewNameAt(pos, sym, dict.varType())
  1578  	name.Class = ir.PEXTERN
  1579  	sym.Def = name // break cycles with mutual subdictionaries
  1580  
  1581  	lsym := name.Linksym()
  1582  	ot := 0
  1583  
  1584  	assertOffset := func(section string, offset int) {
  1585  		base.AssertfAt(ot == offset*types.PtrSize, pos, "writing section %v at offset %v, but it should be at %v*%v", section, ot, offset, types.PtrSize)
  1586  	}
  1587  
  1588  	assertOffset("type param method exprs", dict.typeParamMethodExprsOffset())
  1589  	for _, info := range dict.typeParamMethodExprs {
  1590  		typeParam := dict.targs[info.typeParamIdx]
  1591  		method := typecheck.NewMethodExpr(pos, typeParam, info.method)
  1592  
  1593  		rsym := method.FuncName().Linksym()
  1594  		assert(rsym.ABI() == obj.ABIInternal) // must be ABIInternal; see ir.OCFUNC in ssagen/ssa.go
  1595  
  1596  		ot = objw.SymPtr(lsym, ot, rsym, 0)
  1597  	}
  1598  
  1599  	assertOffset("subdictionaries", dict.subdictsOffset())
  1600  	for _, info := range dict.subdicts {
  1601  		explicits := pr.typListIdx(info.explicits, dict)
  1602  
  1603  		// Careful: Due to subdictionary cycles, name may not be fully
  1604  		// initialized yet.
  1605  		name := pr.objDictName(info.idx, dict.targs, explicits)
  1606  
  1607  		ot = objw.SymPtr(lsym, ot, name.Linksym(), 0)
  1608  	}
  1609  
  1610  	assertOffset("rtypes", dict.rtypesOffset())
  1611  	for _, info := range dict.rtypes {
  1612  		typ := pr.typIdx(info, dict, true)
  1613  		ot = objw.SymPtr(lsym, ot, reflectdata.TypeLinksym(typ), 0)
  1614  
  1615  		// TODO(mdempsky): Double check this.
  1616  		reflectdata.MarkTypeUsedInInterface(typ, lsym)
  1617  	}
  1618  
  1619  	// For each (typ, iface) pair, we write the *runtime.itab pointer
  1620  	// for the pair. For pairs that don't actually require an itab
  1621  	// (i.e., typ is an interface, or iface is an empty interface), we
  1622  	// write a nil pointer instead. This is wasteful, but rare in
  1623  	// practice (e.g., instantiating a type parameter with an interface
  1624  	// type).
  1625  	assertOffset("itabs", dict.itabsOffset())
  1626  	for _, info := range dict.itabs {
  1627  		typ := pr.typIdx(info.typ, dict, true)
  1628  		iface := pr.typIdx(info.iface, dict, true)
  1629  
  1630  		if !typ.IsInterface() && iface.IsInterface() && !iface.IsEmptyInterface() {
  1631  			ot = objw.SymPtr(lsym, ot, reflectdata.ITabLsym(typ, iface), 0)
  1632  		} else {
  1633  			ot += types.PtrSize
  1634  		}
  1635  
  1636  		// TODO(mdempsky): Double check this.
  1637  		reflectdata.MarkTypeUsedInInterface(typ, lsym)
  1638  		reflectdata.MarkTypeUsedInInterface(iface, lsym)
  1639  	}
  1640  
  1641  	objw.Global(lsym, int32(ot), obj.DUPOK|obj.RODATA)
  1642  
  1643  	return name
  1644  }
  1645  
  1646  // typeParamMethodExprsOffset returns the offset of the runtime
  1647  // dictionary's type parameter method expressions section, in words.
  1648  func (dict *readerDict) typeParamMethodExprsOffset() int {
  1649  	return 0
  1650  }
  1651  
  1652  // subdictsOffset returns the offset of the runtime dictionary's
  1653  // subdictionary section, in words.
  1654  func (dict *readerDict) subdictsOffset() int {
  1655  	return dict.typeParamMethodExprsOffset() + len(dict.typeParamMethodExprs)
  1656  }
  1657  
  1658  // rtypesOffset returns the offset of the runtime dictionary's rtypes
  1659  // section, in words.
  1660  func (dict *readerDict) rtypesOffset() int {
  1661  	return dict.subdictsOffset() + len(dict.subdicts)
  1662  }
  1663  
  1664  // itabsOffset returns the offset of the runtime dictionary's itabs
  1665  // section, in words.
  1666  func (dict *readerDict) itabsOffset() int {
  1667  	return dict.rtypesOffset() + len(dict.rtypes)
  1668  }
  1669  
  1670  // numWords returns the total number of words that comprise dict's
  1671  // runtime dictionary variable.
  1672  func (dict *readerDict) numWords() int64 {
  1673  	return int64(dict.itabsOffset() + len(dict.itabs))
  1674  }
  1675  
  1676  // varType returns the type of dict's runtime dictionary variable.
  1677  func (dict *readerDict) varType() *types.Type {
  1678  	return types.NewArray(types.Types[types.TUINTPTR], dict.numWords())
  1679  }
  1680  
  1681  func (r *reader) declareParams() {
  1682  	r.curfn.DeclareParams(!r.funarghack)
  1683  
  1684  	for _, name := range r.curfn.Dcl {
  1685  		if name.Sym().Name == dictParamName {
  1686  			r.dictParam = name
  1687  			continue
  1688  		}
  1689  
  1690  		r.addLocal(name)
  1691  	}
  1692  }
  1693  
  1694  func (r *reader) addLocal(name *ir.Name) {
  1695  	if r.synthetic == nil {
  1696  		r.Sync(pkgbits.SyncAddLocal)
  1697  		if r.p.SyncMarkers() {
  1698  			want := r.Int()
  1699  			if have := len(r.locals); have != want {
  1700  				base.FatalfAt(name.Pos(), "locals table has desynced")
  1701  			}
  1702  		}
  1703  		r.varDictIndex(name)
  1704  	}
  1705  
  1706  	r.locals = append(r.locals, name)
  1707  }
  1708  
  1709  func (r *reader) useLocal() *ir.Name {
  1710  	r.Sync(pkgbits.SyncUseObjLocal)
  1711  	if r.Bool() {
  1712  		return r.locals[r.Len()]
  1713  	}
  1714  	return r.closureVars[r.Len()]
  1715  }
  1716  
  1717  func (r *reader) openScope() {
  1718  	r.Sync(pkgbits.SyncOpenScope)
  1719  	pos := r.pos()
  1720  
  1721  	if base.Flag.Dwarf {
  1722  		r.scopeVars = append(r.scopeVars, len(r.curfn.Dcl))
  1723  		r.marker.Push(pos)
  1724  	}
  1725  }
  1726  
  1727  func (r *reader) closeScope() {
  1728  	r.Sync(pkgbits.SyncCloseScope)
  1729  	r.lastCloseScopePos = r.pos()
  1730  
  1731  	r.closeAnotherScope()
  1732  }
  1733  
  1734  // closeAnotherScope is like closeScope, but it reuses the same mark
  1735  // position as the last closeScope call. This is useful for "for" and
  1736  // "if" statements, as their implicit blocks always end at the same
  1737  // position as an explicit block.
  1738  func (r *reader) closeAnotherScope() {
  1739  	r.Sync(pkgbits.SyncCloseAnotherScope)
  1740  
  1741  	if base.Flag.Dwarf {
  1742  		scopeVars := r.scopeVars[len(r.scopeVars)-1]
  1743  		r.scopeVars = r.scopeVars[:len(r.scopeVars)-1]
  1744  
  1745  		// Quirkish: noder decides which scopes to keep before
  1746  		// typechecking, whereas incremental typechecking during IR
  1747  		// construction can result in new autotemps being allocated. To
  1748  		// produce identical output, we ignore autotemps here for the
  1749  		// purpose of deciding whether to retract the scope.
  1750  		//
  1751  		// This is important for net/http/fcgi, because it contains:
  1752  		//
  1753  		//	var body io.ReadCloser
  1754  		//	if len(content) > 0 {
  1755  		//		body, req.pw = io.Pipe()
  1756  		//	} else { … }
  1757  		//
  1758  		// Notably, io.Pipe is inlinable, and inlining it introduces a ~R0
  1759  		// variable at the call site.
  1760  		//
  1761  		// Noder does not preserve the scope where the io.Pipe() call
  1762  		// resides, because it doesn't contain any declared variables in
  1763  		// source. So the ~R0 variable ends up being assigned to the
  1764  		// enclosing scope instead.
  1765  		//
  1766  		// However, typechecking this assignment also introduces
  1767  		// autotemps, because io.Pipe's results need conversion before
  1768  		// they can be assigned to their respective destination variables.
  1769  		//
  1770  		// TODO(mdempsky): We should probably just keep all scopes, and
  1771  		// let dwarfgen take care of pruning them instead.
  1772  		retract := true
  1773  		for _, n := range r.curfn.Dcl[scopeVars:] {
  1774  			if !n.AutoTemp() {
  1775  				retract = false
  1776  				break
  1777  			}
  1778  		}
  1779  
  1780  		if retract {
  1781  			// no variables were declared in this scope, so we can retract it.
  1782  			r.marker.Unpush()
  1783  		} else {
  1784  			r.marker.Pop(r.lastCloseScopePos)
  1785  		}
  1786  	}
  1787  }
  1788  
  1789  // @@@ Statements
  1790  
  1791  func (r *reader) stmt() ir.Node {
  1792  	return block(r.stmts())
  1793  }
  1794  
  1795  func block(stmts []ir.Node) ir.Node {
  1796  	switch len(stmts) {
  1797  	case 0:
  1798  		return nil
  1799  	case 1:
  1800  		return stmts[0]
  1801  	default:
  1802  		return ir.NewBlockStmt(stmts[0].Pos(), stmts)
  1803  	}
  1804  }
  1805  
  1806  func (r *reader) stmts() ir.Nodes {
  1807  	assert(r.curfn == r.curfn)
  1808  	var res ir.Nodes
  1809  
  1810  	r.Sync(pkgbits.SyncStmts)
  1811  	for {
  1812  		tag := codeStmt(r.Code(pkgbits.SyncStmt1))
  1813  		if tag == stmtEnd {
  1814  			r.Sync(pkgbits.SyncStmtsEnd)
  1815  			return res
  1816  		}
  1817  
  1818  		if n := r.stmt1(tag, &res); n != nil {
  1819  			res.Append(typecheck.Stmt(r.curfn, n))
  1820  		}
  1821  	}
  1822  }
  1823  
  1824  func (r *reader) stmt1(tag codeStmt, out *ir.Nodes) ir.Node {
  1825  	var label *types.Sym
  1826  	if n := len(*out); n > 0 {
  1827  		if ls, ok := (*out)[n-1].(*ir.LabelStmt); ok {
  1828  			label = ls.Label
  1829  		}
  1830  	}
  1831  
  1832  	switch tag {
  1833  	default:
  1834  		panic("unexpected statement")
  1835  
  1836  	case stmtAssign:
  1837  		pos := r.pos()
  1838  		lno := base.Pos
  1839  		defer func() { base.Pos = lno }()
  1840  		base.Pos = pos
  1841  		names, lhs := r.assignList()
  1842  		rhs := r.multiExpr()
  1843  
  1844  		if len(rhs) == 0 {
  1845  			for _, name := range names {
  1846  				as := ir.NewAssignStmt(pos, name, nil)
  1847  				as.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, name))
  1848  				out.Append(typecheck.Stmt(r.curfn, as))
  1849  			}
  1850  			return nil
  1851  		}
  1852  
  1853  		if len(lhs) == 1 && len(rhs) == 1 {
  1854  			n := ir.NewAssignStmt(pos, lhs[0], rhs[0])
  1855  			n.Def = r.initDefn(n, names)
  1856  			return n
  1857  		}
  1858  
  1859  		n := ir.NewAssignListStmt(pos, ir.OAS2, lhs, rhs)
  1860  		n.Def = r.initDefn(n, names)
  1861  		return n
  1862  
  1863  	case stmtAssignOp:
  1864  		op := r.op()
  1865  		lhs := r.expr()
  1866  		pos := r.pos()
  1867  		rhs := r.expr()
  1868  		return ir.NewAssignOpStmt(pos, op, lhs, rhs)
  1869  
  1870  	case stmtIncDec:
  1871  		op := r.op()
  1872  		lhs := r.expr()
  1873  		pos := r.pos()
  1874  		n := ir.NewAssignOpStmt(pos, op, lhs, ir.NewOne(pos, lhs.Type()))
  1875  		n.IncDec = true
  1876  		return n
  1877  
  1878  	case stmtBlock:
  1879  		out.Append(r.blockStmt()...)
  1880  		return nil
  1881  
  1882  	case stmtBranch:
  1883  		pos := r.pos()
  1884  		op := r.op()
  1885  		sym := r.optLabel()
  1886  		return ir.NewBranchStmt(pos, op, sym)
  1887  
  1888  	case stmtCall:
  1889  		pos := r.pos()
  1890  		op := r.op()
  1891  		call := r.expr()
  1892  		stmt := ir.NewGoDeferStmt(pos, op, call)
  1893  		if op == ir.ODEFER {
  1894  			x := r.optExpr()
  1895  			if x != nil {
  1896  				stmt.DeferAt = x.(ir.Expr)
  1897  			}
  1898  		}
  1899  		return stmt
  1900  
  1901  	case stmtExpr:
  1902  		return r.expr()
  1903  
  1904  	case stmtFor:
  1905  		return r.forStmt(label)
  1906  
  1907  	case stmtIf:
  1908  		return r.ifStmt()
  1909  
  1910  	case stmtLabel:
  1911  		pos := r.pos()
  1912  		sym := r.label()
  1913  		return ir.NewLabelStmt(pos, sym)
  1914  
  1915  	case stmtReturn:
  1916  		pos := r.pos()
  1917  		results := r.multiExpr()
  1918  		return ir.NewReturnStmt(pos, results)
  1919  
  1920  	case stmtSelect:
  1921  		return r.selectStmt(label)
  1922  
  1923  	case stmtSend:
  1924  		pos := r.pos()
  1925  		ch := r.expr()
  1926  		value := r.expr()
  1927  		return ir.NewSendStmt(pos, ch, value)
  1928  
  1929  	case stmtSwitch:
  1930  		return r.switchStmt(label)
  1931  	}
  1932  }
  1933  
  1934  func (r *reader) assignList() ([]*ir.Name, []ir.Node) {
  1935  	lhs := make([]ir.Node, r.Len())
  1936  	var names []*ir.Name
  1937  
  1938  	for i := range lhs {
  1939  		expr, def := r.assign()
  1940  		lhs[i] = expr
  1941  		if def {
  1942  			names = append(names, expr.(*ir.Name))
  1943  		}
  1944  	}
  1945  
  1946  	return names, lhs
  1947  }
  1948  
  1949  // assign returns an assignee expression. It also reports whether the
  1950  // returned expression is a newly declared variable.
  1951  func (r *reader) assign() (ir.Node, bool) {
  1952  	switch tag := codeAssign(r.Code(pkgbits.SyncAssign)); tag {
  1953  	default:
  1954  		panic("unhandled assignee expression")
  1955  
  1956  	case assignBlank:
  1957  		return typecheck.AssignExpr(r.curfn, ir.BlankNode), false
  1958  
  1959  	case assignDef:
  1960  		pos := r.pos()
  1961  		lno := base.Pos
  1962  		defer func() { base.Pos = lno }()
  1963  		setBasePos(pos) // test/fixedbugs/issue49767.go depends on base.Pos being set for the r.typ() call here, ugh
  1964  		name := r.curfn.NewLocal(pos, r.localIdent(), r.typ())
  1965  		r.addLocal(name)
  1966  		return name, true
  1967  
  1968  	case assignExpr:
  1969  		return r.expr(), false
  1970  	}
  1971  }
  1972  
  1973  func (r *reader) blockStmt() []ir.Node {
  1974  	r.Sync(pkgbits.SyncBlockStmt)
  1975  	r.openScope()
  1976  	stmts := r.stmts()
  1977  	r.closeScope()
  1978  	return stmts
  1979  }
  1980  
  1981  func (r *reader) forStmt(label *types.Sym) ir.Node {
  1982  	r.Sync(pkgbits.SyncForStmt)
  1983  
  1984  	r.openScope()
  1985  
  1986  	isRange := r.Bool()
  1987  	pos := r.pos()
  1988  	lno := base.Pos
  1989  	defer func() { base.Pos = lno }()
  1990  	base.Pos = pos
  1991  
  1992  	if isRange {
  1993  		rang := ir.NewRangeStmt(pos, nil, nil, nil, nil, false)
  1994  		rang.Label = label
  1995  
  1996  		names, lhs := r.assignList()
  1997  		if len(lhs) >= 1 {
  1998  			rang.Key = lhs[0]
  1999  			if len(lhs) >= 2 {
  2000  				rang.Value = lhs[1]
  2001  			}
  2002  		}
  2003  		rang.Def = r.initDefn(rang, names)
  2004  
  2005  		rang.X = r.expr()
  2006  		if rang.X.Type().IsMap() {
  2007  			rang.RType = r.rtype(pos)
  2008  		}
  2009  		if rang.Key != nil && !ir.IsBlank(rang.Key) {
  2010  			rang.KeyTypeWord, rang.KeySrcRType = r.convRTTI(pos)
  2011  		}
  2012  		if rang.Value != nil && !ir.IsBlank(rang.Value) {
  2013  			rang.ValueTypeWord, rang.ValueSrcRType = r.convRTTI(pos)
  2014  		}
  2015  
  2016  		rang.Body = r.blockStmt()
  2017  		rang.DistinctVars = r.Bool()
  2018  		r.closeAnotherScope()
  2019  
  2020  		return rang
  2021  	}
  2022  
  2023  	init := r.stmt()
  2024  	if init != nil && init.Pos().IsKnown() {
  2025  		lno := base.Pos
  2026  		defer func() { base.Pos = lno }()
  2027  		base.Pos = init.Pos()
  2028  	}
  2029  	cond := r.optExpr()
  2030  	post := r.stmt()
  2031  	body := r.blockStmt()
  2032  	perLoopVars := r.Bool()
  2033  	r.closeAnotherScope()
  2034  
  2035  	if ir.IsConst(cond, constant.Bool) && !ir.BoolVal(cond) {
  2036  		return init // simplify "for init; false; post { ... }" into "init"
  2037  	}
  2038  
  2039  	stmt := ir.NewForStmt(pos, init, cond, post, body, perLoopVars)
  2040  	stmt.Label = label
  2041  	return stmt
  2042  }
  2043  
  2044  func (r *reader) ifStmt() ir.Node {
  2045  	r.Sync(pkgbits.SyncIfStmt)
  2046  	r.openScope()
  2047  	pos := r.pos()
  2048  	lno := base.Pos
  2049  	defer func() { base.Pos = lno }()
  2050  	base.Pos = pos
  2051  	init := r.stmts()
  2052  	if len(init) > 0 && init[len(init)-1].Pos().IsKnown() {
  2053  		lno := base.Pos
  2054  		defer func() { base.Pos = lno }()
  2055  		base.Pos = init[len(init)-1].Pos()
  2056  	}
  2057  	cond := r.expr()
  2058  	staticCond := r.Int()
  2059  	var then, els []ir.Node
  2060  	if staticCond >= 0 {
  2061  		then = r.blockStmt()
  2062  	} else {
  2063  		r.lastCloseScopePos = r.pos()
  2064  	}
  2065  	if staticCond <= 0 {
  2066  		els = r.stmts()
  2067  	}
  2068  	r.closeAnotherScope()
  2069  
  2070  	if staticCond != 0 {
  2071  		// We may have removed a dead return statement, which can trip up
  2072  		// later passes (#62211). To avoid confusion, we instead flatten
  2073  		// the if statement into a block.
  2074  
  2075  		if cond.Op() != ir.OLITERAL {
  2076  			init.Append(typecheck.Stmt(r.curfn, ir.NewAssignStmt(pos, ir.BlankNode, cond))) // for side effects
  2077  		}
  2078  		init.Append(then...)
  2079  		init.Append(els...)
  2080  		return block(init)
  2081  	}
  2082  
  2083  	n := ir.NewIfStmt(pos, cond, then, els)
  2084  	n.SetInit(init)
  2085  	return n
  2086  }
  2087  
  2088  func (r *reader) selectStmt(label *types.Sym) ir.Node {
  2089  	r.Sync(pkgbits.SyncSelectStmt)
  2090  
  2091  	pos := r.pos()
  2092  	clauses := make([]*ir.CommClause, r.Len())
  2093  	for i := range clauses {
  2094  		if i > 0 {
  2095  			r.closeScope()
  2096  		}
  2097  		r.openScope()
  2098  
  2099  		pos := r.pos()
  2100  		comm := r.stmt()
  2101  		body := r.stmts()
  2102  
  2103  		// "case i = <-c: ..." may require an implicit conversion (e.g.,
  2104  		// see fixedbugs/bug312.go). Currently, typecheck throws away the
  2105  		// implicit conversion and relies on it being reinserted later,
  2106  		// but that would lose any explicit RTTI operands too. To preserve
  2107  		// RTTI, we rewrite this as "case tmp := <-c: i = tmp; ...".
  2108  		if as, ok := comm.(*ir.AssignStmt); ok && as.Op() == ir.OAS && !as.Def {
  2109  			if conv, ok := as.Y.(*ir.ConvExpr); ok && conv.Op() == ir.OCONVIFACE {
  2110  				base.AssertfAt(conv.Implicit(), conv.Pos(), "expected implicit conversion: %v", conv)
  2111  
  2112  				recv := conv.X
  2113  				base.AssertfAt(recv.Op() == ir.ORECV, recv.Pos(), "expected receive expression: %v", recv)
  2114  
  2115  				tmp := r.temp(pos, recv.Type())
  2116  
  2117  				// Replace comm with `tmp := <-c`.
  2118  				tmpAs := ir.NewAssignStmt(pos, tmp, recv)
  2119  				tmpAs.Def = true
  2120  				tmpAs.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, tmp))
  2121  				comm = tmpAs
  2122  
  2123  				// Change original assignment to `i = tmp`, and prepend to body.
  2124  				conv.X = tmp
  2125  				body = append([]ir.Node{as}, body...)
  2126  			}
  2127  		}
  2128  
  2129  		// multiExpr will have desugared a comma-ok receive expression
  2130  		// into a separate statement. However, the rest of the compiler
  2131  		// expects comm to be the OAS2RECV statement itself, so we need to
  2132  		// shuffle things around to fit that pattern.
  2133  		if as2, ok := comm.(*ir.AssignListStmt); ok && as2.Op() == ir.OAS2 {
  2134  			init := ir.TakeInit(as2.Rhs[0])
  2135  			base.AssertfAt(len(init) == 1 && init[0].Op() == ir.OAS2RECV, as2.Pos(), "unexpected assignment: %+v", as2)
  2136  
  2137  			comm = init[0]
  2138  			body = append([]ir.Node{as2}, body...)
  2139  		}
  2140  
  2141  		clauses[i] = ir.NewCommStmt(pos, comm, body)
  2142  	}
  2143  	if len(clauses) > 0 {
  2144  		r.closeScope()
  2145  	}
  2146  	n := ir.NewSelectStmt(pos, clauses)
  2147  	n.Label = label
  2148  	return n
  2149  }
  2150  
  2151  func (r *reader) switchStmt(label *types.Sym) ir.Node {
  2152  	r.Sync(pkgbits.SyncSwitchStmt)
  2153  
  2154  	r.openScope()
  2155  	pos := r.pos()
  2156  	lno := base.Pos
  2157  	defer func() { base.Pos = lno }()
  2158  	base.Pos = pos
  2159  	init := r.stmt()
  2160  	if init != nil && init.Pos().IsKnown() {
  2161  		lno := base.Pos
  2162  		defer func() { base.Pos = lno }()
  2163  		base.Pos = init.Pos()
  2164  	}
  2165  
  2166  	var tag ir.Node
  2167  	var ident *ir.Ident
  2168  	var iface *types.Type
  2169  	if r.Bool() {
  2170  		pos := r.pos()
  2171  		lno := base.Pos
  2172  		defer func() { base.Pos = lno }()
  2173  		base.Pos = pos
  2174  		if r.Bool() {
  2175  			ident = ir.NewIdent(r.pos(), r.localIdent())
  2176  		}
  2177  		x := r.expr()
  2178  		iface = x.Type()
  2179  		tag = ir.NewTypeSwitchGuard(pos, ident, x)
  2180  	} else {
  2181  		tag = r.optExpr()
  2182  	}
  2183  
  2184  	clauses := make([]*ir.CaseClause, r.Len())
  2185  	for i := range clauses {
  2186  		if i > 0 {
  2187  			r.closeScope()
  2188  		}
  2189  		r.openScope()
  2190  
  2191  		pos := r.pos()
  2192  		lno := base.Pos
  2193  		base.Pos = pos
  2194  		var cases, rtypes []ir.Node
  2195  		if iface != nil {
  2196  			cases = make([]ir.Node, r.Len())
  2197  			if len(cases) == 0 {
  2198  				cases = nil // TODO(mdempsky): Unclear if this matters.
  2199  			}
  2200  			for i := range cases {
  2201  				if r.Bool() { // case nil
  2202  					cases[i] = typecheck.Expr(r.curfn, types.BuiltinPkg.Lookup("nil").Def.(*ir.NilExpr))
  2203  				} else {
  2204  					cases[i] = r.exprType()
  2205  				}
  2206  			}
  2207  		} else {
  2208  			cases = r.exprList()
  2209  
  2210  			// For `switch { case any(true): }` (e.g., issue 3980 in
  2211  			// test/switch.go), the backend still creates a mixed bool/any
  2212  			// comparison, and we need to explicitly supply the RTTI for the
  2213  			// comparison.
  2214  			//
  2215  			// TODO(mdempsky): Change writer.go to desugar "switch {" into
  2216  			// "switch true {", which we already handle correctly.
  2217  			if tag == nil {
  2218  				for i, cas := range cases {
  2219  					if cas.Type().IsEmptyInterface() {
  2220  						for len(rtypes) < i {
  2221  							rtypes = append(rtypes, nil)
  2222  						}
  2223  						rtypes = append(rtypes, reflectdata.TypePtrAt(r.curfn, cas.Pos(), types.Types[types.TBOOL]))
  2224  					}
  2225  				}
  2226  			}
  2227  		}
  2228  
  2229  		clause := ir.NewCaseStmt(pos, cases, nil)
  2230  		clause.RTypes = rtypes
  2231  
  2232  		if ident != nil {
  2233  			name := r.curfn.NewLocal(r.pos(), ident.Sym(), r.typ())
  2234  			r.addLocal(name)
  2235  			clause.Var = name
  2236  			name.Defn = tag
  2237  		}
  2238  
  2239  		clause.Body = r.stmts()
  2240  		clauses[i] = clause
  2241  		base.Pos = lno
  2242  	}
  2243  	if len(clauses) > 0 {
  2244  		r.closeScope()
  2245  	}
  2246  	r.closeScope()
  2247  
  2248  	n := ir.NewSwitchStmt(pos, tag, clauses)
  2249  	n.Label = label
  2250  	if init != nil {
  2251  		n.SetInit([]ir.Node{init})
  2252  	}
  2253  	return n
  2254  }
  2255  
  2256  func (r *reader) label() *types.Sym {
  2257  	r.Sync(pkgbits.SyncLabel)
  2258  	name := r.String()
  2259  	if r.inlCall != nil && name != "_" {
  2260  		name = fmt.Sprintf("~%s·%d", name, inlgen)
  2261  	}
  2262  	return typecheck.Lookup(name)
  2263  }
  2264  
  2265  func (r *reader) optLabel() *types.Sym {
  2266  	r.Sync(pkgbits.SyncOptLabel)
  2267  	if r.Bool() {
  2268  		return r.label()
  2269  	}
  2270  	return nil
  2271  }
  2272  
  2273  // initDefn marks the given names as declared by defn and populates
  2274  // its Init field with ODCL nodes. It then reports whether any names
  2275  // were so declared, which can be used to initialize defn.Def.
  2276  func (r *reader) initDefn(defn ir.InitNode, names []*ir.Name) bool {
  2277  	if len(names) == 0 {
  2278  		return false
  2279  	}
  2280  
  2281  	init := make([]ir.Node, len(names))
  2282  	for i, name := range names {
  2283  		name.Defn = defn
  2284  		init[i] = ir.NewDecl(name.Pos(), ir.ODCL, name)
  2285  	}
  2286  	defn.SetInit(init)
  2287  	return true
  2288  }
  2289  
  2290  // @@@ Expressions
  2291  
  2292  // expr reads and returns a typechecked expression.
  2293  func (r *reader) expr() (res ir.Node) {
  2294  	defer func() {
  2295  		if res != nil && res.Typecheck() == 0 {
  2296  			base.FatalfAt(res.Pos(), "%v missed typecheck", res)
  2297  		}
  2298  	}()
  2299  
  2300  	switch tag := codeExpr(r.Code(pkgbits.SyncExpr)); tag {
  2301  	default:
  2302  		panic("unhandled expression")
  2303  
  2304  	case exprLocal:
  2305  		return typecheck.Expr(r.curfn, r.useLocal())
  2306  
  2307  	case exprGlobal:
  2308  		// Callee instead of Expr allows builtins
  2309  		// TODO(mdempsky): Handle builtins directly in exprCall, like method calls?
  2310  		return typecheck.Callee(r.curfn, r.obj())
  2311  
  2312  	case exprFuncInst:
  2313  		origPos, pos := r.origPos()
  2314  		wrapperFn, baseFn, dictPtr := r.funcInst(pos)
  2315  		if wrapperFn != nil {
  2316  			return wrapperFn
  2317  		}
  2318  		return r.curry(origPos, false, baseFn, dictPtr, nil)
  2319  
  2320  	case exprConst:
  2321  		pos := r.pos()
  2322  		typ := r.typ()
  2323  		val := FixValue(typ, r.Value())
  2324  		return ir.NewBasicLit(pos, typ, val)
  2325  
  2326  	case exprZero:
  2327  		pos := r.pos()
  2328  		typ := r.typ()
  2329  		return ir.NewZero(pos, typ)
  2330  
  2331  	case exprCompLit:
  2332  		return r.compLit()
  2333  
  2334  	case exprFuncLit:
  2335  		return r.funcLit()
  2336  
  2337  	case exprFieldVal:
  2338  		x := r.expr()
  2339  		pos := r.pos()
  2340  		sym := r.selector()
  2341  
  2342  		return typecheck.XDotField(r.curfn, pos, x, sym)
  2343  
  2344  	case exprMethodVal:
  2345  		recv := r.expr()
  2346  		origPos, pos := r.origPos()
  2347  		wrapperFn, baseFn, dictPtr := r.methodExpr()
  2348  
  2349  		// For simple wrapperFn values, the existing machinery for creating
  2350  		// and deduplicating wrapperFn value wrappers still works fine.
  2351  		if wrapperFn, ok := wrapperFn.(*ir.SelectorExpr); ok && wrapperFn.Op() == ir.OMETHEXPR {
  2352  			// The receiver expression we constructed may have a shape type.
  2353  			// For example, in fixedbugs/issue54343.go, `New[int]()` is
  2354  			// constructed as `New[go.shape.int](&.dict.New[int])`, which
  2355  			// has type `*T[go.shape.int]`, not `*T[int]`.
  2356  			//
  2357  			// However, the method we want to select here is `(*T[int]).M`,
  2358  			// not `(*T[go.shape.int]).M`, so we need to manually convert
  2359  			// the type back so that the OXDOT resolves correctly.
  2360  			//
  2361  			// TODO(mdempsky): Logically it might make more sense for
  2362  			// exprCall to take responsibility for setting a non-shaped
  2363  			// result type, but this is the only place where we care
  2364  			// currently. And only because existing ir.OMETHVALUE backend
  2365  			// code relies on n.X.Type() instead of n.Selection.Recv().Type
  2366  			// (because the latter is types.FakeRecvType() in the case of
  2367  			// interface method values).
  2368  			//
  2369  			if recv.Type().HasShape() {
  2370  				typ := wrapperFn.Type().Param(0).Type
  2371  				if !types.Identical(typ, recv.Type()) {
  2372  					base.FatalfAt(wrapperFn.Pos(), "receiver %L does not match %L", recv, wrapperFn)
  2373  				}
  2374  				recv = typecheck.Expr(r.curfn, ir.NewConvExpr(recv.Pos(), ir.OCONVNOP, typ, recv))
  2375  			}
  2376  
  2377  			n := typecheck.XDotMethod(r.curfn, pos, recv, wrapperFn.Sel, false)
  2378  
  2379  			// As a consistency check here, we make sure "n" selected the
  2380  			// same method (represented by a types.Field) that wrapperFn
  2381  			// selected. However, for anonymous receiver types, there can be
  2382  			// multiple such types.Field instances (#58563). So we may need
  2383  			// to fallback to making sure Sym and Type (including the
  2384  			// receiver parameter's type) match.
  2385  			if n.Selection != wrapperFn.Selection {
  2386  				assert(n.Selection.Sym == wrapperFn.Selection.Sym)
  2387  				assert(types.Identical(n.Selection.Type, wrapperFn.Selection.Type))
  2388  				assert(types.Identical(n.Selection.Type.Recv().Type, wrapperFn.Selection.Type.Recv().Type))
  2389  			}
  2390  
  2391  			wrapper := methodValueWrapper{
  2392  				rcvr:   n.X.Type(),
  2393  				method: n.Selection,
  2394  			}
  2395  
  2396  			if r.importedDef() {
  2397  				haveMethodValueWrappers = append(haveMethodValueWrappers, wrapper)
  2398  			} else {
  2399  				needMethodValueWrappers = append(needMethodValueWrappers, wrapper)
  2400  			}
  2401  			return n
  2402  		}
  2403  
  2404  		// For more complicated method expressions, we construct a
  2405  		// function literal wrapper.
  2406  		return r.curry(origPos, true, baseFn, recv, dictPtr)
  2407  
  2408  	case exprMethodExpr:
  2409  		recv := r.typ()
  2410  
  2411  		implicits := make([]int, r.Len())
  2412  		for i := range implicits {
  2413  			implicits[i] = r.Len()
  2414  		}
  2415  		var deref, addr bool
  2416  		if r.Bool() {
  2417  			deref = true
  2418  		} else if r.Bool() {
  2419  			addr = true
  2420  		}
  2421  
  2422  		origPos, pos := r.origPos()
  2423  		wrapperFn, baseFn, dictPtr := r.methodExpr()
  2424  
  2425  		// If we already have a wrapper and don't need to do anything with
  2426  		// it, we can just return the wrapper directly.
  2427  		//
  2428  		// N.B., we use implicits/deref/addr here as the source of truth
  2429  		// rather than types.Identical, because the latter can be confused
  2430  		// by tricky promoted methods (e.g., typeparam/mdempsky/21.go).
  2431  		if wrapperFn != nil && len(implicits) == 0 && !deref && !addr {
  2432  			if !types.Identical(recv, wrapperFn.Type().Param(0).Type) {
  2433  				base.FatalfAt(pos, "want receiver type %v, but have method %L", recv, wrapperFn)
  2434  			}
  2435  			return wrapperFn
  2436  		}
  2437  
  2438  		// Otherwise, if the wrapper function is a static method
  2439  		// expression (OMETHEXPR) and the receiver type is unshaped, then
  2440  		// we can rely on a statically generated wrapper being available.
  2441  		if method, ok := wrapperFn.(*ir.SelectorExpr); ok && method.Op() == ir.OMETHEXPR && !recv.HasShape() {
  2442  			return typecheck.NewMethodExpr(pos, recv, method.Sel)
  2443  		}
  2444  
  2445  		return r.methodExprWrap(origPos, recv, implicits, deref, addr, baseFn, dictPtr)
  2446  
  2447  	case exprIndex:
  2448  		x := r.expr()
  2449  		pos := r.pos()
  2450  		index := r.expr()
  2451  		n := typecheck.Expr(r.curfn, ir.NewIndexExpr(pos, x, index))
  2452  		switch n.Op() {
  2453  		case ir.OINDEXMAP:
  2454  			n := n.(*ir.IndexExpr)
  2455  			n.RType = r.rtype(pos)
  2456  		}
  2457  		return n
  2458  
  2459  	case exprSlice:
  2460  		x := r.expr()
  2461  		pos := r.pos()
  2462  		var index [3]ir.Node
  2463  		for i := range index {
  2464  			index[i] = r.optExpr()
  2465  		}
  2466  		op := ir.OSLICE
  2467  		if index[2] != nil {
  2468  			op = ir.OSLICE3
  2469  		}
  2470  		return typecheck.Expr(r.curfn, ir.NewSliceExpr(pos, op, x, index[0], index[1], index[2]))
  2471  
  2472  	case exprAssert:
  2473  		x := r.expr()
  2474  		pos := r.pos()
  2475  		typ := r.exprType()
  2476  		srcRType := r.rtype(pos)
  2477  
  2478  		// TODO(mdempsky): Always emit ODYNAMICDOTTYPE for uniformity?
  2479  		if typ, ok := typ.(*ir.DynamicType); ok && typ.Op() == ir.ODYNAMICTYPE {
  2480  			assert := ir.NewDynamicTypeAssertExpr(pos, ir.ODYNAMICDOTTYPE, x, typ.RType)
  2481  			assert.SrcRType = srcRType
  2482  			assert.ITab = typ.ITab
  2483  			return typed(typ.Type(), assert)
  2484  		}
  2485  		return typecheck.Expr(r.curfn, ir.NewTypeAssertExpr(pos, x, typ.Type()))
  2486  
  2487  	case exprUnaryOp:
  2488  		op := r.op()
  2489  		pos := r.pos()
  2490  		x := r.expr()
  2491  
  2492  		switch op {
  2493  		case ir.OADDR:
  2494  			return typecheck.Expr(r.curfn, typecheck.NodAddrAt(r.curfn, pos, x))
  2495  		case ir.ODEREF:
  2496  			return typecheck.Expr(r.curfn, ir.NewStarExpr(pos, x))
  2497  		}
  2498  		return typecheck.Expr(r.curfn, ir.NewUnaryExpr(pos, op, x))
  2499  
  2500  	case exprBinaryOp:
  2501  		op := r.op()
  2502  		x := r.expr()
  2503  		pos := r.pos()
  2504  		y := r.expr()
  2505  
  2506  		switch op {
  2507  		case ir.OANDAND, ir.OOROR:
  2508  			return typecheck.Expr(r.curfn, ir.NewLogicalExpr(pos, op, x, y))
  2509  		case ir.OLSH, ir.ORSH:
  2510  			// Untyped rhs of non-constant shift, e.g. x << 1.0.
  2511  			// If we have a constant value, it must be an int >= 0.
  2512  			if ir.IsConstNode(y) {
  2513  				val := constant.ToInt(y.Val())
  2514  				assert(val.Kind() == constant.Int && constant.Sign(val) >= 0)
  2515  			}
  2516  		}
  2517  		return typecheck.Expr(r.curfn, ir.NewBinaryExpr(pos, op, x, y))
  2518  
  2519  	case exprRecv:
  2520  		x := r.expr()
  2521  		pos := r.pos()
  2522  		for i, n := 0, r.Len(); i < n; i++ {
  2523  			x = Implicit(typecheck.DotField(pos, x, r.Len()))
  2524  		}
  2525  		if r.Bool() { // needs deref
  2526  			x = Implicit(Deref(pos, x.Type().Elem(), x))
  2527  		} else if r.Bool() { // needs addr
  2528  			x = Implicit(Addr(r.curfn, pos, x))
  2529  		}
  2530  		return x
  2531  
  2532  	case exprCall:
  2533  		var fun ir.Node
  2534  		var args ir.Nodes
  2535  		if r.Bool() { // method call
  2536  			recv := r.expr()
  2537  			_, method, dictPtr := r.methodExpr()
  2538  
  2539  			if recv.Type().IsInterface() && method.Op() == ir.OMETHEXPR {
  2540  				method := method.(*ir.SelectorExpr)
  2541  
  2542  				// The compiler backend (e.g., devirtualization) handle
  2543  				// OCALLINTER/ODOTINTER better than OCALLFUNC/OMETHEXPR for
  2544  				// interface calls, so we prefer to continue constructing
  2545  				// calls that way where possible.
  2546  				//
  2547  				// There are also corner cases where semantically it's perhaps
  2548  				// significant; e.g., fixedbugs/issue15975.go, #38634, #52025.
  2549  
  2550  				fun = typecheck.XDotMethod(r.curfn, method.Pos(), recv, method.Sel, true)
  2551  			} else {
  2552  				if recv.Type().IsInterface() {
  2553  					// N.B., this happens currently for typeparam/issue51521.go
  2554  					// and typeparam/typeswitch3.go.
  2555  					if base.Flag.LowerM != 0 {
  2556  						base.WarnfAt(method.Pos(), "imprecise interface call")
  2557  					}
  2558  				}
  2559  
  2560  				fun = method
  2561  				args.Append(recv)
  2562  			}
  2563  			if dictPtr != nil {
  2564  				args.Append(dictPtr)
  2565  			}
  2566  		} else if r.Bool() { // call to instanced function
  2567  			pos := r.pos()
  2568  			_, shapedFn, dictPtr := r.funcInst(pos)
  2569  			fun = shapedFn
  2570  			args.Append(dictPtr)
  2571  		} else {
  2572  			fun = r.expr()
  2573  		}
  2574  		pos := r.pos()
  2575  		args.Append(r.multiExpr()...)
  2576  		dots := r.Bool()
  2577  		n := typecheck.Call(r.curfn, pos, fun, args, dots)
  2578  		switch n.Op() {
  2579  		case ir.OAPPEND:
  2580  			n := n.(*ir.CallExpr)
  2581  			n.RType = r.rtype(pos)
  2582  			// For append(a, b...), we don't need the implicit conversion. The typechecker already
  2583  			// ensured that a and b are both slices with the same base type, or []byte and string.
  2584  			if n.IsDDD {
  2585  				if conv, ok := n.Args[1].(*ir.ConvExpr); ok && conv.Op() == ir.OCONVNOP && conv.Implicit() {
  2586  					n.Args[1] = conv.X
  2587  				}
  2588  			}
  2589  		case ir.OCOPY:
  2590  			n := n.(*ir.BinaryExpr)
  2591  			n.RType = r.rtype(pos)
  2592  		case ir.ODELETE:
  2593  			n := n.(*ir.CallExpr)
  2594  			n.RType = r.rtype(pos)
  2595  		case ir.OUNSAFESLICE:
  2596  			n := n.(*ir.BinaryExpr)
  2597  			n.RType = r.rtype(pos)
  2598  		}
  2599  		return n
  2600  
  2601  	case exprMake:
  2602  		pos := r.pos()
  2603  		typ := r.exprType()
  2604  		extra := r.exprs()
  2605  		n := typecheck.Expr(r.curfn, ir.NewCallExpr(pos, ir.OMAKE, nil, append([]ir.Node{typ}, extra...))).(*ir.MakeExpr)
  2606  		n.RType = r.rtype(pos)
  2607  		return n
  2608  
  2609  	case exprNew:
  2610  		pos := r.pos()
  2611  		if r.Bool() {
  2612  			// new(expr) -> tmp := expr; &tmp
  2613  			x := r.expr()
  2614  			x = typecheck.DefaultLit(x, nil) // See TODO in exprConvert case.
  2615  			var init ir.Nodes
  2616  			addr := ir.NewAddrExpr(pos, r.tempCopy(pos, x, &init))
  2617  			addr.SetInit(init)
  2618  			return typecheck.Expr(r.curfn, addr)
  2619  		}
  2620  		// new(T)
  2621  		return typecheck.Expr(r.curfn, ir.NewUnaryExpr(pos, ir.ONEW, r.exprType()))
  2622  
  2623  	case exprSizeof:
  2624  		return ir.NewUintptr(r.pos(), r.typ().Size())
  2625  
  2626  	case exprAlignof:
  2627  		return ir.NewUintptr(r.pos(), r.typ().Alignment())
  2628  
  2629  	case exprOffsetof:
  2630  		pos := r.pos()
  2631  		typ := r.typ()
  2632  		types.CalcSize(typ)
  2633  
  2634  		var offset int64
  2635  		for i := r.Len(); i >= 0; i-- {
  2636  			field := typ.Field(r.Len())
  2637  			offset += field.Offset
  2638  			typ = field.Type
  2639  		}
  2640  
  2641  		return ir.NewUintptr(pos, offset)
  2642  
  2643  	case exprReshape:
  2644  		typ := r.typ()
  2645  		x := r.expr()
  2646  
  2647  		if types.IdenticalStrict(x.Type(), typ) {
  2648  			return x
  2649  		}
  2650  
  2651  		// Comparison expressions are constructed as "untyped bool" still.
  2652  		//
  2653  		// TODO(mdempsky): It should be safe to reshape them here too, but
  2654  		// maybe it's better to construct them with the proper type
  2655  		// instead.
  2656  		if x.Type() == types.UntypedBool && typ.IsBoolean() {
  2657  			return x
  2658  		}
  2659  
  2660  		base.AssertfAt(x.Type().HasShape() || typ.HasShape(), x.Pos(), "%L and %v are not shape types", x, typ)
  2661  		base.AssertfAt(types.Identical(x.Type(), typ), x.Pos(), "%L is not shape-identical to %v", x, typ)
  2662  
  2663  		// We use ir.HasUniquePos here as a check that x only appears once
  2664  		// in the AST, so it's okay for us to call SetType without
  2665  		// breaking any other uses of it.
  2666  		//
  2667  		// Notably, any ONAMEs should already have the exactly right shape
  2668  		// type and been caught by types.IdenticalStrict above.
  2669  		base.AssertfAt(ir.HasUniquePos(x), x.Pos(), "cannot call SetType(%v) on %L", typ, x)
  2670  
  2671  		if base.Debug.Reshape != 0 {
  2672  			base.WarnfAt(x.Pos(), "reshaping %L to %v", x, typ)
  2673  		}
  2674  
  2675  		x.SetType(typ)
  2676  
  2677  		if call, ok := x.(*ir.CallExpr); ok {
  2678  			call.Reshape = true
  2679  		}
  2680  
  2681  		return x
  2682  
  2683  	case exprConvert:
  2684  		implicit := r.Bool()
  2685  		typ := r.typ()
  2686  		pos := r.pos()
  2687  		typeWord, srcRType := r.convRTTI(pos)
  2688  		dstTypeParam := r.Bool()
  2689  		identical := r.Bool()
  2690  		x := r.expr()
  2691  
  2692  		// spec: "If the type is a type parameter, the constant is converted
  2693  		// into a non-constant value of the type parameter."
  2694  		if dstTypeParam && ir.IsConstNode(x) {
  2695  			// ConvertVal only handles conversions to constant types.
  2696  			if v := typecheck.ConvertVal(x.Val(), typ, false); v.Kind() != constant.Unknown {
  2697  				x = ir.NewBasicLit(x.Pos(), typ, v)
  2698  				// Wrap in an OCONVNOP node to ensure result is non-constant.
  2699  				n := Implicit(ir.NewConvExpr(pos, ir.OCONVNOP, typ, x))
  2700  				n.SetTypecheck(1)
  2701  				return n
  2702  			}
  2703  			// A Go language constant could be converted to a non-constant value,
  2704  			// like converting string to []byte/[]rune. In this case, just construct
  2705  			// the conversion expression as usual, see #79960.
  2706  		}
  2707  
  2708  		// TODO(mdempsky): Stop constructing expressions of untyped type.
  2709  		x = typecheck.DefaultLit(x, typ)
  2710  
  2711  		ce := ir.NewConvExpr(pos, ir.OCONV, typ, x)
  2712  		ce.TypeWord, ce.SrcRType = typeWord, srcRType
  2713  		if implicit {
  2714  			ce.SetImplicit(true)
  2715  		}
  2716  		n := typecheck.Expr(r.curfn, ce)
  2717  
  2718  		// Conversions between non-identical, non-empty interfaces always
  2719  		// requires a runtime call, even if they have identical underlying
  2720  		// interfaces. This is because we create separate itab instances
  2721  		// for each unique interface type, not merely each unique
  2722  		// interface shape.
  2723  		//
  2724  		// However, due to shape types, typecheck.Expr might mistakenly
  2725  		// think a conversion between two non-empty interfaces are
  2726  		// identical and set ir.OCONVNOP, instead of ir.OCONVIFACE. To
  2727  		// ensure we update the itab field appropriately, we force it to
  2728  		// ir.OCONVIFACE instead when shape types are involved.
  2729  		//
  2730  		// TODO(mdempsky): Are there other places we might get this wrong?
  2731  		// Should this be moved down into typecheck.{Assign,Convert}op?
  2732  		// This would be a non-issue if itabs were unique for each
  2733  		// *underlying* interface type instead.
  2734  		if !identical {
  2735  			if n, ok := n.(*ir.ConvExpr); ok && n.Op() == ir.OCONVNOP && n.Type().IsInterface() && !n.Type().IsEmptyInterface() && (n.Type().HasShape() || n.X.Type().HasShape()) {
  2736  				n.SetOp(ir.OCONVIFACE)
  2737  			}
  2738  		}
  2739  
  2740  		return n
  2741  
  2742  	case exprRuntimeBuiltin:
  2743  		builtin := typecheck.LookupRuntime(r.String())
  2744  		return builtin
  2745  	}
  2746  }
  2747  
  2748  // funcInst reads an instantiated function reference, and returns
  2749  // three (possibly nil) expressions related to it:
  2750  //
  2751  // baseFn is always non-nil: it's either a function of the appropriate
  2752  // type already, or it has an extra dictionary parameter as the first
  2753  // parameter.
  2754  //
  2755  // If dictPtr is non-nil, then it's a dictionary argument that must be
  2756  // passed as the first argument to baseFn.
  2757  //
  2758  // If wrapperFn is non-nil, then it's either the same as baseFn (if
  2759  // dictPtr is nil), or it's semantically equivalent to currying baseFn
  2760  // to pass dictPtr. (wrapperFn is nil when dictPtr is an expression
  2761  // that needs to be computed dynamically.)
  2762  //
  2763  // For callers that are creating a call to the returned function, it's
  2764  // best to emit a call to baseFn, and include dictPtr in the arguments
  2765  // list as appropriate.
  2766  //
  2767  // For callers that want to return the function without invoking it,
  2768  // they may return wrapperFn if it's non-nil; but otherwise, they need
  2769  // to create their own wrapper.
  2770  func (r *reader) funcInst(pos src.XPos) (wrapperFn, baseFn, dictPtr ir.Node) {
  2771  	// Like in methodExpr, I'm pretty sure this isn't needed.
  2772  	var implicits []*types.Type
  2773  	if r.dict != nil {
  2774  		implicits = r.dict.targs
  2775  	}
  2776  
  2777  	if r.Bool() { // dynamic subdictionary
  2778  		idx := r.Len()
  2779  		info := r.dict.subdicts[idx]
  2780  		explicits := r.p.typListIdx(info.explicits, r.dict)
  2781  
  2782  		baseFn = r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
  2783  
  2784  		// TODO(mdempsky): Is there a more robust way to get the
  2785  		// dictionary pointer type here?
  2786  		dictPtrType := baseFn.Type().Param(0).Type
  2787  		dictPtr = typecheck.Expr(r.curfn, ir.NewConvExpr(pos, ir.OCONVNOP, dictPtrType, r.dictWord(pos, r.dict.subdictsOffset()+idx)))
  2788  
  2789  		return
  2790  	}
  2791  
  2792  	info := r.objInfo()
  2793  	explicits := r.p.typListIdx(info.explicits, r.dict)
  2794  
  2795  	wrapperFn = r.p.objIdx(info.idx, implicits, explicits, false).(*ir.Name)
  2796  	baseFn = r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
  2797  
  2798  	dictName := r.p.objDictName(info.idx, implicits, explicits)
  2799  	dictPtr = typecheck.Expr(r.curfn, ir.NewAddrExpr(pos, dictName))
  2800  
  2801  	return
  2802  }
  2803  
  2804  func (pr *pkgReader) objDictName(idx index, implicits, explicits []*types.Type) *ir.Name {
  2805  	rname := pr.newReader(pkgbits.SectionName, idx, pkgbits.SyncObject1)
  2806  	_, sym := rname.qualifiedIdent()
  2807  	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
  2808  
  2809  	if tag == pkgbits.ObjStub {
  2810  		assert(!sym.IsBlank())
  2811  		if pri, ok := objReader[sym]; ok {
  2812  			return pri.pr.objDictName(pri.idx, nil, explicits)
  2813  		}
  2814  		base.Fatalf("unresolved stub: %v", sym)
  2815  	}
  2816  
  2817  	dict, err := pr.objDictIdx(sym, idx, implicits, explicits, false)
  2818  	if err != nil {
  2819  		base.Fatalf("%v", err)
  2820  	}
  2821  
  2822  	return pr.dictNameOf(dict)
  2823  }
  2824  
  2825  // curry returns a function literal that calls fun with arg0 and
  2826  // (optionally) arg1, accepting additional arguments to the function
  2827  // literal as necessary to satisfy fun's signature.
  2828  //
  2829  // If nilCheck is true and arg0 is an interface value, then it's
  2830  // checked to be non-nil as an initial step at the point of evaluating
  2831  // the function literal itself.
  2832  func (r *reader) curry(origPos src.XPos, ifaceHack bool, fun ir.Node, arg0, arg1 ir.Node) ir.Node {
  2833  	var captured ir.Nodes
  2834  	captured.Append(fun, arg0)
  2835  	if arg1 != nil {
  2836  		captured.Append(arg1)
  2837  	}
  2838  
  2839  	params, results := syntheticSig(fun.Type())
  2840  	params = params[len(captured)-1:] // skip curried parameters
  2841  	typ := types.NewSignature(nil, params, results)
  2842  
  2843  	addBody := func(pos src.XPos, r *reader, captured []ir.Node) {
  2844  		fun := captured[0]
  2845  
  2846  		var args ir.Nodes
  2847  		args.Append(captured[1:]...)
  2848  		args.Append(r.syntheticArgs()...)
  2849  
  2850  		r.syntheticTailCall(pos, fun, args)
  2851  	}
  2852  
  2853  	return r.syntheticClosure(origPos, typ, ifaceHack, captured, addBody)
  2854  }
  2855  
  2856  // methodExprWrap returns a function literal that changes method's
  2857  // first parameter's type to recv, and uses implicits/deref/addr to
  2858  // select the appropriate receiver parameter to pass to method.
  2859  func (r *reader) methodExprWrap(origPos src.XPos, recv *types.Type, implicits []int, deref, addr bool, method, dictPtr ir.Node) ir.Node {
  2860  	var captured ir.Nodes
  2861  	captured.Append(method)
  2862  
  2863  	params, results := syntheticSig(method.Type())
  2864  
  2865  	// Change first parameter to recv.
  2866  	params[0].Type = recv
  2867  
  2868  	// If we have a dictionary pointer argument to pass, then omit the
  2869  	// underlying method expression's dictionary parameter from the
  2870  	// returned signature too.
  2871  	if dictPtr != nil {
  2872  		captured.Append(dictPtr)
  2873  		params = append(params[:1], params[2:]...)
  2874  	}
  2875  
  2876  	typ := types.NewSignature(nil, params, results)
  2877  
  2878  	addBody := func(pos src.XPos, r *reader, captured []ir.Node) {
  2879  		fn := captured[0]
  2880  		args := r.syntheticArgs()
  2881  
  2882  		// Rewrite first argument based on implicits/deref/addr.
  2883  		{
  2884  			arg := args[0]
  2885  			for _, ix := range implicits {
  2886  				arg = Implicit(typecheck.DotField(pos, arg, ix))
  2887  			}
  2888  			if deref {
  2889  				arg = Implicit(Deref(pos, arg.Type().Elem(), arg))
  2890  			} else if addr {
  2891  				arg = Implicit(Addr(r.curfn, pos, arg))
  2892  			}
  2893  			args[0] = arg
  2894  		}
  2895  
  2896  		// Insert dictionary argument, if provided.
  2897  		if dictPtr != nil {
  2898  			newArgs := make([]ir.Node, len(args)+1)
  2899  			newArgs[0] = args[0]
  2900  			newArgs[1] = captured[1]
  2901  			copy(newArgs[2:], args[1:])
  2902  			args = newArgs
  2903  		}
  2904  
  2905  		r.syntheticTailCall(pos, fn, args)
  2906  	}
  2907  
  2908  	return r.syntheticClosure(origPos, typ, false, captured, addBody)
  2909  }
  2910  
  2911  // syntheticClosure constructs a synthetic function literal for
  2912  // currying dictionary arguments. origPos is the position used for the
  2913  // closure, which must be a non-inlined position. typ is the function
  2914  // literal's signature type.
  2915  //
  2916  // captures is a list of expressions that need to be evaluated at the
  2917  // point of function literal evaluation and captured by the function
  2918  // literal. If ifaceHack is true and captures[1] is an interface type,
  2919  // it's checked to be non-nil after evaluation.
  2920  //
  2921  // addBody is a callback function to populate the function body. The
  2922  // list of captured values passed back has the captured variables for
  2923  // use within the function literal, corresponding to the expressions
  2924  // in captures.
  2925  func (r *reader) syntheticClosure(origPos src.XPos, typ *types.Type, ifaceHack bool, captures ir.Nodes, addBody func(pos src.XPos, r *reader, captured []ir.Node)) ir.Node {
  2926  	// isSafe reports whether n is an expression that we can safely
  2927  	// defer to evaluating inside the closure instead, to avoid storing
  2928  	// them into the closure.
  2929  	//
  2930  	// In practice this is always (and only) the wrappee function.
  2931  	isSafe := func(n ir.Node) bool {
  2932  		if n.Op() == ir.ONAME && n.(*ir.Name).Class == ir.PFUNC {
  2933  			return true
  2934  		}
  2935  		if n.Op() == ir.OMETHEXPR {
  2936  			return true
  2937  		}
  2938  
  2939  		return false
  2940  	}
  2941  
  2942  	fn := r.inlClosureFunc(origPos, typ, ir.OCLOSURE)
  2943  	fn.SetWrapper(true)
  2944  
  2945  	clo := fn.OClosure
  2946  	inlPos := clo.Pos()
  2947  
  2948  	var init ir.Nodes
  2949  	for i, n := range captures {
  2950  		if isSafe(n) {
  2951  			continue // skip capture; can reference directly
  2952  		}
  2953  
  2954  		tmp := r.tempCopy(inlPos, n, &init)
  2955  		ir.NewClosureVar(origPos, fn, tmp)
  2956  
  2957  		// We need to nil check interface receivers at the point of method
  2958  		// value evaluation, ugh.
  2959  		if ifaceHack && i == 1 && n.Type().IsInterface() {
  2960  			check := ir.NewUnaryExpr(inlPos, ir.OCHECKNIL, ir.NewUnaryExpr(inlPos, ir.OITAB, tmp))
  2961  			init.Append(typecheck.Stmt(r.curfn, check))
  2962  		}
  2963  	}
  2964  
  2965  	pri := pkgReaderIndex{synthetic: func(pos src.XPos, r *reader) {
  2966  		captured := make([]ir.Node, len(captures))
  2967  		next := 0
  2968  		for i, n := range captures {
  2969  			if isSafe(n) {
  2970  				captured[i] = n
  2971  			} else {
  2972  				captured[i] = r.closureVars[next]
  2973  				next++
  2974  			}
  2975  		}
  2976  		assert(next == len(r.closureVars))
  2977  
  2978  		addBody(origPos, r, captured)
  2979  	}}
  2980  	bodyReader[fn] = pri
  2981  	pri.funcBody(fn)
  2982  
  2983  	return ir.InitExpr(init, clo)
  2984  }
  2985  
  2986  // syntheticSig duplicates and returns the params and results lists
  2987  // for sig, but renaming anonymous parameters so they can be assigned
  2988  // ir.Names.
  2989  func syntheticSig(sig *types.Type) (params, results []*types.Field) {
  2990  	clone := func(params []*types.Field) []*types.Field {
  2991  		res := make([]*types.Field, len(params))
  2992  		for i, param := range params {
  2993  			// TODO(mdempsky): It would be nice to preserve the original
  2994  			// parameter positions here instead, but at least
  2995  			// typecheck.NewMethodType replaces them with base.Pos, making
  2996  			// them useless. Worse, the positions copied from base.Pos may
  2997  			// have inlining contexts, which we definitely don't want here
  2998  			// (e.g., #54625).
  2999  			res[i] = types.NewField(base.AutogeneratedPos, param.Sym, param.Type)
  3000  			res[i].SetIsDDD(param.IsDDD())
  3001  		}
  3002  		return res
  3003  	}
  3004  
  3005  	return clone(sig.Params()), clone(sig.Results())
  3006  }
  3007  
  3008  func (r *reader) optExpr() ir.Node {
  3009  	if r.Bool() {
  3010  		return r.expr()
  3011  	}
  3012  	return nil
  3013  }
  3014  
  3015  // methodExpr reads a method expression reference, and returns three
  3016  // (possibly nil) expressions related to it:
  3017  //
  3018  // baseFn is always non-nil: it's either a function of the appropriate
  3019  // type already, or it has an extra dictionary parameter as the second
  3020  // parameter (i.e., immediately after the promoted receiver
  3021  // parameter).
  3022  //
  3023  // If dictPtr is non-nil, then it's a dictionary argument that must be
  3024  // passed as the second argument to baseFn.
  3025  //
  3026  // If wrapperFn is non-nil, then it's either the same as baseFn (if
  3027  // dictPtr is nil), or it's semantically equivalent to currying baseFn
  3028  // to pass dictPtr. (wrapperFn is nil when dictPtr is an expression
  3029  // that needs to be computed dynamically.)
  3030  //
  3031  // For callers that are creating a call to the returned method, it's
  3032  // best to emit a call to baseFn, and include dictPtr in the arguments
  3033  // list as appropriate.
  3034  //
  3035  // For callers that want to return a method expression without
  3036  // invoking it, they may return wrapperFn if it's non-nil; but
  3037  // otherwise, they need to create their own wrapper.
  3038  func (r *reader) methodExpr() (wrapperFn, baseFn, dictPtr ir.Node) {
  3039  	recv := r.typ()
  3040  
  3041  	var sig *types.Type
  3042  	generic := r.Version().Has(pkgbits.GenericMethods) && r.Bool()
  3043  	if !generic {
  3044  		// Signature type to return (i.e., recv prepended to the method's
  3045  		// normal parameters list).
  3046  		sig = typecheck.NewMethodType(r.typ(), recv)
  3047  	}
  3048  
  3049  	pos := r.pos()
  3050  	sym := r.selector()
  3051  
  3052  	if r.Bool() { // type parameter method expression
  3053  		idx := r.Len()
  3054  		word := r.dictWord(pos, r.dict.typeParamMethodExprsOffset()+idx)
  3055  
  3056  		// TODO(mdempsky): If the type parameter was instantiated with an
  3057  		// interface type (i.e., embed.IsInterface()), then we could
  3058  		// return the OMETHEXPR instead and save an indirection.
  3059  
  3060  		// We wrote the method expression's entry point PC into the
  3061  		// dictionary, but for Go `func` values we need to return a
  3062  		// closure (i.e., pointer to a structure with the PC as the first
  3063  		// field). Because method expressions don't have any closure
  3064  		// variables, we pun the dictionary entry as the closure struct.
  3065  		fn := typecheck.Expr(r.curfn, ir.NewConvExpr(pos, ir.OCONVNOP, sig, ir.NewAddrExpr(pos, word)))
  3066  		return fn, fn, nil
  3067  	}
  3068  
  3069  	if r.Bool() { // dynamic subdictionary
  3070  		idx := r.Len()
  3071  		info := r.dict.subdicts[idx]
  3072  		explicits := r.p.typListIdx(info.explicits, r.dict)
  3073  
  3074  		shapedObj := r.p.objIdx(info.idx, nil, explicits, true).(*ir.Name)
  3075  		shapedFn := shapedMethodExpr(pos, shapedObj, sym)
  3076  
  3077  		// TODO(mdempsky): Is there a more robust way to get the
  3078  		// dictionary pointer type here?
  3079  		dictPtrType := shapedFn.Type().Param(1).Type
  3080  		dictPtr := typecheck.Expr(r.curfn, ir.NewConvExpr(pos, ir.OCONVNOP, dictPtrType, r.dictWord(pos, r.dict.subdictsOffset()+idx)))
  3081  
  3082  		return nil, shapedFn, dictPtr
  3083  	}
  3084  
  3085  	if r.Bool() { // static dictionary
  3086  		info := r.objInfo()
  3087  		explicits := r.p.typListIdx(info.explicits, r.dict)
  3088  
  3089  		shapedObj := r.p.objIdx(info.idx, nil, explicits, true).(*ir.Name)
  3090  		shapedFn := shapedMethodExpr(pos, shapedObj, sym)
  3091  
  3092  		dict := r.p.objDictName(info.idx, nil, explicits)
  3093  		dictPtr := typecheck.Expr(r.curfn, ir.NewAddrExpr(pos, dict))
  3094  
  3095  		// Check that dictPtr matches shapedFn's dictionary parameter.
  3096  		if !types.Identical(dictPtr.Type(), shapedFn.Type().Param(1).Type) {
  3097  			base.FatalfAt(pos, "dict %L, but shaped method %L", dict, shapedFn)
  3098  		}
  3099  
  3100  		if !generic {
  3101  			// For statically known instantiations, we can take advantage of
  3102  			// the stenciled wrapper.
  3103  			base.AssertfAt(!recv.HasShape(), pos, "shaped receiver %v", recv)
  3104  			wrapperFn := typecheck.NewMethodExpr(pos, recv, sym)
  3105  			base.AssertfAt(types.Identical(sig, wrapperFn.Type()), pos, "wrapper %L does not have type %v", wrapperFn, sig)
  3106  			return wrapperFn, shapedFn, dictPtr
  3107  		} else {
  3108  			// Also statically known, but there is a good amount of existing
  3109  			// machinery downstream which makes assumptions about method
  3110  			// wrapper functions. It's safest not to emit them for now.
  3111  			// TODO(mark): Emit wrapper functions for generic methods.
  3112  			return nil, shapedFn, dictPtr
  3113  		}
  3114  	}
  3115  
  3116  	// Simple method expression; no dictionary needed.
  3117  	base.AssertfAt(!recv.HasShape() || recv.IsInterface(), pos, "shaped receiver %v", recv)
  3118  	fn := typecheck.NewMethodExpr(pos, recv, sym)
  3119  	return fn, fn, nil
  3120  }
  3121  
  3122  // shapedMethodExpr creates an OMETHEXPR for obj using sym.
  3123  //
  3124  // If obj is an OTYPE, it must refer to a generic type. If obj is an ONAME,
  3125  // it must refer to a generic method. In either case, sym.Name must be the
  3126  // unqualified name of the method.
  3127  //
  3128  // For example, given:
  3129  //
  3130  //	package p
  3131  //
  3132  //	type T[P any] struct {}
  3133  //
  3134  //	func (T[P]) m() {}
  3135  //	func (T[P]) n[Q any]() {}
  3136  //
  3137  // then, using S as go.shape.int:
  3138  //   - in T[int].m,      obj is T[S]      and sym.Name is "m".
  3139  //   - in T[int].n[int], obj is T[S].n[S] and sym.Name is "n".
  3140  //
  3141  // Note that we could have pushed dictionaries down to methods in every case,
  3142  // but since non-generic methods will always share the same "type environment"
  3143  // as their defining type, we can optimize by reusing the type's dictionary.
  3144  func shapedMethodExpr(pos src.XPos, obj *ir.Name, sym *types.Sym) ir.Node {
  3145  	if obj.Op() == ir.OTYPE {
  3146  		// non-generic method on generic type
  3147  		typ := obj.Type()
  3148  		assert(typ.HasShape())
  3149  
  3150  		method := func() *types.Field {
  3151  			for _, m := range typ.Methods() {
  3152  				if m.Sym == sym {
  3153  					return m
  3154  				}
  3155  			}
  3156  
  3157  			base.FatalfAt(pos, "failed to find method %v in shaped type %v", sym, typ)
  3158  			panic("unreachable")
  3159  		}()
  3160  
  3161  		return typecheck.NewMethodExpr(pos, method.Type.Recv().Type, sym)
  3162  	} else {
  3163  		// generic method on possibly generic type
  3164  		assert(obj.Op() == ir.ONAME && obj.Class == ir.PFUNC)
  3165  		typ := obj.Type()
  3166  		assert(typ.HasShape())
  3167  
  3168  		// OMETHEXPR assumes that the linker symbol to call looks like "<type sym>.<method sym>".
  3169  		// This works because non-generic method symbols are relative to their type. But generic
  3170  		// methods use fully-qualified names, so this won't work.
  3171  		//
  3172  		// To use OMETHEXPR for generic methods, we craft a dummy field on the type by removing
  3173  		// the qualifier; OMETHEXPR will put it back later.
  3174  		lsym := obj.Linksym().Name
  3175  		// Since the method is generic, we know the method name must be followed by a bracket.
  3176  		// TODO(mark): It's not ideal to rely on string naming here. Find a more robust solution.
  3177  		idx := func() int { // Find the index of the bracket following the method name.
  3178  			depth, i := 0, len(lsym)-1
  3179  			for {
  3180  				switch lsym[i] {
  3181  				case ']':
  3182  					depth++
  3183  				case '[':
  3184  					depth--
  3185  				}
  3186  				if depth == 0 {
  3187  					return i
  3188  				}
  3189  				i--
  3190  			}
  3191  		}()
  3192  		msym := sym.Pkg.Lookup(lsym[idx-len(sym.Name):])
  3193  
  3194  		// Note that the field name here includes the type arguments; while also not ideal, the
  3195  		// types package does not seem to complain.
  3196  		m := types.NewField(obj.Pos(), msym, typ)
  3197  		m.Nname = obj
  3198  
  3199  		n := ir.NewSelectorExpr(pos, ir.OMETHEXPR, ir.TypeNode(typ.Recv().Type), msym)
  3200  		n.Selection = m
  3201  		n.SetType(typecheck.NewMethodType(typ, typ.Recv().Type))
  3202  		n.SetTypecheck(1)
  3203  
  3204  		return n
  3205  	}
  3206  }
  3207  
  3208  func (r *reader) multiExpr() []ir.Node {
  3209  	r.Sync(pkgbits.SyncMultiExpr)
  3210  
  3211  	if r.Bool() { // N:1
  3212  		pos := r.pos()
  3213  		expr := r.expr()
  3214  
  3215  		results := make([]ir.Node, r.Len())
  3216  		as := ir.NewAssignListStmt(pos, ir.OAS2, nil, []ir.Node{expr})
  3217  		as.Def = true
  3218  		for i := range results {
  3219  			tmp := r.temp(pos, r.typ())
  3220  			tmp.Defn = as
  3221  			as.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, tmp))
  3222  			as.Lhs.Append(tmp)
  3223  
  3224  			res := ir.Node(tmp)
  3225  			if r.Bool() {
  3226  				n := ir.NewConvExpr(pos, ir.OCONV, r.typ(), res)
  3227  				n.TypeWord, n.SrcRType = r.convRTTI(pos)
  3228  				n.SetImplicit(true)
  3229  				res = typecheck.Expr(r.curfn, n)
  3230  			}
  3231  			results[i] = res
  3232  		}
  3233  
  3234  		// TODO(mdempsky): Could use ir.InlinedCallExpr instead?
  3235  		results[0] = ir.InitExpr([]ir.Node{typecheck.Stmt(r.curfn, as)}, results[0])
  3236  		return results
  3237  	}
  3238  
  3239  	// N:N
  3240  	exprs := make([]ir.Node, r.Len())
  3241  	if len(exprs) == 0 {
  3242  		return nil
  3243  	}
  3244  	for i := range exprs {
  3245  		exprs[i] = r.expr()
  3246  	}
  3247  	return exprs
  3248  }
  3249  
  3250  // temp returns a new autotemp of the specified type.
  3251  func (r *reader) temp(pos src.XPos, typ *types.Type) *ir.Name {
  3252  	return typecheck.TempAt(pos, r.curfn, typ)
  3253  }
  3254  
  3255  // tempCopy declares and returns a new autotemp initialized to the
  3256  // value of expr.
  3257  func (r *reader) tempCopy(pos src.XPos, expr ir.Node, init *ir.Nodes) *ir.Name {
  3258  	tmp := r.temp(pos, expr.Type())
  3259  
  3260  	init.Append(typecheck.Stmt(r.curfn, ir.NewDecl(pos, ir.ODCL, tmp)))
  3261  
  3262  	assign := ir.NewAssignStmt(pos, tmp, expr)
  3263  	assign.Def = true
  3264  	init.Append(typecheck.Stmt(r.curfn, assign))
  3265  
  3266  	tmp.Defn = assign
  3267  
  3268  	return tmp
  3269  }
  3270  
  3271  func (r *reader) compLit() ir.Node {
  3272  	r.Sync(pkgbits.SyncCompLit)
  3273  	pos := r.pos()
  3274  	typ0 := r.typ()
  3275  
  3276  	typ := typ0
  3277  	if typ.IsPtr() {
  3278  		typ = typ.Elem()
  3279  	}
  3280  	if typ.Kind() == types.TFORW {
  3281  		base.FatalfAt(pos, "unresolved composite literal type: %v", typ)
  3282  	}
  3283  	var rtype ir.Node
  3284  	if typ.IsMap() {
  3285  		rtype = r.rtype(pos)
  3286  	}
  3287  
  3288  	var elems []ir.Node
  3289  	if r.Version().Has(pkgbits.CompactCompLiterals) {
  3290  		n := r.Int()
  3291  		elems = make([]ir.Node, max(n, -n) /* abs(n) */)
  3292  		switch typ.Kind() {
  3293  		default:
  3294  			base.FatalfAt(pos, "unexpected composite literal type: %v", typ)
  3295  		case types.TARRAY:
  3296  			r.arrayElems(n >= 0, elems)
  3297  		case types.TMAP:
  3298  			r.mapElems(elems)
  3299  		case types.TSLICE:
  3300  			r.arrayElems(n >= 0, elems)
  3301  		case types.TSTRUCT:
  3302  			r.structElems(typ, n >= 0, elems)
  3303  		}
  3304  	} else {
  3305  		elems = make([]ir.Node, r.Len())
  3306  		isStruct := typ.Kind() == types.TSTRUCT
  3307  		for i := range elems {
  3308  			elemp := &elems[i]
  3309  			if isStruct {
  3310  				sk := ir.NewStructKeyExpr(r.pos(), typ.Field(r.Len()), nil)
  3311  				*elemp, elemp = sk, &sk.Value
  3312  			} else if r.Bool() {
  3313  				kv := ir.NewKeyExpr(r.pos(), r.expr(), nil)
  3314  				*elemp, elemp = kv, &kv.Value
  3315  			}
  3316  			*elemp = r.expr()
  3317  		}
  3318  	}
  3319  
  3320  	lit := typecheck.Expr(r.curfn, ir.NewCompLitExpr(pos, ir.OCOMPLIT, typ, elems))
  3321  	if rtype != nil {
  3322  		lit := lit.(*ir.CompLitExpr)
  3323  		lit.RType = rtype
  3324  	}
  3325  	if typ0.IsPtr() {
  3326  		lit = typecheck.Expr(r.curfn, typecheck.NodAddrAt(r.curfn, pos, lit))
  3327  		lit.SetType(typ0)
  3328  	}
  3329  	return lit
  3330  }
  3331  
  3332  func (r *reader) arrayElems(valuesOnly bool, elems []ir.Node) {
  3333  	if valuesOnly {
  3334  		for i := range elems {
  3335  			elems[i] = r.expr()
  3336  		}
  3337  		return
  3338  	}
  3339  	// some elements may have a key
  3340  	for i := range elems {
  3341  		if r.Bool() {
  3342  			kv := ir.NewKeyExpr(r.pos(), r.expr(), nil)
  3343  			kv.Value = r.expr()
  3344  			elems[i] = kv
  3345  		} else {
  3346  			elems[i] = r.expr()
  3347  		}
  3348  	}
  3349  }
  3350  
  3351  func (r *reader) mapElems(elems []ir.Node) {
  3352  	// all elements have a key
  3353  	for i := range elems {
  3354  		kv := ir.NewKeyExpr(r.pos(), r.expr(), nil)
  3355  		kv.Value = r.expr()
  3356  		elems[i] = kv
  3357  	}
  3358  }
  3359  
  3360  func (r *reader) structElems(typ *types.Type, valuesOnly bool, elems []ir.Node) {
  3361  	if valuesOnly {
  3362  		for i := range elems {
  3363  			sk := ir.NewStructKeyExpr(r.pos(), typ.Field(i), nil)
  3364  			sk.Value = r.expr()
  3365  			elems[i] = sk
  3366  		}
  3367  		return
  3368  	}
  3369  
  3370  	// all elements have a key
  3371  	for i := range elems {
  3372  		pos := r.pos()
  3373  		var fld *types.Field
  3374  		if n := r.Int(); n < 0 {
  3375  			// embedded field
  3376  			typ := typ // don't modify the original typ
  3377  			for range -n {
  3378  				fld = typ.Field(r.Int())
  3379  				typ = fld.Type
  3380  			}
  3381  		} else { // n >= 0
  3382  			fld = typ.Field(n)
  3383  		}
  3384  		sk := ir.NewStructKeyExpr(pos, fld, nil)
  3385  		sk.Value = r.expr()
  3386  		elems[i] = sk
  3387  	}
  3388  }
  3389  
  3390  func (r *reader) funcLit() ir.Node {
  3391  	r.Sync(pkgbits.SyncFuncLit)
  3392  
  3393  	// The underlying function declaration (including its parameters'
  3394  	// positions, if any) need to remain the original, uninlined
  3395  	// positions. This is because we track inlining-context on nodes so
  3396  	// we can synthesize the extra implied stack frames dynamically when
  3397  	// generating tracebacks, whereas those stack frames don't make
  3398  	// sense *within* the function literal. (Any necessary inlining
  3399  	// adjustments will have been applied to the call expression
  3400  	// instead.)
  3401  	//
  3402  	// This is subtle, and getting it wrong leads to cycles in the
  3403  	// inlining tree, which lead to infinite loops during stack
  3404  	// unwinding (#46234, #54625).
  3405  	//
  3406  	// Note that we *do* want the inline-adjusted position for the
  3407  	// OCLOSURE node, because that position represents where any heap
  3408  	// allocation of the closure is credited (#49171).
  3409  	r.suppressInlPos++
  3410  	origPos := r.pos()
  3411  	sig := r.signature(nil)
  3412  	r.suppressInlPos--
  3413  	why := ir.OCLOSURE
  3414  	if r.Bool() {
  3415  		why = ir.ORANGE
  3416  	}
  3417  
  3418  	fn := r.inlClosureFunc(origPos, sig, why)
  3419  
  3420  	fn.ClosureVars = make([]*ir.Name, 0, r.Len())
  3421  	for len(fn.ClosureVars) < cap(fn.ClosureVars) {
  3422  		// TODO(mdempsky): I think these should be original positions too
  3423  		// (i.e., not inline-adjusted).
  3424  		ir.NewClosureVar(r.pos(), fn, r.useLocal())
  3425  	}
  3426  	if param := r.dictParam; param != nil {
  3427  		// If we have a dictionary parameter, capture it too. For
  3428  		// simplicity, we capture it last and unconditionally.
  3429  		ir.NewClosureVar(param.Pos(), fn, param)
  3430  	}
  3431  
  3432  	r.addBody(fn, nil)
  3433  
  3434  	return fn.OClosure
  3435  }
  3436  
  3437  // inlClosureFunc constructs a new closure function, but correctly
  3438  // handles inlining.
  3439  func (r *reader) inlClosureFunc(origPos src.XPos, sig *types.Type, why ir.Op) *ir.Func {
  3440  	curfn := r.inlCaller
  3441  	if curfn == nil {
  3442  		curfn = r.curfn
  3443  	}
  3444  
  3445  	var gen int
  3446  	if why == ir.ORANGE {
  3447  		r.rangeLitGen++
  3448  		gen = r.rangeLitGen
  3449  	} else {
  3450  		r.funcLitGen++
  3451  		gen = r.funcLitGen
  3452  	}
  3453  
  3454  	// TODO(mdempsky): Remove hard-coding of typecheck.Target.
  3455  	return ir.NewClosureFunc(origPos, r.inlPos(origPos), why, sig, curfn, typecheck.Target, gen)
  3456  }
  3457  
  3458  func (r *reader) exprList() []ir.Node {
  3459  	r.Sync(pkgbits.SyncExprList)
  3460  	return r.exprs()
  3461  }
  3462  
  3463  func (r *reader) exprs() []ir.Node {
  3464  	r.Sync(pkgbits.SyncExprs)
  3465  	nodes := make([]ir.Node, r.Len())
  3466  	if len(nodes) == 0 {
  3467  		return nil // TODO(mdempsky): Unclear if this matters.
  3468  	}
  3469  	for i := range nodes {
  3470  		nodes[i] = r.expr()
  3471  	}
  3472  	return nodes
  3473  }
  3474  
  3475  // dictWord returns an expression to return the specified
  3476  // uintptr-typed word from the dictionary parameter.
  3477  func (r *reader) dictWord(pos src.XPos, idx int) ir.Node {
  3478  	base.AssertfAt(r.dictParam != nil, pos, "expected dictParam in %v", r.curfn)
  3479  	return typecheck.Expr(r.curfn, ir.NewIndexExpr(pos, r.dictParam, ir.NewInt(pos, int64(idx))))
  3480  }
  3481  
  3482  // rttiWord is like dictWord, but converts it to *byte (the type used
  3483  // internally to represent *runtime._type and *runtime.itab).
  3484  func (r *reader) rttiWord(pos src.XPos, idx int) ir.Node {
  3485  	return typecheck.Expr(r.curfn, ir.NewConvExpr(pos, ir.OCONVNOP, types.NewPtr(types.Types[types.TUINT8]), r.dictWord(pos, idx)))
  3486  }
  3487  
  3488  // rtype reads a type reference from the element bitstream, and
  3489  // returns an expression of type *runtime._type representing that
  3490  // type.
  3491  func (r *reader) rtype(pos src.XPos) ir.Node {
  3492  	_, rtype := r.rtype0(pos)
  3493  	return rtype
  3494  }
  3495  
  3496  func (r *reader) rtype0(pos src.XPos) (typ *types.Type, rtype ir.Node) {
  3497  	r.Sync(pkgbits.SyncRType)
  3498  	if r.Bool() { // derived type
  3499  		idx := r.Len()
  3500  		info := r.dict.rtypes[idx]
  3501  		typ = r.p.typIdx(info, r.dict, true)
  3502  		rtype = r.rttiWord(pos, r.dict.rtypesOffset()+idx)
  3503  		return
  3504  	}
  3505  
  3506  	typ = r.typ()
  3507  	rtype = reflectdata.TypePtrAt(r.curfn, pos, typ)
  3508  	return
  3509  }
  3510  
  3511  // varDictIndex populates name.DictIndex if name is a derived type.
  3512  func (r *reader) varDictIndex(name *ir.Name) {
  3513  	if r.Bool() {
  3514  		idx := 1 + r.dict.rtypesOffset() + r.Len()
  3515  		if int(uint16(idx)) != idx {
  3516  			base.FatalfAt(name.Pos(), "DictIndex overflow for %v: %v", name, idx)
  3517  		}
  3518  		name.DictIndex = uint16(idx)
  3519  	}
  3520  }
  3521  
  3522  // itab returns a (typ, iface) pair of types.
  3523  //
  3524  // typRType and ifaceRType are expressions that evaluate to the
  3525  // *runtime._type for typ and iface, respectively.
  3526  //
  3527  // If typ is a concrete type and iface is a non-empty interface type,
  3528  // then itab is an expression that evaluates to the *runtime.itab for
  3529  // the pair. Otherwise, itab is nil.
  3530  func (r *reader) itab(pos src.XPos) (typ *types.Type, typRType ir.Node, iface *types.Type, ifaceRType ir.Node, itab ir.Node) {
  3531  	typ, typRType = r.rtype0(pos)
  3532  	iface, ifaceRType = r.rtype0(pos)
  3533  
  3534  	idx := -1
  3535  	if r.Bool() {
  3536  		idx = r.Len()
  3537  	}
  3538  
  3539  	if !typ.IsInterface() && iface.IsInterface() && !iface.IsEmptyInterface() {
  3540  		if idx >= 0 {
  3541  			itab = r.rttiWord(pos, r.dict.itabsOffset()+idx)
  3542  		} else {
  3543  			base.AssertfAt(!typ.HasShape(), pos, "%v is a shape type", typ)
  3544  			base.AssertfAt(!iface.HasShape(), pos, "%v is a shape type", iface)
  3545  
  3546  			lsym := reflectdata.ITabLsym(typ, iface)
  3547  			itab = typecheck.LinksymAddr(r.curfn, pos, lsym, types.Types[types.TUINT8])
  3548  		}
  3549  	}
  3550  
  3551  	return
  3552  }
  3553  
  3554  // convRTTI returns expressions appropriate for populating an
  3555  // ir.ConvExpr's TypeWord and SrcRType fields, respectively.
  3556  func (r *reader) convRTTI(pos src.XPos) (typeWord, srcRType ir.Node) {
  3557  	r.Sync(pkgbits.SyncConvRTTI)
  3558  	src, srcRType0, dst, dstRType, itab := r.itab(pos)
  3559  	if !dst.IsInterface() {
  3560  		return
  3561  	}
  3562  
  3563  	// See reflectdata.ConvIfaceTypeWord.
  3564  	switch {
  3565  	case dst.IsEmptyInterface():
  3566  		if !src.IsInterface() {
  3567  			typeWord = srcRType0 // direct eface construction
  3568  		}
  3569  	case !src.IsInterface():
  3570  		typeWord = itab // direct iface construction
  3571  	default:
  3572  		typeWord = dstRType // convI2I
  3573  	}
  3574  
  3575  	// See reflectdata.ConvIfaceSrcRType.
  3576  	if !src.IsInterface() {
  3577  		srcRType = srcRType0
  3578  	}
  3579  
  3580  	return
  3581  }
  3582  
  3583  func (r *reader) exprType() ir.Node {
  3584  	r.Sync(pkgbits.SyncExprType)
  3585  	pos := r.pos()
  3586  
  3587  	var typ *types.Type
  3588  	var rtype, itab ir.Node
  3589  
  3590  	if r.Bool() {
  3591  		// non-empty interface
  3592  		typ, rtype, _, _, itab = r.itab(pos)
  3593  		if !typ.IsInterface() {
  3594  			rtype = nil // TODO(mdempsky): Leave set?
  3595  		}
  3596  	} else {
  3597  		typ, rtype = r.rtype0(pos)
  3598  
  3599  		if !r.Bool() { // not derived
  3600  			return ir.TypeNode(typ)
  3601  		}
  3602  	}
  3603  
  3604  	dt := ir.NewDynamicType(pos, rtype)
  3605  	dt.ITab = itab
  3606  	dt = typed(typ, dt).(*ir.DynamicType)
  3607  	if st := dt.ToStatic(); st != nil {
  3608  		return st
  3609  	}
  3610  	return dt
  3611  }
  3612  
  3613  func (r *reader) op() ir.Op {
  3614  	r.Sync(pkgbits.SyncOp)
  3615  	return ir.Op(r.Len())
  3616  }
  3617  
  3618  // @@@ Package initialization
  3619  
  3620  func (r *reader) pkgInit(self *types.Pkg, target *ir.Package) {
  3621  	cgoPragmas := make([][]string, r.Len())
  3622  	for i := range cgoPragmas {
  3623  		cgoPragmas[i] = r.Strings()
  3624  	}
  3625  	target.CgoPragmas = cgoPragmas
  3626  
  3627  	r.pkgInitOrder(target)
  3628  
  3629  	r.pkgDecls(target)
  3630  
  3631  	r.Sync(pkgbits.SyncEOF)
  3632  }
  3633  
  3634  // pkgInitOrder creates a synthetic init function to handle any
  3635  // package-scope initialization statements.
  3636  func (r *reader) pkgInitOrder(target *ir.Package) {
  3637  	initOrder := make([]ir.Node, r.Len())
  3638  	if len(initOrder) == 0 {
  3639  		return
  3640  	}
  3641  
  3642  	// Make a function that contains all the initialization statements.
  3643  	pos := base.AutogeneratedPos
  3644  	lno := base.Pos
  3645  	defer func() { base.Pos = lno }()
  3646  	base.Pos = pos
  3647  
  3648  	fn := ir.NewFunc(pos, pos, typecheck.Lookup("init"), types.NewSignature(nil, nil, nil))
  3649  	fn.SetIsPackageInit(true)
  3650  	fn.SetInlinabilityChecked(true) // suppress useless "can inline" diagnostics
  3651  
  3652  	typecheck.DeclFunc(fn)
  3653  	r.curfn = fn
  3654  
  3655  	var varInitFns []*ir.Func
  3656  	if len(initOrder) <= maxInitStatements {
  3657  		fn.Body = r.doPkgInitOrder(initOrder)
  3658  	} else {
  3659  		varInitFns = r.splitLargeInitOrder(initOrder)
  3660  		calls := make([]ir.Node, len(varInitFns))
  3661  		for i, varInitFn := range varInitFns {
  3662  			ir.WithPos(fn, func() {
  3663  				calls[i] = typecheck.Call(r.curfn, varInitFn.Pos(), varInitFn.Nname, nil, false)
  3664  			})
  3665  		}
  3666  		fn.Body = calls
  3667  	}
  3668  
  3669  	r.curfn = nil
  3670  	r.locals = nil
  3671  
  3672  	// Outline (if legal/profitable) global map inits.
  3673  	staticinit.OutlineMapInits(fn)
  3674  	for _, varInitFn := range varInitFns {
  3675  		staticinit.OutlineMapInits(varInitFn)
  3676  	}
  3677  
  3678  	target.Inits = append(target.Inits, fn)
  3679  }
  3680  
  3681  const maxInitStatements = 1000
  3682  
  3683  func (r *reader) generateVarInitFunc(body []ir.Node) *ir.Func {
  3684  	fn := staticinit.GenerateVarInitFunc()
  3685  	typecheck.DeclFunc(fn)
  3686  
  3687  	old := r.curfn
  3688  	r.curfn = fn
  3689  	fn.Body = r.doPkgInitOrder(body)
  3690  	r.curfn = old
  3691  
  3692  	return fn
  3693  }
  3694  
  3695  func (r *reader) doPkgInitOrder(initOrder []ir.Node) []ir.Node {
  3696  	for i := range initOrder {
  3697  		lhs := make([]ir.Node, r.Len())
  3698  		for j := range lhs {
  3699  			lhs[j] = r.obj()
  3700  		}
  3701  		rhs := r.expr()
  3702  		pos := lhs[0].Pos()
  3703  
  3704  		var as ir.Node
  3705  		if len(lhs) == 1 {
  3706  			as = typecheck.Stmt(r.curfn, ir.NewAssignStmt(pos, lhs[0], rhs))
  3707  		} else {
  3708  			as = typecheck.Stmt(r.curfn, ir.NewAssignListStmt(pos, ir.OAS2, lhs, []ir.Node{rhs}))
  3709  		}
  3710  
  3711  		for _, v := range lhs {
  3712  			v.(*ir.Name).Defn = as
  3713  		}
  3714  
  3715  		initOrder[i] = as
  3716  	}
  3717  	return initOrder
  3718  }
  3719  
  3720  func (r *reader) splitLargeInitOrder(initOrder []ir.Node) []*ir.Func {
  3721  	var initFuncs []*ir.Func
  3722  	for chunk := range slices.Chunk(initOrder, maxInitStatements) {
  3723  		initFuncs = append(initFuncs, r.generateVarInitFunc(chunk))
  3724  	}
  3725  	return initFuncs
  3726  }
  3727  
  3728  func (r *reader) pkgDecls(target *ir.Package) {
  3729  	r.Sync(pkgbits.SyncDecls)
  3730  	for {
  3731  		switch code := codeDecl(r.Code(pkgbits.SyncDecl)); code {
  3732  		default:
  3733  			panic(fmt.Sprintf("unhandled decl: %v", code))
  3734  
  3735  		case declEnd:
  3736  			return
  3737  
  3738  		case declFunc:
  3739  			names := r.pkgObjs(target)
  3740  			assert(len(names) == 1)
  3741  			target.Funcs = append(target.Funcs, names[0].Func)
  3742  
  3743  		case declMethod:
  3744  			typ := r.typ()
  3745  			sym := r.selector()
  3746  
  3747  			method := typecheck.Lookdot1(nil, sym, typ, typ.Methods(), 0)
  3748  			target.Funcs = append(target.Funcs, method.Nname.(*ir.Name).Func)
  3749  
  3750  		case declVar:
  3751  			names := r.pkgObjs(target)
  3752  
  3753  			if n := r.Len(); n > 0 {
  3754  				assert(len(names) == 1)
  3755  				embeds := make([]ir.Embed, n)
  3756  				for i := range embeds {
  3757  					embeds[i] = ir.Embed{Pos: r.pos(), Patterns: r.Strings()}
  3758  				}
  3759  				names[0].Embed = &embeds
  3760  				target.Embeds = append(target.Embeds, names[0])
  3761  			}
  3762  
  3763  		case declOther:
  3764  			r.pkgObjs(target)
  3765  		}
  3766  	}
  3767  }
  3768  
  3769  func (r *reader) pkgObjs(target *ir.Package) []*ir.Name {
  3770  	r.Sync(pkgbits.SyncDeclNames)
  3771  	nodes := make([]*ir.Name, r.Len())
  3772  	for i := range nodes {
  3773  		r.Sync(pkgbits.SyncDeclName)
  3774  
  3775  		name := r.obj().(*ir.Name)
  3776  		nodes[i] = name
  3777  
  3778  		sym := name.Sym()
  3779  		if sym.IsBlank() {
  3780  			continue
  3781  		}
  3782  
  3783  		switch name.Class {
  3784  		default:
  3785  			base.FatalfAt(name.Pos(), "unexpected class: %v", name.Class)
  3786  
  3787  		case ir.PEXTERN:
  3788  			target.Externs = append(target.Externs, name)
  3789  
  3790  		case ir.PFUNC:
  3791  			assert(name.Type().Recv() == nil)
  3792  
  3793  			// TODO(mdempsky): Cleaner way to recognize init?
  3794  			if strings.HasPrefix(sym.Name, "init.") {
  3795  				target.Inits = append(target.Inits, name.Func)
  3796  			}
  3797  		}
  3798  
  3799  		if base.Ctxt.Flag_dynlink && types.LocalPkg.Name == "main" && types.IsExported(sym.Name) && name.Op() == ir.ONAME {
  3800  			assert(!sym.OnExportList())
  3801  			target.PluginExports = append(target.PluginExports, name)
  3802  			sym.SetOnExportList(true)
  3803  		}
  3804  
  3805  		if base.Flag.AsmHdr != "" && (name.Op() == ir.OLITERAL || name.Op() == ir.OTYPE) {
  3806  			assert(!sym.Asm())
  3807  			target.AsmHdrDecls = append(target.AsmHdrDecls, name)
  3808  			sym.SetAsm(true)
  3809  		}
  3810  	}
  3811  
  3812  	return nodes
  3813  }
  3814  
  3815  // @@@ Inlining
  3816  
  3817  // unifiedHaveInlineBody reports whether we have the function body for
  3818  // fn, so we can inline it.
  3819  func unifiedHaveInlineBody(fn *ir.Func) bool {
  3820  	if fn.Inl == nil {
  3821  		return false
  3822  	}
  3823  
  3824  	_, ok := bodyReaderFor(fn)
  3825  	return ok
  3826  }
  3827  
  3828  var inlgen = 0
  3829  
  3830  // unifiedInlineCall implements inline.NewInline by re-reading the function
  3831  // body from its Unified IR export data.
  3832  func unifiedInlineCall(callerfn *ir.Func, call *ir.CallExpr, fn *ir.Func, inlIndex int, profile *pgoir.Profile) *ir.InlinedCallExpr {
  3833  	pri, ok := bodyReaderFor(fn)
  3834  	if !ok {
  3835  		base.FatalfAt(call.Pos(), "cannot inline call to %v: missing inline body", fn)
  3836  	}
  3837  
  3838  	if !fn.Inl.HaveDcl {
  3839  		expandInline(fn, pri)
  3840  	}
  3841  
  3842  	r := pri.asReader(pkgbits.SectionBody, pkgbits.SyncFuncBody)
  3843  
  3844  	tmpfn := ir.NewFunc(fn.Pos(), fn.Nname.Pos(), callerfn.Sym(), fn.Type())
  3845  
  3846  	r.curfn = tmpfn
  3847  
  3848  	r.inlCaller = callerfn
  3849  	r.inlCall = call
  3850  	r.inlFunc = fn
  3851  	r.inlTreeIndex = inlIndex
  3852  	r.inlPosBases = make(map[*src.PosBase]*src.PosBase)
  3853  	r.funarghack = true
  3854  
  3855  	r.closureVars = make([]*ir.Name, len(r.inlFunc.ClosureVars))
  3856  	for i, cv := range r.inlFunc.ClosureVars {
  3857  		// TODO(mdempsky): It should be possible to support this case, but
  3858  		// for now we rely on the inliner avoiding it.
  3859  		if cv.Outer.Curfn != callerfn {
  3860  			base.FatalfAt(call.Pos(), "inlining closure call across frames")
  3861  		}
  3862  		r.closureVars[i] = cv.Outer
  3863  	}
  3864  	if len(r.closureVars) != 0 && r.hasTypeParams() {
  3865  		r.dictParam = r.closureVars[len(r.closureVars)-1] // dictParam is last; see reader.funcLit
  3866  	}
  3867  
  3868  	r.declareParams()
  3869  
  3870  	var inlvars, retvars []*ir.Name
  3871  	{
  3872  		sig := r.curfn.Type()
  3873  		endParams := sig.NumRecvs() + sig.NumParams()
  3874  		endResults := endParams + sig.NumResults()
  3875  
  3876  		inlvars = r.curfn.Dcl[:endParams]
  3877  		retvars = r.curfn.Dcl[endParams:endResults]
  3878  	}
  3879  
  3880  	r.delayResults = fn.Inl.CanDelayResults
  3881  
  3882  	r.retlabel = typecheck.AutoLabel(callerfn, ".i")
  3883  	inlgen++
  3884  
  3885  	init := ir.TakeInit(call)
  3886  
  3887  	// For normal function calls, the function callee expression
  3888  	// may contain side effects. Make sure to preserve these,
  3889  	// if necessary (#42703).
  3890  	if call.Op() == ir.OCALLFUNC {
  3891  		inline.CalleeEffects(&init, call.Fun)
  3892  	}
  3893  
  3894  	var args ir.Nodes
  3895  	if call.Op() == ir.OCALLMETH {
  3896  		base.FatalfAt(call.Pos(), "OCALLMETH missed by typecheck")
  3897  	}
  3898  	args.Append(call.Args...)
  3899  
  3900  	// Create assignment to declare and initialize inlvars.
  3901  	as2 := ir.NewAssignListStmt(call.Pos(), ir.OAS2, ir.ToNodes(inlvars), args)
  3902  	as2.Def = true
  3903  	var as2init ir.Nodes
  3904  	for _, name := range inlvars {
  3905  		if ir.IsBlank(name) {
  3906  			continue
  3907  		}
  3908  		// TODO(mdempsky): Use inlined position of name.Pos() instead?
  3909  		as2init.Append(ir.NewDecl(call.Pos(), ir.ODCL, name))
  3910  		name.Defn = as2
  3911  	}
  3912  	as2.SetInit(as2init)
  3913  	init.Append(typecheck.Stmt(callerfn, as2))
  3914  
  3915  	if !r.delayResults {
  3916  		// If not delaying retvars, declare and zero initialize the
  3917  		// result variables now.
  3918  		for _, name := range retvars {
  3919  			// TODO(mdempsky): Use inlined position of name.Pos() instead?
  3920  			init.Append(ir.NewDecl(call.Pos(), ir.ODCL, name))
  3921  			ras := ir.NewAssignStmt(call.Pos(), name, nil)
  3922  			init.Append(typecheck.Stmt(callerfn, ras))
  3923  		}
  3924  	}
  3925  
  3926  	// Add an inline mark just before the inlined body.
  3927  	// This mark is inline in the code so that it's a reasonable spot
  3928  	// to put a breakpoint. Not sure if that's really necessary or not
  3929  	// (in which case it could go at the end of the function instead).
  3930  	// Note issue 28603.
  3931  	init.Append(ir.NewInlineMarkStmt(call.Pos().WithIsStmt(), int64(r.inlTreeIndex)))
  3932  
  3933  	ir.WithPos(r.curfn, func() {
  3934  		if !r.syntheticBody(call.Pos()) {
  3935  			assert(r.Bool()) // have body
  3936  
  3937  			r.curfn.Body = r.stmts()
  3938  			r.curfn.Endlineno = r.pos()
  3939  		}
  3940  
  3941  		// TODO(mdempsky): This shouldn't be necessary. Inlining might
  3942  		// read in new function/method declarations, which could
  3943  		// potentially be recursively inlined themselves; but we shouldn't
  3944  		// need to read in the non-inlined bodies for the declarations
  3945  		// themselves. But currently it's an easy fix to #50552.
  3946  		readBodies(typecheck.Target, true, profile)
  3947  
  3948  		// Replace any "return" statements within the function body.
  3949  		var edit func(ir.Node) ir.Node
  3950  		edit = func(n ir.Node) ir.Node {
  3951  			if ret, ok := n.(*ir.ReturnStmt); ok {
  3952  				n = typecheck.Stmt(callerfn, r.inlReturn(ret, retvars))
  3953  			}
  3954  			ir.EditChildren(n, edit)
  3955  			return n
  3956  		}
  3957  		edit(r.curfn)
  3958  	})
  3959  
  3960  	body := r.curfn.Body
  3961  
  3962  	// Reparent any declarations into the caller function.
  3963  	for _, name := range r.curfn.Dcl {
  3964  		name.Curfn = callerfn
  3965  
  3966  		if name.Class != ir.PAUTO {
  3967  			name.SetPos(r.inlPos(name.Pos()))
  3968  			name.SetInlFormal(true)
  3969  			name.Class = ir.PAUTO
  3970  		} else {
  3971  			name.SetInlLocal(true)
  3972  		}
  3973  	}
  3974  	callerfn.Dcl = append(callerfn.Dcl, r.curfn.Dcl...)
  3975  
  3976  	body.Append(ir.NewLabelStmt(call.Pos(), r.retlabel))
  3977  
  3978  	res := ir.NewInlinedCallExpr(call.Pos(), body, ir.ToNodes(retvars))
  3979  	res.SetInit(init)
  3980  	res.SetType(call.Type())
  3981  	res.SetTypecheck(1)
  3982  	res.Reshape = call.Reshape
  3983  
  3984  	// Inlining shouldn't add any functions to todoBodies.
  3985  	assert(len(todoBodies) == 0)
  3986  
  3987  	return res
  3988  }
  3989  
  3990  // inlReturn returns a statement that can substitute for the given
  3991  // return statement when inlining.
  3992  func (r *reader) inlReturn(ret *ir.ReturnStmt, retvars []*ir.Name) *ir.BlockStmt {
  3993  	pos := r.inlCall.Pos()
  3994  
  3995  	block := ir.TakeInit(ret)
  3996  
  3997  	if results := ret.Results; len(results) != 0 {
  3998  		assert(len(retvars) == len(results))
  3999  
  4000  		as2 := ir.NewAssignListStmt(pos, ir.OAS2, ir.ToNodes(retvars), ret.Results)
  4001  
  4002  		if r.delayResults {
  4003  			for _, name := range retvars {
  4004  				// TODO(mdempsky): Use inlined position of name.Pos() instead?
  4005  				block.Append(ir.NewDecl(pos, ir.ODCL, name))
  4006  				name.Defn = as2
  4007  			}
  4008  		}
  4009  
  4010  		block.Append(as2)
  4011  	}
  4012  
  4013  	block.Append(ir.NewBranchStmt(pos, ir.OGOTO, r.retlabel))
  4014  	return ir.NewBlockStmt(pos, block)
  4015  }
  4016  
  4017  // expandInline reads in an extra copy of IR to populate
  4018  // fn.Inl.Dcl.
  4019  func expandInline(fn *ir.Func, pri pkgReaderIndex) {
  4020  	// TODO(mdempsky): Remove this function. It's currently needed by
  4021  	// dwarfgen/dwarf.go:preInliningDcls, which requires fn.Inl.Dcl to
  4022  	// create abstract function DIEs. But we should be able to provide it
  4023  	// with the same information some other way.
  4024  
  4025  	fndcls := len(fn.Dcl)
  4026  	topdcls := len(typecheck.Target.Funcs)
  4027  
  4028  	tmpfn := ir.NewFunc(fn.Pos(), fn.Nname.Pos(), fn.Sym(), fn.Type())
  4029  	tmpfn.ClosureVars = fn.ClosureVars
  4030  
  4031  	{
  4032  		r := pri.asReader(pkgbits.SectionBody, pkgbits.SyncFuncBody)
  4033  
  4034  		// Don't change parameter's Sym/Nname fields.
  4035  		r.funarghack = true
  4036  
  4037  		r.funcBody(tmpfn)
  4038  	}
  4039  
  4040  	// Move tmpfn's params to fn.Inl.Dcl, and reparent under fn.
  4041  	for _, name := range tmpfn.Dcl {
  4042  		name.Curfn = fn
  4043  	}
  4044  	fn.Inl.Dcl = tmpfn.Dcl
  4045  	fn.Inl.HaveDcl = true
  4046  
  4047  	// Double check that we didn't change fn.Dcl by accident.
  4048  	assert(fndcls == len(fn.Dcl))
  4049  
  4050  	// typecheck.Stmts may have added function literals to
  4051  	// typecheck.Target.Decls. Remove them again so we don't risk trying
  4052  	// to compile them multiple times.
  4053  	typecheck.Target.Funcs = typecheck.Target.Funcs[:topdcls]
  4054  }
  4055  
  4056  // @@@ Method wrappers
  4057  //
  4058  // Here we handle constructing "method wrappers," alternative entry
  4059  // points that adapt methods to different calling conventions. Given a
  4060  // user-declared method "func (T) M(i int) bool { ... }", there are a
  4061  // few wrappers we may need to construct:
  4062  //
  4063  //	- Implicit dereferencing. Methods declared with a value receiver T
  4064  //	  are also included in the method set of the pointer type *T, so
  4065  //	  we need to construct a wrapper like "func (recv *T) M(i int)
  4066  //	  bool { return (*recv).M(i) }".
  4067  //
  4068  //	- Promoted methods. If struct type U contains an embedded field of
  4069  //	  type T or *T, we need to construct a wrapper like "func (recv U)
  4070  //	  M(i int) bool { return recv.T.M(i) }".
  4071  //
  4072  //	- Method values. If x is an expression of type T, then "x.M" is
  4073  //	  roughly "tmp := x; func(i int) bool { return tmp.M(i) }".
  4074  //
  4075  // At call sites, we always prefer to call the user-declared method
  4076  // directly, if known, so wrappers are only needed for indirect calls
  4077  // (for example, interface method calls that can't be devirtualized).
  4078  // Consequently, we can save some compile time by skipping
  4079  // construction of wrappers that are never needed.
  4080  //
  4081  // Alternatively, because the linker doesn't care which compilation
  4082  // unit constructed a particular wrapper, we can instead construct
  4083  // them as needed. However, if a wrapper is needed in multiple
  4084  // downstream packages, we may end up needing to compile it multiple
  4085  // times, costing us more compile time and object file size. (We mark
  4086  // the wrappers as DUPOK, so the linker doesn't complain about the
  4087  // duplicate symbols.)
  4088  //
  4089  // The current heuristics we use to balance these trade offs are:
  4090  //
  4091  //	- For a (non-parameterized) defined type T, we construct wrappers
  4092  //	  for *T and any promoted methods on T (and *T) in the same
  4093  //	  compilation unit as the type declaration.
  4094  //
  4095  //	- For a parameterized defined type, we construct wrappers in the
  4096  //	  compilation units in which the type is instantiated. We
  4097  //	  similarly handle wrappers for anonymous types with methods and
  4098  //	  compilation units where their type literals appear in source.
  4099  //
  4100  //	- Method value expressions are relatively uncommon, so we
  4101  //	  construct their wrappers in the compilation units that they
  4102  //	  appear in.
  4103  //
  4104  // Finally, as an opportunistic compile-time optimization, if we know
  4105  // a wrapper was constructed in any imported package's compilation
  4106  // unit, then we skip constructing a duplicate one. However, currently
  4107  // this is only done on a best-effort basis.
  4108  
  4109  // needWrapperTypes lists types for which we may need to generate
  4110  // method wrappers.
  4111  var needWrapperTypes []*types.Type
  4112  
  4113  // haveWrapperTypes lists types for which we know we already have
  4114  // method wrappers, because we found the type in an imported package.
  4115  var haveWrapperTypes []*types.Type
  4116  
  4117  // needMethodValueWrappers lists methods for which we may need to
  4118  // generate method value wrappers.
  4119  var needMethodValueWrappers []methodValueWrapper
  4120  
  4121  // haveMethodValueWrappers lists methods for which we know we already
  4122  // have method value wrappers, because we found it in an imported
  4123  // package.
  4124  var haveMethodValueWrappers []methodValueWrapper
  4125  
  4126  type methodValueWrapper struct {
  4127  	rcvr   *types.Type
  4128  	method *types.Field
  4129  }
  4130  
  4131  // needWrapper records that wrapper methods may be needed at link
  4132  // time.
  4133  func (r *reader) needWrapper(typ *types.Type) {
  4134  	if typ.IsPtr() || typ.IsKind(types.TFORW) {
  4135  		return
  4136  	}
  4137  
  4138  	// Special case: runtime must define error even if imported packages mention it (#29304).
  4139  	forceNeed := typ == types.ErrorType && base.Ctxt.Pkgpath == "runtime"
  4140  
  4141  	// If a type was found in an imported package, then we can assume
  4142  	// that package (or one of its transitive dependencies) already
  4143  	// generated method wrappers for it.
  4144  	if r.importedDef() && !forceNeed {
  4145  		haveWrapperTypes = append(haveWrapperTypes, typ)
  4146  	} else {
  4147  		needWrapperTypes = append(needWrapperTypes, typ)
  4148  	}
  4149  }
  4150  
  4151  // importedDef reports whether r is reading from an imported and
  4152  // non-generic element.
  4153  //
  4154  // If a type was found in an imported package, then we can assume that
  4155  // package (or one of its transitive dependencies) already generated
  4156  // method wrappers for it.
  4157  //
  4158  // Exception: If we're instantiating an imported generic type or
  4159  // function, we might be instantiating it with type arguments not
  4160  // previously seen before.
  4161  //
  4162  // TODO(mdempsky): Distinguish when a generic function or type was
  4163  // instantiated in an imported package so that we can add types to
  4164  // haveWrapperTypes instead.
  4165  func (r *reader) importedDef() bool {
  4166  	return r.p != localPkgReader && !r.hasTypeParams()
  4167  }
  4168  
  4169  // MakeWrappers constructs all wrapper methods needed for the target
  4170  // compilation unit.
  4171  func MakeWrappers(target *ir.Package) {
  4172  	// always generate a wrapper for error.Error (#29304)
  4173  	needWrapperTypes = append(needWrapperTypes, types.ErrorType)
  4174  
  4175  	seen := make(map[string]*types.Type)
  4176  
  4177  	for _, typ := range haveWrapperTypes {
  4178  		wrapType(typ, target, seen, false)
  4179  	}
  4180  	haveWrapperTypes = nil
  4181  
  4182  	for _, typ := range needWrapperTypes {
  4183  		wrapType(typ, target, seen, true)
  4184  	}
  4185  	needWrapperTypes = nil
  4186  
  4187  	for _, wrapper := range haveMethodValueWrappers {
  4188  		wrapMethodValue(wrapper.rcvr, wrapper.method, target, false)
  4189  	}
  4190  	haveMethodValueWrappers = nil
  4191  
  4192  	for _, wrapper := range needMethodValueWrappers {
  4193  		wrapMethodValue(wrapper.rcvr, wrapper.method, target, true)
  4194  	}
  4195  	needMethodValueWrappers = nil
  4196  }
  4197  
  4198  func wrapType(typ *types.Type, target *ir.Package, seen map[string]*types.Type, needed bool) {
  4199  	key := typ.LinkString()
  4200  	if prev := seen[key]; prev != nil {
  4201  		if !types.Identical(typ, prev) {
  4202  			base.Fatalf("collision: types %v and %v have link string %q", typ, prev, key)
  4203  		}
  4204  		// Wrapper generation is shared by structurally identical types.
  4205  		// Share the cached TFlag too, without computing duplicate method sets.
  4206  		typ.CopyTFlagFrom(prev)
  4207  		return
  4208  	}
  4209  	seen[key] = typ
  4210  
  4211  	if !needed {
  4212  		// Only called to add to 'seen'.
  4213  		return
  4214  	}
  4215  
  4216  	if !typ.IsInterface() {
  4217  		typecheck.CalcMethods(typ)
  4218  	}
  4219  	if !typ.IsUntyped() {
  4220  		typ.TFlag()
  4221  	}
  4222  	for _, meth := range typ.AllMethods() {
  4223  		if meth.Sym.IsBlank() || !meth.IsMethod() {
  4224  			base.FatalfAt(meth.Pos, "invalid method: %v", meth)
  4225  		}
  4226  
  4227  		methodWrapper(0, typ, meth, target)
  4228  
  4229  		// For non-interface types, we also want *T wrappers.
  4230  		if !typ.IsInterface() {
  4231  			methodWrapper(1, typ, meth, target)
  4232  
  4233  			// For not-in-heap types, *T is a scalar, not pointer shaped,
  4234  			// so the interface wrappers use **T.
  4235  			if typ.NotInHeap() {
  4236  				methodWrapper(2, typ, meth, target)
  4237  			}
  4238  		}
  4239  	}
  4240  }
  4241  
  4242  func methodWrapper(derefs int, tbase *types.Type, method *types.Field, target *ir.Package) {
  4243  	wrapper := tbase
  4244  	for i := 0; i < derefs; i++ {
  4245  		wrapper = types.NewPtr(wrapper)
  4246  	}
  4247  
  4248  	wrappee := method.Type.Recv().Type
  4249  	if types.Identical(wrapper, wrappee) ||
  4250  		!types.IsMethodApplicable(wrapper, method) ||
  4251  		!reflectdata.NeedEmit(tbase) {
  4252  		return
  4253  	}
  4254  	sym, sharedPromoted := ir.MethodSym(wrapper, method)
  4255  	if sym.Siggen() {
  4256  		if sharedPromoted {
  4257  			return
  4258  		}
  4259  		base.Fatalf("already generated wrapper %v", sym)
  4260  	}
  4261  	sym.SetSiggen(true)
  4262  
  4263  	// TODO(mdempsky): Use method.Pos instead?
  4264  	pos := base.AutogeneratedPos
  4265  
  4266  	fn := newWrapperFunc(pos, sym, wrapper, method)
  4267  
  4268  	var recv ir.Node = fn.Nname.Type().Recv().Nname.(*ir.Name)
  4269  
  4270  	// For simple *T wrappers around T methods, panicwrap produces a
  4271  	// nicer panic message.
  4272  	if wrapper.IsPtr() && types.Identical(wrapper.Elem(), wrappee) {
  4273  		cond := ir.NewBinaryExpr(pos, ir.OEQ, recv, types.BuiltinPkg.Lookup("nil").Def.(ir.Node))
  4274  		then := []ir.Node{ir.NewCallExpr(pos, ir.OCALL, typecheck.LookupRuntime("panicwrap"), nil)}
  4275  		fn.Body.Append(ir.NewIfStmt(pos, cond, then, nil))
  4276  	}
  4277  
  4278  	// typecheck will add one implicit deref, if necessary,
  4279  	// but not-in-heap types require more for their **T wrappers.
  4280  	for i := 1; i < derefs; i++ {
  4281  		recv = Implicit(ir.NewStarExpr(pos, recv))
  4282  	}
  4283  
  4284  	addTailCall(pos, fn, recv, method)
  4285  
  4286  	finishWrapperFunc(fn, target)
  4287  }
  4288  
  4289  func wrapMethodValue(recvType *types.Type, method *types.Field, target *ir.Package, needed bool) {
  4290  	sym := ir.ReceiverMethodSymSuffix(recvType, method.Sym, "-fm")
  4291  	if sym.Uniq() {
  4292  		return
  4293  	}
  4294  	sym.SetUniq(true)
  4295  
  4296  	// TODO(mdempsky): Use method.Pos instead?
  4297  	pos := base.AutogeneratedPos
  4298  
  4299  	fn := newWrapperFunc(pos, sym, nil, method)
  4300  	sym.Def = fn.Nname
  4301  
  4302  	// Declare and initialize variable holding receiver.
  4303  	recv := ir.NewHiddenParam(pos, fn, typecheck.Lookup(".this"), recvType)
  4304  
  4305  	if !needed {
  4306  		return
  4307  	}
  4308  
  4309  	addTailCall(pos, fn, recv, method)
  4310  
  4311  	finishWrapperFunc(fn, target)
  4312  }
  4313  
  4314  func newWrapperFunc(pos src.XPos, sym *types.Sym, wrapper *types.Type, method *types.Field) *ir.Func {
  4315  	sig := newWrapperType(wrapper, method)
  4316  	fn := ir.NewFunc(pos, pos, sym, sig)
  4317  	fn.DeclareParams(true)
  4318  	fn.SetDupok(true) // TODO(mdempsky): Leave unset for local, non-generic wrappers?
  4319  
  4320  	return fn
  4321  }
  4322  
  4323  func finishWrapperFunc(fn *ir.Func, target *ir.Package) {
  4324  	ir.WithPos(fn, func() {
  4325  		typecheck.Stmts(fn, fn.Body)
  4326  	})
  4327  
  4328  	// We generate wrappers after the global inlining pass,
  4329  	// so we're responsible for applying inlining ourselves here.
  4330  	// TODO(prattmic): plumb PGO.
  4331  	interleaved.DevirtualizeAndInlineFunc(fn, nil)
  4332  
  4333  	// The body of wrapper function after inlining may reveal new ir.OMETHVALUE node,
  4334  	// we don't know whether wrapper function has been generated for it or not, so
  4335  	// generate one immediately here.
  4336  	//
  4337  	// Further, after CL 492017, function that construct closures is allowed to be inlined,
  4338  	// even though the closure itself can't be inline. So we also need to visit body of any
  4339  	// closure that we see when visiting body of the wrapper function.
  4340  	ir.VisitFuncAndClosures(fn, func(n ir.Node) {
  4341  		if n, ok := n.(*ir.SelectorExpr); ok && n.Op() == ir.OMETHVALUE {
  4342  			wrapMethodValue(n.X.Type(), n.Selection, target, true)
  4343  		}
  4344  	})
  4345  
  4346  	fn.Nname.Defn = fn
  4347  	target.Funcs = append(target.Funcs, fn)
  4348  }
  4349  
  4350  // newWrapperType returns a copy of the given signature type, but with
  4351  // the receiver parameter type substituted with recvType.
  4352  // If recvType is nil, newWrapperType returns a signature
  4353  // without a receiver parameter.
  4354  func newWrapperType(recvType *types.Type, method *types.Field) *types.Type {
  4355  	clone := func(params []*types.Field) []*types.Field {
  4356  		res := make([]*types.Field, len(params))
  4357  		for i, param := range params {
  4358  			res[i] = types.NewField(param.Pos, param.Sym, param.Type)
  4359  			res[i].SetIsDDD(param.IsDDD())
  4360  		}
  4361  		return res
  4362  	}
  4363  
  4364  	sig := method.Type
  4365  
  4366  	var recv *types.Field
  4367  	if recvType != nil {
  4368  		recv = types.NewField(sig.Recv().Pos, sig.Recv().Sym, recvType)
  4369  	}
  4370  	params := clone(sig.Params())
  4371  	results := clone(sig.Results())
  4372  
  4373  	return types.NewSignature(recv, params, results)
  4374  }
  4375  
  4376  func addTailCall(pos src.XPos, fn *ir.Func, recv ir.Node, method *types.Field) {
  4377  	sig := fn.Nname.Type()
  4378  	args := make([]ir.Node, sig.NumParams())
  4379  	for i, param := range sig.Params() {
  4380  		args[i] = param.Nname.(*ir.Name)
  4381  	}
  4382  
  4383  	dot := typecheck.XDotMethod(fn, pos, recv, method.Sym, true)
  4384  	call := typecheck.Call(fn, pos, dot, args, method.Type.IsVariadic()).(*ir.CallExpr)
  4385  
  4386  	if recv.Type() != nil && recv.Type().IsPtr() && method.Type.Recv().Type.IsPtr() &&
  4387  		method.Embedded != 0 &&
  4388  		(types.IsInterfaceMethod(method.Type) && base.Ctxt.Arch.Name != "wasm" ||
  4389  			!types.IsInterfaceMethod(method.Type) && !unifiedHaveInlineBody(ir.MethodExprName(dot).Func)) &&
  4390  		// TODO: implement wasm indirect tail calls
  4391  		// TODO: do we need the ppc64le/dynlink restriction for interface tail calls?
  4392  		!((base.Ctxt.Arch.Name == "ppc64le" || base.Ctxt.Arch.Name == "ppc64") && base.Ctxt.Flag_dynlink) {
  4393  		if base.Debug.TailCall != 0 {
  4394  			base.WarnfAt(fn.Nname.Type().Recv().Type.Elem().Pos(), "tail call emitted for the method %v wrapper", method.Nname)
  4395  		}
  4396  		// Prefer OTAILCALL to reduce code size (except the case when the called method can be inlined).
  4397  		fn.Body.Append(ir.NewTailCallStmt(pos, call))
  4398  		return
  4399  	}
  4400  
  4401  	fn.SetWrapper(true)
  4402  
  4403  	if method.Type.NumResults() == 0 {
  4404  		fn.Body.Append(call)
  4405  		return
  4406  	}
  4407  
  4408  	ret := ir.NewReturnStmt(pos, nil)
  4409  	ret.Results = []ir.Node{call}
  4410  	fn.Body.Append(ret)
  4411  }
  4412  
  4413  func setBasePos(pos src.XPos) {
  4414  	// Set the position for any error messages we might print (e.g. too large types).
  4415  	base.Pos = pos
  4416  }
  4417  
  4418  // dictParamName is the name of the synthetic dictionary parameter
  4419  // added to shaped functions.
  4420  //
  4421  // N.B., this variable name is known to Delve:
  4422  // https://github.com/go-delve/delve/blob/cb91509630529e6055be845688fd21eb89ae8714/pkg/proc/eval.go#L28
  4423  const dictParamName = typecheck.LocalDictName
  4424  
  4425  // shapeSig returns a copy of fn's signature, except adding a
  4426  // dictionary parameter and promoting the receiver parameter (if any)
  4427  // to a normal parameter.
  4428  //
  4429  // The parameter types.Fields are all copied too, so their Nname
  4430  // fields can be initialized for use by the shape function.
  4431  //
  4432  // All signatures returned by shapeSig are marked as shaped.
  4433  func shapeSig(fn *ir.Func, dict *readerDict) *types.Type {
  4434  	sig := fn.Nname.Type()
  4435  	oldRecv := sig.Recv()
  4436  
  4437  	var recv *types.Field
  4438  	if oldRecv != nil {
  4439  		recv = types.NewField(oldRecv.Pos, oldRecv.Sym, oldRecv.Type)
  4440  	}
  4441  
  4442  	params := make([]*types.Field, 1+sig.NumParams())
  4443  	params[0] = types.NewField(fn.Pos(), fn.Sym().Pkg.Lookup(dictParamName), types.NewPtr(dict.varType()))
  4444  	for i, param := range sig.Params() {
  4445  		d := types.NewField(param.Pos, param.Sym, param.Type)
  4446  		d.SetIsDDD(param.IsDDD())
  4447  		params[1+i] = d
  4448  	}
  4449  
  4450  	results := make([]*types.Field, sig.NumResults())
  4451  	for i, result := range sig.Results() {
  4452  		results[i] = types.NewField(result.Pos, result.Sym, result.Type)
  4453  	}
  4454  
  4455  	typ := types.NewSignature(recv, params, results)
  4456  	typ.SetHasShape(true)
  4457  	return typ
  4458  }
  4459  

View as plain text