1
2
3
4
5
6
7
8
9 package importer
10
11 import (
12 "bytes"
13 "cmd/compile/internal/syntax"
14 "cmd/compile/internal/types2"
15 "encoding/binary"
16 "fmt"
17 "go/constant"
18 "go/token"
19 "io"
20 "math/big"
21 "sort"
22 )
23
24 type intReader struct {
25 *bytes.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 const predeclReserved = 32
46
47 type itag uint64
48
49 const (
50
51 definedType itag = iota
52 pointerType
53 sliceType
54 arrayType
55 chanType
56 mapType
57 signatureType
58 structType
59 interfaceType
60 )
61
62 const io_SeekCurrent = 1
63
64
65
66
67
68 func iImportData(imports map[string]*types2.Package, data []byte, path string) (_ int, pkg *types2.Package, err error) {
69 const currentVersion = 1
70 version := int64(-1)
71 defer func() {
72 if e := recover(); e != nil {
73 if version > currentVersion {
74 err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
75 } else {
76 err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
77 }
78 }
79 }()
80
81 r := &intReader{bytes.NewReader(data), path}
82
83 version = int64(r.uint64())
84 switch version {
85 case currentVersion, 0:
86 default:
87 errorf("unknown iexport format version %d", version)
88 }
89
90 sLen := int64(r.uint64())
91 dLen := int64(r.uint64())
92
93 whence, _ := r.Seek(0, io_SeekCurrent)
94 stringData := data[whence : whence+sLen]
95 declData := data[whence+sLen : whence+sLen+dLen]
96 r.Seek(sLen+dLen, io_SeekCurrent)
97
98 p := iimporter{
99 ipath: path,
100 version: int(version),
101
102 stringData: stringData,
103 stringCache: make(map[uint64]string),
104 pkgCache: make(map[uint64]*types2.Package),
105
106 declData: declData,
107 pkgIndex: make(map[*types2.Package]map[string]uint64),
108 typCache: make(map[uint64]types2.Type),
109 }
110
111 for i, pt := range predeclared {
112 p.typCache[uint64(i)] = pt
113 }
114
115 pkgList := make([]*types2.Package, r.uint64())
116 for i := range pkgList {
117 pkgPathOff := r.uint64()
118 pkgPath := p.stringAt(pkgPathOff)
119 pkgName := p.stringAt(r.uint64())
120 _ = r.uint64()
121
122 if pkgPath == "" {
123 pkgPath = path
124 }
125 pkg := imports[pkgPath]
126 if pkg == nil {
127 pkg = types2.NewPackage(pkgPath, pkgName)
128 imports[pkgPath] = pkg
129 } else if pkg.Name() != pkgName {
130 errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
131 }
132
133 p.pkgCache[pkgPathOff] = pkg
134
135 nameIndex := make(map[string]uint64)
136 for nSyms := r.uint64(); nSyms > 0; nSyms-- {
137 name := p.stringAt(r.uint64())
138 nameIndex[name] = r.uint64()
139 }
140
141 p.pkgIndex[pkg] = nameIndex
142 pkgList[i] = pkg
143 }
144
145 localpkg := pkgList[0]
146
147 names := make([]string, 0, len(p.pkgIndex[localpkg]))
148 for name := range p.pkgIndex[localpkg] {
149 names = append(names, name)
150 }
151 sort.Strings(names)
152 for _, name := range names {
153 p.doDecl(localpkg, name)
154 }
155
156 for _, typ := range p.interfaceList {
157 typ.Complete()
158 }
159
160
161 list := append(([]*types2.Package)(nil), pkgList[1:]...)
162 sort.Sort(byPath(list))
163 localpkg.SetImports(list)
164
165
166 localpkg.MarkComplete()
167
168 consumed, _ := r.Seek(0, io_SeekCurrent)
169 return int(consumed), localpkg, nil
170 }
171
172 type iimporter struct {
173 ipath string
174 version int
175
176 stringData []byte
177 stringCache map[uint64]string
178 pkgCache map[uint64]*types2.Package
179
180 declData []byte
181 pkgIndex map[*types2.Package]map[string]uint64
182 typCache map[uint64]types2.Type
183
184 interfaceList []*types2.Interface
185 }
186
187 func (p *iimporter) doDecl(pkg *types2.Package, name string) {
188
189 if obj := pkg.Scope().Lookup(name); obj != nil {
190 return
191 }
192
193 off, ok := p.pkgIndex[pkg][name]
194 if !ok {
195 errorf("%v.%v not in index", pkg, name)
196 }
197
198 r := &importReader{p: p, currPkg: pkg}
199
200
201
202 r.declReader = *bytes.NewReader(p.declData[off:])
203
204 r.obj(name)
205 }
206
207 func (p *iimporter) stringAt(off uint64) string {
208 if s, ok := p.stringCache[off]; ok {
209 return s
210 }
211
212 slen, n := binary.Uvarint(p.stringData[off:])
213 if n <= 0 {
214 errorf("varint failed")
215 }
216 spos := off + uint64(n)
217 s := string(p.stringData[spos : spos+slen])
218 p.stringCache[off] = s
219 return s
220 }
221
222 func (p *iimporter) pkgAt(off uint64) *types2.Package {
223 if pkg, ok := p.pkgCache[off]; ok {
224 return pkg
225 }
226 path := p.stringAt(off)
227 errorf("missing package %q in %q", path, p.ipath)
228 return nil
229 }
230
231 func (p *iimporter) typAt(off uint64, base *types2.Named) types2.Type {
232 if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) {
233 return t
234 }
235
236 if off < predeclReserved {
237 errorf("predeclared type missing from cache: %v", off)
238 }
239
240 r := &importReader{p: p}
241
242
243
244 r.declReader = *bytes.NewReader(p.declData[off-predeclReserved:])
245 t := r.doType(base)
246
247 if base == nil || !isInterface(t) {
248 p.typCache[off] = t
249 }
250 return t
251 }
252
253 type importReader struct {
254 p *iimporter
255 declReader bytes.Reader
256 currPkg *types2.Package
257 prevFile string
258 prevLine int64
259 prevColumn int64
260 }
261
262 func (r *importReader) obj(name string) {
263 tag := r.byte()
264 pos := r.pos()
265
266 switch tag {
267 case 'A':
268 typ := r.typ()
269
270 r.declare(types2.NewTypeName(pos, r.currPkg, name, typ))
271
272 case 'C':
273 typ, val := r.value()
274
275 r.declare(types2.NewConst(pos, r.currPkg, name, typ, val))
276
277 case 'F':
278 sig := r.signature(nil)
279
280 r.declare(types2.NewFunc(pos, r.currPkg, name, sig))
281
282 case 'T':
283
284
285 obj := types2.NewTypeName(pos, r.currPkg, name, nil)
286 named := types2.NewNamed(obj, nil, nil)
287 r.declare(obj)
288
289 underlying := r.p.typAt(r.uint64(), named).Underlying()
290 named.SetUnderlying(underlying)
291
292 if !isInterface(underlying) {
293 for n := r.uint64(); n > 0; n-- {
294 mpos := r.pos()
295 mname := r.ident()
296 recv := r.param()
297 msig := r.signature(recv)
298
299 named.AddMethod(types2.NewFunc(mpos, r.currPkg, mname, msig))
300 }
301 }
302
303 case 'V':
304 typ := r.typ()
305
306 r.declare(types2.NewVar(pos, r.currPkg, name, typ))
307
308 default:
309 errorf("unexpected tag: %v", tag)
310 }
311 }
312
313 func (r *importReader) declare(obj types2.Object) {
314 obj.Pkg().Scope().Insert(obj)
315 }
316
317 func (r *importReader) value() (typ types2.Type, val constant.Value) {
318 typ = r.typ()
319
320 switch b := typ.Underlying().(*types2.Basic); b.Info() & types2.IsConstType {
321 case types2.IsBoolean:
322 val = constant.MakeBool(r.bool())
323
324 case types2.IsString:
325 val = constant.MakeString(r.string())
326
327 case types2.IsInteger:
328 var x big.Int
329 r.mpint(&x, b)
330 val = constant.Make(&x)
331
332 case types2.IsFloat:
333 val = r.mpfloat(b)
334
335 case types2.IsComplex:
336 re := r.mpfloat(b)
337 im := r.mpfloat(b)
338 val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
339
340 default:
341 errorf("unexpected type %v", typ)
342 panic("unreachable")
343 }
344
345 return
346 }
347
348 func intSize(b *types2.Basic) (signed bool, maxBytes uint) {
349 if (b.Info() & types2.IsUntyped) != 0 {
350 return true, 64
351 }
352
353 switch b.Kind() {
354 case types2.Float32, types2.Complex64:
355 return true, 3
356 case types2.Float64, types2.Complex128:
357 return true, 7
358 }
359
360 signed = (b.Info() & types2.IsUnsigned) == 0
361 switch b.Kind() {
362 case types2.Int8, types2.Uint8:
363 maxBytes = 1
364 case types2.Int16, types2.Uint16:
365 maxBytes = 2
366 case types2.Int32, types2.Uint32:
367 maxBytes = 4
368 default:
369 maxBytes = 8
370 }
371
372 return
373 }
374
375 func (r *importReader) mpint(x *big.Int, typ *types2.Basic) {
376 signed, maxBytes := intSize(typ)
377
378 maxSmall := 256 - maxBytes
379 if signed {
380 maxSmall = 256 - 2*maxBytes
381 }
382 if maxBytes == 1 {
383 maxSmall = 256
384 }
385
386 n, _ := r.declReader.ReadByte()
387 if uint(n) < maxSmall {
388 v := int64(n)
389 if signed {
390 v >>= 1
391 if n&1 != 0 {
392 v = ^v
393 }
394 }
395 x.SetInt64(v)
396 return
397 }
398
399 v := -n
400 if signed {
401 v = -(n &^ 1) >> 1
402 }
403 if v < 1 || uint(v) > maxBytes {
404 errorf("weird decoding: %v, %v => %v", n, signed, v)
405 }
406 b := make([]byte, v)
407 io.ReadFull(&r.declReader, b)
408 x.SetBytes(b)
409 if signed && n&1 != 0 {
410 x.Neg(x)
411 }
412 }
413
414 func (r *importReader) mpfloat(typ *types2.Basic) constant.Value {
415 var mant big.Int
416 r.mpint(&mant, typ)
417 var f big.Float
418 f.SetInt(&mant)
419 if f.Sign() != 0 {
420 f.SetMantExp(&f, int(r.int64()))
421 }
422 return constant.Make(&f)
423 }
424
425 func (r *importReader) ident() string {
426 return r.string()
427 }
428
429 func (r *importReader) qualifiedIdent() (*types2.Package, string) {
430 name := r.string()
431 pkg := r.pkg()
432 return pkg, name
433 }
434
435 func (r *importReader) pos() syntax.Pos {
436 if r.p.version >= 1 {
437 r.posv1()
438 } else {
439 r.posv0()
440 }
441
442 if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 {
443 return syntax.Pos{}
444 }
445
446
447 return syntax.Pos{}
448 }
449
450 func (r *importReader) posv0() {
451 delta := r.int64()
452 if delta != deltaNewFile {
453 r.prevLine += delta
454 } else if l := r.int64(); l == -1 {
455 r.prevLine += deltaNewFile
456 } else {
457 r.prevFile = r.string()
458 r.prevLine = l
459 }
460 }
461
462 func (r *importReader) posv1() {
463 delta := r.int64()
464 r.prevColumn += delta >> 1
465 if delta&1 != 0 {
466 delta = r.int64()
467 r.prevLine += delta >> 1
468 if delta&1 != 0 {
469 r.prevFile = r.string()
470 }
471 }
472 }
473
474 func (r *importReader) typ() types2.Type {
475 return r.p.typAt(r.uint64(), nil)
476 }
477
478 func isInterface(t types2.Type) bool {
479 _, ok := t.(*types2.Interface)
480 return ok
481 }
482
483 func (r *importReader) pkg() *types2.Package { return r.p.pkgAt(r.uint64()) }
484 func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
485
486 func (r *importReader) doType(base *types2.Named) types2.Type {
487 switch k := r.kind(); k {
488 default:
489 errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
490 return nil
491
492 case definedType:
493 pkg, name := r.qualifiedIdent()
494 r.p.doDecl(pkg, name)
495 return pkg.Scope().Lookup(name).(*types2.TypeName).Type()
496 case pointerType:
497 return types2.NewPointer(r.typ())
498 case sliceType:
499 return types2.NewSlice(r.typ())
500 case arrayType:
501 n := r.uint64()
502 return types2.NewArray(r.typ(), int64(n))
503 case chanType:
504 dir := chanDir(int(r.uint64()))
505 return types2.NewChan(dir, r.typ())
506 case mapType:
507 return types2.NewMap(r.typ(), r.typ())
508 case signatureType:
509 r.currPkg = r.pkg()
510 return r.signature(nil)
511
512 case structType:
513 r.currPkg = r.pkg()
514
515 fields := make([]*types2.Var, r.uint64())
516 tags := make([]string, len(fields))
517 for i := range fields {
518 fpos := r.pos()
519 fname := r.ident()
520 ftyp := r.typ()
521 emb := r.bool()
522 tag := r.string()
523
524 fields[i] = types2.NewField(fpos, r.currPkg, fname, ftyp, emb)
525 tags[i] = tag
526 }
527 return types2.NewStruct(fields, tags)
528
529 case interfaceType:
530 r.currPkg = r.pkg()
531
532 embeddeds := make([]types2.Type, r.uint64())
533 for i := range embeddeds {
534 _ = r.pos()
535 embeddeds[i] = r.typ()
536 }
537
538 methods := make([]*types2.Func, r.uint64())
539 for i := range methods {
540 mpos := r.pos()
541 mname := r.ident()
542
543
544
545 var recv *types2.Var
546 if base != nil {
547 recv = types2.NewVar(syntax.Pos{}, r.currPkg, "", base)
548 }
549
550 msig := r.signature(recv)
551 methods[i] = types2.NewFunc(mpos, r.currPkg, mname, msig)
552 }
553
554 typ := types2.NewInterfaceType(methods, embeddeds)
555 r.p.interfaceList = append(r.p.interfaceList, typ)
556 return typ
557 }
558 }
559
560 func (r *importReader) kind() itag {
561 return itag(r.uint64())
562 }
563
564 func (r *importReader) signature(recv *types2.Var) *types2.Signature {
565 params := r.paramList()
566 results := r.paramList()
567 variadic := params.Len() > 0 && r.bool()
568 return types2.NewSignature(recv, params, results, variadic)
569 }
570
571 func (r *importReader) paramList() *types2.Tuple {
572 xs := make([]*types2.Var, r.uint64())
573 for i := range xs {
574 xs[i] = r.param()
575 }
576 return types2.NewTuple(xs...)
577 }
578
579 func (r *importReader) param() *types2.Var {
580 pos := r.pos()
581 name := r.ident()
582 typ := r.typ()
583 return types2.NewParam(pos, r.currPkg, name, typ)
584 }
585
586 func (r *importReader) bool() bool {
587 return r.uint64() != 0
588 }
589
590 func (r *importReader) int64() int64 {
591 n, err := binary.ReadVarint(&r.declReader)
592 if err != nil {
593 errorf("readVarint: %v", err)
594 }
595 return n
596 }
597
598 func (r *importReader) uint64() uint64 {
599 n, err := binary.ReadUvarint(&r.declReader)
600 if err != nil {
601 errorf("readUvarint: %v", err)
602 }
603 return n
604 }
605
606 func (r *importReader) byte() byte {
607 x, err := r.declReader.ReadByte()
608 if err != nil {
609 errorf("declReader.ReadByte: %v", err)
610 }
611 return x
612 }
613
View as plain text