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

     1  // UNREVIEWED
     2  
     3  // Copyright 2021 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package noder
     8  
     9  import (
    10  	"cmd/compile/internal/base"
    11  	"cmd/compile/internal/syntax"
    12  	"cmd/compile/internal/types2"
    13  	"cmd/internal/src"
    14  )
    15  
    16  type pkgReader2 struct {
    17  	pkgDecoder
    18  
    19  	ctxt    *types2.Context
    20  	imports map[string]*types2.Package
    21  
    22  	posBases []*syntax.PosBase
    23  	pkgs     []*types2.Package
    24  	typs     []types2.Type
    25  }
    26  
    27  func readPackage2(ctxt *types2.Context, imports map[string]*types2.Package, input pkgDecoder) *types2.Package {
    28  	pr := pkgReader2{
    29  		pkgDecoder: input,
    30  
    31  		ctxt:    ctxt,
    32  		imports: imports,
    33  
    34  		posBases: make([]*syntax.PosBase, input.numElems(relocPosBase)),
    35  		pkgs:     make([]*types2.Package, input.numElems(relocPkg)),
    36  		typs:     make([]types2.Type, input.numElems(relocType)),
    37  	}
    38  
    39  	r := pr.newReader(relocMeta, publicRootIdx, syncPublic)
    40  	pkg := r.pkg()
    41  	r.bool() // has init
    42  
    43  	for i, n := 0, r.len(); i < n; i++ {
    44  		// As if r.obj(), but avoiding the Scope.Lookup call,
    45  		// to avoid eager loading of imports.
    46  		r.sync(syncObject)
    47  		assert(!r.bool())
    48  		r.p.objIdx(r.reloc(relocObj))
    49  		assert(r.len() == 0)
    50  	}
    51  
    52  	r.sync(syncEOF)
    53  
    54  	pkg.MarkComplete()
    55  	return pkg
    56  }
    57  
    58  type reader2 struct {
    59  	decoder
    60  
    61  	p *pkgReader2
    62  
    63  	dict *reader2Dict
    64  }
    65  
    66  type reader2Dict struct {
    67  	bounds []typeInfo
    68  
    69  	tparams []*types2.TypeParam
    70  
    71  	derived      []derivedInfo
    72  	derivedTypes []types2.Type
    73  }
    74  
    75  type reader2TypeBound struct {
    76  	derived  bool
    77  	boundIdx int
    78  }
    79  
    80  func (pr *pkgReader2) newReader(k reloc, idx int, marker syncMarker) *reader2 {
    81  	return &reader2{
    82  		decoder: pr.newDecoder(k, idx, marker),
    83  		p:       pr,
    84  	}
    85  }
    86  
    87  // @@@ Positions
    88  
    89  func (r *reader2) pos() syntax.Pos {
    90  	r.sync(syncPos)
    91  	if !r.bool() {
    92  		return syntax.Pos{}
    93  	}
    94  
    95  	// TODO(mdempsky): Delta encoding.
    96  	posBase := r.posBase()
    97  	line := r.uint()
    98  	col := r.uint()
    99  	return syntax.MakePos(posBase, line, col)
   100  }
   101  
   102  func (r *reader2) posBase() *syntax.PosBase {
   103  	return r.p.posBaseIdx(r.reloc(relocPosBase))
   104  }
   105  
   106  func (pr *pkgReader2) posBaseIdx(idx int) *syntax.PosBase {
   107  	if b := pr.posBases[idx]; b != nil {
   108  		return b
   109  	}
   110  
   111  	r := pr.newReader(relocPosBase, idx, syncPosBase)
   112  	var b *syntax.PosBase
   113  
   114  	filename := r.string()
   115  
   116  	if r.bool() {
   117  		b = syntax.NewTrimmedFileBase(filename, true)
   118  	} else {
   119  		pos := r.pos()
   120  		line := r.uint()
   121  		col := r.uint()
   122  		b = syntax.NewLineBase(pos, filename, true, line, col)
   123  	}
   124  
   125  	pr.posBases[idx] = b
   126  	return b
   127  }
   128  
   129  // @@@ Packages
   130  
   131  func (r *reader2) pkg() *types2.Package {
   132  	r.sync(syncPkg)
   133  	return r.p.pkgIdx(r.reloc(relocPkg))
   134  }
   135  
   136  func (pr *pkgReader2) pkgIdx(idx int) *types2.Package {
   137  	// TODO(mdempsky): Consider using some non-nil pointer to indicate
   138  	// the universe scope, so we don't need to keep re-reading it.
   139  	if pkg := pr.pkgs[idx]; pkg != nil {
   140  		return pkg
   141  	}
   142  
   143  	pkg := pr.newReader(relocPkg, idx, syncPkgDef).doPkg()
   144  	pr.pkgs[idx] = pkg
   145  	return pkg
   146  }
   147  
   148  func (r *reader2) doPkg() *types2.Package {
   149  	path := r.string()
   150  	if path == "builtin" {
   151  		return nil // universe
   152  	}
   153  	if path == "" {
   154  		path = r.p.pkgPath
   155  	}
   156  
   157  	if pkg := r.p.imports[path]; pkg != nil {
   158  		return pkg
   159  	}
   160  
   161  	name := r.string()
   162  	height := r.len()
   163  
   164  	pkg := types2.NewPackageHeight(path, name, height)
   165  	r.p.imports[path] = pkg
   166  
   167  	// TODO(mdempsky): The list of imported packages is important for
   168  	// go/types, but we could probably skip populating it for types2.
   169  	imports := make([]*types2.Package, r.len())
   170  	for i := range imports {
   171  		imports[i] = r.pkg()
   172  	}
   173  	pkg.SetImports(imports)
   174  
   175  	return pkg
   176  }
   177  
   178  // @@@ Types
   179  
   180  func (r *reader2) typ() types2.Type {
   181  	return r.p.typIdx(r.typInfo(), r.dict)
   182  }
   183  
   184  func (r *reader2) typInfo() typeInfo {
   185  	r.sync(syncType)
   186  	if r.bool() {
   187  		return typeInfo{idx: r.len(), derived: true}
   188  	}
   189  	return typeInfo{idx: r.reloc(relocType), derived: false}
   190  }
   191  
   192  func (pr *pkgReader2) typIdx(info typeInfo, dict *reader2Dict) types2.Type {
   193  	idx := info.idx
   194  	var where *types2.Type
   195  	if info.derived {
   196  		where = &dict.derivedTypes[idx]
   197  		idx = dict.derived[idx].idx
   198  	} else {
   199  		where = &pr.typs[idx]
   200  	}
   201  
   202  	if typ := *where; typ != nil {
   203  		return typ
   204  	}
   205  
   206  	r := pr.newReader(relocType, idx, syncTypeIdx)
   207  	r.dict = dict
   208  
   209  	typ := r.doTyp()
   210  	assert(typ != nil)
   211  
   212  	// See comment in pkgReader.typIdx explaining how this happens.
   213  	if prev := *where; prev != nil {
   214  		return prev
   215  	}
   216  
   217  	*where = typ
   218  	return typ
   219  }
   220  
   221  func (r *reader2) doTyp() (res types2.Type) {
   222  	switch tag := codeType(r.code(syncType)); tag {
   223  	default:
   224  		base.FatalfAt(src.NoXPos, "unhandled type tag: %v", tag)
   225  		panic("unreachable")
   226  
   227  	case typeBasic:
   228  		return types2.Typ[r.len()]
   229  
   230  	case typeNamed:
   231  		obj, targs := r.obj()
   232  		name := obj.(*types2.TypeName)
   233  		if len(targs) != 0 {
   234  			t, _ := types2.Instantiate(r.p.ctxt, name.Type(), targs, false)
   235  			return t
   236  		}
   237  		return name.Type()
   238  
   239  	case typeTypeParam:
   240  		return r.dict.tparams[r.len()]
   241  
   242  	case typeArray:
   243  		len := int64(r.uint64())
   244  		return types2.NewArray(r.typ(), len)
   245  	case typeChan:
   246  		dir := types2.ChanDir(r.len())
   247  		return types2.NewChan(dir, r.typ())
   248  	case typeMap:
   249  		return types2.NewMap(r.typ(), r.typ())
   250  	case typePointer:
   251  		return types2.NewPointer(r.typ())
   252  	case typeSignature:
   253  		return r.signature(nil, nil, nil)
   254  	case typeSlice:
   255  		return types2.NewSlice(r.typ())
   256  	case typeStruct:
   257  		return r.structType()
   258  	case typeInterface:
   259  		return r.interfaceType()
   260  	case typeUnion:
   261  		return r.unionType()
   262  	}
   263  }
   264  
   265  func (r *reader2) structType() *types2.Struct {
   266  	fields := make([]*types2.Var, r.len())
   267  	var tags []string
   268  	for i := range fields {
   269  		pos := r.pos()
   270  		pkg, name := r.selector()
   271  		ftyp := r.typ()
   272  		tag := r.string()
   273  		embedded := r.bool()
   274  
   275  		fields[i] = types2.NewField(pos, pkg, name, ftyp, embedded)
   276  		if tag != "" {
   277  			for len(tags) < i {
   278  				tags = append(tags, "")
   279  			}
   280  			tags = append(tags, tag)
   281  		}
   282  	}
   283  	return types2.NewStruct(fields, tags)
   284  }
   285  
   286  func (r *reader2) unionType() *types2.Union {
   287  	terms := make([]*types2.Term, r.len())
   288  	for i := range terms {
   289  		terms[i] = types2.NewTerm(r.bool(), r.typ())
   290  	}
   291  	return types2.NewUnion(terms)
   292  }
   293  
   294  func (r *reader2) interfaceType() *types2.Interface {
   295  	methods := make([]*types2.Func, r.len())
   296  	embeddeds := make([]types2.Type, r.len())
   297  
   298  	for i := range methods {
   299  		pos := r.pos()
   300  		pkg, name := r.selector()
   301  		mtyp := r.signature(nil, nil, nil)
   302  		methods[i] = types2.NewFunc(pos, pkg, name, mtyp)
   303  	}
   304  
   305  	for i := range embeddeds {
   306  		embeddeds[i] = r.typ()
   307  	}
   308  
   309  	return types2.NewInterfaceType(methods, embeddeds)
   310  }
   311  
   312  func (r *reader2) signature(recv *types2.Var, rtparams, tparams []*types2.TypeParam) *types2.Signature {
   313  	r.sync(syncSignature)
   314  
   315  	params := r.params()
   316  	results := r.params()
   317  	variadic := r.bool()
   318  
   319  	return types2.NewSignatureType(recv, rtparams, tparams, params, results, variadic)
   320  }
   321  
   322  func (r *reader2) params() *types2.Tuple {
   323  	r.sync(syncParams)
   324  	params := make([]*types2.Var, r.len())
   325  	for i := range params {
   326  		params[i] = r.param()
   327  	}
   328  	return types2.NewTuple(params...)
   329  }
   330  
   331  func (r *reader2) param() *types2.Var {
   332  	r.sync(syncParam)
   333  
   334  	pos := r.pos()
   335  	pkg, name := r.localIdent()
   336  	typ := r.typ()
   337  
   338  	return types2.NewParam(pos, pkg, name, typ)
   339  }
   340  
   341  // @@@ Objects
   342  
   343  func (r *reader2) obj() (types2.Object, []types2.Type) {
   344  	r.sync(syncObject)
   345  
   346  	assert(!r.bool())
   347  
   348  	pkg, name := r.p.objIdx(r.reloc(relocObj))
   349  	obj := pkg.Scope().Lookup(name)
   350  
   351  	targs := make([]types2.Type, r.len())
   352  	for i := range targs {
   353  		targs[i] = r.typ()
   354  	}
   355  
   356  	return obj, targs
   357  }
   358  
   359  func (pr *pkgReader2) objIdx(idx int) (*types2.Package, string) {
   360  	rname := pr.newReader(relocName, idx, syncObject1)
   361  
   362  	objPkg, objName := rname.qualifiedIdent()
   363  	assert(objName != "")
   364  
   365  	tag := codeObj(rname.code(syncCodeObj))
   366  
   367  	if tag == objStub {
   368  		assert(objPkg == nil || objPkg == types2.Unsafe)
   369  		return objPkg, objName
   370  	}
   371  
   372  	dict := pr.objDictIdx(idx)
   373  
   374  	r := pr.newReader(relocObj, idx, syncObject1)
   375  	r.dict = dict
   376  
   377  	objPkg.Scope().InsertLazy(objName, func() types2.Object {
   378  		switch tag {
   379  		default:
   380  			panic("weird")
   381  
   382  		case objAlias:
   383  			pos := r.pos()
   384  			typ := r.typ()
   385  			return types2.NewTypeName(pos, objPkg, objName, typ)
   386  
   387  		case objConst:
   388  			pos := r.pos()
   389  			typ := r.typ()
   390  			val := r.value()
   391  			return types2.NewConst(pos, objPkg, objName, typ, val)
   392  
   393  		case objFunc:
   394  			pos := r.pos()
   395  			tparams := r.typeParamNames()
   396  			sig := r.signature(nil, nil, tparams)
   397  			return types2.NewFunc(pos, objPkg, objName, sig)
   398  
   399  		case objType:
   400  			pos := r.pos()
   401  
   402  			return types2.NewTypeNameLazy(pos, objPkg, objName, func(named *types2.Named) (tparams []*types2.TypeParam, underlying types2.Type, methods []*types2.Func) {
   403  				tparams = r.typeParamNames()
   404  
   405  				// TODO(mdempsky): Rewrite receiver types to underlying is an
   406  				// Interface? The go/types importer does this (I think because
   407  				// unit tests expected that), but cmd/compile doesn't care
   408  				// about it, so maybe we can avoid worrying about that here.
   409  				underlying = r.typ().Underlying()
   410  
   411  				methods = make([]*types2.Func, r.len())
   412  				for i := range methods {
   413  					methods[i] = r.method()
   414  				}
   415  
   416  				return
   417  			})
   418  
   419  		case objVar:
   420  			pos := r.pos()
   421  			typ := r.typ()
   422  			return types2.NewVar(pos, objPkg, objName, typ)
   423  		}
   424  	})
   425  
   426  	return objPkg, objName
   427  }
   428  
   429  func (pr *pkgReader2) objDictIdx(idx int) *reader2Dict {
   430  	r := pr.newReader(relocObjDict, idx, syncObject1)
   431  
   432  	var dict reader2Dict
   433  
   434  	if implicits := r.len(); implicits != 0 {
   435  		base.Fatalf("unexpected object with %v implicit type parameter(s)", implicits)
   436  	}
   437  
   438  	dict.bounds = make([]typeInfo, r.len())
   439  	for i := range dict.bounds {
   440  		dict.bounds[i] = r.typInfo()
   441  	}
   442  
   443  	dict.derived = make([]derivedInfo, r.len())
   444  	dict.derivedTypes = make([]types2.Type, len(dict.derived))
   445  	for i := range dict.derived {
   446  		dict.derived[i] = derivedInfo{r.reloc(relocType), r.bool()}
   447  	}
   448  
   449  	// function references follow, but reader2 doesn't need those
   450  
   451  	return &dict
   452  }
   453  
   454  func (r *reader2) typeParamNames() []*types2.TypeParam {
   455  	r.sync(syncTypeParamNames)
   456  
   457  	// Note: This code assumes it only processes objects without
   458  	// implement type parameters. This is currently fine, because
   459  	// reader2 is only used to read in exported declarations, which are
   460  	// always package scoped.
   461  
   462  	if len(r.dict.bounds) == 0 {
   463  		return nil
   464  	}
   465  
   466  	// Careful: Type parameter lists may have cycles. To allow for this,
   467  	// we construct the type parameter list in two passes: first we
   468  	// create all the TypeNames and TypeParams, then we construct and
   469  	// set the bound type.
   470  
   471  	r.dict.tparams = make([]*types2.TypeParam, len(r.dict.bounds))
   472  	for i := range r.dict.bounds {
   473  		pos := r.pos()
   474  		pkg, name := r.localIdent()
   475  
   476  		tname := types2.NewTypeName(pos, pkg, name, nil)
   477  		r.dict.tparams[i] = types2.NewTypeParam(tname, nil)
   478  	}
   479  
   480  	for i, bound := range r.dict.bounds {
   481  		r.dict.tparams[i].SetConstraint(r.p.typIdx(bound, r.dict))
   482  	}
   483  
   484  	return r.dict.tparams
   485  }
   486  
   487  func (r *reader2) method() *types2.Func {
   488  	r.sync(syncMethod)
   489  	pos := r.pos()
   490  	pkg, name := r.selector()
   491  
   492  	rtparams := r.typeParamNames()
   493  	sig := r.signature(r.param(), rtparams, nil)
   494  
   495  	_ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go.
   496  	return types2.NewFunc(pos, pkg, name, sig)
   497  }
   498  
   499  func (r *reader2) qualifiedIdent() (*types2.Package, string) { return r.ident(syncSym) }
   500  func (r *reader2) localIdent() (*types2.Package, string)     { return r.ident(syncLocalIdent) }
   501  func (r *reader2) selector() (*types2.Package, string)       { return r.ident(syncSelector) }
   502  
   503  func (r *reader2) ident(marker syncMarker) (*types2.Package, string) {
   504  	r.sync(marker)
   505  	return r.pkg(), r.string()
   506  }
   507  

View as plain text