github.com/bir3/gocompiler@v0.3.205/src/cmd/compile/internal/importer/iimport.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Indexed package import. 6 // See cmd/compile/internal/typecheck/iexport.go for the export data format. 7 8 package importer 9 10 import ( 11 "github.com/bir3/gocompiler/src/cmd/compile/internal/syntax" 12 "github.com/bir3/gocompiler/src/cmd/compile/internal/typecheck" 13 "github.com/bir3/gocompiler/src/cmd/compile/internal/types2" 14 "encoding/binary" 15 "fmt" 16 "github.com/bir3/gocompiler/src/go/constant" 17 "github.com/bir3/gocompiler/src/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 // Keep this in sync with constants in iexport.go. 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 // Types 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 // io.SeekCurrent (not defined in Go 1.4) 81 82 // ImportData imports a package from the serialized package data 83 // and returns the number of bytes consumed and a reference to the package. 84 // If the export data version is not recognized or the format is otherwise 85 // compromised, an error is returned. 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 // Separate map for typeparams, keyed by their package and unique 129 // name (name with subscript). 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 _ = int(r.uint64()) // was package height, but not necessary anymore. 143 144 if pkgPath == "" { 145 pkgPath = path 146 } 147 pkg := imports[pkgPath] 148 if pkg == nil { 149 pkg = types2.NewPackage(pkgPath, pkgName) 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 } 156 157 p.pkgCache[pkgPathOff] = pkg 158 159 nameIndex := make(map[string]uint64) 160 for nSyms := r.uint64(); nSyms > 0; nSyms-- { 161 name := p.stringAt(r.uint64()) 162 nameIndex[name] = r.uint64() 163 } 164 165 p.pkgIndex[pkg] = nameIndex 166 pkgList[i] = pkg 167 } 168 169 localpkg := pkgList[0] 170 171 names := make([]string, 0, len(p.pkgIndex[localpkg])) 172 for name := range p.pkgIndex[localpkg] { 173 names = append(names, name) 174 } 175 sort.Strings(names) 176 for _, name := range names { 177 p.doDecl(localpkg, name) 178 } 179 180 // SetConstraint can't be called if the constraint type is not yet complete. 181 // When type params are created in the 'P' case of (*importReader).obj(), 182 // the associated constraint type may not be complete due to recursion. 183 // Therefore, we defer calling SetConstraint there, and call it here instead 184 // after all types are complete. 185 for _, d := range p.later { 186 d.t.SetConstraint(d.constraint) 187 } 188 // record all referenced packages as imports 189 list := append(([]*types2.Package)(nil), pkgList[1:]...) 190 sort.Sort(byPath(list)) 191 localpkg.SetImports(list) 192 193 // package was imported completely and without errors 194 localpkg.MarkComplete() 195 196 return localpkg, nil 197 } 198 199 type setConstraintArgs struct { 200 t *types2.TypeParam 201 constraint types2.Type 202 } 203 204 type iimporter struct { 205 exportVersion int64 206 ipath string 207 version int 208 209 stringData string 210 pkgCache map[uint64]*types2.Package 211 posBaseCache map[uint64]*syntax.PosBase 212 213 declData string 214 pkgIndex map[*types2.Package]map[string]uint64 215 typCache map[uint64]types2.Type 216 tparamIndex map[ident]*types2.TypeParam 217 218 interfaceList []*types2.Interface 219 220 // Arguments for calls to SetConstraint that are deferred due to recursive types 221 later []setConstraintArgs 222 } 223 224 func (p *iimporter) doDecl(pkg *types2.Package, name string) { 225 // See if we've already imported this declaration. 226 if obj := pkg.Scope().Lookup(name); obj != nil { 227 return 228 } 229 230 off, ok := p.pkgIndex[pkg][name] 231 if !ok { 232 errorf("%v.%v not in index", pkg, name) 233 } 234 235 r := &importReader{p: p, currPkg: pkg} 236 r.declReader.Reset(p.declData[off:]) 237 238 r.obj(name) 239 } 240 241 func (p *iimporter) stringAt(off uint64) string { 242 var x [binary.MaxVarintLen64]byte 243 n := copy(x[:], p.stringData[off:]) 244 245 slen, n := binary.Uvarint(x[:n]) 246 if n <= 0 { 247 errorf("varint failed") 248 } 249 spos := off + uint64(n) 250 return p.stringData[spos : spos+slen] 251 } 252 253 func (p *iimporter) pkgAt(off uint64) *types2.Package { 254 if pkg, ok := p.pkgCache[off]; ok { 255 return pkg 256 } 257 path := p.stringAt(off) 258 errorf("missing package %q in %q", path, p.ipath) 259 return nil 260 } 261 262 func (p *iimporter) posBaseAt(off uint64) *syntax.PosBase { 263 if posBase, ok := p.posBaseCache[off]; ok { 264 return posBase 265 } 266 filename := p.stringAt(off) 267 posBase := syntax.NewTrimmedFileBase(filename, true) 268 p.posBaseCache[off] = posBase 269 return posBase 270 } 271 272 func (p *iimporter) typAt(off uint64, base *types2.Named) types2.Type { 273 if t, ok := p.typCache[off]; ok && canReuse(base, t) { 274 return t 275 } 276 277 if off < predeclReserved { 278 errorf("predeclared type missing from cache: %v", off) 279 } 280 281 r := &importReader{p: p} 282 r.declReader.Reset(p.declData[off-predeclReserved:]) 283 t := r.doType(base) 284 285 if canReuse(base, t) { 286 p.typCache[off] = t 287 } 288 return t 289 } 290 291 // canReuse reports whether the type rhs on the RHS of the declaration for def 292 // may be re-used. 293 // 294 // Specifically, if def is non-nil and rhs is an interface type with methods, it 295 // may not be re-used because we have a convention of setting the receiver type 296 // for interface methods to def. 297 func canReuse(def *types2.Named, rhs types2.Type) bool { 298 if def == nil { 299 return true 300 } 301 iface, _ := rhs.(*types2.Interface) 302 if iface == nil { 303 return true 304 } 305 // Don't use iface.Empty() here as iface may not be complete. 306 return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0 307 } 308 309 type importReader struct { 310 p *iimporter 311 declReader strings.Reader 312 currPkg *types2.Package 313 prevPosBase *syntax.PosBase 314 prevLine int64 315 prevColumn int64 316 } 317 318 func (r *importReader) obj(name string) { 319 tag := r.byte() 320 pos := r.pos() 321 322 switch tag { 323 case 'A': 324 typ := r.typ() 325 326 r.declare(types2.NewTypeName(pos, r.currPkg, name, typ)) 327 328 case 'C': 329 typ, val := r.value() 330 331 r.declare(types2.NewConst(pos, r.currPkg, name, typ, val)) 332 333 case 'F', 'G': 334 var tparams []*types2.TypeParam 335 if tag == 'G' { 336 tparams = r.tparamList() 337 } 338 sig := r.signature(nil, nil, tparams) 339 r.declare(types2.NewFunc(pos, r.currPkg, name, sig)) 340 341 case 'T', 'U': 342 // Types can be recursive. We need to setup a stub 343 // declaration before recursing. 344 obj := types2.NewTypeName(pos, r.currPkg, name, nil) 345 named := types2.NewNamed(obj, nil, nil) 346 // Declare obj before calling r.tparamList, so the new type name is recognized 347 // if used in the constraint of one of its own typeparams (see #48280). 348 r.declare(obj) 349 if tag == 'U' { 350 tparams := r.tparamList() 351 named.SetTypeParams(tparams) 352 } 353 354 underlying := r.p.typAt(r.uint64(), named).Underlying() 355 named.SetUnderlying(underlying) 356 357 if !isInterface(underlying) { 358 for n := r.uint64(); n > 0; n-- { 359 mpos := r.pos() 360 mname := r.ident() 361 recv := r.param() 362 363 // If the receiver has any targs, set those as the 364 // rparams of the method (since those are the 365 // typeparams being used in the method sig/body). 366 targs := baseType(recv.Type()).TypeArgs() 367 var rparams []*types2.TypeParam 368 if targs.Len() > 0 { 369 rparams = make([]*types2.TypeParam, targs.Len()) 370 for i := range rparams { 371 rparams[i], _ = targs.At(i).(*types2.TypeParam) 372 } 373 } 374 msig := r.signature(recv, rparams, nil) 375 376 named.AddMethod(types2.NewFunc(mpos, r.currPkg, mname, msig)) 377 } 378 } 379 380 case 'P': 381 // We need to "declare" a typeparam in order to have a name that 382 // can be referenced recursively (if needed) in the type param's 383 // bound. 384 if r.p.exportVersion < iexportVersionGenerics { 385 errorf("unexpected type param type") 386 } 387 name0 := typecheck.TparamName(name) 388 if name0 == "" { 389 errorf("malformed type parameter export name %s: missing prefix", name) 390 } 391 392 tn := types2.NewTypeName(pos, r.currPkg, name0, nil) 393 t := types2.NewTypeParam(tn, nil) 394 // To handle recursive references to the typeparam within its 395 // bound, save the partial type in tparamIndex before reading the bounds. 396 id := ident{r.currPkg, name} 397 r.p.tparamIndex[id] = t 398 399 var implicit bool 400 if r.p.exportVersion >= iexportVersionGo1_18 { 401 implicit = r.bool() 402 } 403 constraint := r.typ() 404 if implicit { 405 iface, _ := constraint.(*types2.Interface) 406 if iface == nil { 407 errorf("non-interface constraint marked implicit") 408 } 409 iface.MarkImplicit() 410 } 411 // The constraint type may not be complete, if we 412 // are in the middle of a type recursion involving type 413 // constraints. So, we defer SetConstraint until we have 414 // completely set up all types in ImportData. 415 r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint}) 416 417 case 'V': 418 typ := r.typ() 419 420 r.declare(types2.NewVar(pos, r.currPkg, name, typ)) 421 422 default: 423 errorf("unexpected tag: %v", tag) 424 } 425 } 426 427 func (r *importReader) declare(obj types2.Object) { 428 obj.Pkg().Scope().Insert(obj) 429 } 430 431 func (r *importReader) value() (typ types2.Type, val constant.Value) { 432 typ = r.typ() 433 if r.p.exportVersion >= iexportVersionGo1_18 { 434 // TODO: add support for using the kind 435 _ = constant.Kind(r.int64()) 436 } 437 438 switch b := typ.Underlying().(*types2.Basic); b.Info() & types2.IsConstType { 439 case types2.IsBoolean: 440 val = constant.MakeBool(r.bool()) 441 442 case types2.IsString: 443 val = constant.MakeString(r.string()) 444 445 case types2.IsInteger: 446 var x big.Int 447 r.mpint(&x, b) 448 val = constant.Make(&x) 449 450 case types2.IsFloat: 451 val = r.mpfloat(b) 452 453 case types2.IsComplex: 454 re := r.mpfloat(b) 455 im := r.mpfloat(b) 456 val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) 457 458 default: 459 errorf("unexpected type %v", typ) // panics 460 panic("unreachable") 461 } 462 463 return 464 } 465 466 func intSize(b *types2.Basic) (signed bool, maxBytes uint) { 467 if (b.Info() & types2.IsUntyped) != 0 { 468 return true, 64 469 } 470 471 switch b.Kind() { 472 case types2.Float32, types2.Complex64: 473 return true, 3 474 case types2.Float64, types2.Complex128: 475 return true, 7 476 } 477 478 signed = (b.Info() & types2.IsUnsigned) == 0 479 switch b.Kind() { 480 case types2.Int8, types2.Uint8: 481 maxBytes = 1 482 case types2.Int16, types2.Uint16: 483 maxBytes = 2 484 case types2.Int32, types2.Uint32: 485 maxBytes = 4 486 default: 487 maxBytes = 8 488 } 489 490 return 491 } 492 493 func (r *importReader) mpint(x *big.Int, typ *types2.Basic) { 494 signed, maxBytes := intSize(typ) 495 496 maxSmall := 256 - maxBytes 497 if signed { 498 maxSmall = 256 - 2*maxBytes 499 } 500 if maxBytes == 1 { 501 maxSmall = 256 502 } 503 504 n, _ := r.declReader.ReadByte() 505 if uint(n) < maxSmall { 506 v := int64(n) 507 if signed { 508 v >>= 1 509 if n&1 != 0 { 510 v = ^v 511 } 512 } 513 x.SetInt64(v) 514 return 515 } 516 517 v := -n 518 if signed { 519 v = -(n &^ 1) >> 1 520 } 521 if v < 1 || uint(v) > maxBytes { 522 errorf("weird decoding: %v, %v => %v", n, signed, v) 523 } 524 b := make([]byte, v) 525 io.ReadFull(&r.declReader, b) 526 x.SetBytes(b) 527 if signed && n&1 != 0 { 528 x.Neg(x) 529 } 530 } 531 532 func (r *importReader) mpfloat(typ *types2.Basic) constant.Value { 533 var mant big.Int 534 r.mpint(&mant, typ) 535 var f big.Float 536 f.SetInt(&mant) 537 if f.Sign() != 0 { 538 f.SetMantExp(&f, int(r.int64())) 539 } 540 return constant.Make(&f) 541 } 542 543 func (r *importReader) ident() string { 544 return r.string() 545 } 546 547 func (r *importReader) qualifiedIdent() (*types2.Package, string) { 548 name := r.string() 549 pkg := r.pkg() 550 return pkg, name 551 } 552 553 func (r *importReader) pos() syntax.Pos { 554 if r.p.version >= 1 { 555 r.posv1() 556 } else { 557 r.posv0() 558 } 559 560 if (r.prevPosBase == nil || r.prevPosBase.Filename() == "") && r.prevLine == 0 && r.prevColumn == 0 { 561 return syntax.Pos{} 562 } 563 564 return syntax.MakePos(r.prevPosBase, uint(r.prevLine), uint(r.prevColumn)) 565 } 566 567 func (r *importReader) posv0() { 568 delta := r.int64() 569 if delta != deltaNewFile { 570 r.prevLine += delta 571 } else if l := r.int64(); l == -1 { 572 r.prevLine += deltaNewFile 573 } else { 574 r.prevPosBase = r.posBase() 575 r.prevLine = l 576 } 577 } 578 579 func (r *importReader) posv1() { 580 delta := r.int64() 581 r.prevColumn += delta >> 1 582 if delta&1 != 0 { 583 delta = r.int64() 584 r.prevLine += delta >> 1 585 if delta&1 != 0 { 586 r.prevPosBase = r.posBase() 587 } 588 } 589 } 590 591 func (r *importReader) typ() types2.Type { 592 return r.p.typAt(r.uint64(), nil) 593 } 594 595 func isInterface(t types2.Type) bool { 596 _, ok := t.(*types2.Interface) 597 return ok 598 } 599 600 func (r *importReader) pkg() *types2.Package { return r.p.pkgAt(r.uint64()) } 601 func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } 602 func (r *importReader) posBase() *syntax.PosBase { return r.p.posBaseAt(r.uint64()) } 603 604 func (r *importReader) doType(base *types2.Named) types2.Type { 605 switch k := r.kind(); k { 606 default: 607 errorf("unexpected kind tag in %q: %v", r.p.ipath, k) 608 return nil 609 610 case definedType: 611 pkg, name := r.qualifiedIdent() 612 r.p.doDecl(pkg, name) 613 return pkg.Scope().Lookup(name).(*types2.TypeName).Type() 614 case pointerType: 615 return types2.NewPointer(r.typ()) 616 case sliceType: 617 return types2.NewSlice(r.typ()) 618 case arrayType: 619 n := r.uint64() 620 return types2.NewArray(r.typ(), int64(n)) 621 case chanType: 622 dir := chanDir(int(r.uint64())) 623 return types2.NewChan(dir, r.typ()) 624 case mapType: 625 return types2.NewMap(r.typ(), r.typ()) 626 case signatureType: 627 r.currPkg = r.pkg() 628 return r.signature(nil, nil, nil) 629 630 case structType: 631 r.currPkg = r.pkg() 632 633 fields := make([]*types2.Var, r.uint64()) 634 tags := make([]string, len(fields)) 635 for i := range fields { 636 fpos := r.pos() 637 fname := r.ident() 638 ftyp := r.typ() 639 emb := r.bool() 640 tag := r.string() 641 642 fields[i] = types2.NewField(fpos, r.currPkg, fname, ftyp, emb) 643 tags[i] = tag 644 } 645 return types2.NewStruct(fields, tags) 646 647 case interfaceType: 648 r.currPkg = r.pkg() 649 650 embeddeds := make([]types2.Type, r.uint64()) 651 for i := range embeddeds { 652 _ = r.pos() 653 embeddeds[i] = r.typ() 654 } 655 656 methods := make([]*types2.Func, r.uint64()) 657 for i := range methods { 658 mpos := r.pos() 659 mname := r.ident() 660 661 // TODO(mdempsky): Matches bimport.go, but I 662 // don't agree with this. 663 var recv *types2.Var 664 if base != nil { 665 recv = types2.NewVar(syntax.Pos{}, r.currPkg, "", base) 666 } 667 668 msig := r.signature(recv, nil, nil) 669 methods[i] = types2.NewFunc(mpos, r.currPkg, mname, msig) 670 } 671 672 typ := types2.NewInterfaceType(methods, embeddeds) 673 r.p.interfaceList = append(r.p.interfaceList, typ) 674 return typ 675 676 case typeParamType: 677 if r.p.exportVersion < iexportVersionGenerics { 678 errorf("unexpected type param type") 679 } 680 pkg, name := r.qualifiedIdent() 681 id := ident{pkg, name} 682 if t, ok := r.p.tparamIndex[id]; ok { 683 // We're already in the process of importing this typeparam. 684 return t 685 } 686 // Otherwise, import the definition of the typeparam now. 687 r.p.doDecl(pkg, name) 688 return r.p.tparamIndex[id] 689 690 case instanceType: 691 if r.p.exportVersion < iexportVersionGenerics { 692 errorf("unexpected instantiation type") 693 } 694 // pos does not matter for instances: they are positioned on the original 695 // type. 696 _ = r.pos() 697 len := r.uint64() 698 targs := make([]types2.Type, len) 699 for i := range targs { 700 targs[i] = r.typ() 701 } 702 baseType := r.typ() 703 // The imported instantiated type doesn't include any methods, so 704 // we must always use the methods of the base (orig) type. 705 // TODO provide a non-nil *Context 706 t, _ := types2.Instantiate(nil, baseType, targs, false) 707 return t 708 709 case unionType: 710 if r.p.exportVersion < iexportVersionGenerics { 711 errorf("unexpected instantiation type") 712 } 713 terms := make([]*types2.Term, r.uint64()) 714 for i := range terms { 715 terms[i] = types2.NewTerm(r.bool(), r.typ()) 716 } 717 return types2.NewUnion(terms) 718 } 719 } 720 721 func (r *importReader) kind() itag { 722 return itag(r.uint64()) 723 } 724 725 func (r *importReader) signature(recv *types2.Var, rparams, tparams []*types2.TypeParam) *types2.Signature { 726 params := r.paramList() 727 results := r.paramList() 728 variadic := params.Len() > 0 && r.bool() 729 return types2.NewSignatureType(recv, rparams, tparams, params, results, variadic) 730 } 731 732 func (r *importReader) tparamList() []*types2.TypeParam { 733 n := r.uint64() 734 if n == 0 { 735 return nil 736 } 737 xs := make([]*types2.TypeParam, n) 738 for i := range xs { 739 xs[i] = r.typ().(*types2.TypeParam) 740 } 741 return xs 742 } 743 744 func (r *importReader) paramList() *types2.Tuple { 745 xs := make([]*types2.Var, r.uint64()) 746 for i := range xs { 747 xs[i] = r.param() 748 } 749 return types2.NewTuple(xs...) 750 } 751 752 func (r *importReader) param() *types2.Var { 753 pos := r.pos() 754 name := r.ident() 755 typ := r.typ() 756 return types2.NewParam(pos, r.currPkg, name, typ) 757 } 758 759 func (r *importReader) bool() bool { 760 return r.uint64() != 0 761 } 762 763 func (r *importReader) int64() int64 { 764 n, err := binary.ReadVarint(&r.declReader) 765 if err != nil { 766 errorf("readVarint: %v", err) 767 } 768 return n 769 } 770 771 func (r *importReader) uint64() uint64 { 772 n, err := binary.ReadUvarint(&r.declReader) 773 if err != nil { 774 errorf("readUvarint: %v", err) 775 } 776 return n 777 } 778 779 func (r *importReader) byte() byte { 780 x, err := r.declReader.ReadByte() 781 if err != nil { 782 errorf("declReader.ReadByte: %v", err) 783 } 784 return x 785 } 786 787 func baseType(typ types2.Type) *types2.Named { 788 // pointer receivers are never types2.Named types 789 if p, _ := typ.(*types2.Pointer); p != nil { 790 typ = p.Elem() 791 } 792 // receiver base types are always (possibly generic) types2.Named types 793 n, _ := typ.(*types2.Named) 794 return n 795 }