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