github.com/corona10/go@v0.0.0-20180224231303-7a218942be57/src/go/internal/gcimporter/bimport.go (about) 1 // Copyright 2015 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 package gcimporter 6 7 import ( 8 "encoding/binary" 9 "fmt" 10 "go/constant" 11 "go/token" 12 "go/types" 13 "sort" 14 "strconv" 15 "strings" 16 "sync" 17 "unicode" 18 "unicode/utf8" 19 ) 20 21 type importer struct { 22 imports map[string]*types.Package 23 data []byte 24 importpath string 25 buf []byte // for reading strings 26 version int // export format version 27 28 // object lists 29 strList []string // in order of appearance 30 pathList []string // in order of appearance 31 pkgList []*types.Package // in order of appearance 32 typList []types.Type // in order of appearance 33 interfaceList []*types.Interface // for delayed completion only 34 trackAllTypes bool 35 36 // position encoding 37 posInfoFormat bool 38 prevFile string 39 prevLine int 40 fset *token.FileSet 41 files map[string]*token.File 42 43 // debugging support 44 debugFormat bool 45 read int // bytes read 46 } 47 48 // BImportData imports a package from the serialized package data 49 // and returns the number of bytes consumed and a reference to the package. 50 // If the export data version is not recognized or the format is otherwise 51 // compromised, an error is returned. 52 func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { 53 // catch panics and return them as errors 54 defer func() { 55 if e := recover(); e != nil { 56 // The package (filename) causing the problem is added to this 57 // error by a wrapper in the caller (Import in gcimporter.go). 58 // Return a (possibly nil or incomplete) package unchanged (see #16088). 59 err = fmt.Errorf("cannot import, possibly version skew (%v) - reinstall package", e) 60 } 61 }() 62 63 p := importer{ 64 imports: imports, 65 data: data, 66 importpath: path, 67 version: -1, // unknown version 68 strList: []string{""}, // empty string is mapped to 0 69 pathList: []string{""}, // empty string is mapped to 0 70 fset: fset, 71 files: make(map[string]*token.File), 72 } 73 74 // read version info 75 var versionstr string 76 if b := p.rawByte(); b == 'c' || b == 'd' { 77 // Go1.7 encoding; first byte encodes low-level 78 // encoding format (compact vs debug). 79 // For backward-compatibility only (avoid problems with 80 // old installed packages). Newly compiled packages use 81 // the extensible format string. 82 // TODO(gri) Remove this support eventually; after Go1.8. 83 if b == 'd' { 84 p.debugFormat = true 85 } 86 p.trackAllTypes = p.rawByte() == 'a' 87 p.posInfoFormat = p.int() != 0 88 versionstr = p.string() 89 if versionstr == "v1" { 90 p.version = 0 91 } 92 } else { 93 // Go1.8 extensible encoding 94 // read version string and extract version number (ignore anything after the version number) 95 versionstr = p.rawStringln(b) 96 if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" { 97 if v, err := strconv.Atoi(s[1]); err == nil && v > 0 { 98 p.version = v 99 } 100 } 101 } 102 103 // read version specific flags - extend as necessary 104 switch p.version { 105 // case 6: 106 // ... 107 // fallthrough 108 case 5, 4, 3, 2, 1: 109 p.debugFormat = p.rawStringln(p.rawByte()) == "debug" 110 p.trackAllTypes = p.int() != 0 111 p.posInfoFormat = p.int() != 0 112 case 0: 113 // Go1.7 encoding format - nothing to do here 114 default: 115 errorf("unknown export format version %d (%q)", p.version, versionstr) 116 } 117 118 // --- generic export data --- 119 120 // populate typList with predeclared "known" types 121 p.typList = append(p.typList, predeclared...) 122 123 // read package data 124 pkg = p.pkg() 125 126 // read objects of phase 1 only (see cmd/compile/internal/gc/bexport.go) 127 objcount := 0 128 for { 129 tag := p.tagOrIndex() 130 if tag == endTag { 131 break 132 } 133 p.obj(tag) 134 objcount++ 135 } 136 137 // self-verification 138 if count := p.int(); count != objcount { 139 errorf("got %d objects; want %d", objcount, count) 140 } 141 142 // ignore compiler-specific import data 143 144 // complete interfaces 145 // TODO(gri) re-investigate if we still need to do this in a delayed fashion 146 for _, typ := range p.interfaceList { 147 typ.Complete() 148 } 149 150 // record all referenced packages as imports 151 list := append(([]*types.Package)(nil), p.pkgList[1:]...) 152 sort.Sort(byPath(list)) 153 pkg.SetImports(list) 154 155 // package was imported completely and without errors 156 pkg.MarkComplete() 157 158 return p.read, pkg, nil 159 } 160 161 func errorf(format string, args ...interface{}) { 162 panic(fmt.Sprintf(format, args...)) 163 } 164 165 func (p *importer) pkg() *types.Package { 166 // if the package was seen before, i is its index (>= 0) 167 i := p.tagOrIndex() 168 if i >= 0 { 169 return p.pkgList[i] 170 } 171 172 // otherwise, i is the package tag (< 0) 173 if i != packageTag { 174 errorf("unexpected package tag %d version %d", i, p.version) 175 } 176 177 // read package data 178 name := p.string() 179 var path string 180 if p.version >= 5 { 181 path = p.path() 182 } else { 183 path = p.string() 184 } 185 186 // we should never see an empty package name 187 if name == "" { 188 errorf("empty package name in import") 189 } 190 191 // an empty path denotes the package we are currently importing; 192 // it must be the first package we see 193 if (path == "") != (len(p.pkgList) == 0) { 194 errorf("package path %q for pkg index %d", path, len(p.pkgList)) 195 } 196 197 // if the package was imported before, use that one; otherwise create a new one 198 if path == "" { 199 path = p.importpath 200 } 201 pkg := p.imports[path] 202 if pkg == nil { 203 pkg = types.NewPackage(path, name) 204 p.imports[path] = pkg 205 } else if pkg.Name() != name { 206 errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path) 207 } 208 p.pkgList = append(p.pkgList, pkg) 209 210 return pkg 211 } 212 213 // objTag returns the tag value for each object kind. 214 func objTag(obj types.Object) int { 215 switch obj.(type) { 216 case *types.Const: 217 return constTag 218 case *types.TypeName: 219 return typeTag 220 case *types.Var: 221 return varTag 222 case *types.Func: 223 return funcTag 224 default: 225 errorf("unexpected object: %v (%T)", obj, obj) // panics 226 panic("unreachable") 227 } 228 } 229 230 func sameObj(a, b types.Object) bool { 231 // Because unnamed types are not canonicalized, we cannot simply compare types for 232 // (pointer) identity. 233 // Ideally we'd check equality of constant values as well, but this is good enough. 234 return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type()) 235 } 236 237 func (p *importer) declare(obj types.Object) { 238 pkg := obj.Pkg() 239 if alt := pkg.Scope().Insert(obj); alt != nil { 240 // This can only trigger if we import a (non-type) object a second time. 241 // Excluding type aliases, this cannot happen because 1) we only import a package 242 // once; and b) we ignore compiler-specific export data which may contain 243 // functions whose inlined function bodies refer to other functions that 244 // were already imported. 245 // However, type aliases require reexporting the original type, so we need 246 // to allow it (see also the comment in cmd/compile/internal/gc/bimport.go, 247 // method importer.obj, switch case importing functions). 248 // TODO(gri) review/update this comment once the gc compiler handles type aliases. 249 if !sameObj(obj, alt) { 250 errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt) 251 } 252 } 253 } 254 255 func (p *importer) obj(tag int) { 256 switch tag { 257 case constTag: 258 pos := p.pos() 259 pkg, name := p.qualifiedName() 260 typ := p.typ(nil, nil) 261 val := p.value() 262 p.declare(types.NewConst(pos, pkg, name, typ, val)) 263 264 case aliasTag: 265 // TODO(gri) verify type alias hookup is correct 266 pos := p.pos() 267 pkg, name := p.qualifiedName() 268 typ := p.typ(nil, nil) 269 p.declare(types.NewTypeName(pos, pkg, name, typ)) 270 271 case typeTag: 272 p.typ(nil, nil) 273 274 case varTag: 275 pos := p.pos() 276 pkg, name := p.qualifiedName() 277 typ := p.typ(nil, nil) 278 p.declare(types.NewVar(pos, pkg, name, typ)) 279 280 case funcTag: 281 pos := p.pos() 282 pkg, name := p.qualifiedName() 283 params, isddd := p.paramList() 284 result, _ := p.paramList() 285 sig := types.NewSignature(nil, params, result, isddd) 286 p.declare(types.NewFunc(pos, pkg, name, sig)) 287 288 default: 289 errorf("unexpected object tag %d", tag) 290 } 291 } 292 293 const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go 294 295 func (p *importer) pos() token.Pos { 296 if !p.posInfoFormat { 297 return token.NoPos 298 } 299 300 file := p.prevFile 301 line := p.prevLine 302 delta := p.int() 303 line += delta 304 if p.version >= 5 { 305 if delta == deltaNewFile { 306 if n := p.int(); n >= 0 { 307 // file changed 308 file = p.path() 309 line = n 310 } 311 } 312 } else { 313 if delta == 0 { 314 if n := p.int(); n >= 0 { 315 // file changed 316 file = p.prevFile[:n] + p.string() 317 line = p.int() 318 } 319 } 320 } 321 p.prevFile = file 322 p.prevLine = line 323 324 // Synthesize a token.Pos 325 326 // Since we don't know the set of needed file positions, we 327 // reserve maxlines positions per file. 328 const maxlines = 64 * 1024 329 f := p.files[file] 330 if f == nil { 331 f = p.fset.AddFile(file, -1, maxlines) 332 p.files[file] = f 333 // Allocate the fake linebreak indices on first use. 334 // TODO(adonovan): opt: save ~512KB using a more complex scheme? 335 fakeLinesOnce.Do(func() { 336 fakeLines = make([]int, maxlines) 337 for i := range fakeLines { 338 fakeLines[i] = i 339 } 340 }) 341 f.SetLines(fakeLines) 342 } 343 344 if line > maxlines { 345 line = 1 346 } 347 348 // Treat the file as if it contained only newlines 349 // and column=1: use the line number as the offset. 350 return f.Pos(line - 1) 351 } 352 353 var ( 354 fakeLines []int 355 fakeLinesOnce sync.Once 356 ) 357 358 func (p *importer) qualifiedName() (pkg *types.Package, name string) { 359 name = p.string() 360 pkg = p.pkg() 361 return 362 } 363 364 func (p *importer) record(t types.Type) { 365 p.typList = append(p.typList, t) 366 } 367 368 // A dddSlice is a types.Type representing ...T parameters. 369 // It only appears for parameter types and does not escape 370 // the importer. 371 type dddSlice struct { 372 elem types.Type 373 } 374 375 func (t *dddSlice) Underlying() types.Type { return t } 376 func (t *dddSlice) String() string { return "..." + t.elem.String() } 377 378 // parent is the package which declared the type; parent == nil means 379 // the package currently imported. The parent package is needed for 380 // exported struct fields and interface methods which don't contain 381 // explicit package information in the export data. 382 // 383 // A non-nil tname is used as the "owner" of the result type; i.e., 384 // the result type is the underlying type of tname. tname is used 385 // to give interface methods a named receiver type where possible. 386 func (p *importer) typ(parent *types.Package, tname *types.Named) types.Type { 387 // if the type was seen before, i is its index (>= 0) 388 i := p.tagOrIndex() 389 if i >= 0 { 390 return p.typList[i] 391 } 392 393 // otherwise, i is the type tag (< 0) 394 switch i { 395 case namedTag: 396 // read type object 397 pos := p.pos() 398 parent, name := p.qualifiedName() 399 scope := parent.Scope() 400 obj := scope.Lookup(name) 401 402 // if the object doesn't exist yet, create and insert it 403 if obj == nil { 404 obj = types.NewTypeName(pos, parent, name, nil) 405 scope.Insert(obj) 406 } 407 408 if _, ok := obj.(*types.TypeName); !ok { 409 errorf("pkg = %s, name = %s => %s", parent, name, obj) 410 } 411 412 // associate new named type with obj if it doesn't exist yet 413 t0 := types.NewNamed(obj.(*types.TypeName), nil, nil) 414 415 // but record the existing type, if any 416 tname := obj.Type().(*types.Named) // tname is either t0 or the existing type 417 p.record(tname) 418 419 // read underlying type 420 t0.SetUnderlying(p.typ(parent, t0)) 421 422 // interfaces don't have associated methods 423 if types.IsInterface(t0) { 424 return tname 425 } 426 427 // read associated methods 428 for i := p.int(); i > 0; i-- { 429 // TODO(gri) replace this with something closer to fieldName 430 pos := p.pos() 431 name := p.string() 432 if !exported(name) { 433 p.pkg() 434 } 435 436 recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver? 437 params, isddd := p.paramList() 438 result, _ := p.paramList() 439 p.int() // go:nointerface pragma - discarded 440 441 sig := types.NewSignature(recv.At(0), params, result, isddd) 442 t0.AddMethod(types.NewFunc(pos, parent, name, sig)) 443 } 444 445 return tname 446 447 case arrayTag: 448 t := new(types.Array) 449 if p.trackAllTypes { 450 p.record(t) 451 } 452 453 n := p.int64() 454 *t = *types.NewArray(p.typ(parent, nil), n) 455 return t 456 457 case sliceTag: 458 t := new(types.Slice) 459 if p.trackAllTypes { 460 p.record(t) 461 } 462 463 *t = *types.NewSlice(p.typ(parent, nil)) 464 return t 465 466 case dddTag: 467 t := new(dddSlice) 468 if p.trackAllTypes { 469 p.record(t) 470 } 471 472 t.elem = p.typ(parent, nil) 473 return t 474 475 case structTag: 476 t := new(types.Struct) 477 if p.trackAllTypes { 478 p.record(t) 479 } 480 481 *t = *types.NewStruct(p.fieldList(parent)) 482 return t 483 484 case pointerTag: 485 t := new(types.Pointer) 486 if p.trackAllTypes { 487 p.record(t) 488 } 489 490 *t = *types.NewPointer(p.typ(parent, nil)) 491 return t 492 493 case signatureTag: 494 t := new(types.Signature) 495 if p.trackAllTypes { 496 p.record(t) 497 } 498 499 params, isddd := p.paramList() 500 result, _ := p.paramList() 501 *t = *types.NewSignature(nil, params, result, isddd) 502 return t 503 504 case interfaceTag: 505 // Create a dummy entry in the type list. This is safe because we 506 // cannot expect the interface type to appear in a cycle, as any 507 // such cycle must contain a named type which would have been 508 // first defined earlier. 509 // TODO(gri) Is this still true now that we have type aliases? 510 // See issue #23225. 511 n := len(p.typList) 512 if p.trackAllTypes { 513 p.record(nil) 514 } 515 516 var embeddeds []*types.Named 517 for n := p.int(); n > 0; n-- { 518 p.pos() 519 embeddeds = append(embeddeds, p.typ(parent, nil).(*types.Named)) 520 } 521 522 t := types.NewInterface(p.methodList(parent, tname), embeddeds) 523 p.interfaceList = append(p.interfaceList, t) 524 if p.trackAllTypes { 525 p.typList[n] = t 526 } 527 return t 528 529 case mapTag: 530 t := new(types.Map) 531 if p.trackAllTypes { 532 p.record(t) 533 } 534 535 key := p.typ(parent, nil) 536 val := p.typ(parent, nil) 537 *t = *types.NewMap(key, val) 538 return t 539 540 case chanTag: 541 t := new(types.Chan) 542 if p.trackAllTypes { 543 p.record(t) 544 } 545 546 var dir types.ChanDir 547 // tag values must match the constants in cmd/compile/internal/gc/go.go 548 switch d := p.int(); d { 549 case 1 /* Crecv */ : 550 dir = types.RecvOnly 551 case 2 /* Csend */ : 552 dir = types.SendOnly 553 case 3 /* Cboth */ : 554 dir = types.SendRecv 555 default: 556 errorf("unexpected channel dir %d", d) 557 } 558 val := p.typ(parent, nil) 559 *t = *types.NewChan(dir, val) 560 return t 561 562 default: 563 errorf("unexpected type tag %d", i) // panics 564 panic("unreachable") 565 } 566 } 567 568 func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) { 569 if n := p.int(); n > 0 { 570 fields = make([]*types.Var, n) 571 tags = make([]string, n) 572 for i := range fields { 573 fields[i], tags[i] = p.field(parent) 574 } 575 } 576 return 577 } 578 579 func (p *importer) field(parent *types.Package) (*types.Var, string) { 580 pos := p.pos() 581 pkg, name, alias := p.fieldName(parent) 582 typ := p.typ(parent, nil) 583 tag := p.string() 584 585 anonymous := false 586 if name == "" { 587 // anonymous field - typ must be T or *T and T must be a type name 588 switch typ := deref(typ).(type) { 589 case *types.Basic: // basic types are named types 590 pkg = nil // // objects defined in Universe scope have no package 591 name = typ.Name() 592 case *types.Named: 593 name = typ.Obj().Name() 594 default: 595 errorf("named base type expected") 596 } 597 anonymous = true 598 } else if alias { 599 // anonymous field: we have an explicit name because it's an alias 600 anonymous = true 601 } 602 603 return types.NewField(pos, pkg, name, typ, anonymous), tag 604 } 605 606 func (p *importer) methodList(parent *types.Package, baseType *types.Named) (methods []*types.Func) { 607 if n := p.int(); n > 0 { 608 methods = make([]*types.Func, n) 609 for i := range methods { 610 methods[i] = p.method(parent, baseType) 611 } 612 } 613 return 614 } 615 616 func (p *importer) method(parent *types.Package, baseType *types.Named) *types.Func { 617 pos := p.pos() 618 pkg, name, _ := p.fieldName(parent) 619 // If we don't have a baseType, use a nil receiver. 620 // A receiver using the actual interface type (which 621 // we don't know yet) will be filled in when we call 622 // types.Interface.Complete. 623 var recv *types.Var 624 if baseType != nil { 625 recv = types.NewVar(token.NoPos, parent, "", baseType) 626 } 627 params, isddd := p.paramList() 628 result, _ := p.paramList() 629 sig := types.NewSignature(recv, params, result, isddd) 630 return types.NewFunc(pos, pkg, name, sig) 631 } 632 633 func (p *importer) fieldName(parent *types.Package) (pkg *types.Package, name string, alias bool) { 634 name = p.string() 635 pkg = parent 636 if pkg == nil { 637 // use the imported package instead 638 pkg = p.pkgList[0] 639 } 640 if p.version == 0 && name == "_" { 641 // version 0 didn't export a package for _ fields 642 return 643 } 644 switch name { 645 case "": 646 // 1) field name matches base type name and is exported: nothing to do 647 case "?": 648 // 2) field name matches base type name and is not exported: need package 649 name = "" 650 pkg = p.pkg() 651 case "@": 652 // 3) field name doesn't match type name (alias) 653 name = p.string() 654 alias = true 655 fallthrough 656 default: 657 if !exported(name) { 658 pkg = p.pkg() 659 } 660 } 661 return 662 } 663 664 func (p *importer) paramList() (*types.Tuple, bool) { 665 n := p.int() 666 if n == 0 { 667 return nil, false 668 } 669 // negative length indicates unnamed parameters 670 named := true 671 if n < 0 { 672 n = -n 673 named = false 674 } 675 // n > 0 676 params := make([]*types.Var, n) 677 isddd := false 678 for i := range params { 679 params[i], isddd = p.param(named) 680 } 681 return types.NewTuple(params...), isddd 682 } 683 684 func (p *importer) param(named bool) (*types.Var, bool) { 685 t := p.typ(nil, nil) 686 td, isddd := t.(*dddSlice) 687 if isddd { 688 t = types.NewSlice(td.elem) 689 } 690 691 var pkg *types.Package 692 var name string 693 if named { 694 name = p.string() 695 if name == "" { 696 errorf("expected named parameter") 697 } 698 if name != "_" { 699 pkg = p.pkg() 700 } 701 if i := strings.Index(name, "ยท"); i > 0 { 702 name = name[:i] // cut off gc-specific parameter numbering 703 } 704 } 705 706 // read and discard compiler-specific info 707 p.string() 708 709 return types.NewVar(token.NoPos, pkg, name, t), isddd 710 } 711 712 func exported(name string) bool { 713 ch, _ := utf8.DecodeRuneInString(name) 714 return unicode.IsUpper(ch) 715 } 716 717 func (p *importer) value() constant.Value { 718 switch tag := p.tagOrIndex(); tag { 719 case falseTag: 720 return constant.MakeBool(false) 721 case trueTag: 722 return constant.MakeBool(true) 723 case int64Tag: 724 return constant.MakeInt64(p.int64()) 725 case floatTag: 726 return p.float() 727 case complexTag: 728 re := p.float() 729 im := p.float() 730 return constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) 731 case stringTag: 732 return constant.MakeString(p.string()) 733 case unknownTag: 734 return constant.MakeUnknown() 735 default: 736 errorf("unexpected value tag %d", tag) // panics 737 panic("unreachable") 738 } 739 } 740 741 func (p *importer) float() constant.Value { 742 sign := p.int() 743 if sign == 0 { 744 return constant.MakeInt64(0) 745 } 746 747 exp := p.int() 748 mant := []byte(p.string()) // big endian 749 750 // remove leading 0's if any 751 for len(mant) > 0 && mant[0] == 0 { 752 mant = mant[1:] 753 } 754 755 // convert to little endian 756 // TODO(gri) go/constant should have a more direct conversion function 757 // (e.g., once it supports a big.Float based implementation) 758 for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 { 759 mant[i], mant[j] = mant[j], mant[i] 760 } 761 762 // adjust exponent (constant.MakeFromBytes creates an integer value, 763 // but mant represents the mantissa bits such that 0.5 <= mant < 1.0) 764 exp -= len(mant) << 3 765 if len(mant) > 0 { 766 for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 { 767 exp++ 768 } 769 } 770 771 x := constant.MakeFromBytes(mant) 772 switch { 773 case exp < 0: 774 d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) 775 x = constant.BinaryOp(x, token.QUO, d) 776 case exp > 0: 777 x = constant.Shift(x, token.SHL, uint(exp)) 778 } 779 780 if sign < 0 { 781 x = constant.UnaryOp(token.SUB, x, 0) 782 } 783 return x 784 } 785 786 // ---------------------------------------------------------------------------- 787 // Low-level decoders 788 789 func (p *importer) tagOrIndex() int { 790 if p.debugFormat { 791 p.marker('t') 792 } 793 794 return int(p.rawInt64()) 795 } 796 797 func (p *importer) int() int { 798 x := p.int64() 799 if int64(int(x)) != x { 800 errorf("exported integer too large") 801 } 802 return int(x) 803 } 804 805 func (p *importer) int64() int64 { 806 if p.debugFormat { 807 p.marker('i') 808 } 809 810 return p.rawInt64() 811 } 812 813 func (p *importer) path() string { 814 if p.debugFormat { 815 p.marker('p') 816 } 817 // if the path was seen before, i is its index (>= 0) 818 // (the empty string is at index 0) 819 i := p.rawInt64() 820 if i >= 0 { 821 return p.pathList[i] 822 } 823 // otherwise, i is the negative path length (< 0) 824 a := make([]string, -i) 825 for n := range a { 826 a[n] = p.string() 827 } 828 s := strings.Join(a, "/") 829 p.pathList = append(p.pathList, s) 830 return s 831 } 832 833 func (p *importer) string() string { 834 if p.debugFormat { 835 p.marker('s') 836 } 837 // if the string was seen before, i is its index (>= 0) 838 // (the empty string is at index 0) 839 i := p.rawInt64() 840 if i >= 0 { 841 return p.strList[i] 842 } 843 // otherwise, i is the negative string length (< 0) 844 if n := int(-i); n <= cap(p.buf) { 845 p.buf = p.buf[:n] 846 } else { 847 p.buf = make([]byte, n) 848 } 849 for i := range p.buf { 850 p.buf[i] = p.rawByte() 851 } 852 s := string(p.buf) 853 p.strList = append(p.strList, s) 854 return s 855 } 856 857 func (p *importer) marker(want byte) { 858 if got := p.rawByte(); got != want { 859 errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read) 860 } 861 862 pos := p.read 863 if n := int(p.rawInt64()); n != pos { 864 errorf("incorrect position: got %d; want %d", n, pos) 865 } 866 } 867 868 // rawInt64 should only be used by low-level decoders. 869 func (p *importer) rawInt64() int64 { 870 i, err := binary.ReadVarint(p) 871 if err != nil { 872 errorf("read error: %v", err) 873 } 874 return i 875 } 876 877 // rawStringln should only be used to read the initial version string. 878 func (p *importer) rawStringln(b byte) string { 879 p.buf = p.buf[:0] 880 for b != '\n' { 881 p.buf = append(p.buf, b) 882 b = p.rawByte() 883 } 884 return string(p.buf) 885 } 886 887 // needed for binary.ReadVarint in rawInt64 888 func (p *importer) ReadByte() (byte, error) { 889 return p.rawByte(), nil 890 } 891 892 // byte is the bottleneck interface for reading p.data. 893 // It unescapes '|' 'S' to '$' and '|' '|' to '|'. 894 // rawByte should only be used by low-level decoders. 895 func (p *importer) rawByte() byte { 896 b := p.data[0] 897 r := 1 898 if b == '|' { 899 b = p.data[1] 900 r = 2 901 switch b { 902 case 'S': 903 b = '$' 904 case '|': 905 // nothing to do 906 default: 907 errorf("unexpected escape sequence in export data") 908 } 909 } 910 p.data = p.data[r:] 911 p.read += r 912 return b 913 914 } 915 916 // ---------------------------------------------------------------------------- 917 // Export format 918 919 // Tags. Must be < 0. 920 const ( 921 // Objects 922 packageTag = -(iota + 1) 923 constTag 924 typeTag 925 varTag 926 funcTag 927 endTag 928 929 // Types 930 namedTag 931 arrayTag 932 sliceTag 933 dddTag 934 structTag 935 pointerTag 936 signatureTag 937 interfaceTag 938 mapTag 939 chanTag 940 941 // Values 942 falseTag 943 trueTag 944 int64Tag 945 floatTag 946 fractionTag // not used by gc 947 complexTag 948 stringTag 949 nilTag // only used by gc (appears in exported inlined function bodies) 950 unknownTag // not used by gc (only appears in packages with errors) 951 952 // Type aliases 953 aliasTag 954 ) 955 956 var predeclared = []types.Type{ 957 // basic types 958 types.Typ[types.Bool], 959 types.Typ[types.Int], 960 types.Typ[types.Int8], 961 types.Typ[types.Int16], 962 types.Typ[types.Int32], 963 types.Typ[types.Int64], 964 types.Typ[types.Uint], 965 types.Typ[types.Uint8], 966 types.Typ[types.Uint16], 967 types.Typ[types.Uint32], 968 types.Typ[types.Uint64], 969 types.Typ[types.Uintptr], 970 types.Typ[types.Float32], 971 types.Typ[types.Float64], 972 types.Typ[types.Complex64], 973 types.Typ[types.Complex128], 974 types.Typ[types.String], 975 976 // basic type aliases 977 types.Universe.Lookup("byte").Type(), 978 types.Universe.Lookup("rune").Type(), 979 980 // error 981 types.Universe.Lookup("error").Type(), 982 983 // untyped types 984 types.Typ[types.UntypedBool], 985 types.Typ[types.UntypedInt], 986 types.Typ[types.UntypedRune], 987 types.Typ[types.UntypedFloat], 988 types.Typ[types.UntypedComplex], 989 types.Typ[types.UntypedString], 990 types.Typ[types.UntypedNil], 991 992 // package unsafe 993 types.Typ[types.UnsafePointer], 994 995 // invalid type 996 types.Typ[types.Invalid], // only appears in packages with errors 997 998 // used internally by gc; never used by this package or in .a files 999 anyType{}, 1000 } 1001 1002 type anyType struct{} 1003 1004 func (t anyType) Underlying() types.Type { return t } 1005 func (t anyType) String() string { return "any" }