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