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