1
2
3
4
5
6
7
8 package importer
9
10 import (
11 "cmd/compile/internal/syntax"
12 "cmd/compile/internal/typecheck"
13 "cmd/compile/internal/types2"
14 "encoding/binary"
15 "fmt"
16 "go/constant"
17 "go/token"
18 "io"
19 "math/big"
20 "sort"
21 "strings"
22 )
23
24 type intReader struct {
25 *strings.Reader
26 path string
27 }
28
29 func (r *intReader) int64() int64 {
30 i, err := binary.ReadVarint(r.Reader)
31 if err != nil {
32 errorf("import %q: read varint error: %v", r.path, err)
33 }
34 return i
35 }
36
37 func (r *intReader) uint64() uint64 {
38 i, err := binary.ReadUvarint(r.Reader)
39 if err != nil {
40 errorf("import %q: read varint error: %v", r.path, err)
41 }
42 return i
43 }
44
45
46 const (
47 iexportVersionGo1_11 = 0
48 iexportVersionPosCol = 1
49 iexportVersionGenerics = 2
50 iexportVersionGo1_18 = 2
51
52 iexportVersionCurrent = 2
53 )
54
55 type ident struct {
56 pkg *types2.Package
57 name string
58 }
59
60 const predeclReserved = 32
61
62 type itag uint64
63
64 const (
65
66 definedType itag = iota
67 pointerType
68 sliceType
69 arrayType
70 chanType
71 mapType
72 signatureType
73 structType
74 interfaceType
75 typeParamType
76 instanceType
77 unionType
78 )
79
80 const io_SeekCurrent = 1
81
82
83
84
85
86 func ImportData(imports map[string]*types2.Package, data, path string) (pkg *types2.Package, err error) {
87 const currentVersion = iexportVersionCurrent
88 version := int64(-1)
89 defer func() {
90 if e := recover(); e != nil {
91 if version > currentVersion {
92 err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
93 } else {
94 err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
95 }
96 }
97 }()
98
99 r := &intReader{strings.NewReader(data), path}
100
101 version = int64(r.uint64())
102 switch version {
103 case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
104 default:
105 errorf("unknown iexport format version %d", version)
106 }
107
108 sLen := int64(r.uint64())
109 dLen := int64(r.uint64())
110
111 whence, _ := r.Seek(0, io_SeekCurrent)
112 stringData := data[whence : whence+sLen]
113 declData := data[whence+sLen : whence+sLen+dLen]
114 r.Seek(sLen+dLen, io_SeekCurrent)
115
116 p := iimporter{
117 exportVersion: version,
118 ipath: path,
119 version: int(version),
120
121 stringData: stringData,
122 pkgCache: make(map[uint64]*types2.Package),
123 posBaseCache: make(map[uint64]*syntax.PosBase),
124
125 declData: declData,
126 pkgIndex: make(map[*types2.Package]map[string]uint64),
127 typCache: make(map[uint64]types2.Type),
128
129
130 tparamIndex: make(map[ident]*types2.TypeParam),
131 }
132
133 for i, pt := range predeclared {
134 p.typCache[uint64(i)] = pt
135 }
136
137 pkgList := make([]*types2.Package, r.uint64())
138 for i := range pkgList {
139 pkgPathOff := r.uint64()
140 pkgPath := p.stringAt(pkgPathOff)
141 pkgName := p.stringAt(r.uint64())
142 pkgHeight := int(r.uint64())
143
144 if pkgPath == "" {
145 pkgPath = path
146 }
147 pkg := imports[pkgPath]
148 if pkg == nil {
149 pkg = types2.NewPackageHeight(pkgPath, pkgName, pkgHeight)
150 imports[pkgPath] = pkg
151 } else {
152 if pkg.Name() != pkgName {
153 errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
154 }
155 if pkg.Height() != pkgHeight {
156 errorf("conflicting heights %v and %v for package %q", pkg.Height(), pkgHeight, path)
157 }
158 }
159
160 p.pkgCache[pkgPathOff] = pkg
161
162 nameIndex := make(map[string]uint64)
163 for nSyms := r.uint64(); nSyms > 0; nSyms-- {
164 name := p.stringAt(r.uint64())
165 nameIndex[name] = r.uint64()
166 }
167
168 p.pkgIndex[pkg] = nameIndex
169 pkgList[i] = pkg
170 }
171
172 localpkg := pkgList[0]
173
174 names := make([]string, 0, len(p.pkgIndex[localpkg]))
175 for name := range p.pkgIndex[localpkg] {
176 names = append(names, name)
177 }
178 sort.Strings(names)
179 for _, name := range names {
180 p.doDecl(localpkg, name)
181 }
182
183
184
185
186
187
188 for _, d := range p.later {
189 d.t.SetConstraint(d.constraint)
190 }
191
192 list := append(([]*types2.Package)(nil), pkgList[1:]...)
193 sort.Sort(byPath(list))
194 localpkg.SetImports(list)
195
196
197 localpkg.MarkComplete()
198
199 return localpkg, nil
200 }
201
202 type setConstraintArgs struct {
203 t *types2.TypeParam
204 constraint types2.Type
205 }
206
207 type iimporter struct {
208 exportVersion int64
209 ipath string
210 version int
211
212 stringData string
213 pkgCache map[uint64]*types2.Package
214 posBaseCache map[uint64]*syntax.PosBase
215
216 declData string
217 pkgIndex map[*types2.Package]map[string]uint64
218 typCache map[uint64]types2.Type
219 tparamIndex map[ident]*types2.TypeParam
220
221 interfaceList []*types2.Interface
222
223
224 later []setConstraintArgs
225 }
226
227 func (p *iimporter) doDecl(pkg *types2.Package, name string) {
228
229 if obj := pkg.Scope().Lookup(name); obj != nil {
230 return
231 }
232
233 off, ok := p.pkgIndex[pkg][name]
234 if !ok {
235 errorf("%v.%v not in index", pkg, name)
236 }
237
238 r := &importReader{p: p, currPkg: pkg}
239
240
241
242 r.declReader = *strings.NewReader(p.declData[off:])
243
244 r.obj(name)
245 }
246
247 func (p *iimporter) stringAt(off uint64) string {
248 var x [binary.MaxVarintLen64]byte
249 n := copy(x[:], p.stringData[off:])
250
251 slen, n := binary.Uvarint(x[:n])
252 if n <= 0 {
253 errorf("varint failed")
254 }
255 spos := off + uint64(n)
256 return p.stringData[spos : spos+slen]
257 }
258
259 func (p *iimporter) pkgAt(off uint64) *types2.Package {
260 if pkg, ok := p.pkgCache[off]; ok {
261 return pkg
262 }
263 path := p.stringAt(off)
264 errorf("missing package %q in %q", path, p.ipath)
265 return nil
266 }
267
268 func (p *iimporter) posBaseAt(off uint64) *syntax.PosBase {
269 if posBase, ok := p.posBaseCache[off]; ok {
270 return posBase
271 }
272 filename := p.stringAt(off)
273 posBase := syntax.NewTrimmedFileBase(filename, true)
274 p.posBaseCache[off] = posBase
275 return posBase
276 }
277
278 func (p *iimporter) typAt(off uint64, base *types2.Named) types2.Type {
279 if t, ok := p.typCache[off]; ok && canReuse(base, t) {
280 return t
281 }
282
283 if off < predeclReserved {
284 errorf("predeclared type missing from cache: %v", off)
285 }
286
287 r := &importReader{p: p}
288
289
290
291 r.declReader = *strings.NewReader(p.declData[off-predeclReserved:])
292 t := r.doType(base)
293
294 if canReuse(base, t) {
295 p.typCache[off] = t
296 }
297 return t
298 }
299
300
301
302
303
304
305
306 func canReuse(def *types2.Named, rhs types2.Type) bool {
307 if def == nil {
308 return true
309 }
310 iface, _ := rhs.(*types2.Interface)
311 if iface == nil {
312 return true
313 }
314
315 return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0
316 }
317
318 type importReader struct {
319 p *iimporter
320 declReader strings.Reader
321 currPkg *types2.Package
322 prevPosBase *syntax.PosBase
323 prevLine int64
324 prevColumn int64
325 }
326
327 func (r *importReader) obj(name string) {
328 tag := r.byte()
329 pos := r.pos()
330
331 switch tag {
332 case 'A':
333 typ := r.typ()
334
335 r.declare(types2.NewTypeName(pos, r.currPkg, name, typ))
336
337 case 'C':
338 typ, val := r.value()
339
340 r.declare(types2.NewConst(pos, r.currPkg, name, typ, val))
341
342 case 'F', 'G':
343 var tparams []*types2.TypeParam
344 if tag == 'G' {
345 tparams = r.tparamList()
346 }
347 sig := r.signature(nil, nil, tparams)
348 r.declare(types2.NewFunc(pos, r.currPkg, name, sig))
349
350 case 'T', 'U':
351
352
353 obj := types2.NewTypeName(pos, r.currPkg, name, nil)
354 named := types2.NewNamed(obj, nil, nil)
355
356
357 r.declare(obj)
358 if tag == 'U' {
359 tparams := r.tparamList()
360 named.SetTypeParams(tparams)
361 }
362
363 underlying := r.p.typAt(r.uint64(), named).Underlying()
364 named.SetUnderlying(underlying)
365
366 if !isInterface(underlying) {
367 for n := r.uint64(); n > 0; n-- {
368 mpos := r.pos()
369 mname := r.ident()
370 recv := r.param()
371
372
373
374
375 targs := baseType(recv.Type()).TypeArgs()
376 var rparams []*types2.TypeParam
377 if targs.Len() > 0 {
378 rparams = make([]*types2.TypeParam, targs.Len())
379 for i := range rparams {
380 rparams[i], _ = targs.At(i).(*types2.TypeParam)
381 }
382 }
383 msig := r.signature(recv, rparams, nil)
384
385 named.AddMethod(types2.NewFunc(mpos, r.currPkg, mname, msig))
386 }
387 }
388
389 case 'P':
390
391
392
393 if r.p.exportVersion < iexportVersionGenerics {
394 errorf("unexpected type param type")
395 }
396 name0 := typecheck.TparamName(name)
397 if name0 == "" {
398 errorf("malformed type parameter export name %s: missing prefix", name)
399 }
400
401 tn := types2.NewTypeName(pos, r.currPkg, name0, nil)
402 t := types2.NewTypeParam(tn, nil)
403
404
405 id := ident{r.currPkg, name}
406 r.p.tparamIndex[id] = t
407
408 var implicit bool
409 if r.p.exportVersion >= iexportVersionGo1_18 {
410 implicit = r.bool()
411 }
412 constraint := r.typ()
413 if implicit {
414 iface, _ := constraint.(*types2.Interface)
415 if iface == nil {
416 errorf("non-interface constraint marked implicit")
417 }
418 iface.MarkImplicit()
419 }
420
421
422
423
424 r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint})
425
426 case 'V':
427 typ := r.typ()
428
429 r.declare(types2.NewVar(pos, r.currPkg, name, typ))
430
431 default:
432 errorf("unexpected tag: %v", tag)
433 }
434 }
435
436 func (r *importReader) declare(obj types2.Object) {
437 obj.Pkg().Scope().Insert(obj)
438 }
439
440 func (r *importReader) value() (typ types2.Type, val constant.Value) {
441 typ = r.typ()
442 if r.p.exportVersion >= iexportVersionGo1_18 {
443
444 _ = constant.Kind(r.int64())
445 }
446
447 switch b := typ.Underlying().(*types2.Basic); b.Info() & types2.IsConstType {
448 case types2.IsBoolean:
449 val = constant.MakeBool(r.bool())
450
451 case types2.IsString:
452 val = constant.MakeString(r.string())
453
454 case types2.IsInteger:
455 var x big.Int
456 r.mpint(&x, b)
457 val = constant.Make(&x)
458
459 case types2.IsFloat:
460 val = r.mpfloat(b)
461
462 case types2.IsComplex:
463 re := r.mpfloat(b)
464 im := r.mpfloat(b)
465 val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
466
467 default:
468 errorf("unexpected type %v", typ)
469 panic("unreachable")
470 }
471
472 return
473 }
474
475 func intSize(b *types2.Basic) (signed bool, maxBytes uint) {
476 if (b.Info() & types2.IsUntyped) != 0 {
477 return true, 64
478 }
479
480 switch b.Kind() {
481 case types2.Float32, types2.Complex64:
482 return true, 3
483 case types2.Float64, types2.Complex128:
484 return true, 7
485 }
486
487 signed = (b.Info() & types2.IsUnsigned) == 0
488 switch b.Kind() {
489 case types2.Int8, types2.Uint8:
490 maxBytes = 1
491 case types2.Int16, types2.Uint16:
492 maxBytes = 2
493 case types2.Int32, types2.Uint32:
494 maxBytes = 4
495 default:
496 maxBytes = 8
497 }
498
499 return
500 }
501
502 func (r *importReader) mpint(x *big.Int, typ *types2.Basic) {
503 signed, maxBytes := intSize(typ)
504
505 maxSmall := 256 - maxBytes
506 if signed {
507 maxSmall = 256 - 2*maxBytes
508 }
509 if maxBytes == 1 {
510 maxSmall = 256
511 }
512
513 n, _ := r.declReader.ReadByte()
514 if uint(n) < maxSmall {
515 v := int64(n)
516 if signed {
517 v >>= 1
518 if n&1 != 0 {
519 v = ^v
520 }
521 }
522 x.SetInt64(v)
523 return
524 }
525
526 v := -n
527 if signed {
528 v = -(n &^ 1) >> 1
529 }
530 if v < 1 || uint(v) > maxBytes {
531 errorf("weird decoding: %v, %v => %v", n, signed, v)
532 }
533 b := make([]byte, v)
534 io.ReadFull(&r.declReader, b)
535 x.SetBytes(b)
536 if signed && n&1 != 0 {
537 x.Neg(x)
538 }
539 }
540
541 func (r *importReader) mpfloat(typ *types2.Basic) constant.Value {
542 var mant big.Int
543 r.mpint(&mant, typ)
544 var f big.Float
545 f.SetInt(&mant)
546 if f.Sign() != 0 {
547 f.SetMantExp(&f, int(r.int64()))
548 }
549 return constant.Make(&f)
550 }
551
552 func (r *importReader) ident() string {
553 return r.string()
554 }
555
556 func (r *importReader) qualifiedIdent() (*types2.Package, string) {
557 name := r.string()
558 pkg := r.pkg()
559 return pkg, name
560 }
561
562 func (r *importReader) pos() syntax.Pos {
563 if r.p.version >= 1 {
564 r.posv1()
565 } else {
566 r.posv0()
567 }
568
569 if (r.prevPosBase == nil || r.prevPosBase.Filename() == "") && r.prevLine == 0 && r.prevColumn == 0 {
570 return syntax.Pos{}
571 }
572
573 return syntax.MakePos(r.prevPosBase, uint(r.prevLine), uint(r.prevColumn))
574 }
575
576 func (r *importReader) posv0() {
577 delta := r.int64()
578 if delta != deltaNewFile {
579 r.prevLine += delta
580 } else if l := r.int64(); l == -1 {
581 r.prevLine += deltaNewFile
582 } else {
583 r.prevPosBase = r.posBase()
584 r.prevLine = l
585 }
586 }
587
588 func (r *importReader) posv1() {
589 delta := r.int64()
590 r.prevColumn += delta >> 1
591 if delta&1 != 0 {
592 delta = r.int64()
593 r.prevLine += delta >> 1
594 if delta&1 != 0 {
595 r.prevPosBase = r.posBase()
596 }
597 }
598 }
599
600 func (r *importReader) typ() types2.Type {
601 return r.p.typAt(r.uint64(), nil)
602 }
603
604 func isInterface(t types2.Type) bool {
605 _, ok := t.(*types2.Interface)
606 return ok
607 }
608
609 func (r *importReader) pkg() *types2.Package { return r.p.pkgAt(r.uint64()) }
610 func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
611 func (r *importReader) posBase() *syntax.PosBase { return r.p.posBaseAt(r.uint64()) }
612
613 func (r *importReader) doType(base *types2.Named) types2.Type {
614 switch k := r.kind(); k {
615 default:
616 errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
617 return nil
618
619 case definedType:
620 pkg, name := r.qualifiedIdent()
621 r.p.doDecl(pkg, name)
622 return pkg.Scope().Lookup(name).(*types2.TypeName).Type()
623 case pointerType:
624 return types2.NewPointer(r.typ())
625 case sliceType:
626 return types2.NewSlice(r.typ())
627 case arrayType:
628 n := r.uint64()
629 return types2.NewArray(r.typ(), int64(n))
630 case chanType:
631 dir := chanDir(int(r.uint64()))
632 return types2.NewChan(dir, r.typ())
633 case mapType:
634 return types2.NewMap(r.typ(), r.typ())
635 case signatureType:
636 r.currPkg = r.pkg()
637 return r.signature(nil, nil, nil)
638
639 case structType:
640 r.currPkg = r.pkg()
641
642 fields := make([]*types2.Var, r.uint64())
643 tags := make([]string, len(fields))
644 for i := range fields {
645 fpos := r.pos()
646 fname := r.ident()
647 ftyp := r.typ()
648 emb := r.bool()
649 tag := r.string()
650
651 fields[i] = types2.NewField(fpos, r.currPkg, fname, ftyp, emb)
652 tags[i] = tag
653 }
654 return types2.NewStruct(fields, tags)
655
656 case interfaceType:
657 r.currPkg = r.pkg()
658
659 embeddeds := make([]types2.Type, r.uint64())
660 for i := range embeddeds {
661 _ = r.pos()
662 embeddeds[i] = r.typ()
663 }
664
665 methods := make([]*types2.Func, r.uint64())
666 for i := range methods {
667 mpos := r.pos()
668 mname := r.ident()
669
670
671
672 var recv *types2.Var
673 if base != nil {
674 recv = types2.NewVar(syntax.Pos{}, r.currPkg, "", base)
675 }
676
677 msig := r.signature(recv, nil, nil)
678 methods[i] = types2.NewFunc(mpos, r.currPkg, mname, msig)
679 }
680
681 typ := types2.NewInterfaceType(methods, embeddeds)
682 r.p.interfaceList = append(r.p.interfaceList, typ)
683 return typ
684
685 case typeParamType:
686 if r.p.exportVersion < iexportVersionGenerics {
687 errorf("unexpected type param type")
688 }
689 pkg, name := r.qualifiedIdent()
690 id := ident{pkg, name}
691 if t, ok := r.p.tparamIndex[id]; ok {
692
693 return t
694 }
695
696 r.p.doDecl(pkg, name)
697 return r.p.tparamIndex[id]
698
699 case instanceType:
700 if r.p.exportVersion < iexportVersionGenerics {
701 errorf("unexpected instantiation type")
702 }
703
704
705 _ = r.pos()
706 len := r.uint64()
707 targs := make([]types2.Type, len)
708 for i := range targs {
709 targs[i] = r.typ()
710 }
711 baseType := r.typ()
712
713
714
715 t, _ := types2.Instantiate(nil, baseType, targs, false)
716 return t
717
718 case unionType:
719 if r.p.exportVersion < iexportVersionGenerics {
720 errorf("unexpected instantiation type")
721 }
722 terms := make([]*types2.Term, r.uint64())
723 for i := range terms {
724 terms[i] = types2.NewTerm(r.bool(), r.typ())
725 }
726 return types2.NewUnion(terms)
727 }
728 }
729
730 func (r *importReader) kind() itag {
731 return itag(r.uint64())
732 }
733
734 func (r *importReader) signature(recv *types2.Var, rparams, tparams []*types2.TypeParam) *types2.Signature {
735 params := r.paramList()
736 results := r.paramList()
737 variadic := params.Len() > 0 && r.bool()
738 return types2.NewSignatureType(recv, rparams, tparams, params, results, variadic)
739 }
740
741 func (r *importReader) tparamList() []*types2.TypeParam {
742 n := r.uint64()
743 if n == 0 {
744 return nil
745 }
746 xs := make([]*types2.TypeParam, n)
747 for i := range xs {
748 xs[i] = r.typ().(*types2.TypeParam)
749 }
750 return xs
751 }
752
753 func (r *importReader) paramList() *types2.Tuple {
754 xs := make([]*types2.Var, r.uint64())
755 for i := range xs {
756 xs[i] = r.param()
757 }
758 return types2.NewTuple(xs...)
759 }
760
761 func (r *importReader) param() *types2.Var {
762 pos := r.pos()
763 name := r.ident()
764 typ := r.typ()
765 return types2.NewParam(pos, r.currPkg, name, typ)
766 }
767
768 func (r *importReader) bool() bool {
769 return r.uint64() != 0
770 }
771
772 func (r *importReader) int64() int64 {
773 n, err := binary.ReadVarint(&r.declReader)
774 if err != nil {
775 errorf("readVarint: %v", err)
776 }
777 return n
778 }
779
780 func (r *importReader) uint64() uint64 {
781 n, err := binary.ReadUvarint(&r.declReader)
782 if err != nil {
783 errorf("readUvarint: %v", err)
784 }
785 return n
786 }
787
788 func (r *importReader) byte() byte {
789 x, err := r.declReader.ReadByte()
790 if err != nil {
791 errorf("declReader.ReadByte: %v", err)
792 }
793 return x
794 }
795
796 func baseType(typ types2.Type) *types2.Named {
797
798 if p, _ := typ.(*types2.Pointer); p != nil {
799 typ = p.Elem()
800 }
801
802 n, _ := typ.(*types2.Named)
803 return n
804 }
805
View as plain text