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