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