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