1
2
3
4
5
6
7 package testimporter
8
9
10
11 import (
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 methods := make([]*types2.Func, r.Len())
466 for i := range methods {
467 methods[i] = r.method(true)
468 }
469
470 if r.Version().Has(pkgbits.GenericMethods) {
471 for range r.Len() {
472
473
474
475 idx := r.Reloc(pkgbits.SectionObj)
476
477 t := pr.tempReader(pkgbits.SectionObj, idx, pkgbits.SyncObject1)
478 t.dict = pr.objDictIdx(idx)
479
480 pos := t.pos()
481 assert(t.Bool())
482 pkg, name := t.selector()
483 rtparams := t.typeParamNames(true, true)
484 recv := t.param()
485 tparams := t.typeParamNames(true, false)
486 sig := t.signature(recv, rtparams, tparams)
487
488 r.delayed = append(r.delayed, t.delayed...)
489
490 pr.retireReader(t)
491 methods = append(methods, types2.NewFunc(pos, pkg, name, sig))
492 }
493 }
494
495 return tparams, underlying, methods, r.delayed
496 })
497
498 case pkgbits.ObjVar:
499 pos := r.pos()
500 typ := r.typ()
501 return types2.NewVar(pos, objPkg, objName, typ)
502 }
503 })
504
505 return objPkg, objName
506 }
507
508 func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
509 var dict readerDict
510 {
511 r := pr.tempReader(pkgbits.SectionObjDict, idx, pkgbits.SyncObject1)
512
513 if implicits := r.Len(); implicits != 0 {
514 base.Fatalf("unexpected object with %v implicit type parameter(s)", implicits)
515 }
516
517 nreceivers := 0
518 if r.Version().Has(pkgbits.GenericMethods) {
519 nreceivers = r.Len()
520 }
521 nexplicits := r.Len()
522
523 dict.rtbounds = make([]typeInfo, nreceivers)
524 for i := range dict.rtbounds {
525 dict.rtbounds[i] = r.typInfo()
526 }
527
528 dict.tbounds = make([]typeInfo, nexplicits)
529 for i := range dict.tbounds {
530 dict.tbounds[i] = r.typInfo()
531 }
532
533 dict.derived = make([]derivedInfo, r.Len())
534 dict.derivedTypes = make([]types2.Type, len(dict.derived))
535 for i := range dict.derived {
536 dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.SectionType)}
537 if r.Version().Has(pkgbits.DerivedInfoNeeded) {
538 assert(!r.Bool())
539 }
540 }
541
542 pr.retireReader(r)
543 }
544
545
546 return &dict
547 }
548
549 func (r *reader) typeParamNames(isLazy bool, isGenMeth bool) []*types2.TypeParam {
550 r.Sync(pkgbits.SyncTypeParamNames)
551
552
553
554
555
556 var in []typeInfo
557 var out *[]*types2.TypeParam
558 if isGenMeth {
559 in = r.dict.rtbounds
560 out = &r.dict.rtparams
561 } else {
562 in = r.dict.tbounds
563 out = &r.dict.tparams
564 }
565
566 if len(in) == 0 {
567 return nil
568 }
569
570
571
572
573
574
575
576
577 tparams := make([]*types2.TypeParam, len(in))
578 *out = tparams
579
580 for i := range in {
581 pos := r.pos()
582 pkg, name := r.localIdent()
583
584 tname := types2.NewTypeName(pos, pkg, name, nil)
585 tparams[i] = types2.NewTypeParam(tname, nil)
586 }
587
588
589
590 if isLazy {
591
592
593 types := make([]types2.Type, len(in))
594 for i, info := range in {
595 types[i] = r.p.typIdx(info, r.dict)
596 }
597
598 r.delayed = append(r.delayed, func() {
599 for i, typ := range types {
600 tparams[i].SetConstraint(typ)
601 }
602 })
603 } else {
604 for i, info := range in {
605 tparams[i].SetConstraint(r.p.typIdx(info, r.dict))
606 }
607 }
608
609 return tparams
610 }
611
612 func (r *reader) method(isLazy bool) *types2.Func {
613 r.Sync(pkgbits.SyncMethod)
614 pos := r.pos()
615 pkg, name := r.selector()
616
617 rtparams := r.typeParamNames(isLazy, false)
618 sig := r.signature(r.param(), rtparams, nil)
619
620 _ = r.pos()
621 return types2.NewFunc(pos, pkg, name, sig)
622 }
623
624 func (r *reader) qualifiedIdent() (*types2.Package, string) { return r.ident(pkgbits.SyncSym) }
625 func (r *reader) localIdent() (*types2.Package, string) { return r.ident(pkgbits.SyncLocalIdent) }
626 func (r *reader) selector() (*types2.Package, string) { return r.ident(pkgbits.SyncSelector) }
627
628 func (r *reader) ident(marker pkgbits.SyncMarker) (*types2.Package, string) {
629 r.Sync(marker)
630 return r.pkg(), r.String()
631 }
632
633
634 func newAliasTypeName(aliases bool, pos syntax.Pos, pkg *types2.Package, name string, rhs types2.Type, tparams []*types2.TypeParam) *types2.TypeName {
635
636
637 if aliases {
638 tname := types2.NewTypeName(pos, pkg, name, nil)
639 a := types2.NewAlias(tname, rhs)
640 a.SetTypeParams(tparams)
641 return tname
642 }
643 assert(len(tparams) == 0)
644 return types2.NewTypeName(pos, pkg, name, rhs)
645 }
646
View as plain text