1  
     2  
     3  
     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  	"strings"
    15  
    16  	"cmd/compile/internal/base"
    17  	"cmd/compile/internal/dwarfgen"
    18  	"cmd/compile/internal/inline"
    19  	"cmd/compile/internal/inline/interleaved"
    20  	"cmd/compile/internal/ir"
    21  	"cmd/compile/internal/objw"
    22  	"cmd/compile/internal/reflectdata"
    23  	"cmd/compile/internal/staticinit"
    24  	"cmd/compile/internal/typecheck"
    25  	"cmd/compile/internal/types"
    26  	"cmd/internal/hash"
    27  	"cmd/internal/obj"
    28  	"cmd/internal/objabi"
    29  	"cmd/internal/src"
    30  )
    31  
    32  
    33  
    34  
    35  
    36  type pkgReader struct {
    37  	pkgbits.PkgDecoder
    38  
    39  	
    40  	
    41  	
    42  	
    43  
    44  	posBases []*src.PosBase
    45  	pkgs     []*types.Pkg
    46  	typs     []*types.Type
    47  
    48  	
    49  	
    50  	
    51  	newindex []index
    52  
    53  	
    54  	reshaping bool
    55  }
    56  
    57  func newPkgReader(pr pkgbits.PkgDecoder) *pkgReader {
    58  	return &pkgReader{
    59  		PkgDecoder: pr,
    60  
    61  		posBases: make([]*src.PosBase, pr.NumElems(pkgbits.SectionPosBase)),
    62  		pkgs:     make([]*types.Pkg, pr.NumElems(pkgbits.SectionPkg)),
    63  		typs:     make([]*types.Type, pr.NumElems(pkgbits.SectionType)),
    64  
    65  		newindex: make([]index, pr.TotalElems()),
    66  	}
    67  }
    68  
    69  
    70  
    71  type pkgReaderIndex struct {
    72  	pr        *pkgReader
    73  	idx       index
    74  	dict      *readerDict
    75  	methodSym *types.Sym
    76  
    77  	synthetic func(pos src.XPos, r *reader)
    78  }
    79  
    80  func (pri pkgReaderIndex) asReader(k pkgbits.SectionKind, marker pkgbits.SyncMarker) *reader {
    81  	if pri.synthetic != nil {
    82  		return &reader{synthetic: pri.synthetic}
    83  	}
    84  
    85  	r := pri.pr.newReader(k, pri.idx, marker)
    86  	r.dict = pri.dict
    87  	r.methodSym = pri.methodSym
    88  	return r
    89  }
    90  
    91  func (pr *pkgReader) newReader(k pkgbits.SectionKind, idx index, marker pkgbits.SyncMarker) *reader {
    92  	return &reader{
    93  		Decoder: pr.NewDecoder(k, idx, marker),
    94  		p:       pr,
    95  	}
    96  }
    97  
    98  
    99  type reader struct {
   100  	pkgbits.Decoder
   101  
   102  	p *pkgReader
   103  
   104  	dict *readerDict
   105  
   106  	
   107  	
   108  	
   109  	
   110  
   111  	curfn       *ir.Func
   112  	locals      []*ir.Name
   113  	closureVars []*ir.Name
   114  
   115  	
   116  	
   117  	
   118  	
   119  	
   120  	funarghack bool
   121  
   122  	
   123  	
   124  	reshaping bool
   125  
   126  	
   127  	
   128  	methodSym *types.Sym
   129  
   130  	
   131  	dictParam *ir.Name
   132  
   133  	
   134  	
   135  	
   136  	synthetic func(pos src.XPos, r *reader)
   137  
   138  	
   139  	
   140  	scopeVars         []int
   141  	marker            dwarfgen.ScopeMarker
   142  	lastCloseScopePos src.XPos
   143  
   144  	
   145  
   146  	
   147  	
   148  	inlCaller    *ir.Func
   149  	inlCall      *ir.CallExpr
   150  	inlFunc      *ir.Func
   151  	inlTreeIndex int
   152  	inlPosBases  map[*src.PosBase]*src.PosBase
   153  
   154  	
   155  	
   156  	suppressInlPos int
   157  
   158  	delayResults bool
   159  
   160  	
   161  	retlabel *types.Sym
   162  }
   163  
   164  
   165  
   166  
   167  
   168  
   169  
   170  
   171  
   172  
   173  type readerDict struct {
   174  	shaped bool 
   175  
   176  	
   177  	
   178  	
   179  	baseSym *types.Sym
   180  
   181  	
   182  	
   183  	shapedObj *ir.Name
   184  
   185  	
   186  	
   187  	
   188  	
   189  	
   190  	
   191  	
   192  	
   193  	
   194  	
   195  	
   196  	
   197  	
   198  	
   199  	
   200  	
   201  	
   202  	
   203  	targs []*types.Type
   204  
   205  	
   206  	
   207  	implicits int
   208  
   209  	derived      []derivedInfo 
   210  	derivedTypes []*types.Type 
   211  
   212  	
   213  	typeParamMethodExprs []readerMethodExprInfo
   214  	subdicts             []objInfo
   215  	rtypes               []typeInfo
   216  	itabs                []itabInfo
   217  }
   218  
   219  type readerMethodExprInfo struct {
   220  	typeParamIdx int
   221  	method       *types.Sym
   222  }
   223  
   224  func setType(n ir.Node, typ *types.Type) {
   225  	n.SetType(typ)
   226  	n.SetTypecheck(1)
   227  }
   228  
   229  func setValue(name *ir.Name, val constant.Value) {
   230  	name.SetVal(val)
   231  	name.Defn = nil
   232  }
   233  
   234  
   235  
   236  
   237  func (r *reader) pos() src.XPos {
   238  	return base.Ctxt.PosTable.XPos(r.pos0())
   239  }
   240  
   241  
   242  
   243  func (r *reader) origPos() (origPos, inlPos src.XPos) {
   244  	r.suppressInlPos++
   245  	origPos = r.pos()
   246  	r.suppressInlPos--
   247  	inlPos = r.inlPos(origPos)
   248  	return
   249  }
   250  
   251  func (r *reader) pos0() src.Pos {
   252  	r.Sync(pkgbits.SyncPos)
   253  	if !r.Bool() {
   254  		return src.NoPos
   255  	}
   256  
   257  	posBase := r.posBase()
   258  	line := r.Uint()
   259  	col := r.Uint()
   260  	return src.MakePos(posBase, line, col)
   261  }
   262  
   263  
   264  func (r *reader) posBase() *src.PosBase {
   265  	return r.inlPosBase(r.p.posBaseIdx(r.Reloc(pkgbits.SectionPosBase)))
   266  }
   267  
   268  
   269  
   270  func (pr *pkgReader) posBaseIdx(idx index) *src.PosBase {
   271  	if b := pr.posBases[idx]; b != nil {
   272  		return b
   273  	}
   274  
   275  	r := pr.newReader(pkgbits.SectionPosBase, idx, pkgbits.SyncPosBase)
   276  	var b *src.PosBase
   277  
   278  	absFilename := r.String()
   279  	filename := absFilename
   280  
   281  	
   282  	
   283  	
   284  	
   285  	
   286  	
   287  	
   288  	
   289  	
   290  	
   291  	
   292  	
   293  	const dollarGOROOT = "$GOROOT"
   294  	if buildcfg.GOROOT != "" && strings.HasPrefix(filename, dollarGOROOT) {
   295  		filename = filepath.FromSlash(buildcfg.GOROOT + filename[len(dollarGOROOT):])
   296  	}
   297  
   298  	if r.Bool() {
   299  		b = src.NewFileBase(filename, absFilename)
   300  	} else {
   301  		pos := r.pos0()
   302  		line := r.Uint()
   303  		col := r.Uint()
   304  		b = src.NewLinePragmaBase(pos, filename, absFilename, line, col)
   305  	}
   306  
   307  	pr.posBases[idx] = b
   308  	return b
   309  }
   310  
   311  
   312  
   313  
   314  func (r *reader) inlPosBase(oldBase *src.PosBase) *src.PosBase {
   315  	if index := oldBase.InliningIndex(); index >= 0 {
   316  		base.Fatalf("oldBase %v already has inlining index %v", oldBase, index)
   317  	}
   318  
   319  	if r.inlCall == nil || r.suppressInlPos != 0 {
   320  		return oldBase
   321  	}
   322  
   323  	if newBase, ok := r.inlPosBases[oldBase]; ok {
   324  		return newBase
   325  	}
   326  
   327  	newBase := src.NewInliningBase(oldBase, r.inlTreeIndex)
   328  	r.inlPosBases[oldBase] = newBase
   329  	return newBase
   330  }
   331  
   332  
   333  
   334  
   335  func (r *reader) inlPos(xpos src.XPos) src.XPos {
   336  	pos := base.Ctxt.PosTable.Pos(xpos)
   337  	pos.SetBase(r.inlPosBase(pos.Base()))
   338  	return base.Ctxt.PosTable.XPos(pos)
   339  }
   340  
   341  
   342  
   343  
   344  func (r *reader) pkg() *types.Pkg {
   345  	r.Sync(pkgbits.SyncPkg)
   346  	return r.p.pkgIdx(r.Reloc(pkgbits.SectionPkg))
   347  }
   348  
   349  
   350  
   351  func (pr *pkgReader) pkgIdx(idx index) *types.Pkg {
   352  	if pkg := pr.pkgs[idx]; pkg != nil {
   353  		return pkg
   354  	}
   355  
   356  	pkg := pr.newReader(pkgbits.SectionPkg, idx, pkgbits.SyncPkgDef).doPkg()
   357  	pr.pkgs[idx] = pkg
   358  	return pkg
   359  }
   360  
   361  
   362  func (r *reader) doPkg() *types.Pkg {
   363  	path := r.String()
   364  	switch path {
   365  	case "":
   366  		path = r.p.PkgPath()
   367  	case "builtin":
   368  		return types.BuiltinPkg
   369  	case "unsafe":
   370  		return types.UnsafePkg
   371  	}
   372  
   373  	name := r.String()
   374  
   375  	pkg := types.NewPkg(path, "")
   376  
   377  	if pkg.Name == "" {
   378  		pkg.Name = name
   379  	} else {
   380  		base.Assertf(pkg.Name == name, "package %q has name %q, but want %q", pkg.Path, pkg.Name, name)
   381  	}
   382  
   383  	return pkg
   384  }
   385  
   386  
   387  
   388  func (r *reader) typ() *types.Type {
   389  	return r.typWrapped(true)
   390  }
   391  
   392  
   393  
   394  func (r *reader) typWrapped(wrapped bool) *types.Type {
   395  	return r.p.typIdx(r.typInfo(), r.dict, wrapped)
   396  }
   397  
   398  func (r *reader) typInfo() typeInfo {
   399  	r.Sync(pkgbits.SyncType)
   400  	if r.Bool() {
   401  		return typeInfo{idx: index(r.Len()), derived: true}
   402  	}
   403  	return typeInfo{idx: r.Reloc(pkgbits.SectionType), derived: false}
   404  }
   405  
   406  
   407  
   408  func (pr *pkgReader) typListIdx(infos []typeInfo, dict *readerDict) []*types.Type {
   409  	typs := make([]*types.Type, len(infos))
   410  	for i, info := range infos {
   411  		typs[i] = pr.typIdx(info, dict, true)
   412  	}
   413  	return typs
   414  }
   415  
   416  
   417  
   418  
   419  func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict, wrapped bool) *types.Type {
   420  	idx := info.idx
   421  	var where **types.Type
   422  	if info.derived {
   423  		where = &dict.derivedTypes[idx]
   424  		idx = dict.derived[idx].idx
   425  	} else {
   426  		where = &pr.typs[idx]
   427  	}
   428  
   429  	if typ := *where; typ != nil {
   430  		return typ
   431  	}
   432  
   433  	r := pr.newReader(pkgbits.SectionType, idx, pkgbits.SyncTypeIdx)
   434  	r.dict = dict
   435  
   436  	typ := r.doTyp()
   437  	if typ == nil {
   438  		base.Fatalf("doTyp returned nil for info=%v", info)
   439  	}
   440  
   441  	
   442  	
   443  	
   444  	
   445  	
   446  	
   447  	
   448  	
   449  	
   450  	
   451  	
   452  	
   453  	
   454  	
   455  	
   456  	
   457  	
   458  	
   459  	
   460  	
   461  	
   462  	
   463  	
   464  	
   465  	
   466  	
   467  	
   468  	
   469  	
   470  	
   471  	
   472  	
   473  	
   474  	
   475  	
   476  	
   477  	
   478  	
   479  	
   480  
   481  	if prev := *where; prev != nil {
   482  		return prev
   483  	}
   484  
   485  	if wrapped {
   486  		
   487  		
   488  		*where = typ
   489  
   490  		r.needWrapper(typ)
   491  	}
   492  
   493  	if !typ.IsUntyped() {
   494  		types.CheckSize(typ)
   495  	}
   496  
   497  	return typ
   498  }
   499  
   500  func (r *reader) doTyp() *types.Type {
   501  	switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
   502  	default:
   503  		panic(fmt.Sprintf("unexpected type: %v", tag))
   504  
   505  	case pkgbits.TypeBasic:
   506  		return *basics[r.Len()]
   507  
   508  	case pkgbits.TypeNamed:
   509  		obj := r.obj()
   510  		assert(obj.Op() == ir.OTYPE)
   511  		return obj.Type()
   512  
   513  	case pkgbits.TypeTypeParam:
   514  		return r.dict.targs[r.Len()]
   515  
   516  	case pkgbits.TypeArray:
   517  		len := int64(r.Uint64())
   518  		return types.NewArray(r.typ(), len)
   519  	case pkgbits.TypeChan:
   520  		dir := dirs[r.Len()]
   521  		return types.NewChan(r.typ(), dir)
   522  	case pkgbits.TypeMap:
   523  		return types.NewMap(r.typ(), r.typ())
   524  	case pkgbits.TypePointer:
   525  		return types.NewPtr(r.typ())
   526  	case pkgbits.TypeSignature:
   527  		return r.signature(nil)
   528  	case pkgbits.TypeSlice:
   529  		return types.NewSlice(r.typ())
   530  	case pkgbits.TypeStruct:
   531  		return r.structType()
   532  	case pkgbits.TypeInterface:
   533  		return r.interfaceType()
   534  	case pkgbits.TypeUnion:
   535  		return r.unionType()
   536  	}
   537  }
   538  
   539  func (r *reader) unionType() *types.Type {
   540  	
   541  	
   542  	
   543  	
   544  	
   545  	
   546  	
   547  	
   548  	
   549  	
   550  	
   551  	
   552  
   553  	
   554  	
   555  	
   556  	
   557  	if false {
   558  		pure := false
   559  		for i, n := 0, r.Len(); i < n; i++ {
   560  			_ = r.Bool() 
   561  			term := r.typ()
   562  			if term.IsEmptyInterface() {
   563  				pure = true
   564  			}
   565  		}
   566  		if !pure {
   567  			base.Fatalf("impure type set used in value type")
   568  		}
   569  	}
   570  
   571  	return types.Types[types.TINTER]
   572  }
   573  
   574  func (r *reader) interfaceType() *types.Type {
   575  	nmethods, nembeddeds := r.Len(), r.Len()
   576  	implicit := nmethods == 0 && nembeddeds == 1 && r.Bool()
   577  	assert(!implicit) 
   578  
   579  	fields := make([]*types.Field, nmethods+nembeddeds)
   580  	methods, embeddeds := fields[:nmethods], fields[nmethods:]
   581  
   582  	for i := range methods {
   583  		methods[i] = types.NewField(r.pos(), r.selector(), r.signature(types.FakeRecv()))
   584  	}
   585  	for i := range embeddeds {
   586  		embeddeds[i] = types.NewField(src.NoXPos, nil, r.typ())
   587  	}
   588  
   589  	if len(fields) == 0 {
   590  		return types.Types[types.TINTER] 
   591  	}
   592  	return types.NewInterface(fields)
   593  }
   594  
   595  func (r *reader) structType() *types.Type {
   596  	fields := make([]*types.Field, r.Len())
   597  	for i := range fields {
   598  		field := types.NewField(r.pos(), r.selector(), r.typ())
   599  		field.Note = r.String()
   600  		if r.Bool() {
   601  			field.Embedded = 1
   602  		}
   603  		fields[i] = field
   604  	}
   605  	return types.NewStruct(fields)
   606  }
   607  
   608  func (r *reader) signature(recv *types.Field) *types.Type {
   609  	r.Sync(pkgbits.SyncSignature)
   610  
   611  	params := r.params()
   612  	results := r.params()
   613  	if r.Bool() { 
   614  		params[len(params)-1].SetIsDDD(true)
   615  	}
   616  
   617  	return types.NewSignature(recv, params, results)
   618  }
   619  
   620  func (r *reader) params() []*types.Field {
   621  	r.Sync(pkgbits.SyncParams)
   622  	params := make([]*types.Field, r.Len())
   623  	for i := range params {
   624  		params[i] = r.param()
   625  	}
   626  	return params
   627  }
   628  
   629  func (r *reader) param() *types.Field {
   630  	r.Sync(pkgbits.SyncParam)
   631  	return types.NewField(r.pos(), r.localIdent(), r.typ())
   632  }
   633  
   634  
   635  
   636  
   637  
   638  
   639  var objReader = map[*types.Sym]pkgReaderIndex{}
   640  
   641  
   642  func (r *reader) obj() ir.Node {
   643  	return r.p.objInstIdx(r.objInfo(), r.dict, false)
   644  }
   645  
   646  
   647  
   648  func (r *reader) objInfo() objInfo {
   649  	r.Sync(pkgbits.SyncObject)
   650  	if r.Version().Has(pkgbits.DerivedFuncInstance) {
   651  		assert(!r.Bool())
   652  	}
   653  	idx := r.Reloc(pkgbits.SectionObj)
   654  
   655  	explicits := make([]typeInfo, r.Len())
   656  	for i := range explicits {
   657  		explicits[i] = r.typInfo()
   658  	}
   659  
   660  	return objInfo{idx, explicits}
   661  }
   662  
   663  
   664  
   665  func (pr *pkgReader) objInstIdx(info objInfo, dict *readerDict, shaped bool) ir.Node {
   666  	explicits := pr.typListIdx(info.explicits, dict)
   667  
   668  	var implicits []*types.Type
   669  	if dict != nil {
   670  		implicits = dict.targs
   671  	}
   672  
   673  	return pr.objIdx(info.idx, implicits, explicits, shaped)
   674  }
   675  
   676  
   677  
   678  
   679  
   680  func (pr *pkgReader) objIdx(idx index, implicits, explicits []*types.Type, shaped bool) ir.Node {
   681  	n, err := pr.objIdxMayFail(idx, implicits, explicits, shaped)
   682  	if err != nil {
   683  		base.Fatalf("%v", err)
   684  	}
   685  	return n
   686  }
   687  
   688  
   689  
   690  
   691  
   692  
   693  
   694  func (pr *pkgReader) objIdxMayFail(idx index, implicits, explicits []*types.Type, shaped bool) (ir.Node, error) {
   695  	rname := pr.newReader(pkgbits.SectionName, idx, pkgbits.SyncObject1)
   696  	_, sym := rname.qualifiedIdent()
   697  	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
   698  
   699  	if tag == pkgbits.ObjStub {
   700  		assert(!sym.IsBlank())
   701  		switch sym.Pkg {
   702  		case types.BuiltinPkg, types.UnsafePkg:
   703  			return sym.Def.(ir.Node), nil
   704  		}
   705  		if pri, ok := objReader[sym]; ok {
   706  			return pri.pr.objIdxMayFail(pri.idx, nil, explicits, shaped)
   707  		}
   708  		if sym.Pkg.Path == "runtime" {
   709  			return typecheck.LookupRuntime(sym.Name), nil
   710  		}
   711  		base.Fatalf("unresolved stub: %v", sym)
   712  	}
   713  
   714  	dict, err := pr.objDictIdx(sym, idx, implicits, explicits, shaped)
   715  	if err != nil {
   716  		return nil, err
   717  	}
   718  
   719  	sym = dict.baseSym
   720  	if !sym.IsBlank() && sym.Def != nil {
   721  		return sym.Def.(*ir.Name), nil
   722  	}
   723  
   724  	r := pr.newReader(pkgbits.SectionObj, idx, pkgbits.SyncObject1)
   725  	rext := pr.newReader(pkgbits.SectionObjExt, idx, pkgbits.SyncObject1)
   726  
   727  	r.dict = dict
   728  	rext.dict = dict
   729  
   730  	do := func(op ir.Op, hasTParams bool) *ir.Name {
   731  		pos := r.pos()
   732  		setBasePos(pos)
   733  		if hasTParams {
   734  			r.typeParamNames()
   735  		}
   736  
   737  		name := ir.NewDeclNameAt(pos, op, sym)
   738  		name.Class = ir.PEXTERN 
   739  		if !sym.IsBlank() {
   740  			if sym.Def != nil {
   741  				base.FatalfAt(name.Pos(), "already have a definition for %v", name)
   742  			}
   743  			assert(sym.Def == nil)
   744  			sym.Def = name
   745  		}
   746  		return name
   747  	}
   748  
   749  	switch tag {
   750  	default:
   751  		panic("unexpected object")
   752  
   753  	case pkgbits.ObjAlias:
   754  		name := do(ir.OTYPE, false)
   755  
   756  		if r.Version().Has(pkgbits.AliasTypeParamNames) {
   757  			r.typeParamNames()
   758  		}
   759  
   760  		
   761  		
   762  		
   763  		
   764  		hack := sym.Def == name
   765  		if hack {
   766  			sym.Def = nil
   767  		}
   768  		typ := r.typ()
   769  		if hack {
   770  			if sym.Def != nil {
   771  				name = sym.Def.(*ir.Name)
   772  				assert(types.IdenticalStrict(name.Type(), typ))
   773  				return name, nil
   774  			}
   775  			sym.Def = name
   776  		}
   777  
   778  		setType(name, typ)
   779  		name.SetAlias(true)
   780  		return name, nil
   781  
   782  	case pkgbits.ObjConst:
   783  		name := do(ir.OLITERAL, false)
   784  		typ := r.typ()
   785  		val := FixValue(typ, r.Value())
   786  		setType(name, typ)
   787  		setValue(name, val)
   788  		return name, nil
   789  
   790  	case pkgbits.ObjFunc:
   791  		if sym.Name == "init" {
   792  			sym = Renameinit()
   793  		}
   794  
   795  		npos := r.pos()
   796  		setBasePos(npos)
   797  		r.typeParamNames()
   798  		typ := r.signature(nil)
   799  		fpos := r.pos()
   800  
   801  		fn := ir.NewFunc(fpos, npos, sym, typ)
   802  		name := fn.Nname
   803  		if !sym.IsBlank() {
   804  			if sym.Def != nil {
   805  				base.FatalfAt(name.Pos(), "already have a definition for %v", name)
   806  			}
   807  			assert(sym.Def == nil)
   808  			sym.Def = name
   809  		}
   810  
   811  		if r.hasTypeParams() {
   812  			name.Func.SetDupok(true)
   813  			if r.dict.shaped {
   814  				setType(name, shapeSig(name.Func, r.dict))
   815  			} else {
   816  				todoDicts = append(todoDicts, func() {
   817  					r.dict.shapedObj = pr.objIdx(idx, implicits, explicits, true).(*ir.Name)
   818  				})
   819  			}
   820  		}
   821  
   822  		rext.funcExt(name, nil)
   823  		return name, nil
   824  
   825  	case pkgbits.ObjType:
   826  		name := do(ir.OTYPE, true)
   827  		typ := types.NewNamed(name)
   828  		setType(name, typ)
   829  		if r.hasTypeParams() && r.dict.shaped {
   830  			typ.SetHasShape(true)
   831  		}
   832  
   833  		
   834  		rext.typeExt(name)
   835  
   836  		
   837  		
   838  		types.DeferCheckSize()
   839  		typ.SetUnderlying(r.typWrapped(false))
   840  		types.ResumeCheckSize()
   841  
   842  		if r.hasTypeParams() && !r.dict.shaped {
   843  			todoDicts = append(todoDicts, func() {
   844  				r.dict.shapedObj = pr.objIdx(idx, implicits, explicits, true).(*ir.Name)
   845  			})
   846  		}
   847  
   848  		methods := make([]*types.Field, r.Len())
   849  		for i := range methods {
   850  			methods[i] = r.method(rext)
   851  		}
   852  		if len(methods) != 0 {
   853  			typ.SetMethods(methods)
   854  		}
   855  
   856  		if !r.dict.shaped {
   857  			r.needWrapper(typ)
   858  		}
   859  
   860  		return name, nil
   861  
   862  	case pkgbits.ObjVar:
   863  		name := do(ir.ONAME, false)
   864  		setType(name, r.typ())
   865  		rext.varExt(name)
   866  		return name, nil
   867  	}
   868  }
   869  
   870  func (dict *readerDict) mangle(sym *types.Sym) *types.Sym {
   871  	if !dict.hasTypeParams() {
   872  		return sym
   873  	}
   874  
   875  	
   876  	
   877  	
   878  	base, suffix := types.SplitVargenSuffix(sym.Name)
   879  
   880  	var buf strings.Builder
   881  	buf.WriteString(base)
   882  	buf.WriteByte('[')
   883  	for i, targ := range dict.targs {
   884  		if i > 0 {
   885  			if i == dict.implicits {
   886  				buf.WriteByte(';')
   887  			} else {
   888  				buf.WriteByte(',')
   889  			}
   890  		}
   891  		buf.WriteString(targ.LinkString())
   892  	}
   893  	buf.WriteByte(']')
   894  	buf.WriteString(suffix)
   895  	return sym.Pkg.Lookup(buf.String())
   896  }
   897  
   898  
   899  
   900  
   901  
   902  func shapify(targ *types.Type, basic bool) *types.Type {
   903  	if targ.Kind() == types.TFORW {
   904  		if targ.IsFullyInstantiated() {
   905  			
   906  			
   907  			
   908  			
   909  			if base.Debug.Shapify != 0 {
   910  				base.Warn("skipping shaping of recursive type %v", targ)
   911  			}
   912  			if targ.HasShape() {
   913  				return targ
   914  			}
   915  		} else {
   916  			base.Fatalf("%v is missing its underlying type", targ)
   917  		}
   918  	}
   919  	
   920  	
   921  	if targ.Kind() == types.TINTER && targ.IsFullyInstantiated() && targ.HasShape() {
   922  		return targ
   923  	}
   924  
   925  	
   926  	
   927  	
   928  	
   929  	
   930  	
   931  	
   932  	
   933  	
   934  	
   935  	
   936  	
   937  	
   938  	
   939  	
   940  	under := targ.Underlying()
   941  	if basic && targ.IsPtr() && !targ.Elem().NotInHeap() {
   942  		under = types.NewPtr(types.Types[types.TUINT8])
   943  	}
   944  
   945  	
   946  	
   947  	uls := under.LinkString()
   948  	if base.Debug.MaxShapeLen != 0 &&
   949  		len(uls) > base.Debug.MaxShapeLen {
   950  		h := hash.Sum32([]byte(uls))
   951  		uls = hex.EncodeToString(h[:])
   952  	}
   953  
   954  	sym := types.ShapePkg.Lookup(uls)
   955  	if sym.Def == nil {
   956  		name := ir.NewDeclNameAt(under.Pos(), ir.OTYPE, sym)
   957  		typ := types.NewNamed(name)
   958  		typ.SetUnderlying(under)
   959  		sym.Def = typed(typ, name)
   960  	}
   961  	res := sym.Def.Type()
   962  	assert(res.IsShape())
   963  	assert(res.HasShape())
   964  	return res
   965  }
   966  
   967  
   968  func (pr *pkgReader) objDictIdx(sym *types.Sym, idx index, implicits, explicits []*types.Type, shaped bool) (*readerDict, error) {
   969  	r := pr.newReader(pkgbits.SectionObjDict, idx, pkgbits.SyncObject1)
   970  
   971  	dict := readerDict{
   972  		shaped: shaped,
   973  	}
   974  
   975  	nimplicits := r.Len()
   976  	nexplicits := r.Len()
   977  
   978  	if nimplicits > len(implicits) || nexplicits != len(explicits) {
   979  		return nil, fmt.Errorf("%v has %v+%v params, but instantiated with %v+%v args", sym, nimplicits, nexplicits, len(implicits), len(explicits))
   980  	}
   981  
   982  	dict.targs = append(implicits[:nimplicits:nimplicits], explicits...)
   983  	dict.implicits = nimplicits
   984  
   985  	
   986  	for range dict.targs[dict.implicits:] {
   987  		
   988  		r.typInfo()
   989  	}
   990  
   991  	dict.derived = make([]derivedInfo, r.Len())
   992  	dict.derivedTypes = make([]*types.Type, len(dict.derived))
   993  	for i := range dict.derived {
   994  		dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.SectionType)}
   995  		if r.Version().Has(pkgbits.DerivedInfoNeeded) {
   996  			assert(!r.Bool())
   997  		}
   998  	}
   999  
  1000  	
  1001  
  1002  	
  1003  	
  1004  	
  1005  	
  1006  	for _, targ := range dict.targs {
  1007  		if targ.HasShape() {
  1008  			dict.shaped = true
  1009  			break
  1010  		}
  1011  	}
  1012  
  1013  	
  1014  	
  1015  	for i, targ := range dict.targs {
  1016  		basic := r.Bool()
  1017  		isPointerShape := basic && targ.IsPtr() && !targ.Elem().NotInHeap()
  1018  		
  1019  		
  1020  		
  1021  		
  1022  		
  1023  		
  1024  		
  1025  		
  1026  		
  1027  		
  1028  		
  1029  		
  1030  		
  1031  		
  1032  		
  1033  		
  1034  		canShapify := !pr.reshaping || !isPointerShape
  1035  		if dict.shaped && canShapify {
  1036  			dict.targs[i] = shapify(targ, basic)
  1037  		}
  1038  	}
  1039  
  1040  	dict.baseSym = dict.mangle(sym)
  1041  
  1042  	dict.typeParamMethodExprs = make([]readerMethodExprInfo, r.Len())
  1043  	for i := range dict.typeParamMethodExprs {
  1044  		typeParamIdx := r.Len()
  1045  		method := r.selector()
  1046  
  1047  		dict.typeParamMethodExprs[i] = readerMethodExprInfo{typeParamIdx, method}
  1048  	}
  1049  
  1050  	dict.subdicts = make([]objInfo, r.Len())
  1051  	for i := range dict.subdicts {
  1052  		dict.subdicts[i] = r.objInfo()
  1053  	}
  1054  
  1055  	dict.rtypes = make([]typeInfo, r.Len())
  1056  	for i := range dict.rtypes {
  1057  		dict.rtypes[i] = r.typInfo()
  1058  	}
  1059  
  1060  	dict.itabs = make([]itabInfo, r.Len())
  1061  	for i := range dict.itabs {
  1062  		dict.itabs[i] = itabInfo{typ: r.typInfo(), iface: r.typInfo()}
  1063  	}
  1064  
  1065  	return &dict, nil
  1066  }
  1067  
  1068  func (r *reader) typeParamNames() {
  1069  	r.Sync(pkgbits.SyncTypeParamNames)
  1070  
  1071  	for range r.dict.targs[r.dict.implicits:] {
  1072  		r.pos()
  1073  		r.localIdent()
  1074  	}
  1075  }
  1076  
  1077  func (r *reader) method(rext *reader) *types.Field {
  1078  	r.Sync(pkgbits.SyncMethod)
  1079  	npos := r.pos()
  1080  	sym := r.selector()
  1081  	r.typeParamNames()
  1082  	recv := r.param()
  1083  	typ := r.signature(recv)
  1084  
  1085  	fpos := r.pos()
  1086  	fn := ir.NewFunc(fpos, npos, ir.MethodSym(recv.Type, sym), typ)
  1087  	name := fn.Nname
  1088  
  1089  	if r.hasTypeParams() {
  1090  		name.Func.SetDupok(true)
  1091  		if r.dict.shaped {
  1092  			typ = shapeSig(name.Func, r.dict)
  1093  			setType(name, typ)
  1094  		}
  1095  	}
  1096  
  1097  	rext.funcExt(name, sym)
  1098  
  1099  	meth := types.NewField(name.Func.Pos(), sym, typ)
  1100  	meth.Nname = name
  1101  	meth.SetNointerface(name.Func.Pragma&ir.Nointerface != 0)
  1102  
  1103  	return meth
  1104  }
  1105  
  1106  func (r *reader) qualifiedIdent() (pkg *types.Pkg, sym *types.Sym) {
  1107  	r.Sync(pkgbits.SyncSym)
  1108  	pkg = r.pkg()
  1109  	if name := r.String(); name != "" {
  1110  		sym = pkg.Lookup(name)
  1111  	}
  1112  	return
  1113  }
  1114  
  1115  func (r *reader) localIdent() *types.Sym {
  1116  	r.Sync(pkgbits.SyncLocalIdent)
  1117  	pkg := r.pkg()
  1118  	if name := r.String(); name != "" {
  1119  		return pkg.Lookup(name)
  1120  	}
  1121  	return nil
  1122  }
  1123  
  1124  func (r *reader) selector() *types.Sym {
  1125  	r.Sync(pkgbits.SyncSelector)
  1126  	pkg := r.pkg()
  1127  	name := r.String()
  1128  	if types.IsExported(name) {
  1129  		pkg = types.LocalPkg
  1130  	}
  1131  	return pkg.Lookup(name)
  1132  }
  1133  
  1134  func (r *reader) hasTypeParams() bool {
  1135  	return r.dict.hasTypeParams()
  1136  }
  1137  
  1138  func (dict *readerDict) hasTypeParams() bool {
  1139  	return dict != nil && len(dict.targs) != 0
  1140  }
  1141  
  1142  
  1143  
  1144  func (r *reader) funcExt(name *ir.Name, method *types.Sym) {
  1145  	r.Sync(pkgbits.SyncFuncExt)
  1146  
  1147  	fn := name.Func
  1148  
  1149  	
  1150  	if !fn.Pos().IsKnown() {
  1151  		fn.SetPos(name.Pos())
  1152  	}
  1153  
  1154  	
  1155  	
  1156  	
  1157  	
  1158  	
  1159  	
  1160  	
  1161  	if name.Sym().Pkg == types.LocalPkg || r.hasTypeParams() {
  1162  		name.Defn = fn
  1163  	}
  1164  
  1165  	fn.Pragma = r.pragmaFlag()
  1166  	r.linkname(name)
  1167  
  1168  	if buildcfg.GOARCH == "wasm" {
  1169  		importmod := r.String()
  1170  		importname := r.String()
  1171  		exportname := r.String()
  1172  
  1173  		if importmod != "" && importname != "" {
  1174  			fn.WasmImport = &ir.WasmImport{
  1175  				Module: importmod,
  1176  				Name:   importname,
  1177  			}
  1178  		}
  1179  		if exportname != "" {
  1180  			if method != nil {
  1181  				base.ErrorfAt(fn.Pos(), 0, "cannot use //go:wasmexport on a method")
  1182  			}
  1183  			fn.WasmExport = &ir.WasmExport{Name: exportname}
  1184  		}
  1185  	}
  1186  
  1187  	if r.Bool() {
  1188  		assert(name.Defn == nil)
  1189  
  1190  		fn.ABI = obj.ABI(r.Uint64())
  1191  
  1192  		
  1193  		for _, f := range name.Type().RecvParams() {
  1194  			f.Note = r.String()
  1195  		}
  1196  
  1197  		if r.Bool() {
  1198  			fn.Inl = &ir.Inline{
  1199  				Cost:            int32(r.Len()),
  1200  				CanDelayResults: r.Bool(),
  1201  			}
  1202  			if buildcfg.Experiment.NewInliner {
  1203  				fn.Inl.Properties = r.String()
  1204  			}
  1205  		}
  1206  	} else {
  1207  		r.addBody(name.Func, method)
  1208  	}
  1209  	r.Sync(pkgbits.SyncEOF)
  1210  }
  1211  
  1212  func (r *reader) typeExt(name *ir.Name) {
  1213  	r.Sync(pkgbits.SyncTypeExt)
  1214  
  1215  	typ := name.Type()
  1216  
  1217  	if r.hasTypeParams() {
  1218  		
  1219  		
  1220  		typ.SetIsFullyInstantiated(true)
  1221  		
  1222  		for _, targ := range r.dict.targs {
  1223  			if targ.HasShape() {
  1224  				typ.SetHasShape(true)
  1225  				break
  1226  			}
  1227  		}
  1228  	}
  1229  
  1230  	name.SetPragma(r.pragmaFlag())
  1231  
  1232  	typecheck.SetBaseTypeIndex(typ, r.Int64(), r.Int64())
  1233  }
  1234  
  1235  func (r *reader) varExt(name *ir.Name) {
  1236  	r.Sync(pkgbits.SyncVarExt)
  1237  	r.linkname(name)
  1238  }
  1239  
  1240  func (r *reader) linkname(name *ir.Name) {
  1241  	assert(name.Op() == ir.ONAME)
  1242  	r.Sync(pkgbits.SyncLinkname)
  1243  
  1244  	if idx := r.Int64(); idx >= 0 {
  1245  		lsym := name.Linksym()
  1246  		lsym.SymIdx = int32(idx)
  1247  		lsym.Set(obj.AttrIndexed, true)
  1248  	} else {
  1249  		linkname := r.String()
  1250  		sym := name.Sym()
  1251  		sym.Linkname = linkname
  1252  		if sym.Pkg == types.LocalPkg && linkname != "" {
  1253  			
  1254  			
  1255  			
  1256  			
  1257  			
  1258  			
  1259  			sym.Linksym().Set(obj.AttrLinkname, true)
  1260  		}
  1261  	}
  1262  }
  1263  
  1264  func (r *reader) pragmaFlag() ir.PragmaFlag {
  1265  	r.Sync(pkgbits.SyncPragma)
  1266  	return ir.PragmaFlag(r.Int())
  1267  }
  1268  
  1269  
  1270  
  1271  
  1272  
  1273  var bodyReader = map[*ir.Func]pkgReaderIndex{}
  1274  
  1275  
  1276  
  1277  var importBodyReader = map[*types.Sym]pkgReaderIndex{}
  1278  
  1279  
  1280  
  1281  func bodyReaderFor(fn *ir.Func) (pri pkgReaderIndex, ok bool) {
  1282  	if fn.Nname.Defn != nil {
  1283  		pri, ok = bodyReader[fn]
  1284  		base.AssertfAt(ok, base.Pos, "must have bodyReader for %v", fn) 
  1285  	} else {
  1286  		pri, ok = importBodyReader[fn.Sym()]
  1287  	}
  1288  	return
  1289  }
  1290  
  1291  
  1292  
  1293  var todoDicts []func()
  1294  
  1295  
  1296  
  1297  var todoBodies []*ir.Func
  1298  
  1299  
  1300  
  1301  func (r *reader) addBody(fn *ir.Func, method *types.Sym) {
  1302  	
  1303  	
  1304  	assert(fn.Nname.Defn != nil)
  1305  
  1306  	idx := r.Reloc(pkgbits.SectionBody)
  1307  
  1308  	pri := pkgReaderIndex{r.p, idx, r.dict, method, nil}
  1309  	bodyReader[fn] = pri
  1310  
  1311  	if r.curfn == nil {
  1312  		todoBodies = append(todoBodies, fn)
  1313  		return
  1314  	}
  1315  
  1316  	pri.funcBody(fn)
  1317  }
  1318  
  1319  func (pri pkgReaderIndex) funcBody(fn *ir.Func) {
  1320  	r := pri.asReader(pkgbits.SectionBody, pkgbits.SyncFuncBody)
  1321  	r.funcBody(fn)
  1322  }
  1323  
  1324  
  1325  
  1326  func (r *reader) funcBody(fn *ir.Func) {
  1327  	r.curfn = fn
  1328  	r.closureVars = fn.ClosureVars
  1329  	if len(r.closureVars) != 0 && r.hasTypeParams() {
  1330  		r.dictParam = r.closureVars[len(r.closureVars)-1] 
  1331  	}
  1332  
  1333  	ir.WithFunc(fn, func() {
  1334  		r.declareParams()
  1335  
  1336  		if r.syntheticBody(fn.Pos()) {
  1337  			return
  1338  		}
  1339  
  1340  		if !r.Bool() {
  1341  			return
  1342  		}
  1343  
  1344  		body := r.stmts()
  1345  		if body == nil {
  1346  			body = []ir.Node{typecheck.Stmt(ir.NewBlockStmt(src.NoXPos, nil))}
  1347  		}
  1348  		fn.Body = body
  1349  		fn.Endlineno = r.pos()
  1350  	})
  1351  
  1352  	r.marker.WriteTo(fn)
  1353  }
  1354  
  1355  
  1356  
  1357  func (r *reader) syntheticBody(pos src.XPos) bool {
  1358  	if r.synthetic != nil {
  1359  		r.synthetic(pos, r)
  1360  		return true
  1361  	}
  1362  
  1363  	
  1364  	
  1365  	if r.hasTypeParams() && !r.dict.shaped {
  1366  		r.callShaped(pos)
  1367  		return true
  1368  	}
  1369  
  1370  	return false
  1371  }
  1372  
  1373  
  1374  
  1375  func (r *reader) callShaped(pos src.XPos) {
  1376  	shapedObj := r.dict.shapedObj
  1377  	assert(shapedObj != nil)
  1378  
  1379  	var shapedFn ir.Node
  1380  	if r.methodSym == nil {
  1381  		
  1382  		
  1383  		assert(shapedObj.Op() == ir.ONAME && shapedObj.Class == ir.PFUNC)
  1384  		shapedFn = shapedObj
  1385  	} else {
  1386  		
  1387  		
  1388  		shapedFn = shapedMethodExpr(pos, shapedObj, r.methodSym)
  1389  	}
  1390  
  1391  	params := r.syntheticArgs()
  1392  
  1393  	
  1394  	
  1395  	
  1396  	
  1397  	
  1398  	
  1399  	
  1400  	
  1401  	
  1402  	var args ir.Nodes
  1403  	if r.methodSym != nil {
  1404  		args.Append(params[0])
  1405  		params = params[1:]
  1406  	}
  1407  	args.Append(typecheck.Expr(ir.NewAddrExpr(pos, r.p.dictNameOf(r.dict))))
  1408  	args.Append(params...)
  1409  
  1410  	r.syntheticTailCall(pos, shapedFn, args)
  1411  }
  1412  
  1413  
  1414  
  1415  func (r *reader) syntheticArgs() ir.Nodes {
  1416  	sig := r.curfn.Nname.Type()
  1417  	return ir.ToNodes(r.curfn.Dcl[:sig.NumRecvs()+sig.NumParams()])
  1418  }
  1419  
  1420  
  1421  
  1422  func (r *reader) syntheticTailCall(pos src.XPos, fn ir.Node, args ir.Nodes) {
  1423  	
  1424  	
  1425  	r.curfn.SetWrapper(true)
  1426  
  1427  	call := typecheck.Call(pos, fn, args, fn.Type().IsVariadic()).(*ir.CallExpr)
  1428  
  1429  	var stmt ir.Node
  1430  	if fn.Type().NumResults() != 0 {
  1431  		stmt = typecheck.Stmt(ir.NewReturnStmt(pos, []ir.Node{call}))
  1432  	} else {
  1433  		stmt = call
  1434  	}
  1435  	r.curfn.Body.Append(stmt)
  1436  }
  1437  
  1438  
  1439  func (pr *pkgReader) dictNameOf(dict *readerDict) *ir.Name {
  1440  	pos := base.AutogeneratedPos
  1441  
  1442  	
  1443  	base.AssertfAt(!dict.shaped, pos, "runtime dictionary of shaped object %v", dict.baseSym)
  1444  
  1445  	sym := dict.baseSym.Pkg.Lookup(objabi.GlobalDictPrefix + "." + dict.baseSym.Name)
  1446  	if sym.Def != nil {
  1447  		return sym.Def.(*ir.Name)
  1448  	}
  1449  
  1450  	name := ir.NewNameAt(pos, sym, dict.varType())
  1451  	name.Class = ir.PEXTERN
  1452  	sym.Def = name 
  1453  
  1454  	lsym := name.Linksym()
  1455  	ot := 0
  1456  
  1457  	assertOffset := func(section string, offset int) {
  1458  		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)
  1459  	}
  1460  
  1461  	assertOffset("type param method exprs", dict.typeParamMethodExprsOffset())
  1462  	for _, info := range dict.typeParamMethodExprs {
  1463  		typeParam := dict.targs[info.typeParamIdx]
  1464  		method := typecheck.NewMethodExpr(pos, typeParam, info.method)
  1465  
  1466  		rsym := method.FuncName().Linksym()
  1467  		assert(rsym.ABI() == obj.ABIInternal) 
  1468  
  1469  		ot = objw.SymPtr(lsym, ot, rsym, 0)
  1470  	}
  1471  
  1472  	assertOffset("subdictionaries", dict.subdictsOffset())
  1473  	for _, info := range dict.subdicts {
  1474  		explicits := pr.typListIdx(info.explicits, dict)
  1475  
  1476  		
  1477  		
  1478  		name := pr.objDictName(info.idx, dict.targs, explicits)
  1479  
  1480  		ot = objw.SymPtr(lsym, ot, name.Linksym(), 0)
  1481  	}
  1482  
  1483  	assertOffset("rtypes", dict.rtypesOffset())
  1484  	for _, info := range dict.rtypes {
  1485  		typ := pr.typIdx(info, dict, true)
  1486  		ot = objw.SymPtr(lsym, ot, reflectdata.TypeLinksym(typ), 0)
  1487  
  1488  		
  1489  		reflectdata.MarkTypeUsedInInterface(typ, lsym)
  1490  	}
  1491  
  1492  	
  1493  	
  1494  	
  1495  	
  1496  	
  1497  	
  1498  	assertOffset("itabs", dict.itabsOffset())
  1499  	for _, info := range dict.itabs {
  1500  		typ := pr.typIdx(info.typ, dict, true)
  1501  		iface := pr.typIdx(info.iface, dict, true)
  1502  
  1503  		if !typ.IsInterface() && iface.IsInterface() && !iface.IsEmptyInterface() {
  1504  			ot = objw.SymPtr(lsym, ot, reflectdata.ITabLsym(typ, iface), 0)
  1505  		} else {
  1506  			ot += types.PtrSize
  1507  		}
  1508  
  1509  		
  1510  		reflectdata.MarkTypeUsedInInterface(typ, lsym)
  1511  		reflectdata.MarkTypeUsedInInterface(iface, lsym)
  1512  	}
  1513  
  1514  	objw.Global(lsym, int32(ot), obj.DUPOK|obj.RODATA)
  1515  
  1516  	return name
  1517  }
  1518  
  1519  
  1520  
  1521  func (dict *readerDict) typeParamMethodExprsOffset() int {
  1522  	return 0
  1523  }
  1524  
  1525  
  1526  
  1527  func (dict *readerDict) subdictsOffset() int {
  1528  	return dict.typeParamMethodExprsOffset() + len(dict.typeParamMethodExprs)
  1529  }
  1530  
  1531  
  1532  
  1533  func (dict *readerDict) rtypesOffset() int {
  1534  	return dict.subdictsOffset() + len(dict.subdicts)
  1535  }
  1536  
  1537  
  1538  
  1539  func (dict *readerDict) itabsOffset() int {
  1540  	return dict.rtypesOffset() + len(dict.rtypes)
  1541  }
  1542  
  1543  
  1544  
  1545  func (dict *readerDict) numWords() int64 {
  1546  	return int64(dict.itabsOffset() + len(dict.itabs))
  1547  }
  1548  
  1549  
  1550  func (dict *readerDict) varType() *types.Type {
  1551  	return types.NewArray(types.Types[types.TUINTPTR], dict.numWords())
  1552  }
  1553  
  1554  func (r *reader) declareParams() {
  1555  	r.curfn.DeclareParams(!r.funarghack)
  1556  
  1557  	for _, name := range r.curfn.Dcl {
  1558  		if name.Sym().Name == dictParamName {
  1559  			r.dictParam = name
  1560  			continue
  1561  		}
  1562  
  1563  		r.addLocal(name)
  1564  	}
  1565  }
  1566  
  1567  func (r *reader) addLocal(name *ir.Name) {
  1568  	if r.synthetic == nil {
  1569  		r.Sync(pkgbits.SyncAddLocal)
  1570  		if r.p.SyncMarkers() {
  1571  			want := r.Int()
  1572  			if have := len(r.locals); have != want {
  1573  				base.FatalfAt(name.Pos(), "locals table has desynced")
  1574  			}
  1575  		}
  1576  		r.varDictIndex(name)
  1577  	}
  1578  
  1579  	r.locals = append(r.locals, name)
  1580  }
  1581  
  1582  func (r *reader) useLocal() *ir.Name {
  1583  	r.Sync(pkgbits.SyncUseObjLocal)
  1584  	if r.Bool() {
  1585  		return r.locals[r.Len()]
  1586  	}
  1587  	return r.closureVars[r.Len()]
  1588  }
  1589  
  1590  func (r *reader) openScope() {
  1591  	r.Sync(pkgbits.SyncOpenScope)
  1592  	pos := r.pos()
  1593  
  1594  	if base.Flag.Dwarf {
  1595  		r.scopeVars = append(r.scopeVars, len(r.curfn.Dcl))
  1596  		r.marker.Push(pos)
  1597  	}
  1598  }
  1599  
  1600  func (r *reader) closeScope() {
  1601  	r.Sync(pkgbits.SyncCloseScope)
  1602  	r.lastCloseScopePos = r.pos()
  1603  
  1604  	r.closeAnotherScope()
  1605  }
  1606  
  1607  
  1608  
  1609  
  1610  
  1611  func (r *reader) closeAnotherScope() {
  1612  	r.Sync(pkgbits.SyncCloseAnotherScope)
  1613  
  1614  	if base.Flag.Dwarf {
  1615  		scopeVars := r.scopeVars[len(r.scopeVars)-1]
  1616  		r.scopeVars = r.scopeVars[:len(r.scopeVars)-1]
  1617  
  1618  		
  1619  		
  1620  		
  1621  		
  1622  		
  1623  		
  1624  		
  1625  		
  1626  		
  1627  		
  1628  		
  1629  		
  1630  		
  1631  		
  1632  		
  1633  		
  1634  		
  1635  		
  1636  		
  1637  		
  1638  		
  1639  		
  1640  		
  1641  		
  1642  		
  1643  		
  1644  		
  1645  		retract := true
  1646  		for _, n := range r.curfn.Dcl[scopeVars:] {
  1647  			if !n.AutoTemp() {
  1648  				retract = false
  1649  				break
  1650  			}
  1651  		}
  1652  
  1653  		if retract {
  1654  			
  1655  			r.marker.Unpush()
  1656  		} else {
  1657  			r.marker.Pop(r.lastCloseScopePos)
  1658  		}
  1659  	}
  1660  }
  1661  
  1662  
  1663  
  1664  func (r *reader) stmt() ir.Node {
  1665  	return block(r.stmts())
  1666  }
  1667  
  1668  func block(stmts []ir.Node) ir.Node {
  1669  	switch len(stmts) {
  1670  	case 0:
  1671  		return nil
  1672  	case 1:
  1673  		return stmts[0]
  1674  	default:
  1675  		return ir.NewBlockStmt(stmts[0].Pos(), stmts)
  1676  	}
  1677  }
  1678  
  1679  func (r *reader) stmts() ir.Nodes {
  1680  	assert(ir.CurFunc == r.curfn)
  1681  	var res ir.Nodes
  1682  
  1683  	r.Sync(pkgbits.SyncStmts)
  1684  	for {
  1685  		tag := codeStmt(r.Code(pkgbits.SyncStmt1))
  1686  		if tag == stmtEnd {
  1687  			r.Sync(pkgbits.SyncStmtsEnd)
  1688  			return res
  1689  		}
  1690  
  1691  		if n := r.stmt1(tag, &res); n != nil {
  1692  			res.Append(typecheck.Stmt(n))
  1693  		}
  1694  	}
  1695  }
  1696  
  1697  func (r *reader) stmt1(tag codeStmt, out *ir.Nodes) ir.Node {
  1698  	var label *types.Sym
  1699  	if n := len(*out); n > 0 {
  1700  		if ls, ok := (*out)[n-1].(*ir.LabelStmt); ok {
  1701  			label = ls.Label
  1702  		}
  1703  	}
  1704  
  1705  	switch tag {
  1706  	default:
  1707  		panic("unexpected statement")
  1708  
  1709  	case stmtAssign:
  1710  		pos := r.pos()
  1711  		names, lhs := r.assignList()
  1712  		rhs := r.multiExpr()
  1713  
  1714  		if len(rhs) == 0 {
  1715  			for _, name := range names {
  1716  				as := ir.NewAssignStmt(pos, name, nil)
  1717  				as.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, name))
  1718  				out.Append(typecheck.Stmt(as))
  1719  			}
  1720  			return nil
  1721  		}
  1722  
  1723  		if len(lhs) == 1 && len(rhs) == 1 {
  1724  			n := ir.NewAssignStmt(pos, lhs[0], rhs[0])
  1725  			n.Def = r.initDefn(n, names)
  1726  			return n
  1727  		}
  1728  
  1729  		n := ir.NewAssignListStmt(pos, ir.OAS2, lhs, rhs)
  1730  		n.Def = r.initDefn(n, names)
  1731  		return n
  1732  
  1733  	case stmtAssignOp:
  1734  		op := r.op()
  1735  		lhs := r.expr()
  1736  		pos := r.pos()
  1737  		rhs := r.expr()
  1738  		return ir.NewAssignOpStmt(pos, op, lhs, rhs)
  1739  
  1740  	case stmtIncDec:
  1741  		op := r.op()
  1742  		lhs := r.expr()
  1743  		pos := r.pos()
  1744  		n := ir.NewAssignOpStmt(pos, op, lhs, ir.NewOne(pos, lhs.Type()))
  1745  		n.IncDec = true
  1746  		return n
  1747  
  1748  	case stmtBlock:
  1749  		out.Append(r.blockStmt()...)
  1750  		return nil
  1751  
  1752  	case stmtBranch:
  1753  		pos := r.pos()
  1754  		op := r.op()
  1755  		sym := r.optLabel()
  1756  		return ir.NewBranchStmt(pos, op, sym)
  1757  
  1758  	case stmtCall:
  1759  		pos := r.pos()
  1760  		op := r.op()
  1761  		call := r.expr()
  1762  		stmt := ir.NewGoDeferStmt(pos, op, call)
  1763  		if op == ir.ODEFER {
  1764  			x := r.optExpr()
  1765  			if x != nil {
  1766  				stmt.DeferAt = x.(ir.Expr)
  1767  			}
  1768  		}
  1769  		return stmt
  1770  
  1771  	case stmtExpr:
  1772  		return r.expr()
  1773  
  1774  	case stmtFor:
  1775  		return r.forStmt(label)
  1776  
  1777  	case stmtIf:
  1778  		return r.ifStmt()
  1779  
  1780  	case stmtLabel:
  1781  		pos := r.pos()
  1782  		sym := r.label()
  1783  		return ir.NewLabelStmt(pos, sym)
  1784  
  1785  	case stmtReturn:
  1786  		pos := r.pos()
  1787  		results := r.multiExpr()
  1788  		return ir.NewReturnStmt(pos, results)
  1789  
  1790  	case stmtSelect:
  1791  		return r.selectStmt(label)
  1792  
  1793  	case stmtSend:
  1794  		pos := r.pos()
  1795  		ch := r.expr()
  1796  		value := r.expr()
  1797  		return ir.NewSendStmt(pos, ch, value)
  1798  
  1799  	case stmtSwitch:
  1800  		return r.switchStmt(label)
  1801  	}
  1802  }
  1803  
  1804  func (r *reader) assignList() ([]*ir.Name, []ir.Node) {
  1805  	lhs := make([]ir.Node, r.Len())
  1806  	var names []*ir.Name
  1807  
  1808  	for i := range lhs {
  1809  		expr, def := r.assign()
  1810  		lhs[i] = expr
  1811  		if def {
  1812  			names = append(names, expr.(*ir.Name))
  1813  		}
  1814  	}
  1815  
  1816  	return names, lhs
  1817  }
  1818  
  1819  
  1820  
  1821  func (r *reader) assign() (ir.Node, bool) {
  1822  	switch tag := codeAssign(r.Code(pkgbits.SyncAssign)); tag {
  1823  	default:
  1824  		panic("unhandled assignee expression")
  1825  
  1826  	case assignBlank:
  1827  		return typecheck.AssignExpr(ir.BlankNode), false
  1828  
  1829  	case assignDef:
  1830  		pos := r.pos()
  1831  		setBasePos(pos) 
  1832  		name := r.curfn.NewLocal(pos, r.localIdent(), r.typ())
  1833  		r.addLocal(name)
  1834  		return name, true
  1835  
  1836  	case assignExpr:
  1837  		return r.expr(), false
  1838  	}
  1839  }
  1840  
  1841  func (r *reader) blockStmt() []ir.Node {
  1842  	r.Sync(pkgbits.SyncBlockStmt)
  1843  	r.openScope()
  1844  	stmts := r.stmts()
  1845  	r.closeScope()
  1846  	return stmts
  1847  }
  1848  
  1849  func (r *reader) forStmt(label *types.Sym) ir.Node {
  1850  	r.Sync(pkgbits.SyncForStmt)
  1851  
  1852  	r.openScope()
  1853  
  1854  	if r.Bool() {
  1855  		pos := r.pos()
  1856  		rang := ir.NewRangeStmt(pos, nil, nil, nil, nil, false)
  1857  		rang.Label = label
  1858  
  1859  		names, lhs := r.assignList()
  1860  		if len(lhs) >= 1 {
  1861  			rang.Key = lhs[0]
  1862  			if len(lhs) >= 2 {
  1863  				rang.Value = lhs[1]
  1864  			}
  1865  		}
  1866  		rang.Def = r.initDefn(rang, names)
  1867  
  1868  		rang.X = r.expr()
  1869  		if rang.X.Type().IsMap() {
  1870  			rang.RType = r.rtype(pos)
  1871  		}
  1872  		if rang.Key != nil && !ir.IsBlank(rang.Key) {
  1873  			rang.KeyTypeWord, rang.KeySrcRType = r.convRTTI(pos)
  1874  		}
  1875  		if rang.Value != nil && !ir.IsBlank(rang.Value) {
  1876  			rang.ValueTypeWord, rang.ValueSrcRType = r.convRTTI(pos)
  1877  		}
  1878  
  1879  		rang.Body = r.blockStmt()
  1880  		rang.DistinctVars = r.Bool()
  1881  		r.closeAnotherScope()
  1882  
  1883  		return rang
  1884  	}
  1885  
  1886  	pos := r.pos()
  1887  	init := r.stmt()
  1888  	cond := r.optExpr()
  1889  	post := r.stmt()
  1890  	body := r.blockStmt()
  1891  	perLoopVars := r.Bool()
  1892  	r.closeAnotherScope()
  1893  
  1894  	if ir.IsConst(cond, constant.Bool) && !ir.BoolVal(cond) {
  1895  		return init 
  1896  	}
  1897  
  1898  	stmt := ir.NewForStmt(pos, init, cond, post, body, perLoopVars)
  1899  	stmt.Label = label
  1900  	return stmt
  1901  }
  1902  
  1903  func (r *reader) ifStmt() ir.Node {
  1904  	r.Sync(pkgbits.SyncIfStmt)
  1905  	r.openScope()
  1906  	pos := r.pos()
  1907  	init := r.stmts()
  1908  	cond := r.expr()
  1909  	staticCond := r.Int()
  1910  	var then, els []ir.Node
  1911  	if staticCond >= 0 {
  1912  		then = r.blockStmt()
  1913  	} else {
  1914  		r.lastCloseScopePos = r.pos()
  1915  	}
  1916  	if staticCond <= 0 {
  1917  		els = r.stmts()
  1918  	}
  1919  	r.closeAnotherScope()
  1920  
  1921  	if staticCond != 0 {
  1922  		
  1923  		
  1924  		
  1925  
  1926  		if cond.Op() != ir.OLITERAL {
  1927  			init.Append(typecheck.Stmt(ir.NewAssignStmt(pos, ir.BlankNode, cond))) 
  1928  		}
  1929  		init.Append(then...)
  1930  		init.Append(els...)
  1931  		return block(init)
  1932  	}
  1933  
  1934  	n := ir.NewIfStmt(pos, cond, then, els)
  1935  	n.SetInit(init)
  1936  	return n
  1937  }
  1938  
  1939  func (r *reader) selectStmt(label *types.Sym) ir.Node {
  1940  	r.Sync(pkgbits.SyncSelectStmt)
  1941  
  1942  	pos := r.pos()
  1943  	clauses := make([]*ir.CommClause, r.Len())
  1944  	for i := range clauses {
  1945  		if i > 0 {
  1946  			r.closeScope()
  1947  		}
  1948  		r.openScope()
  1949  
  1950  		pos := r.pos()
  1951  		comm := r.stmt()
  1952  		body := r.stmts()
  1953  
  1954  		
  1955  		
  1956  		
  1957  		
  1958  		
  1959  		if as, ok := comm.(*ir.AssignStmt); ok && as.Op() == ir.OAS && !as.Def {
  1960  			if conv, ok := as.Y.(*ir.ConvExpr); ok && conv.Op() == ir.OCONVIFACE {
  1961  				base.AssertfAt(conv.Implicit(), conv.Pos(), "expected implicit conversion: %v", conv)
  1962  
  1963  				recv := conv.X
  1964  				base.AssertfAt(recv.Op() == ir.ORECV, recv.Pos(), "expected receive expression: %v", recv)
  1965  
  1966  				tmp := r.temp(pos, recv.Type())
  1967  
  1968  				
  1969  				tmpAs := ir.NewAssignStmt(pos, tmp, recv)
  1970  				tmpAs.Def = true
  1971  				tmpAs.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, tmp))
  1972  				comm = tmpAs
  1973  
  1974  				
  1975  				conv.X = tmp
  1976  				body = append([]ir.Node{as}, body...)
  1977  			}
  1978  		}
  1979  
  1980  		
  1981  		
  1982  		
  1983  		
  1984  		if as2, ok := comm.(*ir.AssignListStmt); ok && as2.Op() == ir.OAS2 {
  1985  			init := ir.TakeInit(as2.Rhs[0])
  1986  			base.AssertfAt(len(init) == 1 && init[0].Op() == ir.OAS2RECV, as2.Pos(), "unexpected assignment: %+v", as2)
  1987  
  1988  			comm = init[0]
  1989  			body = append([]ir.Node{as2}, body...)
  1990  		}
  1991  
  1992  		clauses[i] = ir.NewCommStmt(pos, comm, body)
  1993  	}
  1994  	if len(clauses) > 0 {
  1995  		r.closeScope()
  1996  	}
  1997  	n := ir.NewSelectStmt(pos, clauses)
  1998  	n.Label = label
  1999  	return n
  2000  }
  2001  
  2002  func (r *reader) switchStmt(label *types.Sym) ir.Node {
  2003  	r.Sync(pkgbits.SyncSwitchStmt)
  2004  
  2005  	r.openScope()
  2006  	pos := r.pos()
  2007  	init := r.stmt()
  2008  
  2009  	var tag ir.Node
  2010  	var ident *ir.Ident
  2011  	var iface *types.Type
  2012  	if r.Bool() {
  2013  		pos := r.pos()
  2014  		if r.Bool() {
  2015  			ident = ir.NewIdent(r.pos(), r.localIdent())
  2016  		}
  2017  		x := r.expr()
  2018  		iface = x.Type()
  2019  		tag = ir.NewTypeSwitchGuard(pos, ident, x)
  2020  	} else {
  2021  		tag = r.optExpr()
  2022  	}
  2023  
  2024  	clauses := make([]*ir.CaseClause, r.Len())
  2025  	for i := range clauses {
  2026  		if i > 0 {
  2027  			r.closeScope()
  2028  		}
  2029  		r.openScope()
  2030  
  2031  		pos := r.pos()
  2032  		var cases, rtypes []ir.Node
  2033  		if iface != nil {
  2034  			cases = make([]ir.Node, r.Len())
  2035  			if len(cases) == 0 {
  2036  				cases = nil 
  2037  			}
  2038  			for i := range cases {
  2039  				if r.Bool() { 
  2040  					cases[i] = typecheck.Expr(types.BuiltinPkg.Lookup("nil").Def.(*ir.NilExpr))
  2041  				} else {
  2042  					cases[i] = r.exprType()
  2043  				}
  2044  			}
  2045  		} else {
  2046  			cases = r.exprList()
  2047  
  2048  			
  2049  			
  2050  			
  2051  			
  2052  			
  2053  			
  2054  			
  2055  			if tag == nil {
  2056  				for i, cas := range cases {
  2057  					if cas.Type().IsEmptyInterface() {
  2058  						for len(rtypes) < i {
  2059  							rtypes = append(rtypes, nil)
  2060  						}
  2061  						rtypes = append(rtypes, reflectdata.TypePtrAt(cas.Pos(), types.Types[types.TBOOL]))
  2062  					}
  2063  				}
  2064  			}
  2065  		}
  2066  
  2067  		clause := ir.NewCaseStmt(pos, cases, nil)
  2068  		clause.RTypes = rtypes
  2069  
  2070  		if ident != nil {
  2071  			name := r.curfn.NewLocal(r.pos(), ident.Sym(), r.typ())
  2072  			r.addLocal(name)
  2073  			clause.Var = name
  2074  			name.Defn = tag
  2075  		}
  2076  
  2077  		clause.Body = r.stmts()
  2078  		clauses[i] = clause
  2079  	}
  2080  	if len(clauses) > 0 {
  2081  		r.closeScope()
  2082  	}
  2083  	r.closeScope()
  2084  
  2085  	n := ir.NewSwitchStmt(pos, tag, clauses)
  2086  	n.Label = label
  2087  	if init != nil {
  2088  		n.SetInit([]ir.Node{init})
  2089  	}
  2090  	return n
  2091  }
  2092  
  2093  func (r *reader) label() *types.Sym {
  2094  	r.Sync(pkgbits.SyncLabel)
  2095  	name := r.String()
  2096  	if r.inlCall != nil && name != "_" {
  2097  		name = fmt.Sprintf("~%s·%d", name, inlgen)
  2098  	}
  2099  	return typecheck.Lookup(name)
  2100  }
  2101  
  2102  func (r *reader) optLabel() *types.Sym {
  2103  	r.Sync(pkgbits.SyncOptLabel)
  2104  	if r.Bool() {
  2105  		return r.label()
  2106  	}
  2107  	return nil
  2108  }
  2109  
  2110  
  2111  
  2112  
  2113  func (r *reader) initDefn(defn ir.InitNode, names []*ir.Name) bool {
  2114  	if len(names) == 0 {
  2115  		return false
  2116  	}
  2117  
  2118  	init := make([]ir.Node, len(names))
  2119  	for i, name := range names {
  2120  		name.Defn = defn
  2121  		init[i] = ir.NewDecl(name.Pos(), ir.ODCL, name)
  2122  	}
  2123  	defn.SetInit(init)
  2124  	return true
  2125  }
  2126  
  2127  
  2128  
  2129  
  2130  func (r *reader) expr() (res ir.Node) {
  2131  	defer func() {
  2132  		if res != nil && res.Typecheck() == 0 {
  2133  			base.FatalfAt(res.Pos(), "%v missed typecheck", res)
  2134  		}
  2135  	}()
  2136  
  2137  	switch tag := codeExpr(r.Code(pkgbits.SyncExpr)); tag {
  2138  	default:
  2139  		panic("unhandled expression")
  2140  
  2141  	case exprLocal:
  2142  		return typecheck.Expr(r.useLocal())
  2143  
  2144  	case exprGlobal:
  2145  		
  2146  		
  2147  		return typecheck.Callee(r.obj())
  2148  
  2149  	case exprFuncInst:
  2150  		origPos, pos := r.origPos()
  2151  		wrapperFn, baseFn, dictPtr := r.funcInst(pos)
  2152  		if wrapperFn != nil {
  2153  			return wrapperFn
  2154  		}
  2155  		return r.curry(origPos, false, baseFn, dictPtr, nil)
  2156  
  2157  	case exprConst:
  2158  		pos := r.pos()
  2159  		typ := r.typ()
  2160  		val := FixValue(typ, r.Value())
  2161  		return ir.NewBasicLit(pos, typ, val)
  2162  
  2163  	case exprZero:
  2164  		pos := r.pos()
  2165  		typ := r.typ()
  2166  		return ir.NewZero(pos, typ)
  2167  
  2168  	case exprCompLit:
  2169  		return r.compLit()
  2170  
  2171  	case exprFuncLit:
  2172  		return r.funcLit()
  2173  
  2174  	case exprFieldVal:
  2175  		x := r.expr()
  2176  		pos := r.pos()
  2177  		sym := r.selector()
  2178  
  2179  		return typecheck.XDotField(pos, x, sym)
  2180  
  2181  	case exprMethodVal:
  2182  		recv := r.expr()
  2183  		origPos, pos := r.origPos()
  2184  		wrapperFn, baseFn, dictPtr := r.methodExpr()
  2185  
  2186  		
  2187  		
  2188  		if wrapperFn, ok := wrapperFn.(*ir.SelectorExpr); ok && wrapperFn.Op() == ir.OMETHEXPR {
  2189  			
  2190  			
  2191  			
  2192  			
  2193  			
  2194  			
  2195  			
  2196  			
  2197  			
  2198  			
  2199  			
  2200  			
  2201  			
  2202  			
  2203  			
  2204  			
  2205  			
  2206  			if recv.Type().HasShape() {
  2207  				typ := wrapperFn.Type().Param(0).Type
  2208  				if !types.Identical(typ, recv.Type()) {
  2209  					base.FatalfAt(wrapperFn.Pos(), "receiver %L does not match %L", recv, wrapperFn)
  2210  				}
  2211  				recv = typecheck.Expr(ir.NewConvExpr(recv.Pos(), ir.OCONVNOP, typ, recv))
  2212  			}
  2213  
  2214  			n := typecheck.XDotMethod(pos, recv, wrapperFn.Sel, false)
  2215  
  2216  			
  2217  			
  2218  			
  2219  			
  2220  			
  2221  			
  2222  			if n.Selection != wrapperFn.Selection {
  2223  				assert(n.Selection.Sym == wrapperFn.Selection.Sym)
  2224  				assert(types.Identical(n.Selection.Type, wrapperFn.Selection.Type))
  2225  				assert(types.Identical(n.Selection.Type.Recv().Type, wrapperFn.Selection.Type.Recv().Type))
  2226  			}
  2227  
  2228  			wrapper := methodValueWrapper{
  2229  				rcvr:   n.X.Type(),
  2230  				method: n.Selection,
  2231  			}
  2232  
  2233  			if r.importedDef() {
  2234  				haveMethodValueWrappers = append(haveMethodValueWrappers, wrapper)
  2235  			} else {
  2236  				needMethodValueWrappers = append(needMethodValueWrappers, wrapper)
  2237  			}
  2238  			return n
  2239  		}
  2240  
  2241  		
  2242  		
  2243  		return r.curry(origPos, true, baseFn, recv, dictPtr)
  2244  
  2245  	case exprMethodExpr:
  2246  		recv := r.typ()
  2247  
  2248  		implicits := make([]int, r.Len())
  2249  		for i := range implicits {
  2250  			implicits[i] = r.Len()
  2251  		}
  2252  		var deref, addr bool
  2253  		if r.Bool() {
  2254  			deref = true
  2255  		} else if r.Bool() {
  2256  			addr = true
  2257  		}
  2258  
  2259  		origPos, pos := r.origPos()
  2260  		wrapperFn, baseFn, dictPtr := r.methodExpr()
  2261  
  2262  		
  2263  		
  2264  		
  2265  		
  2266  		
  2267  		
  2268  		if wrapperFn != nil && len(implicits) == 0 && !deref && !addr {
  2269  			if !types.Identical(recv, wrapperFn.Type().Param(0).Type) {
  2270  				base.FatalfAt(pos, "want receiver type %v, but have method %L", recv, wrapperFn)
  2271  			}
  2272  			return wrapperFn
  2273  		}
  2274  
  2275  		
  2276  		
  2277  		
  2278  		if method, ok := wrapperFn.(*ir.SelectorExpr); ok && method.Op() == ir.OMETHEXPR && !recv.HasShape() {
  2279  			return typecheck.NewMethodExpr(pos, recv, method.Sel)
  2280  		}
  2281  
  2282  		return r.methodExprWrap(origPos, recv, implicits, deref, addr, baseFn, dictPtr)
  2283  
  2284  	case exprIndex:
  2285  		x := r.expr()
  2286  		pos := r.pos()
  2287  		index := r.expr()
  2288  		n := typecheck.Expr(ir.NewIndexExpr(pos, x, index))
  2289  		switch n.Op() {
  2290  		case ir.OINDEXMAP:
  2291  			n := n.(*ir.IndexExpr)
  2292  			n.RType = r.rtype(pos)
  2293  		}
  2294  		return n
  2295  
  2296  	case exprSlice:
  2297  		x := r.expr()
  2298  		pos := r.pos()
  2299  		var index [3]ir.Node
  2300  		for i := range index {
  2301  			index[i] = r.optExpr()
  2302  		}
  2303  		op := ir.OSLICE
  2304  		if index[2] != nil {
  2305  			op = ir.OSLICE3
  2306  		}
  2307  		return typecheck.Expr(ir.NewSliceExpr(pos, op, x, index[0], index[1], index[2]))
  2308  
  2309  	case exprAssert:
  2310  		x := r.expr()
  2311  		pos := r.pos()
  2312  		typ := r.exprType()
  2313  		srcRType := r.rtype(pos)
  2314  
  2315  		
  2316  		if typ, ok := typ.(*ir.DynamicType); ok && typ.Op() == ir.ODYNAMICTYPE {
  2317  			assert := ir.NewDynamicTypeAssertExpr(pos, ir.ODYNAMICDOTTYPE, x, typ.RType)
  2318  			assert.SrcRType = srcRType
  2319  			assert.ITab = typ.ITab
  2320  			return typed(typ.Type(), assert)
  2321  		}
  2322  		return typecheck.Expr(ir.NewTypeAssertExpr(pos, x, typ.Type()))
  2323  
  2324  	case exprUnaryOp:
  2325  		op := r.op()
  2326  		pos := r.pos()
  2327  		x := r.expr()
  2328  
  2329  		switch op {
  2330  		case ir.OADDR:
  2331  			return typecheck.Expr(typecheck.NodAddrAt(pos, x))
  2332  		case ir.ODEREF:
  2333  			return typecheck.Expr(ir.NewStarExpr(pos, x))
  2334  		}
  2335  		return typecheck.Expr(ir.NewUnaryExpr(pos, op, x))
  2336  
  2337  	case exprBinaryOp:
  2338  		op := r.op()
  2339  		x := r.expr()
  2340  		pos := r.pos()
  2341  		y := r.expr()
  2342  
  2343  		switch op {
  2344  		case ir.OANDAND, ir.OOROR:
  2345  			return typecheck.Expr(ir.NewLogicalExpr(pos, op, x, y))
  2346  		case ir.OLSH, ir.ORSH:
  2347  			
  2348  			
  2349  			if ir.IsConstNode(y) {
  2350  				val := constant.ToInt(y.Val())
  2351  				assert(val.Kind() == constant.Int && constant.Sign(val) >= 0)
  2352  			}
  2353  		}
  2354  		return typecheck.Expr(ir.NewBinaryExpr(pos, op, x, y))
  2355  
  2356  	case exprRecv:
  2357  		x := r.expr()
  2358  		pos := r.pos()
  2359  		for i, n := 0, r.Len(); i < n; i++ {
  2360  			x = Implicit(typecheck.DotField(pos, x, r.Len()))
  2361  		}
  2362  		if r.Bool() { 
  2363  			x = Implicit(Deref(pos, x.Type().Elem(), x))
  2364  		} else if r.Bool() { 
  2365  			x = Implicit(Addr(pos, x))
  2366  		}
  2367  		return x
  2368  
  2369  	case exprCall:
  2370  		var fun ir.Node
  2371  		var args ir.Nodes
  2372  		if r.Bool() { 
  2373  			recv := r.expr()
  2374  			_, method, dictPtr := r.methodExpr()
  2375  
  2376  			if recv.Type().IsInterface() && method.Op() == ir.OMETHEXPR {
  2377  				method := method.(*ir.SelectorExpr)
  2378  
  2379  				
  2380  				
  2381  				
  2382  				
  2383  				
  2384  				
  2385  				
  2386  
  2387  				fun = typecheck.XDotMethod(method.Pos(), recv, method.Sel, true)
  2388  			} else {
  2389  				if recv.Type().IsInterface() {
  2390  					
  2391  					
  2392  					if base.Flag.LowerM != 0 {
  2393  						base.WarnfAt(method.Pos(), "imprecise interface call")
  2394  					}
  2395  				}
  2396  
  2397  				fun = method
  2398  				args.Append(recv)
  2399  			}
  2400  			if dictPtr != nil {
  2401  				args.Append(dictPtr)
  2402  			}
  2403  		} else if r.Bool() { 
  2404  			pos := r.pos()
  2405  			_, shapedFn, dictPtr := r.funcInst(pos)
  2406  			fun = shapedFn
  2407  			args.Append(dictPtr)
  2408  		} else {
  2409  			fun = r.expr()
  2410  		}
  2411  		pos := r.pos()
  2412  		args.Append(r.multiExpr()...)
  2413  		dots := r.Bool()
  2414  		n := typecheck.Call(pos, fun, args, dots)
  2415  		switch n.Op() {
  2416  		case ir.OAPPEND:
  2417  			n := n.(*ir.CallExpr)
  2418  			n.RType = r.rtype(pos)
  2419  			
  2420  			
  2421  			if n.IsDDD {
  2422  				if conv, ok := n.Args[1].(*ir.ConvExpr); ok && conv.Op() == ir.OCONVNOP && conv.Implicit() {
  2423  					n.Args[1] = conv.X
  2424  				}
  2425  			}
  2426  		case ir.OCOPY:
  2427  			n := n.(*ir.BinaryExpr)
  2428  			n.RType = r.rtype(pos)
  2429  		case ir.ODELETE:
  2430  			n := n.(*ir.CallExpr)
  2431  			n.RType = r.rtype(pos)
  2432  		case ir.OUNSAFESLICE:
  2433  			n := n.(*ir.BinaryExpr)
  2434  			n.RType = r.rtype(pos)
  2435  		}
  2436  		return n
  2437  
  2438  	case exprMake:
  2439  		pos := r.pos()
  2440  		typ := r.exprType()
  2441  		extra := r.exprs()
  2442  		n := typecheck.Expr(ir.NewCallExpr(pos, ir.OMAKE, nil, append([]ir.Node{typ}, extra...))).(*ir.MakeExpr)
  2443  		n.RType = r.rtype(pos)
  2444  		return n
  2445  
  2446  	case exprNew:
  2447  		pos := r.pos()
  2448  		typ := r.exprType()
  2449  		return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, typ))
  2450  
  2451  	case exprSizeof:
  2452  		return ir.NewUintptr(r.pos(), r.typ().Size())
  2453  
  2454  	case exprAlignof:
  2455  		return ir.NewUintptr(r.pos(), r.typ().Alignment())
  2456  
  2457  	case exprOffsetof:
  2458  		pos := r.pos()
  2459  		typ := r.typ()
  2460  		types.CalcSize(typ)
  2461  
  2462  		var offset int64
  2463  		for i := r.Len(); i >= 0; i-- {
  2464  			field := typ.Field(r.Len())
  2465  			offset += field.Offset
  2466  			typ = field.Type
  2467  		}
  2468  
  2469  		return ir.NewUintptr(pos, offset)
  2470  
  2471  	case exprReshape:
  2472  		typ := r.typ()
  2473  		old := r.reshaping
  2474  		r.reshaping = true
  2475  		x := r.expr()
  2476  		r.reshaping = old
  2477  
  2478  		if types.IdenticalStrict(x.Type(), typ) {
  2479  			return x
  2480  		}
  2481  
  2482  		
  2483  		
  2484  		
  2485  		
  2486  		
  2487  		if x.Type() == types.UntypedBool && typ.IsBoolean() {
  2488  			return x
  2489  		}
  2490  
  2491  		base.AssertfAt(x.Type().HasShape() || typ.HasShape(), x.Pos(), "%L and %v are not shape types", x, typ)
  2492  		base.AssertfAt(types.Identical(x.Type(), typ), x.Pos(), "%L is not shape-identical to %v", x, typ)
  2493  
  2494  		
  2495  		
  2496  		
  2497  		
  2498  		
  2499  		
  2500  		base.AssertfAt(ir.HasUniquePos(x), x.Pos(), "cannot call SetType(%v) on %L", typ, x)
  2501  
  2502  		if base.Debug.Reshape != 0 {
  2503  			base.WarnfAt(x.Pos(), "reshaping %L to %v", x, typ)
  2504  		}
  2505  
  2506  		x.SetType(typ)
  2507  		return x
  2508  
  2509  	case exprConvert:
  2510  		implicit := r.Bool()
  2511  		typ := r.typ()
  2512  		pos := r.pos()
  2513  		typeWord, srcRType := r.convRTTI(pos)
  2514  		dstTypeParam := r.Bool()
  2515  		identical := r.Bool()
  2516  		x := r.expr()
  2517  
  2518  		
  2519  		x = typecheck.DefaultLit(x, typ)
  2520  
  2521  		ce := ir.NewConvExpr(pos, ir.OCONV, typ, x)
  2522  		ce.TypeWord, ce.SrcRType = typeWord, srcRType
  2523  		if implicit {
  2524  			ce.SetImplicit(true)
  2525  		}
  2526  		n := typecheck.Expr(ce)
  2527  
  2528  		
  2529  		
  2530  		
  2531  		
  2532  		
  2533  		
  2534  		
  2535  		
  2536  		
  2537  		
  2538  		
  2539  		
  2540  		
  2541  		
  2542  		
  2543  		
  2544  		if !identical {
  2545  			if n, ok := n.(*ir.ConvExpr); ok && n.Op() == ir.OCONVNOP && n.Type().IsInterface() && !n.Type().IsEmptyInterface() && (n.Type().HasShape() || n.X.Type().HasShape()) {
  2546  				n.SetOp(ir.OCONVIFACE)
  2547  			}
  2548  		}
  2549  
  2550  		
  2551  		
  2552  		if dstTypeParam && ir.IsConstNode(n) {
  2553  			
  2554  			n = Implicit(ir.NewConvExpr(pos, ir.OCONVNOP, n.Type(), n))
  2555  			n.SetTypecheck(1)
  2556  		}
  2557  		return n
  2558  
  2559  	case exprRuntimeBuiltin:
  2560  		builtin := typecheck.LookupRuntime(r.String())
  2561  		return builtin
  2562  	}
  2563  }
  2564  
  2565  
  2566  
  2567  
  2568  
  2569  
  2570  
  2571  
  2572  
  2573  
  2574  
  2575  
  2576  
  2577  
  2578  
  2579  
  2580  
  2581  
  2582  
  2583  
  2584  
  2585  
  2586  
  2587  func (r *reader) funcInst(pos src.XPos) (wrapperFn, baseFn, dictPtr ir.Node) {
  2588  	
  2589  	var implicits []*types.Type
  2590  	if r.dict != nil {
  2591  		implicits = r.dict.targs
  2592  	}
  2593  
  2594  	if r.Bool() { 
  2595  		idx := r.Len()
  2596  		info := r.dict.subdicts[idx]
  2597  		explicits := r.p.typListIdx(info.explicits, r.dict)
  2598  
  2599  		old := r.p.reshaping
  2600  		r.p.reshaping = r.reshaping
  2601  		baseFn = r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
  2602  		r.p.reshaping = old
  2603  
  2604  		
  2605  		
  2606  		dictPtrType := baseFn.Type().Param(0).Type
  2607  		dictPtr = typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, dictPtrType, r.dictWord(pos, r.dict.subdictsOffset()+idx)))
  2608  
  2609  		return
  2610  	}
  2611  
  2612  	info := r.objInfo()
  2613  	explicits := r.p.typListIdx(info.explicits, r.dict)
  2614  
  2615  	wrapperFn = r.p.objIdx(info.idx, implicits, explicits, false).(*ir.Name)
  2616  	baseFn = r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
  2617  
  2618  	dictName := r.p.objDictName(info.idx, implicits, explicits)
  2619  	dictPtr = typecheck.Expr(ir.NewAddrExpr(pos, dictName))
  2620  
  2621  	return
  2622  }
  2623  
  2624  func (pr *pkgReader) objDictName(idx index, implicits, explicits []*types.Type) *ir.Name {
  2625  	rname := pr.newReader(pkgbits.SectionName, idx, pkgbits.SyncObject1)
  2626  	_, sym := rname.qualifiedIdent()
  2627  	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
  2628  
  2629  	if tag == pkgbits.ObjStub {
  2630  		assert(!sym.IsBlank())
  2631  		if pri, ok := objReader[sym]; ok {
  2632  			return pri.pr.objDictName(pri.idx, nil, explicits)
  2633  		}
  2634  		base.Fatalf("unresolved stub: %v", sym)
  2635  	}
  2636  
  2637  	dict, err := pr.objDictIdx(sym, idx, implicits, explicits, false)
  2638  	if err != nil {
  2639  		base.Fatalf("%v", err)
  2640  	}
  2641  
  2642  	return pr.dictNameOf(dict)
  2643  }
  2644  
  2645  
  2646  
  2647  
  2648  
  2649  
  2650  
  2651  
  2652  func (r *reader) curry(origPos src.XPos, ifaceHack bool, fun ir.Node, arg0, arg1 ir.Node) ir.Node {
  2653  	var captured ir.Nodes
  2654  	captured.Append(fun, arg0)
  2655  	if arg1 != nil {
  2656  		captured.Append(arg1)
  2657  	}
  2658  
  2659  	params, results := syntheticSig(fun.Type())
  2660  	params = params[len(captured)-1:] 
  2661  	typ := types.NewSignature(nil, params, results)
  2662  
  2663  	addBody := func(pos src.XPos, r *reader, captured []ir.Node) {
  2664  		fun := captured[0]
  2665  
  2666  		var args ir.Nodes
  2667  		args.Append(captured[1:]...)
  2668  		args.Append(r.syntheticArgs()...)
  2669  
  2670  		r.syntheticTailCall(pos, fun, args)
  2671  	}
  2672  
  2673  	return r.syntheticClosure(origPos, typ, ifaceHack, captured, addBody)
  2674  }
  2675  
  2676  
  2677  
  2678  
  2679  func (r *reader) methodExprWrap(origPos src.XPos, recv *types.Type, implicits []int, deref, addr bool, method, dictPtr ir.Node) ir.Node {
  2680  	var captured ir.Nodes
  2681  	captured.Append(method)
  2682  
  2683  	params, results := syntheticSig(method.Type())
  2684  
  2685  	
  2686  	params[0].Type = recv
  2687  
  2688  	
  2689  	
  2690  	
  2691  	if dictPtr != nil {
  2692  		captured.Append(dictPtr)
  2693  		params = append(params[:1], params[2:]...)
  2694  	}
  2695  
  2696  	typ := types.NewSignature(nil, params, results)
  2697  
  2698  	addBody := func(pos src.XPos, r *reader, captured []ir.Node) {
  2699  		fn := captured[0]
  2700  		args := r.syntheticArgs()
  2701  
  2702  		
  2703  		{
  2704  			arg := args[0]
  2705  			for _, ix := range implicits {
  2706  				arg = Implicit(typecheck.DotField(pos, arg, ix))
  2707  			}
  2708  			if deref {
  2709  				arg = Implicit(Deref(pos, arg.Type().Elem(), arg))
  2710  			} else if addr {
  2711  				arg = Implicit(Addr(pos, arg))
  2712  			}
  2713  			args[0] = arg
  2714  		}
  2715  
  2716  		
  2717  		if dictPtr != nil {
  2718  			newArgs := make([]ir.Node, len(args)+1)
  2719  			newArgs[0] = args[0]
  2720  			newArgs[1] = captured[1]
  2721  			copy(newArgs[2:], args[1:])
  2722  			args = newArgs
  2723  		}
  2724  
  2725  		r.syntheticTailCall(pos, fn, args)
  2726  	}
  2727  
  2728  	return r.syntheticClosure(origPos, typ, false, captured, addBody)
  2729  }
  2730  
  2731  
  2732  
  2733  
  2734  
  2735  
  2736  
  2737  
  2738  
  2739  
  2740  
  2741  
  2742  
  2743  
  2744  
  2745  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 {
  2746  	
  2747  	
  2748  	
  2749  	
  2750  	
  2751  	isSafe := func(n ir.Node) bool {
  2752  		if n.Op() == ir.ONAME && n.(*ir.Name).Class == ir.PFUNC {
  2753  			return true
  2754  		}
  2755  		if n.Op() == ir.OMETHEXPR {
  2756  			return true
  2757  		}
  2758  
  2759  		return false
  2760  	}
  2761  
  2762  	fn := r.inlClosureFunc(origPos, typ, ir.OCLOSURE)
  2763  	fn.SetWrapper(true)
  2764  
  2765  	clo := fn.OClosure
  2766  	inlPos := clo.Pos()
  2767  
  2768  	var init ir.Nodes
  2769  	for i, n := range captures {
  2770  		if isSafe(n) {
  2771  			continue 
  2772  		}
  2773  
  2774  		tmp := r.tempCopy(inlPos, n, &init)
  2775  		ir.NewClosureVar(origPos, fn, tmp)
  2776  
  2777  		
  2778  		
  2779  		if ifaceHack && i == 1 && n.Type().IsInterface() {
  2780  			check := ir.NewUnaryExpr(inlPos, ir.OCHECKNIL, ir.NewUnaryExpr(inlPos, ir.OITAB, tmp))
  2781  			init.Append(typecheck.Stmt(check))
  2782  		}
  2783  	}
  2784  
  2785  	pri := pkgReaderIndex{synthetic: func(pos src.XPos, r *reader) {
  2786  		captured := make([]ir.Node, len(captures))
  2787  		next := 0
  2788  		for i, n := range captures {
  2789  			if isSafe(n) {
  2790  				captured[i] = n
  2791  			} else {
  2792  				captured[i] = r.closureVars[next]
  2793  				next++
  2794  			}
  2795  		}
  2796  		assert(next == len(r.closureVars))
  2797  
  2798  		addBody(origPos, r, captured)
  2799  	}}
  2800  	bodyReader[fn] = pri
  2801  	pri.funcBody(fn)
  2802  
  2803  	return ir.InitExpr(init, clo)
  2804  }
  2805  
  2806  
  2807  
  2808  
  2809  func syntheticSig(sig *types.Type) (params, results []*types.Field) {
  2810  	clone := func(params []*types.Field) []*types.Field {
  2811  		res := make([]*types.Field, len(params))
  2812  		for i, param := range params {
  2813  			
  2814  			
  2815  			
  2816  			
  2817  			
  2818  			
  2819  			res[i] = types.NewField(base.AutogeneratedPos, param.Sym, param.Type)
  2820  			res[i].SetIsDDD(param.IsDDD())
  2821  		}
  2822  		return res
  2823  	}
  2824  
  2825  	return clone(sig.Params()), clone(sig.Results())
  2826  }
  2827  
  2828  func (r *reader) optExpr() ir.Node {
  2829  	if r.Bool() {
  2830  		return r.expr()
  2831  	}
  2832  	return nil
  2833  }
  2834  
  2835  
  2836  
  2837  
  2838  
  2839  
  2840  
  2841  
  2842  
  2843  
  2844  
  2845  
  2846  
  2847  
  2848  
  2849  
  2850  
  2851  
  2852  
  2853  
  2854  
  2855  
  2856  
  2857  
  2858  func (r *reader) methodExpr() (wrapperFn, baseFn, dictPtr ir.Node) {
  2859  	recv := r.typ()
  2860  	sig0 := r.typ()
  2861  	pos := r.pos()
  2862  	sym := r.selector()
  2863  
  2864  	
  2865  	
  2866  	sig := typecheck.NewMethodType(sig0, recv)
  2867  
  2868  	if r.Bool() { 
  2869  		idx := r.Len()
  2870  		word := r.dictWord(pos, r.dict.typeParamMethodExprsOffset()+idx)
  2871  
  2872  		
  2873  		
  2874  		
  2875  
  2876  		
  2877  		
  2878  		
  2879  		
  2880  		
  2881  		fn := typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, sig, ir.NewAddrExpr(pos, word)))
  2882  		return fn, fn, nil
  2883  	}
  2884  
  2885  	
  2886  	
  2887  	
  2888  	var implicits []*types.Type
  2889  	if r.dict != nil {
  2890  		implicits = r.dict.targs
  2891  	}
  2892  
  2893  	if r.Bool() { 
  2894  		idx := r.Len()
  2895  		info := r.dict.subdicts[idx]
  2896  		explicits := r.p.typListIdx(info.explicits, r.dict)
  2897  
  2898  		shapedObj := r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
  2899  		shapedFn := shapedMethodExpr(pos, shapedObj, sym)
  2900  
  2901  		
  2902  		
  2903  		dictPtrType := shapedFn.Type().Param(1).Type
  2904  		dictPtr := typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, dictPtrType, r.dictWord(pos, r.dict.subdictsOffset()+idx)))
  2905  
  2906  		return nil, shapedFn, dictPtr
  2907  	}
  2908  
  2909  	if r.Bool() { 
  2910  		info := r.objInfo()
  2911  		explicits := r.p.typListIdx(info.explicits, r.dict)
  2912  
  2913  		shapedObj := r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
  2914  		shapedFn := shapedMethodExpr(pos, shapedObj, sym)
  2915  
  2916  		dict := r.p.objDictName(info.idx, implicits, explicits)
  2917  		dictPtr := typecheck.Expr(ir.NewAddrExpr(pos, dict))
  2918  
  2919  		
  2920  		if !types.Identical(dictPtr.Type(), shapedFn.Type().Param(1).Type) {
  2921  			base.FatalfAt(pos, "dict %L, but shaped method %L", dict, shapedFn)
  2922  		}
  2923  
  2924  		
  2925  		
  2926  		base.AssertfAt(!recv.HasShape(), pos, "shaped receiver %v", recv)
  2927  		wrapperFn := typecheck.NewMethodExpr(pos, recv, sym)
  2928  		base.AssertfAt(types.Identical(sig, wrapperFn.Type()), pos, "wrapper %L does not have type %v", wrapperFn, sig)
  2929  
  2930  		return wrapperFn, shapedFn, dictPtr
  2931  	}
  2932  
  2933  	
  2934  	base.AssertfAt(!recv.HasShape() || recv.IsInterface(), pos, "shaped receiver %v", recv)
  2935  	fn := typecheck.NewMethodExpr(pos, recv, sym)
  2936  	return fn, fn, nil
  2937  }
  2938  
  2939  
  2940  
  2941  func shapedMethodExpr(pos src.XPos, obj *ir.Name, sym *types.Sym) *ir.SelectorExpr {
  2942  	assert(obj.Op() == ir.OTYPE)
  2943  
  2944  	typ := obj.Type()
  2945  	assert(typ.HasShape())
  2946  
  2947  	method := func() *types.Field {
  2948  		for _, method := range typ.Methods() {
  2949  			if method.Sym == sym {
  2950  				return method
  2951  			}
  2952  		}
  2953  
  2954  		base.FatalfAt(pos, "failed to find method %v in shaped type %v", sym, typ)
  2955  		panic("unreachable")
  2956  	}()
  2957  
  2958  	
  2959  	recv := method.Type.Recv().Type
  2960  	return typecheck.NewMethodExpr(pos, recv, sym)
  2961  }
  2962  
  2963  func (r *reader) multiExpr() []ir.Node {
  2964  	r.Sync(pkgbits.SyncMultiExpr)
  2965  
  2966  	if r.Bool() { 
  2967  		pos := r.pos()
  2968  		expr := r.expr()
  2969  
  2970  		results := make([]ir.Node, r.Len())
  2971  		as := ir.NewAssignListStmt(pos, ir.OAS2, nil, []ir.Node{expr})
  2972  		as.Def = true
  2973  		for i := range results {
  2974  			tmp := r.temp(pos, r.typ())
  2975  			as.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, tmp))
  2976  			as.Lhs.Append(tmp)
  2977  
  2978  			res := ir.Node(tmp)
  2979  			if r.Bool() {
  2980  				n := ir.NewConvExpr(pos, ir.OCONV, r.typ(), res)
  2981  				n.TypeWord, n.SrcRType = r.convRTTI(pos)
  2982  				n.SetImplicit(true)
  2983  				res = typecheck.Expr(n)
  2984  			}
  2985  			results[i] = res
  2986  		}
  2987  
  2988  		
  2989  		results[0] = ir.InitExpr([]ir.Node{typecheck.Stmt(as)}, results[0])
  2990  		return results
  2991  	}
  2992  
  2993  	
  2994  	exprs := make([]ir.Node, r.Len())
  2995  	if len(exprs) == 0 {
  2996  		return nil
  2997  	}
  2998  	for i := range exprs {
  2999  		exprs[i] = r.expr()
  3000  	}
  3001  	return exprs
  3002  }
  3003  
  3004  
  3005  func (r *reader) temp(pos src.XPos, typ *types.Type) *ir.Name {
  3006  	return typecheck.TempAt(pos, r.curfn, typ)
  3007  }
  3008  
  3009  
  3010  
  3011  func (r *reader) tempCopy(pos src.XPos, expr ir.Node, init *ir.Nodes) *ir.Name {
  3012  	tmp := r.temp(pos, expr.Type())
  3013  
  3014  	init.Append(typecheck.Stmt(ir.NewDecl(pos, ir.ODCL, tmp)))
  3015  
  3016  	assign := ir.NewAssignStmt(pos, tmp, expr)
  3017  	assign.Def = true
  3018  	init.Append(typecheck.Stmt(ir.NewAssignStmt(pos, tmp, expr)))
  3019  
  3020  	tmp.Defn = assign
  3021  
  3022  	return tmp
  3023  }
  3024  
  3025  func (r *reader) compLit() ir.Node {
  3026  	r.Sync(pkgbits.SyncCompLit)
  3027  	pos := r.pos()
  3028  	typ0 := r.typ()
  3029  
  3030  	typ := typ0
  3031  	if typ.IsPtr() {
  3032  		typ = typ.Elem()
  3033  	}
  3034  	if typ.Kind() == types.TFORW {
  3035  		base.FatalfAt(pos, "unresolved composite literal type: %v", typ)
  3036  	}
  3037  	var rtype ir.Node
  3038  	if typ.IsMap() {
  3039  		rtype = r.rtype(pos)
  3040  	}
  3041  	isStruct := typ.Kind() == types.TSTRUCT
  3042  
  3043  	elems := make([]ir.Node, r.Len())
  3044  	for i := range elems {
  3045  		elemp := &elems[i]
  3046  
  3047  		if isStruct {
  3048  			sk := ir.NewStructKeyExpr(r.pos(), typ.Field(r.Len()), nil)
  3049  			*elemp, elemp = sk, &sk.Value
  3050  		} else if r.Bool() {
  3051  			kv := ir.NewKeyExpr(r.pos(), r.expr(), nil)
  3052  			*elemp, elemp = kv, &kv.Value
  3053  		}
  3054  
  3055  		*elemp = r.expr()
  3056  	}
  3057  
  3058  	lit := typecheck.Expr(ir.NewCompLitExpr(pos, ir.OCOMPLIT, typ, elems))
  3059  	if rtype != nil {
  3060  		lit := lit.(*ir.CompLitExpr)
  3061  		lit.RType = rtype
  3062  	}
  3063  	if typ0.IsPtr() {
  3064  		lit = typecheck.Expr(typecheck.NodAddrAt(pos, lit))
  3065  		lit.SetType(typ0)
  3066  	}
  3067  	return lit
  3068  }
  3069  
  3070  func (r *reader) funcLit() ir.Node {
  3071  	r.Sync(pkgbits.SyncFuncLit)
  3072  
  3073  	
  3074  	
  3075  	
  3076  	
  3077  	
  3078  	
  3079  	
  3080  	
  3081  	
  3082  	
  3083  	
  3084  	
  3085  	
  3086  	
  3087  	
  3088  	
  3089  	r.suppressInlPos++
  3090  	origPos := r.pos()
  3091  	sig := r.signature(nil)
  3092  	r.suppressInlPos--
  3093  	why := ir.OCLOSURE
  3094  	if r.Bool() {
  3095  		why = ir.ORANGE
  3096  	}
  3097  
  3098  	fn := r.inlClosureFunc(origPos, sig, why)
  3099  
  3100  	fn.ClosureVars = make([]*ir.Name, 0, r.Len())
  3101  	for len(fn.ClosureVars) < cap(fn.ClosureVars) {
  3102  		
  3103  		
  3104  		ir.NewClosureVar(r.pos(), fn, r.useLocal())
  3105  	}
  3106  	if param := r.dictParam; param != nil {
  3107  		
  3108  		
  3109  		ir.NewClosureVar(param.Pos(), fn, param)
  3110  	}
  3111  
  3112  	r.addBody(fn, nil)
  3113  
  3114  	return fn.OClosure
  3115  }
  3116  
  3117  
  3118  
  3119  func (r *reader) inlClosureFunc(origPos src.XPos, sig *types.Type, why ir.Op) *ir.Func {
  3120  	curfn := r.inlCaller
  3121  	if curfn == nil {
  3122  		curfn = r.curfn
  3123  	}
  3124  
  3125  	
  3126  	return ir.NewClosureFunc(origPos, r.inlPos(origPos), why, sig, curfn, typecheck.Target)
  3127  }
  3128  
  3129  func (r *reader) exprList() []ir.Node {
  3130  	r.Sync(pkgbits.SyncExprList)
  3131  	return r.exprs()
  3132  }
  3133  
  3134  func (r *reader) exprs() []ir.Node {
  3135  	r.Sync(pkgbits.SyncExprs)
  3136  	nodes := make([]ir.Node, r.Len())
  3137  	if len(nodes) == 0 {
  3138  		return nil 
  3139  	}
  3140  	for i := range nodes {
  3141  		nodes[i] = r.expr()
  3142  	}
  3143  	return nodes
  3144  }
  3145  
  3146  
  3147  
  3148  func (r *reader) dictWord(pos src.XPos, idx int) ir.Node {
  3149  	base.AssertfAt(r.dictParam != nil, pos, "expected dictParam in %v", r.curfn)
  3150  	return typecheck.Expr(ir.NewIndexExpr(pos, r.dictParam, ir.NewInt(pos, int64(idx))))
  3151  }
  3152  
  3153  
  3154  
  3155  func (r *reader) rttiWord(pos src.XPos, idx int) ir.Node {
  3156  	return typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, types.NewPtr(types.Types[types.TUINT8]), r.dictWord(pos, idx)))
  3157  }
  3158  
  3159  
  3160  
  3161  
  3162  func (r *reader) rtype(pos src.XPos) ir.Node {
  3163  	_, rtype := r.rtype0(pos)
  3164  	return rtype
  3165  }
  3166  
  3167  func (r *reader) rtype0(pos src.XPos) (typ *types.Type, rtype ir.Node) {
  3168  	r.Sync(pkgbits.SyncRType)
  3169  	if r.Bool() { 
  3170  		idx := r.Len()
  3171  		info := r.dict.rtypes[idx]
  3172  		typ = r.p.typIdx(info, r.dict, true)
  3173  		rtype = r.rttiWord(pos, r.dict.rtypesOffset()+idx)
  3174  		return
  3175  	}
  3176  
  3177  	typ = r.typ()
  3178  	rtype = reflectdata.TypePtrAt(pos, typ)
  3179  	return
  3180  }
  3181  
  3182  
  3183  func (r *reader) varDictIndex(name *ir.Name) {
  3184  	if r.Bool() {
  3185  		idx := 1 + r.dict.rtypesOffset() + r.Len()
  3186  		if int(uint16(idx)) != idx {
  3187  			base.FatalfAt(name.Pos(), "DictIndex overflow for %v: %v", name, idx)
  3188  		}
  3189  		name.DictIndex = uint16(idx)
  3190  	}
  3191  }
  3192  
  3193  
  3194  
  3195  
  3196  
  3197  
  3198  
  3199  
  3200  
  3201  func (r *reader) itab(pos src.XPos) (typ *types.Type, typRType ir.Node, iface *types.Type, ifaceRType ir.Node, itab ir.Node) {
  3202  	typ, typRType = r.rtype0(pos)
  3203  	iface, ifaceRType = r.rtype0(pos)
  3204  
  3205  	idx := -1
  3206  	if r.Bool() {
  3207  		idx = r.Len()
  3208  	}
  3209  
  3210  	if !typ.IsInterface() && iface.IsInterface() && !iface.IsEmptyInterface() {
  3211  		if idx >= 0 {
  3212  			itab = r.rttiWord(pos, r.dict.itabsOffset()+idx)
  3213  		} else {
  3214  			base.AssertfAt(!typ.HasShape(), pos, "%v is a shape type", typ)
  3215  			base.AssertfAt(!iface.HasShape(), pos, "%v is a shape type", iface)
  3216  
  3217  			lsym := reflectdata.ITabLsym(typ, iface)
  3218  			itab = typecheck.LinksymAddr(pos, lsym, types.Types[types.TUINT8])
  3219  		}
  3220  	}
  3221  
  3222  	return
  3223  }
  3224  
  3225  
  3226  
  3227  func (r *reader) convRTTI(pos src.XPos) (typeWord, srcRType ir.Node) {
  3228  	r.Sync(pkgbits.SyncConvRTTI)
  3229  	src, srcRType0, dst, dstRType, itab := r.itab(pos)
  3230  	if !dst.IsInterface() {
  3231  		return
  3232  	}
  3233  
  3234  	
  3235  	switch {
  3236  	case dst.IsEmptyInterface():
  3237  		if !src.IsInterface() {
  3238  			typeWord = srcRType0 
  3239  		}
  3240  	case !src.IsInterface():
  3241  		typeWord = itab 
  3242  	default:
  3243  		typeWord = dstRType 
  3244  	}
  3245  
  3246  	
  3247  	if !src.IsInterface() {
  3248  		srcRType = srcRType0
  3249  	}
  3250  
  3251  	return
  3252  }
  3253  
  3254  func (r *reader) exprType() ir.Node {
  3255  	r.Sync(pkgbits.SyncExprType)
  3256  	pos := r.pos()
  3257  
  3258  	var typ *types.Type
  3259  	var rtype, itab ir.Node
  3260  
  3261  	if r.Bool() {
  3262  		typ, rtype, _, _, itab = r.itab(pos)
  3263  		if !typ.IsInterface() {
  3264  			rtype = nil 
  3265  		}
  3266  	} else {
  3267  		typ, rtype = r.rtype0(pos)
  3268  
  3269  		if !r.Bool() { 
  3270  			return ir.TypeNode(typ)
  3271  		}
  3272  	}
  3273  
  3274  	dt := ir.NewDynamicType(pos, rtype)
  3275  	dt.ITab = itab
  3276  	dt = typed(typ, dt).(*ir.DynamicType)
  3277  	if st := dt.ToStatic(); st != nil {
  3278  		return st
  3279  	}
  3280  	return dt
  3281  }
  3282  
  3283  func (r *reader) op() ir.Op {
  3284  	r.Sync(pkgbits.SyncOp)
  3285  	return ir.Op(r.Len())
  3286  }
  3287  
  3288  
  3289  
  3290  func (r *reader) pkgInit(self *types.Pkg, target *ir.Package) {
  3291  	cgoPragmas := make([][]string, r.Len())
  3292  	for i := range cgoPragmas {
  3293  		cgoPragmas[i] = r.Strings()
  3294  	}
  3295  	target.CgoPragmas = cgoPragmas
  3296  
  3297  	r.pkgInitOrder(target)
  3298  
  3299  	r.pkgDecls(target)
  3300  
  3301  	r.Sync(pkgbits.SyncEOF)
  3302  }
  3303  
  3304  
  3305  
  3306  func (r *reader) pkgInitOrder(target *ir.Package) {
  3307  	initOrder := make([]ir.Node, r.Len())
  3308  	if len(initOrder) == 0 {
  3309  		return
  3310  	}
  3311  
  3312  	
  3313  	pos := base.AutogeneratedPos
  3314  	base.Pos = pos
  3315  
  3316  	fn := ir.NewFunc(pos, pos, typecheck.Lookup("init"), types.NewSignature(nil, nil, nil))
  3317  	fn.SetIsPackageInit(true)
  3318  	fn.SetInlinabilityChecked(true) 
  3319  
  3320  	typecheck.DeclFunc(fn)
  3321  	r.curfn = fn
  3322  
  3323  	for i := range initOrder {
  3324  		lhs := make([]ir.Node, r.Len())
  3325  		for j := range lhs {
  3326  			lhs[j] = r.obj()
  3327  		}
  3328  		rhs := r.expr()
  3329  		pos := lhs[0].Pos()
  3330  
  3331  		var as ir.Node
  3332  		if len(lhs) == 1 {
  3333  			as = typecheck.Stmt(ir.NewAssignStmt(pos, lhs[0], rhs))
  3334  		} else {
  3335  			as = typecheck.Stmt(ir.NewAssignListStmt(pos, ir.OAS2, lhs, []ir.Node{rhs}))
  3336  		}
  3337  
  3338  		for _, v := range lhs {
  3339  			v.(*ir.Name).Defn = as
  3340  		}
  3341  
  3342  		initOrder[i] = as
  3343  	}
  3344  
  3345  	fn.Body = initOrder
  3346  
  3347  	typecheck.FinishFuncBody()
  3348  	r.curfn = nil
  3349  	r.locals = nil
  3350  
  3351  	
  3352  	staticinit.OutlineMapInits(fn)
  3353  
  3354  	target.Inits = append(target.Inits, fn)
  3355  }
  3356  
  3357  func (r *reader) pkgDecls(target *ir.Package) {
  3358  	r.Sync(pkgbits.SyncDecls)
  3359  	for {
  3360  		switch code := codeDecl(r.Code(pkgbits.SyncDecl)); code {
  3361  		default:
  3362  			panic(fmt.Sprintf("unhandled decl: %v", code))
  3363  
  3364  		case declEnd:
  3365  			return
  3366  
  3367  		case declFunc:
  3368  			names := r.pkgObjs(target)
  3369  			assert(len(names) == 1)
  3370  			target.Funcs = append(target.Funcs, names[0].Func)
  3371  
  3372  		case declMethod:
  3373  			typ := r.typ()
  3374  			sym := r.selector()
  3375  
  3376  			method := typecheck.Lookdot1(nil, sym, typ, typ.Methods(), 0)
  3377  			target.Funcs = append(target.Funcs, method.Nname.(*ir.Name).Func)
  3378  
  3379  		case declVar:
  3380  			names := r.pkgObjs(target)
  3381  
  3382  			if n := r.Len(); n > 0 {
  3383  				assert(len(names) == 1)
  3384  				embeds := make([]ir.Embed, n)
  3385  				for i := range embeds {
  3386  					embeds[i] = ir.Embed{Pos: r.pos(), Patterns: r.Strings()}
  3387  				}
  3388  				names[0].Embed = &embeds
  3389  				target.Embeds = append(target.Embeds, names[0])
  3390  			}
  3391  
  3392  		case declOther:
  3393  			r.pkgObjs(target)
  3394  		}
  3395  	}
  3396  }
  3397  
  3398  func (r *reader) pkgObjs(target *ir.Package) []*ir.Name {
  3399  	r.Sync(pkgbits.SyncDeclNames)
  3400  	nodes := make([]*ir.Name, r.Len())
  3401  	for i := range nodes {
  3402  		r.Sync(pkgbits.SyncDeclName)
  3403  
  3404  		name := r.obj().(*ir.Name)
  3405  		nodes[i] = name
  3406  
  3407  		sym := name.Sym()
  3408  		if sym.IsBlank() {
  3409  			continue
  3410  		}
  3411  
  3412  		switch name.Class {
  3413  		default:
  3414  			base.FatalfAt(name.Pos(), "unexpected class: %v", name.Class)
  3415  
  3416  		case ir.PEXTERN:
  3417  			target.Externs = append(target.Externs, name)
  3418  
  3419  		case ir.PFUNC:
  3420  			assert(name.Type().Recv() == nil)
  3421  
  3422  			
  3423  			if strings.HasPrefix(sym.Name, "init.") {
  3424  				target.Inits = append(target.Inits, name.Func)
  3425  			}
  3426  		}
  3427  
  3428  		if base.Ctxt.Flag_dynlink && types.LocalPkg.Name == "main" && types.IsExported(sym.Name) && name.Op() == ir.ONAME {
  3429  			assert(!sym.OnExportList())
  3430  			target.PluginExports = append(target.PluginExports, name)
  3431  			sym.SetOnExportList(true)
  3432  		}
  3433  
  3434  		if base.Flag.AsmHdr != "" && (name.Op() == ir.OLITERAL || name.Op() == ir.OTYPE) {
  3435  			assert(!sym.Asm())
  3436  			target.AsmHdrDecls = append(target.AsmHdrDecls, name)
  3437  			sym.SetAsm(true)
  3438  		}
  3439  	}
  3440  
  3441  	return nodes
  3442  }
  3443  
  3444  
  3445  
  3446  
  3447  
  3448  func unifiedHaveInlineBody(fn *ir.Func) bool {
  3449  	if fn.Inl == nil {
  3450  		return false
  3451  	}
  3452  
  3453  	_, ok := bodyReaderFor(fn)
  3454  	return ok
  3455  }
  3456  
  3457  var inlgen = 0
  3458  
  3459  
  3460  
  3461  func unifiedInlineCall(callerfn *ir.Func, call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
  3462  	pri, ok := bodyReaderFor(fn)
  3463  	if !ok {
  3464  		base.FatalfAt(call.Pos(), "cannot inline call to %v: missing inline body", fn)
  3465  	}
  3466  
  3467  	if !fn.Inl.HaveDcl {
  3468  		expandInline(fn, pri)
  3469  	}
  3470  
  3471  	r := pri.asReader(pkgbits.SectionBody, pkgbits.SyncFuncBody)
  3472  
  3473  	tmpfn := ir.NewFunc(fn.Pos(), fn.Nname.Pos(), callerfn.Sym(), fn.Type())
  3474  
  3475  	r.curfn = tmpfn
  3476  
  3477  	r.inlCaller = callerfn
  3478  	r.inlCall = call
  3479  	r.inlFunc = fn
  3480  	r.inlTreeIndex = inlIndex
  3481  	r.inlPosBases = make(map[*src.PosBase]*src.PosBase)
  3482  	r.funarghack = true
  3483  
  3484  	r.closureVars = make([]*ir.Name, len(r.inlFunc.ClosureVars))
  3485  	for i, cv := range r.inlFunc.ClosureVars {
  3486  		
  3487  		
  3488  		if cv.Outer.Curfn != callerfn {
  3489  			base.FatalfAt(call.Pos(), "inlining closure call across frames")
  3490  		}
  3491  		r.closureVars[i] = cv.Outer
  3492  	}
  3493  	if len(r.closureVars) != 0 && r.hasTypeParams() {
  3494  		r.dictParam = r.closureVars[len(r.closureVars)-1] 
  3495  	}
  3496  
  3497  	r.declareParams()
  3498  
  3499  	var inlvars, retvars []*ir.Name
  3500  	{
  3501  		sig := r.curfn.Type()
  3502  		endParams := sig.NumRecvs() + sig.NumParams()
  3503  		endResults := endParams + sig.NumResults()
  3504  
  3505  		inlvars = r.curfn.Dcl[:endParams]
  3506  		retvars = r.curfn.Dcl[endParams:endResults]
  3507  	}
  3508  
  3509  	r.delayResults = fn.Inl.CanDelayResults
  3510  
  3511  	r.retlabel = typecheck.AutoLabel(".i")
  3512  	inlgen++
  3513  
  3514  	init := ir.TakeInit(call)
  3515  
  3516  	
  3517  	
  3518  	
  3519  	if call.Op() == ir.OCALLFUNC {
  3520  		inline.CalleeEffects(&init, call.Fun)
  3521  	}
  3522  
  3523  	var args ir.Nodes
  3524  	if call.Op() == ir.OCALLMETH {
  3525  		base.FatalfAt(call.Pos(), "OCALLMETH missed by typecheck")
  3526  	}
  3527  	args.Append(call.Args...)
  3528  
  3529  	
  3530  	as2 := ir.NewAssignListStmt(call.Pos(), ir.OAS2, ir.ToNodes(inlvars), args)
  3531  	as2.Def = true
  3532  	var as2init ir.Nodes
  3533  	for _, name := range inlvars {
  3534  		if ir.IsBlank(name) {
  3535  			continue
  3536  		}
  3537  		
  3538  		as2init.Append(ir.NewDecl(call.Pos(), ir.ODCL, name))
  3539  		name.Defn = as2
  3540  	}
  3541  	as2.SetInit(as2init)
  3542  	init.Append(typecheck.Stmt(as2))
  3543  
  3544  	if !r.delayResults {
  3545  		
  3546  		
  3547  		for _, name := range retvars {
  3548  			
  3549  			init.Append(ir.NewDecl(call.Pos(), ir.ODCL, name))
  3550  			ras := ir.NewAssignStmt(call.Pos(), name, nil)
  3551  			init.Append(typecheck.Stmt(ras))
  3552  		}
  3553  	}
  3554  
  3555  	
  3556  	
  3557  	
  3558  	
  3559  	
  3560  	init.Append(ir.NewInlineMarkStmt(call.Pos().WithIsStmt(), int64(r.inlTreeIndex)))
  3561  
  3562  	ir.WithFunc(r.curfn, func() {
  3563  		if !r.syntheticBody(call.Pos()) {
  3564  			assert(r.Bool()) 
  3565  
  3566  			r.curfn.Body = r.stmts()
  3567  			r.curfn.Endlineno = r.pos()
  3568  		}
  3569  
  3570  		
  3571  		
  3572  		
  3573  		
  3574  		
  3575  		readBodies(typecheck.Target, true)
  3576  
  3577  		
  3578  		var edit func(ir.Node) ir.Node
  3579  		edit = func(n ir.Node) ir.Node {
  3580  			if ret, ok := n.(*ir.ReturnStmt); ok {
  3581  				n = typecheck.Stmt(r.inlReturn(ret, retvars))
  3582  			}
  3583  			ir.EditChildren(n, edit)
  3584  			return n
  3585  		}
  3586  		edit(r.curfn)
  3587  	})
  3588  
  3589  	body := ir.Nodes(r.curfn.Body)
  3590  
  3591  	
  3592  	for _, name := range r.curfn.Dcl {
  3593  		name.Curfn = callerfn
  3594  
  3595  		if name.Class != ir.PAUTO {
  3596  			name.SetPos(r.inlPos(name.Pos()))
  3597  			name.SetInlFormal(true)
  3598  			name.Class = ir.PAUTO
  3599  		} else {
  3600  			name.SetInlLocal(true)
  3601  		}
  3602  	}
  3603  	callerfn.Dcl = append(callerfn.Dcl, r.curfn.Dcl...)
  3604  
  3605  	body.Append(ir.NewLabelStmt(call.Pos(), r.retlabel))
  3606  
  3607  	res := ir.NewInlinedCallExpr(call.Pos(), body, ir.ToNodes(retvars))
  3608  	res.SetInit(init)
  3609  	res.SetType(call.Type())
  3610  	res.SetTypecheck(1)
  3611  
  3612  	
  3613  	assert(len(todoBodies) == 0)
  3614  
  3615  	return res
  3616  }
  3617  
  3618  
  3619  
  3620  func (r *reader) inlReturn(ret *ir.ReturnStmt, retvars []*ir.Name) *ir.BlockStmt {
  3621  	pos := r.inlCall.Pos()
  3622  
  3623  	block := ir.TakeInit(ret)
  3624  
  3625  	if results := ret.Results; len(results) != 0 {
  3626  		assert(len(retvars) == len(results))
  3627  
  3628  		as2 := ir.NewAssignListStmt(pos, ir.OAS2, ir.ToNodes(retvars), ret.Results)
  3629  
  3630  		if r.delayResults {
  3631  			for _, name := range retvars {
  3632  				
  3633  				block.Append(ir.NewDecl(pos, ir.ODCL, name))
  3634  				name.Defn = as2
  3635  			}
  3636  		}
  3637  
  3638  		block.Append(as2)
  3639  	}
  3640  
  3641  	block.Append(ir.NewBranchStmt(pos, ir.OGOTO, r.retlabel))
  3642  	return ir.NewBlockStmt(pos, block)
  3643  }
  3644  
  3645  
  3646  
  3647  func expandInline(fn *ir.Func, pri pkgReaderIndex) {
  3648  	
  3649  	
  3650  	
  3651  	
  3652  
  3653  	fndcls := len(fn.Dcl)
  3654  	topdcls := len(typecheck.Target.Funcs)
  3655  
  3656  	tmpfn := ir.NewFunc(fn.Pos(), fn.Nname.Pos(), fn.Sym(), fn.Type())
  3657  	tmpfn.ClosureVars = fn.ClosureVars
  3658  
  3659  	{
  3660  		r := pri.asReader(pkgbits.SectionBody, pkgbits.SyncFuncBody)
  3661  
  3662  		
  3663  		r.funarghack = true
  3664  
  3665  		r.funcBody(tmpfn)
  3666  	}
  3667  
  3668  	
  3669  	for _, name := range tmpfn.Dcl {
  3670  		name.Curfn = fn
  3671  	}
  3672  	fn.Inl.Dcl = tmpfn.Dcl
  3673  	fn.Inl.HaveDcl = true
  3674  
  3675  	
  3676  	assert(fndcls == len(fn.Dcl))
  3677  
  3678  	
  3679  	
  3680  	
  3681  	typecheck.Target.Funcs = typecheck.Target.Funcs[:topdcls]
  3682  }
  3683  
  3684  
  3685  func usedLocals(body []ir.Node) ir.NameSet {
  3686  	var used ir.NameSet
  3687  	ir.VisitList(body, func(n ir.Node) {
  3688  		if n, ok := n.(*ir.Name); ok && n.Op() == ir.ONAME && n.Class == ir.PAUTO {
  3689  			used.Add(n)
  3690  		}
  3691  	})
  3692  	return used
  3693  }
  3694  
  3695  
  3696  
  3697  
  3698  
  3699  
  3700  
  3701  
  3702  
  3703  
  3704  
  3705  
  3706  
  3707  
  3708  
  3709  
  3710  
  3711  
  3712  
  3713  
  3714  
  3715  
  3716  
  3717  
  3718  
  3719  
  3720  
  3721  
  3722  
  3723  
  3724  
  3725  
  3726  
  3727  
  3728  
  3729  
  3730  
  3731  
  3732  
  3733  
  3734  
  3735  
  3736  
  3737  
  3738  
  3739  
  3740  
  3741  
  3742  
  3743  
  3744  
  3745  
  3746  
  3747  
  3748  
  3749  
  3750  var needWrapperTypes []*types.Type
  3751  
  3752  
  3753  
  3754  var haveWrapperTypes []*types.Type
  3755  
  3756  
  3757  
  3758  var needMethodValueWrappers []methodValueWrapper
  3759  
  3760  
  3761  
  3762  
  3763  var haveMethodValueWrappers []methodValueWrapper
  3764  
  3765  type methodValueWrapper struct {
  3766  	rcvr   *types.Type
  3767  	method *types.Field
  3768  }
  3769  
  3770  
  3771  
  3772  func (r *reader) needWrapper(typ *types.Type) {
  3773  	if typ.IsPtr() {
  3774  		return
  3775  	}
  3776  
  3777  	
  3778  	forceNeed := typ == types.ErrorType && base.Ctxt.Pkgpath == "runtime"
  3779  
  3780  	
  3781  	
  3782  	
  3783  	if r.importedDef() && !forceNeed {
  3784  		haveWrapperTypes = append(haveWrapperTypes, typ)
  3785  	} else {
  3786  		needWrapperTypes = append(needWrapperTypes, typ)
  3787  	}
  3788  }
  3789  
  3790  
  3791  
  3792  
  3793  
  3794  
  3795  
  3796  
  3797  
  3798  
  3799  
  3800  
  3801  
  3802  
  3803  
  3804  func (r *reader) importedDef() bool {
  3805  	return r.p != localPkgReader && !r.hasTypeParams()
  3806  }
  3807  
  3808  
  3809  
  3810  func MakeWrappers(target *ir.Package) {
  3811  	
  3812  	needWrapperTypes = append(needWrapperTypes, types.ErrorType)
  3813  
  3814  	seen := make(map[string]*types.Type)
  3815  
  3816  	for _, typ := range haveWrapperTypes {
  3817  		wrapType(typ, target, seen, false)
  3818  	}
  3819  	haveWrapperTypes = nil
  3820  
  3821  	for _, typ := range needWrapperTypes {
  3822  		wrapType(typ, target, seen, true)
  3823  	}
  3824  	needWrapperTypes = nil
  3825  
  3826  	for _, wrapper := range haveMethodValueWrappers {
  3827  		wrapMethodValue(wrapper.rcvr, wrapper.method, target, false)
  3828  	}
  3829  	haveMethodValueWrappers = nil
  3830  
  3831  	for _, wrapper := range needMethodValueWrappers {
  3832  		wrapMethodValue(wrapper.rcvr, wrapper.method, target, true)
  3833  	}
  3834  	needMethodValueWrappers = nil
  3835  }
  3836  
  3837  func wrapType(typ *types.Type, target *ir.Package, seen map[string]*types.Type, needed bool) {
  3838  	key := typ.LinkString()
  3839  	if prev := seen[key]; prev != nil {
  3840  		if !types.Identical(typ, prev) {
  3841  			base.Fatalf("collision: types %v and %v have link string %q", typ, prev, key)
  3842  		}
  3843  		return
  3844  	}
  3845  	seen[key] = typ
  3846  
  3847  	if !needed {
  3848  		
  3849  		return
  3850  	}
  3851  
  3852  	if !typ.IsInterface() {
  3853  		typecheck.CalcMethods(typ)
  3854  	}
  3855  	for _, meth := range typ.AllMethods() {
  3856  		if meth.Sym.IsBlank() || !meth.IsMethod() {
  3857  			base.FatalfAt(meth.Pos, "invalid method: %v", meth)
  3858  		}
  3859  
  3860  		methodWrapper(0, typ, meth, target)
  3861  
  3862  		
  3863  		if !typ.IsInterface() {
  3864  			methodWrapper(1, typ, meth, target)
  3865  
  3866  			
  3867  			
  3868  			if typ.NotInHeap() {
  3869  				methodWrapper(2, typ, meth, target)
  3870  			}
  3871  		}
  3872  	}
  3873  }
  3874  
  3875  func methodWrapper(derefs int, tbase *types.Type, method *types.Field, target *ir.Package) {
  3876  	wrapper := tbase
  3877  	for i := 0; i < derefs; i++ {
  3878  		wrapper = types.NewPtr(wrapper)
  3879  	}
  3880  
  3881  	sym := ir.MethodSym(wrapper, method.Sym)
  3882  	base.Assertf(!sym.Siggen(), "already generated wrapper %v", sym)
  3883  	sym.SetSiggen(true)
  3884  
  3885  	wrappee := method.Type.Recv().Type
  3886  	if types.Identical(wrapper, wrappee) ||
  3887  		!types.IsMethodApplicable(wrapper, method) ||
  3888  		!reflectdata.NeedEmit(tbase) {
  3889  		return
  3890  	}
  3891  
  3892  	
  3893  	pos := base.AutogeneratedPos
  3894  
  3895  	fn := newWrapperFunc(pos, sym, wrapper, method)
  3896  
  3897  	var recv ir.Node = fn.Nname.Type().Recv().Nname.(*ir.Name)
  3898  
  3899  	
  3900  	
  3901  	if wrapper.IsPtr() && types.Identical(wrapper.Elem(), wrappee) {
  3902  		cond := ir.NewBinaryExpr(pos, ir.OEQ, recv, types.BuiltinPkg.Lookup("nil").Def.(ir.Node))
  3903  		then := []ir.Node{ir.NewCallExpr(pos, ir.OCALL, typecheck.LookupRuntime("panicwrap"), nil)}
  3904  		fn.Body.Append(ir.NewIfStmt(pos, cond, then, nil))
  3905  	}
  3906  
  3907  	
  3908  	
  3909  	for i := 1; i < derefs; i++ {
  3910  		recv = Implicit(ir.NewStarExpr(pos, recv))
  3911  	}
  3912  
  3913  	addTailCall(pos, fn, recv, method)
  3914  
  3915  	finishWrapperFunc(fn, target)
  3916  }
  3917  
  3918  func wrapMethodValue(recvType *types.Type, method *types.Field, target *ir.Package, needed bool) {
  3919  	sym := ir.MethodSymSuffix(recvType, method.Sym, "-fm")
  3920  	if sym.Uniq() {
  3921  		return
  3922  	}
  3923  	sym.SetUniq(true)
  3924  
  3925  	
  3926  	pos := base.AutogeneratedPos
  3927  
  3928  	fn := newWrapperFunc(pos, sym, nil, method)
  3929  	sym.Def = fn.Nname
  3930  
  3931  	
  3932  	recv := ir.NewHiddenParam(pos, fn, typecheck.Lookup(".this"), recvType)
  3933  
  3934  	if !needed {
  3935  		return
  3936  	}
  3937  
  3938  	addTailCall(pos, fn, recv, method)
  3939  
  3940  	finishWrapperFunc(fn, target)
  3941  }
  3942  
  3943  func newWrapperFunc(pos src.XPos, sym *types.Sym, wrapper *types.Type, method *types.Field) *ir.Func {
  3944  	sig := newWrapperType(wrapper, method)
  3945  	fn := ir.NewFunc(pos, pos, sym, sig)
  3946  	fn.DeclareParams(true)
  3947  	fn.SetDupok(true) 
  3948  
  3949  	return fn
  3950  }
  3951  
  3952  func finishWrapperFunc(fn *ir.Func, target *ir.Package) {
  3953  	ir.WithFunc(fn, func() {
  3954  		typecheck.Stmts(fn.Body)
  3955  	})
  3956  
  3957  	
  3958  	
  3959  	
  3960  	interleaved.DevirtualizeAndInlineFunc(fn, nil)
  3961  
  3962  	
  3963  	
  3964  	
  3965  	
  3966  	
  3967  	
  3968  	
  3969  	ir.VisitFuncAndClosures(fn, func(n ir.Node) {
  3970  		if n, ok := n.(*ir.SelectorExpr); ok && n.Op() == ir.OMETHVALUE {
  3971  			wrapMethodValue(n.X.Type(), n.Selection, target, true)
  3972  		}
  3973  	})
  3974  
  3975  	fn.Nname.Defn = fn
  3976  	target.Funcs = append(target.Funcs, fn)
  3977  }
  3978  
  3979  
  3980  
  3981  
  3982  
  3983  func newWrapperType(recvType *types.Type, method *types.Field) *types.Type {
  3984  	clone := func(params []*types.Field) []*types.Field {
  3985  		res := make([]*types.Field, len(params))
  3986  		for i, param := range params {
  3987  			res[i] = types.NewField(param.Pos, param.Sym, param.Type)
  3988  			res[i].SetIsDDD(param.IsDDD())
  3989  		}
  3990  		return res
  3991  	}
  3992  
  3993  	sig := method.Type
  3994  
  3995  	var recv *types.Field
  3996  	if recvType != nil {
  3997  		recv = types.NewField(sig.Recv().Pos, sig.Recv().Sym, recvType)
  3998  	}
  3999  	params := clone(sig.Params())
  4000  	results := clone(sig.Results())
  4001  
  4002  	return types.NewSignature(recv, params, results)
  4003  }
  4004  
  4005  func addTailCall(pos src.XPos, fn *ir.Func, recv ir.Node, method *types.Field) {
  4006  	sig := fn.Nname.Type()
  4007  	args := make([]ir.Node, sig.NumParams())
  4008  	for i, param := range sig.Params() {
  4009  		args[i] = param.Nname.(*ir.Name)
  4010  	}
  4011  
  4012  	dot := typecheck.XDotMethod(pos, recv, method.Sym, true)
  4013  	call := typecheck.Call(pos, dot, args, method.Type.IsVariadic()).(*ir.CallExpr)
  4014  
  4015  	if recv.Type() != nil && recv.Type().IsPtr() && method.Type.Recv().Type.IsPtr() &&
  4016  		method.Embedded != 0 && !types.IsInterfaceMethod(method.Type) &&
  4017  		!unifiedHaveInlineBody(ir.MethodExprName(dot).Func) &&
  4018  		!(base.Ctxt.Arch.Name == "ppc64le" && base.Ctxt.Flag_dynlink) {
  4019  		if base.Debug.TailCall != 0 {
  4020  			base.WarnfAt(fn.Nname.Type().Recv().Type.Elem().Pos(), "tail call emitted for the method %v wrapper", method.Nname)
  4021  		}
  4022  		
  4023  		fn.Body.Append(ir.NewTailCallStmt(pos, call))
  4024  		return
  4025  	}
  4026  
  4027  	fn.SetWrapper(true)
  4028  
  4029  	if method.Type.NumResults() == 0 {
  4030  		fn.Body.Append(call)
  4031  		return
  4032  	}
  4033  
  4034  	ret := ir.NewReturnStmt(pos, nil)
  4035  	ret.Results = []ir.Node{call}
  4036  	fn.Body.Append(ret)
  4037  }
  4038  
  4039  func setBasePos(pos src.XPos) {
  4040  	
  4041  	base.Pos = pos
  4042  }
  4043  
  4044  
  4045  
  4046  
  4047  
  4048  
  4049  const dictParamName = typecheck.LocalDictName
  4050  
  4051  
  4052  
  4053  
  4054  
  4055  
  4056  
  4057  func shapeSig(fn *ir.Func, dict *readerDict) *types.Type {
  4058  	sig := fn.Nname.Type()
  4059  	oldRecv := sig.Recv()
  4060  
  4061  	var recv *types.Field
  4062  	if oldRecv != nil {
  4063  		recv = types.NewField(oldRecv.Pos, oldRecv.Sym, oldRecv.Type)
  4064  	}
  4065  
  4066  	params := make([]*types.Field, 1+sig.NumParams())
  4067  	params[0] = types.NewField(fn.Pos(), fn.Sym().Pkg.Lookup(dictParamName), types.NewPtr(dict.varType()))
  4068  	for i, param := range sig.Params() {
  4069  		d := types.NewField(param.Pos, param.Sym, param.Type)
  4070  		d.SetIsDDD(param.IsDDD())
  4071  		params[1+i] = d
  4072  	}
  4073  
  4074  	results := make([]*types.Field, sig.NumResults())
  4075  	for i, result := range sig.Results() {
  4076  		results[i] = types.NewField(result.Pos, result.Sym, result.Type)
  4077  	}
  4078  
  4079  	return types.NewSignature(recv, params, results)
  4080  }
  4081  
View as plain text