1
2
3
4
5
6 package importer
7
8 import (
9 "cmp"
10 "slices"
11
12 "cmd/compile/internal/base"
13 "cmd/compile/internal/syntax"
14 "cmd/compile/internal/types2"
15 "cmd/internal/src"
16 "internal/pkgbits"
17 )
18
19 type pkgReader struct {
20 pkgbits.PkgDecoder
21
22 ctxt *types2.Context
23 imports map[string]*types2.Package
24 enableAlias bool
25
26 posBases []*syntax.PosBase
27 pkgs []*types2.Package
28 typs []types2.Type
29 }
30
31 func ReadPackage(ctxt *types2.Context, imports map[string]*types2.Package, input pkgbits.PkgDecoder) *types2.Package {
32 pr := pkgReader{
33 PkgDecoder: input,
34
35 ctxt: ctxt,
36 imports: imports,
37 enableAlias: true,
38
39 posBases: make([]*syntax.PosBase, input.NumElems(pkgbits.SectionPosBase)),
40 pkgs: make([]*types2.Package, input.NumElems(pkgbits.SectionPkg)),
41 typs: make([]types2.Type, input.NumElems(pkgbits.SectionType)),
42 }
43
44 r := pr.newReader(pkgbits.SectionMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
45 pkg := r.pkg()
46
47 if r.Version().Has(pkgbits.HasInit) {
48 r.Bool()
49 }
50
51 for i, n := 0, r.Len(); i < n; i++ {
52
53
54 r.Sync(pkgbits.SyncObject)
55 if r.Version().Has(pkgbits.DerivedFuncInstance) {
56 assert(!r.Bool())
57 }
58 r.p.objIdx(r.Reloc(pkgbits.SectionObj))
59 assert(r.Len() == 0)
60 }
61
62 r.Sync(pkgbits.SyncEOF)
63
64 pkg.MarkComplete()
65 return pkg
66 }
67
68 type reader struct {
69 pkgbits.Decoder
70
71 p *pkgReader
72
73 dict *readerDict
74 delayed []func()
75 }
76
77 type readerDict struct {
78 rtbounds []typeInfo
79 rtparams []*types2.TypeParam
80
81 tbounds []typeInfo
82 tparams []*types2.TypeParam
83
84 derived []derivedInfo
85 derivedTypes []types2.Type
86 }
87
88 type readerTypeBound struct {
89 derived bool
90 boundIdx int
91 }
92
93 func (pr *pkgReader) newReader(k pkgbits.SectionKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
94 return &reader{
95 Decoder: pr.NewDecoder(k, idx, marker),
96 p: pr,
97 }
98 }
99
100 func (pr *pkgReader) tempReader(k pkgbits.SectionKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
101 return &reader{
102 Decoder: pr.TempDecoder(k, idx, marker),
103 p: pr,
104 }
105 }
106
107 func (pr *pkgReader) retireReader(r *reader) {
108 pr.RetireDecoder(&r.Decoder)
109 }
110
111
112
113 func (r *reader) pos() syntax.Pos {
114 r.Sync(pkgbits.SyncPos)
115 if !r.Bool() {
116 return syntax.Pos{}
117 }
118
119
120 posBase := r.posBase()
121 line := r.Uint()
122 col := r.Uint()
123 return syntax.MakePos(posBase, line, col)
124 }
125
126 func (r *reader) posBase() *syntax.PosBase {
127 return r.p.posBaseIdx(r.Reloc(pkgbits.SectionPosBase))
128 }
129
130 func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) *syntax.PosBase {
131 if b := pr.posBases[idx]; b != nil {
132 return b
133 }
134 var b *syntax.PosBase
135 {
136 r := pr.tempReader(pkgbits.SectionPosBase, idx, pkgbits.SyncPosBase)
137
138 filename := r.String()
139
140 if r.Bool() {
141 b = syntax.NewTrimmedFileBase(filename, true)
142 } else {
143 pos := r.pos()
144 line := r.Uint()
145 col := r.Uint()
146 b = syntax.NewLineBase(pos, filename, true, line, col)
147 }
148 pr.retireReader(r)
149 }
150
151 pr.posBases[idx] = b
152 return b
153 }
154
155
156
157 func (r *reader) pkg() *types2.Package {
158 r.Sync(pkgbits.SyncPkg)
159 return r.p.pkgIdx(r.Reloc(pkgbits.SectionPkg))
160 }
161
162 func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types2.Package {
163
164
165 if pkg := pr.pkgs[idx]; pkg != nil {
166 return pkg
167 }
168
169 pkg := pr.newReader(pkgbits.SectionPkg, idx, pkgbits.SyncPkgDef).doPkg()
170 pr.pkgs[idx] = pkg
171 return pkg
172 }
173
174 func (r *reader) doPkg() *types2.Package {
175 path := r.String()
176 switch path {
177 case "":
178 path = r.p.PkgPath()
179 case "builtin":
180 return nil
181 case "unsafe":
182 return types2.Unsafe
183 }
184
185 if pkg := r.p.imports[path]; pkg != nil {
186 return pkg
187 }
188
189 name := r.String()
190 pkg := types2.NewPackage(path, name)
191 r.p.imports[path] = pkg
192
193
194
195 imports := make([]*types2.Package, r.Len())
196 for i := range imports {
197 imports[i] = r.pkg()
198 }
199 pkg.SetImports(imports)
200
201 return pkg
202 }
203
204
205
206 func (r *reader) typ() types2.Type {
207 return r.p.typIdx(r.typInfo(), r.dict)
208 }
209
210 func (r *reader) typInfo() typeInfo {
211 r.Sync(pkgbits.SyncType)
212 if r.Bool() {
213 return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
214 }
215 return typeInfo{idx: r.Reloc(pkgbits.SectionType), derived: false}
216 }
217
218 func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types2.Type {
219 idx := info.idx
220 var where *types2.Type
221 if info.derived {
222 where = &dict.derivedTypes[idx]
223 idx = dict.derived[idx].idx
224 } else {
225 where = &pr.typs[idx]
226 }
227
228 if typ := *where; typ != nil {
229 return typ
230 }
231
232 var typ types2.Type
233 {
234 r := pr.tempReader(pkgbits.SectionType, idx, pkgbits.SyncTypeIdx)
235 r.dict = dict
236
237 typ = r.doTyp()
238 assert(typ != nil)
239 pr.retireReader(r)
240 }
241
242
243 if prev := *where; prev != nil {
244 return prev
245 }
246
247 *where = typ
248 return typ
249 }
250
251 func (r *reader) doTyp() (res types2.Type) {
252 switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
253 default:
254 base.FatalfAt(src.NoXPos, "unhandled type tag: %v", tag)
255 panic("unreachable")
256
257 case pkgbits.TypeBasic:
258 return types2.Typ[r.Len()]
259
260 case pkgbits.TypeNamed:
261 obj, targs := r.obj()
262 name := obj.(*types2.TypeName)
263 if len(targs) != 0 {
264 t, _ := types2.Instantiate(r.p.ctxt, name.Type(), targs, false)
265 return t
266 }
267 return name.Type()
268
269 case pkgbits.TypeTypeParam:
270 n := r.Len()
271 if n < len(r.dict.rtbounds) {
272 return r.dict.rtparams[n]
273 }
274 return r.dict.tparams[n-len(r.dict.rtbounds)]
275
276 case pkgbits.TypeArray:
277 len := int64(r.Uint64())
278 return types2.NewArray(r.typ(), len)
279 case pkgbits.TypeChan:
280 dir := types2.ChanDir(r.Len())
281 return types2.NewChan(dir, r.typ())
282 case pkgbits.TypeMap:
283 return types2.NewMap(r.typ(), r.typ())
284 case pkgbits.TypePointer:
285 return types2.NewPointer(r.typ())
286 case pkgbits.TypeSignature:
287 return r.signature(nil, nil, nil)
288 case pkgbits.TypeSlice:
289 return types2.NewSlice(r.typ())
290 case pkgbits.TypeStruct:
291 return r.structType()
292 case pkgbits.TypeInterface:
293 return r.interfaceType()
294 case pkgbits.TypeUnion:
295 return r.unionType()
296 }
297 }
298
299 func (r *reader) structType() *types2.Struct {
300 fields := make([]*types2.Var, r.Len())
301 var tags []string
302 for i := range fields {
303 pos := r.pos()
304 pkg, name := r.selector()
305 ftyp := r.typ()
306 tag := r.String()
307 embedded := r.Bool()
308
309 fields[i] = types2.NewField(pos, pkg, name, ftyp, embedded)
310 if tag != "" {
311 for len(tags) < i {
312 tags = append(tags, "")
313 }
314 tags = append(tags, tag)
315 }
316 }
317 return types2.NewStruct(fields, tags)
318 }
319
320 func (r *reader) unionType() *types2.Union {
321 terms := make([]*types2.Term, r.Len())
322 for i := range terms {
323 terms[i] = types2.NewTerm(r.Bool(), r.typ())
324 }
325 return types2.NewUnion(terms)
326 }
327
328 func (r *reader) interfaceType() *types2.Interface {
329 methods := make([]*types2.Func, r.Len())
330 embeddeds := make([]types2.Type, r.Len())
331 implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool()
332
333 for i := range methods {
334 pos := r.pos()
335 pkg, name := r.selector()
336 mtyp := r.signature(nil, nil, nil)
337 methods[i] = types2.NewFunc(pos, pkg, name, mtyp)
338 }
339
340 for i := range embeddeds {
341 embeddeds[i] = r.typ()
342 }
343
344 iface := types2.NewInterfaceType(methods, embeddeds)
345 if implicit {
346 iface.MarkImplicit()
347 }
348 return iface
349 }
350
351 func (r *reader) signature(recv *types2.Var, rtparams, tparams []*types2.TypeParam) *types2.Signature {
352 r.Sync(pkgbits.SyncSignature)
353
354 params := r.params()
355 results := r.params()
356 variadic := r.Bool()
357
358 return types2.NewSignatureType(recv, rtparams, tparams, params, results, variadic)
359 }
360
361 func (r *reader) params() *types2.Tuple {
362 r.Sync(pkgbits.SyncParams)
363 params := make([]*types2.Var, r.Len())
364 for i := range params {
365 params[i] = r.param()
366 }
367 return types2.NewTuple(params...)
368 }
369
370 func (r *reader) param() *types2.Var {
371 r.Sync(pkgbits.SyncParam)
372
373 pos := r.pos()
374 pkg, name := r.localIdent()
375 typ := r.typ()
376
377 return types2.NewParam(pos, pkg, name, typ)
378 }
379
380
381
382 func (r *reader) obj() (types2.Object, []types2.Type) {
383 r.Sync(pkgbits.SyncObject)
384
385 if r.Version().Has(pkgbits.DerivedFuncInstance) {
386 assert(!r.Bool())
387 }
388
389 pkg, name := r.p.objIdx(r.Reloc(pkgbits.SectionObj))
390 obj := pkg.Scope().Lookup(name)
391
392 targs := make([]types2.Type, r.Len())
393 for i := range targs {
394 targs[i] = r.typ()
395 }
396
397 return obj, targs
398 }
399
400 func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types2.Package, string) {
401 var objPkg *types2.Package
402 var objName string
403 var tag pkgbits.CodeObj
404 {
405 rname := pr.tempReader(pkgbits.SectionName, idx, pkgbits.SyncObject1)
406
407 objPkg, objName = rname.qualifiedIdent()
408 assert(objName != "")
409
410 tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
411 pr.retireReader(rname)
412 }
413
414 if tag == pkgbits.ObjStub {
415 base.Assertf(objPkg == nil || objPkg == types2.Unsafe, "unexpected stub package: %v", objPkg)
416 return objPkg, objName
417 }
418
419 objPkg.Scope().InsertLazy(objName, func() types2.Object {
420 dict := pr.objDictIdx(idx)
421
422 r := pr.newReader(pkgbits.SectionObj, idx, pkgbits.SyncObject1)
423 r.dict = dict
424
425 switch tag {
426 default:
427 panic("weird")
428
429 case pkgbits.ObjAlias:
430 pos := r.pos()
431 var tparams []*types2.TypeParam
432 if r.Version().Has(pkgbits.AliasTypeParamNames) {
433 tparams = r.typeParamNames(false, false)
434 }
435 typ := r.typ()
436 return newAliasTypeName(pr.enableAlias, pos, objPkg, objName, typ, tparams)
437
438 case pkgbits.ObjConst:
439 pos := r.pos()
440 typ := r.typ()
441 val := r.Value()
442 return types2.NewConst(pos, objPkg, objName, typ, val)
443
444 case pkgbits.ObjFunc:
445 pos := r.pos()
446 if r.Version().Has(pkgbits.GenericMethods) {
447 assert(!r.Bool())
448 }
449 tparams := r.typeParamNames(false, false)
450 sig := r.signature(nil, nil, tparams)
451 return types2.NewFunc(pos, objPkg, objName, sig)
452
453 case pkgbits.ObjType:
454 pos := r.pos()
455
456 return types2.NewTypeNameLazy(pos, objPkg, objName, func(_ *types2.Named) ([]*types2.TypeParam, types2.Type, []*types2.Func, []func()) {
457 tparams := r.typeParamNames(true, false)
458
459
460
461
462
463 underlying := r.typ().Underlying()
464
465 type indexedMethod struct {
466 index int
467 fn *types2.Func
468 }
469 var methods []indexedMethod
470
471 if r.Version().Has(pkgbits.GenericMethods) {
472
473
474
475
476
477
478
479 for range r.Len() {
480 idx, m := r.method(true)
481 methods = append(methods, indexedMethod{idx, m})
482 }
483
484
485 for range r.Len() {
486
487
488
489 idx := r.Reloc(pkgbits.SectionObj)
490
491 t := pr.tempReader(pkgbits.SectionObj, idx, pkgbits.SyncObject1)
492 t.dict = pr.objDictIdx(idx)
493
494 pos := t.pos()
495 assert(t.Bool())
496 pkg, name := t.selector()
497 rtparams := t.typeParamNames(true, true)
498 recv := t.param()
499 methodIdx := -1
500 if r.Version().Has(pkgbits.PreserveMethodOrder) {
501 methodIdx = t.Len()
502 }
503 tparams := t.typeParamNames(true, false)
504 sig := t.signature(recv, rtparams, tparams)
505
506 r.delayed = append(r.delayed, t.delayed...)
507 pr.retireReader(t)
508 methods = append(methods, indexedMethod{methodIdx, types2.NewFunc(pos, pkg, name, sig)})
509 }
510
511 if r.Version().Has(pkgbits.PreserveMethodOrder) {
512 slices.SortFunc(methods, func(a, b indexedMethod) int {
513 return cmp.Compare(a.index, b.index)
514 })
515 }
516 } else {
517 for range r.Len() {
518 _, m := r.method(true)
519 methods = append(methods, indexedMethod{-1, m})
520 }
521 }
522
523 funcs := make([]*types2.Func, len(methods))
524 for i, m := range methods {
525 funcs[i] = m.fn
526 }
527
528 return tparams, underlying, funcs, r.delayed
529 })
530
531 case pkgbits.ObjVar:
532 pos := r.pos()
533 typ := r.typ()
534 return types2.NewVar(pos, objPkg, objName, typ)
535 }
536 })
537
538 return objPkg, objName
539 }
540
541 func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
542 var dict readerDict
543 {
544 r := pr.tempReader(pkgbits.SectionObjDict, idx, pkgbits.SyncObject1)
545
546 if implicits := r.Len(); implicits != 0 {
547 base.Fatalf("unexpected object with %v implicit type parameter(s)", implicits)
548 }
549
550 nreceivers := 0
551 if r.Version().Has(pkgbits.GenericMethods) {
552 nreceivers = r.Len()
553 }
554 nexplicits := r.Len()
555
556 dict.rtbounds = make([]typeInfo, nreceivers)
557 for i := range dict.rtbounds {
558 dict.rtbounds[i] = r.typInfo()
559 }
560
561 dict.tbounds = make([]typeInfo, nexplicits)
562 for i := range dict.tbounds {
563 dict.tbounds[i] = r.typInfo()
564 }
565
566 dict.derived = make([]derivedInfo, r.Len())
567 dict.derivedTypes = make([]types2.Type, len(dict.derived))
568 for i := range dict.derived {
569 dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.SectionType)}
570 if r.Version().Has(pkgbits.DerivedInfoNeeded) {
571 assert(!r.Bool())
572 }
573 }
574
575 pr.retireReader(r)
576 }
577
578
579 return &dict
580 }
581
582 func (r *reader) typeParamNames(isLazy bool, isGenMeth bool) []*types2.TypeParam {
583 r.Sync(pkgbits.SyncTypeParamNames)
584
585
586
587
588
589 var in []typeInfo
590 var out *[]*types2.TypeParam
591 if isGenMeth {
592 in = r.dict.rtbounds
593 out = &r.dict.rtparams
594 } else {
595 in = r.dict.tbounds
596 out = &r.dict.tparams
597 }
598
599 if len(in) == 0 {
600 return nil
601 }
602
603
604
605
606
607
608
609
610 tparams := make([]*types2.TypeParam, len(in))
611 *out = tparams
612
613 for i := range in {
614 pos := r.pos()
615 pkg, name := r.localIdent()
616
617 tname := types2.NewTypeName(pos, pkg, name, nil)
618 tparams[i] = types2.NewTypeParam(tname, nil)
619 }
620
621
622
623 if isLazy {
624
625
626 types := make([]types2.Type, len(in))
627 for i, info := range in {
628 types[i] = r.p.typIdx(info, r.dict)
629 }
630
631 r.delayed = append(r.delayed, func() {
632 for i, typ := range types {
633 tparams[i].SetConstraint(typ)
634 }
635 })
636 } else {
637 for i, info := range in {
638 tparams[i].SetConstraint(r.p.typIdx(info, r.dict))
639 }
640 }
641
642 return tparams
643 }
644
645 func (r *reader) method(isLazy bool) (int, *types2.Func) {
646 r.Sync(pkgbits.SyncMethod)
647 idx := -1
648 if r.Version().Has(pkgbits.PreserveMethodOrder) {
649 idx = r.Len()
650 }
651 pos := r.pos()
652 pkg, name := r.selector()
653
654 rtparams := r.typeParamNames(isLazy, false)
655 sig := r.signature(r.param(), rtparams, nil)
656
657 _ = r.pos()
658 return idx, types2.NewFunc(pos, pkg, name, sig)
659 }
660
661 func (r *reader) qualifiedIdent() (*types2.Package, string) { return r.ident(pkgbits.SyncSym) }
662 func (r *reader) localIdent() (*types2.Package, string) { return r.ident(pkgbits.SyncLocalIdent) }
663 func (r *reader) selector() (*types2.Package, string) { return r.ident(pkgbits.SyncSelector) }
664
665 func (r *reader) ident(marker pkgbits.SyncMarker) (*types2.Package, string) {
666 r.Sync(marker)
667 return r.pkg(), r.String()
668 }
669
670
671 func newAliasTypeName(aliases bool, pos syntax.Pos, pkg *types2.Package, name string, rhs types2.Type, tparams []*types2.TypeParam) *types2.TypeName {
672
673
674 if aliases {
675 tname := types2.NewTypeName(pos, pkg, name, nil)
676 a := types2.NewAlias(tname, rhs)
677 a.SetTypeParams(tparams)
678 return tname
679 }
680 assert(len(tparams) == 0)
681 return types2.NewTypeName(pos, pkg, name, rhs)
682 }
683
View as plain text