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