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