github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/src/cmd/compile/internal/gc/subr.go (about) 1 // Copyright 2009 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 gc 6 7 import ( 8 "bytes" 9 "cmd/internal/obj" 10 "crypto/md5" 11 "encoding/binary" 12 "fmt" 13 "os" 14 "sort" 15 "strings" 16 "unicode" 17 "unicode/utf8" 18 ) 19 20 type Error struct { 21 lineno int 22 seq int 23 msg string 24 } 25 26 var errors []Error 27 28 func errorexit() { 29 Flusherrors() 30 if outfile != "" { 31 os.Remove(outfile) 32 } 33 os.Exit(2) 34 } 35 36 func parserline() int { 37 return int(lineno) 38 } 39 40 func adderrorname(n *Node) { 41 if n.Op != ODOT { 42 return 43 } 44 old := fmt.Sprintf("%v: undefined: %v\n", n.Line(), n.Left) 45 if len(errors) > 0 && int32(errors[len(errors)-1].lineno) == n.Lineno && errors[len(errors)-1].msg == old { 46 errors[len(errors)-1].msg = fmt.Sprintf("%v: undefined: %v in %v\n", n.Line(), n.Left, n) 47 } 48 } 49 50 func adderr(line int, format string, args ...interface{}) { 51 errors = append(errors, Error{ 52 seq: len(errors), 53 lineno: line, 54 msg: fmt.Sprintf("%v: %s\n", Ctxt.Line(line), fmt.Sprintf(format, args...)), 55 }) 56 } 57 58 // errcmp sorts errors by line, then seq, then message. 59 type errcmp []Error 60 61 func (x errcmp) Len() int { return len(x) } 62 func (x errcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 63 func (x errcmp) Less(i, j int) bool { 64 a := &x[i] 65 b := &x[j] 66 if a.lineno != b.lineno { 67 return a.lineno < b.lineno 68 } 69 if a.seq != b.seq { 70 return a.seq < b.seq 71 } 72 return a.msg < b.msg 73 } 74 75 func Flusherrors() { 76 bstdout.Flush() 77 if len(errors) == 0 { 78 return 79 } 80 sort.Sort(errcmp(errors)) 81 for i := 0; i < len(errors); i++ { 82 if i == 0 || errors[i].msg != errors[i-1].msg { 83 fmt.Printf("%s", errors[i].msg) 84 } 85 } 86 errors = errors[:0] 87 } 88 89 func hcrash() { 90 if Debug['h'] != 0 { 91 Flusherrors() 92 if outfile != "" { 93 os.Remove(outfile) 94 } 95 var x *int 96 *x = 0 97 } 98 } 99 100 func yyerrorl(line int, format string, args ...interface{}) { 101 adderr(line, format, args...) 102 103 hcrash() 104 nerrors++ 105 if nsavederrors+nerrors >= 10 && Debug['e'] == 0 { 106 Flusherrors() 107 fmt.Printf("%v: too many errors\n", Ctxt.Line(line)) 108 errorexit() 109 } 110 } 111 112 var yyerror_lastsyntax int 113 114 func Yyerror(format string, args ...interface{}) { 115 msg := fmt.Sprintf(format, args...) 116 if strings.HasPrefix(msg, "syntax error") { 117 nsyntaxerrors++ 118 119 // An unexpected EOF caused a syntax error. Use the previous 120 // line number since getc generated a fake newline character. 121 if curio.eofnl { 122 lexlineno = prevlineno 123 } 124 125 // only one syntax error per line 126 if int32(yyerror_lastsyntax) == lexlineno { 127 return 128 } 129 yyerror_lastsyntax = int(lexlineno) 130 131 // plain "syntax error" gets "near foo" added 132 if msg == "syntax error" { 133 yyerrorl(int(lexlineno), "syntax error near %s", lexbuf.String()) 134 return 135 } 136 137 yyerrorl(int(lexlineno), "%s", msg) 138 return 139 } 140 141 adderr(parserline(), "%s", msg) 142 143 hcrash() 144 nerrors++ 145 if nsavederrors+nerrors >= 10 && Debug['e'] == 0 { 146 Flusherrors() 147 fmt.Printf("%v: too many errors\n", Ctxt.Line(parserline())) 148 errorexit() 149 } 150 } 151 152 func Warn(fmt_ string, args ...interface{}) { 153 adderr(parserline(), fmt_, args...) 154 155 hcrash() 156 } 157 158 func Warnl(line int, fmt_ string, args ...interface{}) { 159 adderr(line, fmt_, args...) 160 if Debug['m'] != 0 { 161 Flusherrors() 162 } 163 } 164 165 func Fatalf(fmt_ string, args ...interface{}) { 166 Flusherrors() 167 168 fmt.Printf("%v: internal compiler error: ", Ctxt.Line(int(lineno))) 169 fmt.Printf(fmt_, args...) 170 fmt.Printf("\n") 171 172 // If this is a released compiler version, ask for a bug report. 173 if strings.HasPrefix(obj.Getgoversion(), "release") { 174 fmt.Printf("\n") 175 fmt.Printf("Please file a bug report including a short program that triggers the error.\n") 176 fmt.Printf("https://golang.org/issue/new\n") 177 } 178 179 hcrash() 180 errorexit() 181 } 182 183 func linehistpragma(file string) { 184 if Debug['i'] != 0 { 185 fmt.Printf("pragma %s at line %v\n", file, Ctxt.Line(int(lexlineno))) 186 } 187 Ctxt.AddImport(file) 188 } 189 190 func linehistpush(file string) { 191 if Debug['i'] != 0 { 192 fmt.Printf("import %s at line %v\n", file, Ctxt.Line(int(lexlineno))) 193 } 194 Ctxt.LineHist.Push(int(lexlineno), file) 195 } 196 197 func linehistpop() { 198 if Debug['i'] != 0 { 199 fmt.Printf("end of import at line %v\n", Ctxt.Line(int(lexlineno))) 200 } 201 Ctxt.LineHist.Pop(int(lexlineno)) 202 } 203 204 func linehistupdate(file string, off int) { 205 if Debug['i'] != 0 { 206 fmt.Printf("line %s at line %v\n", file, Ctxt.Line(int(lexlineno))) 207 } 208 Ctxt.LineHist.Update(int(lexlineno), file, off) 209 } 210 211 func setlineno(n *Node) int32 { 212 lno := lineno 213 if n != nil { 214 switch n.Op { 215 case ONAME, OTYPE, OPACK: 216 break 217 218 case OLITERAL: 219 if n.Sym != nil { 220 break 221 } 222 fallthrough 223 224 default: 225 lineno = n.Lineno 226 if lineno == 0 { 227 if Debug['K'] != 0 { 228 Warn("setlineno: line 0") 229 } 230 lineno = lno 231 } 232 } 233 } 234 235 return lno 236 } 237 238 func Lookup(name string) *Sym { 239 return localpkg.Lookup(name) 240 } 241 242 func Lookupf(format string, a ...interface{}) *Sym { 243 return Lookup(fmt.Sprintf(format, a...)) 244 } 245 246 func LookupBytes(name []byte) *Sym { 247 return localpkg.LookupBytes(name) 248 } 249 250 var initSyms []*Sym 251 252 var nopkg = &Pkg{ 253 Syms: make(map[string]*Sym), 254 } 255 256 func (pkg *Pkg) Lookup(name string) *Sym { 257 if pkg == nil { 258 pkg = nopkg 259 } 260 if s := pkg.Syms[name]; s != nil { 261 return s 262 } 263 264 s := &Sym{ 265 Name: name, 266 Pkg: pkg, 267 Lexical: LNAME, 268 } 269 if name == "init" { 270 initSyms = append(initSyms, s) 271 } 272 pkg.Syms[name] = s 273 return s 274 } 275 276 func (pkg *Pkg) LookupBytes(name []byte) *Sym { 277 if pkg == nil { 278 pkg = nopkg 279 } 280 if s := pkg.Syms[string(name)]; s != nil { 281 return s 282 } 283 str := internString(name) 284 return pkg.Lookup(str) 285 } 286 287 func Pkglookup(name string, pkg *Pkg) *Sym { 288 return pkg.Lookup(name) 289 } 290 291 func restrictlookup(name string, pkg *Pkg) *Sym { 292 if !exportname(name) && pkg != localpkg { 293 Yyerror("cannot refer to unexported name %s.%s", pkg.Name, name) 294 } 295 return Pkglookup(name, pkg) 296 } 297 298 // find all the exported symbols in package opkg 299 // and make them available in the current package 300 func importdot(opkg *Pkg, pack *Node) { 301 var s1 *Sym 302 var pkgerror string 303 304 n := 0 305 for _, s := range opkg.Syms { 306 if s.Def == nil { 307 continue 308 } 309 if !exportname(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot 310 continue 311 } 312 s1 = Lookup(s.Name) 313 if s1.Def != nil { 314 pkgerror = fmt.Sprintf("during import %q", opkg.Path) 315 redeclare(s1, pkgerror) 316 continue 317 } 318 319 s1.Def = s.Def 320 s1.Block = s.Block 321 if s1.Def.Name == nil { 322 Dump("s1def", s1.Def) 323 Fatalf("missing Name") 324 } 325 s1.Def.Name.Pack = pack 326 s1.Origpkg = opkg 327 n++ 328 } 329 330 if n == 0 { 331 // can't possibly be used - there were no symbols 332 yyerrorl(int(pack.Lineno), "imported and not used: %q", opkg.Path) 333 } 334 } 335 336 func Nod(op Op, nleft *Node, nright *Node) *Node { 337 n := new(Node) 338 n.Op = op 339 n.Left = nleft 340 n.Right = nright 341 n.Lineno = int32(parserline()) 342 n.Xoffset = BADWIDTH 343 n.Orig = n 344 switch op { 345 case OCLOSURE, ODCLFUNC: 346 n.Func = new(Func) 347 n.Func.FCurfn = Curfn 348 case ONAME: 349 n.Name = new(Name) 350 n.Name.Param = new(Param) 351 case OLABEL, OPACK: 352 n.Name = new(Name) 353 case ODCLFIELD: 354 if nleft != nil { 355 n.Name = nleft.Name 356 } else { 357 n.Name = new(Name) 358 n.Name.Param = new(Param) 359 } 360 } 361 if n.Name != nil { 362 n.Name.Curfn = Curfn 363 } 364 return n 365 } 366 367 func saveorignode(n *Node) { 368 if n.Orig != nil { 369 return 370 } 371 norig := Nod(n.Op, nil, nil) 372 *norig = *n 373 n.Orig = norig 374 } 375 376 // ispaddedfield reports whether the given field 377 // is followed by padding. For the case where t is 378 // the last field, total gives the size of the enclosing struct. 379 func ispaddedfield(t *Type, total int64) bool { 380 if t.Etype != TFIELD { 381 Fatalf("ispaddedfield called non-field %v", t) 382 } 383 if t.Down == nil { 384 return t.Width+t.Type.Width != total 385 } 386 return t.Width+t.Type.Width != t.Down.Width 387 } 388 389 func algtype1(t *Type, bad **Type) int { 390 if bad != nil { 391 *bad = nil 392 } 393 if t.Broke { 394 return AMEM 395 } 396 if t.Noalg { 397 return ANOEQ 398 } 399 400 switch t.Etype { 401 // will be defined later. 402 case TANY, TFORW: 403 *bad = t 404 405 return -1 406 407 case TINT8, 408 TUINT8, 409 TINT16, 410 TUINT16, 411 TINT32, 412 TUINT32, 413 TINT64, 414 TUINT64, 415 TINT, 416 TUINT, 417 TUINTPTR, 418 TBOOL, 419 TPTR32, 420 TPTR64, 421 TCHAN, 422 TUNSAFEPTR: 423 return AMEM 424 425 case TFUNC, TMAP: 426 if bad != nil { 427 *bad = t 428 } 429 return ANOEQ 430 431 case TFLOAT32: 432 return AFLOAT32 433 434 case TFLOAT64: 435 return AFLOAT64 436 437 case TCOMPLEX64: 438 return ACPLX64 439 440 case TCOMPLEX128: 441 return ACPLX128 442 443 case TSTRING: 444 return ASTRING 445 446 case TINTER: 447 if isnilinter(t) { 448 return ANILINTER 449 } 450 return AINTER 451 452 case TARRAY: 453 if Isslice(t) { 454 if bad != nil { 455 *bad = t 456 } 457 return ANOEQ 458 } 459 460 a := algtype1(t.Type, bad) 461 if a == ANOEQ || a == AMEM { 462 if a == ANOEQ && bad != nil { 463 *bad = t 464 } 465 return a 466 } 467 468 return -1 // needs special compare 469 470 case TSTRUCT: 471 if t.Type != nil && t.Type.Down == nil && !isblanksym(t.Type.Sym) { 472 // One-field struct is same as that one field alone. 473 return algtype1(t.Type.Type, bad) 474 } 475 476 ret := AMEM 477 var a int 478 for t1 := t.Type; t1 != nil; t1 = t1.Down { 479 // All fields must be comparable. 480 a = algtype1(t1.Type, bad) 481 482 if a == ANOEQ { 483 return ANOEQ 484 } 485 486 // Blank fields, padded fields, fields with non-memory 487 // equality need special compare. 488 if a != AMEM || isblanksym(t1.Sym) || ispaddedfield(t1, t.Width) { 489 ret = -1 490 continue 491 } 492 } 493 494 return ret 495 } 496 497 Fatalf("algtype1: unexpected type %v", t) 498 return 0 499 } 500 501 func algtype(t *Type) int { 502 a := algtype1(t, nil) 503 if a == AMEM || a == ANOEQ { 504 if Isslice(t) { 505 return ASLICE 506 } 507 switch t.Width { 508 case 0: 509 return a + AMEM0 - AMEM 510 511 case 1: 512 return a + AMEM8 - AMEM 513 514 case 2: 515 return a + AMEM16 - AMEM 516 517 case 4: 518 return a + AMEM32 - AMEM 519 520 case 8: 521 return a + AMEM64 - AMEM 522 523 case 16: 524 return a + AMEM128 - AMEM 525 } 526 } 527 528 return a 529 } 530 531 func maptype(key *Type, val *Type) *Type { 532 if key != nil { 533 var bad *Type 534 atype := algtype1(key, &bad) 535 var mtype EType 536 if bad == nil { 537 mtype = key.Etype 538 } else { 539 mtype = bad.Etype 540 } 541 switch mtype { 542 default: 543 if atype == ANOEQ { 544 Yyerror("invalid map key type %v", key) 545 } 546 547 // will be resolved later. 548 case TANY: 549 break 550 551 // map[key] used during definition of key. 552 // postpone check until key is fully defined. 553 // if there are multiple uses of map[key] 554 // before key is fully defined, the error 555 // will only be printed for the first one. 556 // good enough. 557 case TFORW: 558 if key.Maplineno == 0 { 559 key.Maplineno = lineno 560 } 561 } 562 } 563 564 t := typ(TMAP) 565 t.Down = key 566 t.Type = val 567 return t 568 } 569 570 func typ(et EType) *Type { 571 t := new(Type) 572 t.Etype = et 573 t.Width = BADWIDTH 574 t.Lineno = int(lineno) 575 t.Orig = t 576 return t 577 } 578 579 // methcmp sorts by symbol, then by package path for unexported symbols. 580 type methcmp []*Type 581 582 func (x methcmp) Len() int { return len(x) } 583 func (x methcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 584 func (x methcmp) Less(i, j int) bool { 585 a := x[i] 586 b := x[j] 587 if a.Sym == nil && b.Sym == nil { 588 return false 589 } 590 if a.Sym == nil { 591 return true 592 } 593 if b.Sym == nil { 594 return false 595 } 596 if a.Sym.Name != b.Sym.Name { 597 return a.Sym.Name < b.Sym.Name 598 } 599 if !exportname(a.Sym.Name) { 600 if a.Sym.Pkg.Path != b.Sym.Pkg.Path { 601 return a.Sym.Pkg.Path < b.Sym.Pkg.Path 602 } 603 } 604 605 return false 606 } 607 608 func sortinter(t *Type) *Type { 609 if t.Type == nil || t.Type.Down == nil { 610 return t 611 } 612 613 var a []*Type 614 for f := t.Type; f != nil; f = f.Down { 615 a = append(a, f) 616 } 617 sort.Sort(methcmp(a)) 618 619 n := len(a) // n > 0 due to initial conditions. 620 for i := 0; i < n-1; i++ { 621 a[i].Down = a[i+1] 622 } 623 a[n-1].Down = nil 624 625 t.Type = a[0] 626 return t 627 } 628 629 func Nodintconst(v int64) *Node { 630 c := Nod(OLITERAL, nil, nil) 631 c.Addable = true 632 c.SetVal(Val{new(Mpint)}) 633 Mpmovecfix(c.Val().U.(*Mpint), v) 634 c.Type = Types[TIDEAL] 635 ullmancalc(c) 636 return c 637 } 638 639 func nodfltconst(v *Mpflt) *Node { 640 c := Nod(OLITERAL, nil, nil) 641 c.Addable = true 642 c.SetVal(Val{newMpflt()}) 643 mpmovefltflt(c.Val().U.(*Mpflt), v) 644 c.Type = Types[TIDEAL] 645 ullmancalc(c) 646 return c 647 } 648 649 func Nodconst(n *Node, t *Type, v int64) { 650 *n = Node{} 651 n.Op = OLITERAL 652 n.Addable = true 653 ullmancalc(n) 654 n.SetVal(Val{new(Mpint)}) 655 Mpmovecfix(n.Val().U.(*Mpint), v) 656 n.Type = t 657 658 if Isfloat[t.Etype] { 659 Fatalf("nodconst: bad type %v", t) 660 } 661 } 662 663 func nodnil() *Node { 664 c := Nodintconst(0) 665 c.SetVal(Val{new(NilVal)}) 666 c.Type = Types[TNIL] 667 return c 668 } 669 670 func Nodbool(b bool) *Node { 671 c := Nodintconst(0) 672 c.SetVal(Val{b}) 673 c.Type = idealbool 674 return c 675 } 676 677 func aindex(b *Node, t *Type) *Type { 678 bound := int64(-1) // open bound 679 typecheck(&b, Erv) 680 if b != nil { 681 switch consttype(b) { 682 default: 683 Yyerror("array bound must be an integer expression") 684 685 case CTINT, CTRUNE: 686 bound = Mpgetfix(b.Val().U.(*Mpint)) 687 if bound < 0 { 688 Yyerror("array bound must be non negative") 689 } 690 } 691 } 692 693 // fixed array 694 r := typ(TARRAY) 695 696 r.Type = t 697 r.Bound = bound 698 return r 699 } 700 701 // treecopy recursively copies n, with the exception of 702 // ONAME, OLITERAL, OTYPE, and non-iota ONONAME leaves. 703 // Copies of iota ONONAME nodes are assigned the current 704 // value of iota_. If lineno != 0, it sets the line number 705 // of newly allocated nodes to lineno. 706 func treecopy(n *Node, lineno int32) *Node { 707 if n == nil { 708 return nil 709 } 710 711 var m *Node 712 switch n.Op { 713 default: 714 m = Nod(OXXX, nil, nil) 715 *m = *n 716 m.Orig = m 717 m.Left = treecopy(n.Left, lineno) 718 m.Right = treecopy(n.Right, lineno) 719 m.List = listtreecopy(n.List, lineno) 720 if lineno != 0 { 721 m.Lineno = lineno 722 } 723 if m.Name != nil && n.Op != ODCLFIELD { 724 Dump("treecopy", n) 725 Fatalf("treecopy Name") 726 } 727 728 case ONONAME: 729 if n.Sym == Lookup("iota") { 730 // Not sure yet whether this is the real iota, 731 // but make a copy of the Node* just in case, 732 // so that all the copies of this const definition 733 // don't have the same iota value. 734 m = Nod(OXXX, nil, nil) 735 *m = *n 736 if lineno != 0 { 737 m.Lineno = lineno 738 } 739 m.Name = new(Name) 740 *m.Name = *n.Name 741 m.Name.Iota = iota_ 742 break 743 } 744 fallthrough 745 746 case ONAME, OLITERAL, OTYPE: 747 m = n 748 } 749 750 return m 751 } 752 753 // isnil reports whether n represents the universal untyped zero value "nil". 754 func isnil(n *Node) bool { 755 // Check n.Orig because constant propagation may produce typed nil constants, 756 // which don't exist in the Go spec. 757 return Isconst(n.Orig, CTNIL) 758 } 759 760 func isptrto(t *Type, et EType) bool { 761 if t == nil { 762 return false 763 } 764 if !Isptr[t.Etype] { 765 return false 766 } 767 t = t.Type 768 if t == nil { 769 return false 770 } 771 if t.Etype != et { 772 return false 773 } 774 return true 775 } 776 777 func Istype(t *Type, et EType) bool { 778 return t != nil && t.Etype == et 779 } 780 781 func Isfixedarray(t *Type) bool { 782 return t != nil && t.Etype == TARRAY && t.Bound >= 0 783 } 784 785 func Isslice(t *Type) bool { 786 return t != nil && t.Etype == TARRAY && t.Bound < 0 787 } 788 789 func isblank(n *Node) bool { 790 if n == nil { 791 return false 792 } 793 return isblanksym(n.Sym) 794 } 795 796 func isblanksym(s *Sym) bool { 797 return s != nil && s.Name == "_" 798 } 799 800 func Isinter(t *Type) bool { 801 return t != nil && t.Etype == TINTER 802 } 803 804 func isnilinter(t *Type) bool { 805 if !Isinter(t) { 806 return false 807 } 808 if t.Type != nil { 809 return false 810 } 811 return true 812 } 813 814 func isideal(t *Type) bool { 815 if t == nil { 816 return false 817 } 818 if t == idealstring || t == idealbool { 819 return true 820 } 821 switch t.Etype { 822 case TNIL, TIDEAL: 823 return true 824 } 825 826 return false 827 } 828 829 // given receiver of type t (t == r or t == *r) 830 // return type to hang methods off (r). 831 func methtype(t *Type, mustname int) *Type { 832 if t == nil { 833 return nil 834 } 835 836 // strip away pointer if it's there 837 if Isptr[t.Etype] { 838 if t.Sym != nil { 839 return nil 840 } 841 t = t.Type 842 if t == nil { 843 return nil 844 } 845 } 846 847 // need a type name 848 if t.Sym == nil && (mustname != 0 || t.Etype != TSTRUCT) { 849 return nil 850 } 851 852 // check types 853 if !issimple[t.Etype] { 854 switch t.Etype { 855 default: 856 return nil 857 858 case TSTRUCT, 859 TARRAY, 860 TMAP, 861 TCHAN, 862 TSTRING, 863 TFUNC: 864 break 865 } 866 } 867 868 return t 869 } 870 871 func cplxsubtype(et EType) EType { 872 switch et { 873 case TCOMPLEX64: 874 return TFLOAT32 875 876 case TCOMPLEX128: 877 return TFLOAT64 878 } 879 880 Fatalf("cplxsubtype: %v\n", Econv(et)) 881 return 0 882 } 883 884 func eqnote(a, b *string) bool { 885 return a == b || a != nil && b != nil && *a == *b 886 } 887 888 type TypePairList struct { 889 t1 *Type 890 t2 *Type 891 next *TypePairList 892 } 893 894 func onlist(l *TypePairList, t1 *Type, t2 *Type) bool { 895 for ; l != nil; l = l.next { 896 if (l.t1 == t1 && l.t2 == t2) || (l.t1 == t2 && l.t2 == t1) { 897 return true 898 } 899 } 900 return false 901 } 902 903 // Return 1 if t1 and t2 are identical, following the spec rules. 904 // 905 // Any cyclic type must go through a named type, and if one is 906 // named, it is only identical to the other if they are the same 907 // pointer (t1 == t2), so there's no chance of chasing cycles 908 // ad infinitum, so no need for a depth counter. 909 func Eqtype(t1 *Type, t2 *Type) bool { 910 return eqtype1(t1, t2, nil) 911 } 912 913 func eqtype1(t1 *Type, t2 *Type, assumed_equal *TypePairList) bool { 914 if t1 == t2 { 915 return true 916 } 917 if t1 == nil || t2 == nil || t1.Etype != t2.Etype { 918 return false 919 } 920 if t1.Sym != nil || t2.Sym != nil { 921 // Special case: we keep byte and uint8 separate 922 // for error messages. Treat them as equal. 923 switch t1.Etype { 924 case TUINT8: 925 if (t1 == Types[TUINT8] || t1 == bytetype) && (t2 == Types[TUINT8] || t2 == bytetype) { 926 return true 927 } 928 929 case TINT, TINT32: 930 if (t1 == Types[runetype.Etype] || t1 == runetype) && (t2 == Types[runetype.Etype] || t2 == runetype) { 931 return true 932 } 933 } 934 935 return false 936 } 937 938 if onlist(assumed_equal, t1, t2) { 939 return true 940 } 941 var l TypePairList 942 l.next = assumed_equal 943 l.t1 = t1 944 l.t2 = t2 945 946 switch t1.Etype { 947 case TINTER, TSTRUCT: 948 t1 = t1.Type 949 t2 = t2.Type 950 for ; t1 != nil && t2 != nil; t1, t2 = t1.Down, t2.Down { 951 if t1.Etype != TFIELD || t2.Etype != TFIELD { 952 Fatalf("struct/interface missing field: %v %v", t1, t2) 953 } 954 if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, &l) || !eqnote(t1.Note, t2.Note) { 955 return false 956 } 957 } 958 959 if t1 == nil && t2 == nil { 960 return true 961 } 962 return false 963 964 // Loop over structs: receiver, in, out. 965 case TFUNC: 966 t1 = t1.Type 967 t2 = t2.Type 968 for ; t1 != nil && t2 != nil; t1, t2 = t1.Down, t2.Down { 969 if t1.Etype != TSTRUCT || t2.Etype != TSTRUCT { 970 Fatalf("func missing struct: %v %v", t1, t2) 971 } 972 973 // Loop over fields in structs, ignoring argument names. 974 ta := t1.Type 975 tb := t2.Type 976 for ; ta != nil && tb != nil; ta, tb = ta.Down, tb.Down { 977 if ta.Etype != TFIELD || tb.Etype != TFIELD { 978 Fatalf("func struct missing field: %v %v", ta, tb) 979 } 980 if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, &l) { 981 return false 982 } 983 } 984 985 if ta != nil || tb != nil { 986 return false 987 } 988 } 989 990 if t1 == nil && t2 == nil { 991 return true 992 } 993 return false 994 995 case TARRAY: 996 if t1.Bound != t2.Bound { 997 return false 998 } 999 1000 case TCHAN: 1001 if t1.Chan != t2.Chan { 1002 return false 1003 } 1004 } 1005 1006 if eqtype1(t1.Down, t2.Down, &l) && eqtype1(t1.Type, t2.Type, &l) { 1007 return true 1008 } 1009 return false 1010 } 1011 1012 // Are t1 and t2 equal struct types when field names are ignored? 1013 // For deciding whether the result struct from g can be copied 1014 // directly when compiling f(g()). 1015 func eqtypenoname(t1 *Type, t2 *Type) bool { 1016 if t1 == nil || t2 == nil || t1.Etype != TSTRUCT || t2.Etype != TSTRUCT { 1017 return false 1018 } 1019 1020 t1 = t1.Type 1021 t2 = t2.Type 1022 for { 1023 if !Eqtype(t1, t2) { 1024 return false 1025 } 1026 if t1 == nil { 1027 return true 1028 } 1029 t1 = t1.Down 1030 t2 = t2.Down 1031 } 1032 } 1033 1034 // Is type src assignment compatible to type dst? 1035 // If so, return op code to use in conversion. 1036 // If not, return 0. 1037 func assignop(src *Type, dst *Type, why *string) Op { 1038 if why != nil { 1039 *why = "" 1040 } 1041 1042 // TODO(rsc,lvd): This behaves poorly in the presence of inlining. 1043 // https://golang.org/issue/2795 1044 if safemode != 0 && importpkg == nil && src != nil && src.Etype == TUNSAFEPTR { 1045 Yyerror("cannot use unsafe.Pointer") 1046 errorexit() 1047 } 1048 1049 if src == dst { 1050 return OCONVNOP 1051 } 1052 if src == nil || dst == nil || src.Etype == TFORW || dst.Etype == TFORW || src.Orig == nil || dst.Orig == nil { 1053 return 0 1054 } 1055 1056 // 1. src type is identical to dst. 1057 if Eqtype(src, dst) { 1058 return OCONVNOP 1059 } 1060 1061 // 2. src and dst have identical underlying types 1062 // and either src or dst is not a named type or 1063 // both are empty interface types. 1064 // For assignable but different non-empty interface types, 1065 // we want to recompute the itab. 1066 if Eqtype(src.Orig, dst.Orig) && (src.Sym == nil || dst.Sym == nil || isnilinter(src)) { 1067 return OCONVNOP 1068 } 1069 1070 // 3. dst is an interface type and src implements dst. 1071 if dst.Etype == TINTER && src.Etype != TNIL { 1072 var missing *Type 1073 var ptr int 1074 var have *Type 1075 if implements(src, dst, &missing, &have, &ptr) { 1076 return OCONVIFACE 1077 } 1078 1079 // we'll have complained about this method anyway, suppress spurious messages. 1080 if have != nil && have.Sym == missing.Sym && (have.Type.Broke || missing.Type.Broke) { 1081 return OCONVIFACE 1082 } 1083 1084 if why != nil { 1085 if isptrto(src, TINTER) { 1086 *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src) 1087 } else if have != nil && have.Sym == missing.Sym && have.Nointerface { 1088 *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym) 1089 } else if have != nil && have.Sym == missing.Sym { 1090 *why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", src, dst, missing.Sym, have.Sym, Tconv(have.Type, obj.FmtShort|obj.FmtByte), missing.Sym, Tconv(missing.Type, obj.FmtShort|obj.FmtByte)) 1091 } else if ptr != 0 { 1092 *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym) 1093 } else if have != nil { 1094 *why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", src, dst, missing.Sym, have.Sym, Tconv(have.Type, obj.FmtShort|obj.FmtByte), missing.Sym, Tconv(missing.Type, obj.FmtShort|obj.FmtByte)) 1095 } else { 1096 *why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym) 1097 } 1098 } 1099 1100 return 0 1101 } 1102 1103 if isptrto(dst, TINTER) { 1104 if why != nil { 1105 *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst) 1106 } 1107 return 0 1108 } 1109 1110 if src.Etype == TINTER && dst.Etype != TBLANK { 1111 var have *Type 1112 var ptr int 1113 var missing *Type 1114 if why != nil && implements(dst, src, &missing, &have, &ptr) { 1115 *why = ": need type assertion" 1116 } 1117 return 0 1118 } 1119 1120 // 4. src is a bidirectional channel value, dst is a channel type, 1121 // src and dst have identical element types, and 1122 // either src or dst is not a named type. 1123 if src.Etype == TCHAN && src.Chan == Cboth && dst.Etype == TCHAN { 1124 if Eqtype(src.Type, dst.Type) && (src.Sym == nil || dst.Sym == nil) { 1125 return OCONVNOP 1126 } 1127 } 1128 1129 // 5. src is the predeclared identifier nil and dst is a nillable type. 1130 if src.Etype == TNIL { 1131 switch dst.Etype { 1132 case TARRAY: 1133 if dst.Bound != -100 { // not slice 1134 break 1135 } 1136 fallthrough 1137 1138 case TPTR32, 1139 TPTR64, 1140 TFUNC, 1141 TMAP, 1142 TCHAN, 1143 TINTER: 1144 return OCONVNOP 1145 } 1146 } 1147 1148 // 6. rule about untyped constants - already converted by defaultlit. 1149 1150 // 7. Any typed value can be assigned to the blank identifier. 1151 if dst.Etype == TBLANK { 1152 return OCONVNOP 1153 } 1154 1155 return 0 1156 } 1157 1158 // Can we convert a value of type src to a value of type dst? 1159 // If so, return op code to use in conversion (maybe OCONVNOP). 1160 // If not, return 0. 1161 func convertop(src *Type, dst *Type, why *string) Op { 1162 if why != nil { 1163 *why = "" 1164 } 1165 1166 if src == dst { 1167 return OCONVNOP 1168 } 1169 if src == nil || dst == nil { 1170 return 0 1171 } 1172 1173 // 1. src can be assigned to dst. 1174 op := assignop(src, dst, why) 1175 if op != 0 { 1176 return op 1177 } 1178 1179 // The rules for interfaces are no different in conversions 1180 // than assignments. If interfaces are involved, stop now 1181 // with the good message from assignop. 1182 // Otherwise clear the error. 1183 if src.Etype == TINTER || dst.Etype == TINTER { 1184 return 0 1185 } 1186 if why != nil { 1187 *why = "" 1188 } 1189 1190 // 2. src and dst have identical underlying types. 1191 if Eqtype(src.Orig, dst.Orig) { 1192 return OCONVNOP 1193 } 1194 1195 // 3. src and dst are unnamed pointer types 1196 // and their base types have identical underlying types. 1197 if Isptr[src.Etype] && Isptr[dst.Etype] && src.Sym == nil && dst.Sym == nil { 1198 if Eqtype(src.Type.Orig, dst.Type.Orig) { 1199 return OCONVNOP 1200 } 1201 } 1202 1203 // 4. src and dst are both integer or floating point types. 1204 if (Isint[src.Etype] || Isfloat[src.Etype]) && (Isint[dst.Etype] || Isfloat[dst.Etype]) { 1205 if Simtype[src.Etype] == Simtype[dst.Etype] { 1206 return OCONVNOP 1207 } 1208 return OCONV 1209 } 1210 1211 // 5. src and dst are both complex types. 1212 if Iscomplex[src.Etype] && Iscomplex[dst.Etype] { 1213 if Simtype[src.Etype] == Simtype[dst.Etype] { 1214 return OCONVNOP 1215 } 1216 return OCONV 1217 } 1218 1219 // 6. src is an integer or has type []byte or []rune 1220 // and dst is a string type. 1221 if Isint[src.Etype] && dst.Etype == TSTRING { 1222 return ORUNESTR 1223 } 1224 1225 if Isslice(src) && dst.Etype == TSTRING { 1226 if src.Type.Etype == bytetype.Etype { 1227 return OARRAYBYTESTR 1228 } 1229 if src.Type.Etype == runetype.Etype { 1230 return OARRAYRUNESTR 1231 } 1232 } 1233 1234 // 7. src is a string and dst is []byte or []rune. 1235 // String to slice. 1236 if src.Etype == TSTRING && Isslice(dst) { 1237 if dst.Type.Etype == bytetype.Etype { 1238 return OSTRARRAYBYTE 1239 } 1240 if dst.Type.Etype == runetype.Etype { 1241 return OSTRARRAYRUNE 1242 } 1243 } 1244 1245 // 8. src is a pointer or uintptr and dst is unsafe.Pointer. 1246 if (Isptr[src.Etype] || src.Etype == TUINTPTR) && dst.Etype == TUNSAFEPTR { 1247 return OCONVNOP 1248 } 1249 1250 // 9. src is unsafe.Pointer and dst is a pointer or uintptr. 1251 if src.Etype == TUNSAFEPTR && (Isptr[dst.Etype] || dst.Etype == TUINTPTR) { 1252 return OCONVNOP 1253 } 1254 1255 return 0 1256 } 1257 1258 func assignconv(n *Node, t *Type, context string) *Node { 1259 return assignconvfn(n, t, func() string { return context }) 1260 } 1261 1262 // Convert node n for assignment to type t. 1263 func assignconvfn(n *Node, t *Type, context func() string) *Node { 1264 if n == nil || n.Type == nil || n.Type.Broke { 1265 return n 1266 } 1267 1268 if t.Etype == TBLANK && n.Type.Etype == TNIL { 1269 Yyerror("use of untyped nil") 1270 } 1271 1272 old := n 1273 old.Diag++ // silence errors about n; we'll issue one below 1274 defaultlit(&n, t) 1275 old.Diag-- 1276 if t.Etype == TBLANK { 1277 return n 1278 } 1279 1280 // Convert ideal bool from comparison to plain bool 1281 // if the next step is non-bool (like interface{}). 1282 if n.Type == idealbool && t.Etype != TBOOL { 1283 if n.Op == ONAME || n.Op == OLITERAL { 1284 r := Nod(OCONVNOP, n, nil) 1285 r.Type = Types[TBOOL] 1286 r.Typecheck = 1 1287 r.Implicit = true 1288 n = r 1289 } 1290 } 1291 1292 if Eqtype(n.Type, t) { 1293 return n 1294 } 1295 1296 var why string 1297 op := assignop(n.Type, t, &why) 1298 if op == 0 { 1299 Yyerror("cannot use %v as type %v in %s%s", Nconv(n, obj.FmtLong), t, context(), why) 1300 op = OCONV 1301 } 1302 1303 r := Nod(op, n, nil) 1304 r.Type = t 1305 r.Typecheck = 1 1306 r.Implicit = true 1307 r.Orig = n.Orig 1308 return r 1309 } 1310 1311 // substArgTypes substitutes the given list of types for 1312 // successive occurrences of the "any" placeholder in the 1313 // type syntax expression n.Type. 1314 func substArgTypes(n *Node, types ...*Type) { 1315 for _, t := range types { 1316 dowidth(t) 1317 } 1318 substAny(&n.Type, &types) 1319 if len(types) > 0 { 1320 Fatalf("substArgTypes: too many argument types") 1321 } 1322 } 1323 1324 // substAny walks *tp, replacing instances of "any" with successive 1325 // elements removed from types. 1326 func substAny(tp **Type, types *[]*Type) { 1327 for { 1328 t := *tp 1329 if t == nil { 1330 return 1331 } 1332 if t.Etype == TANY && t.Copyany { 1333 if len(*types) == 0 { 1334 Fatalf("substArgTypes: not enough argument types") 1335 } 1336 *tp = (*types)[0] 1337 *types = (*types)[1:] 1338 } 1339 1340 switch t.Etype { 1341 case TPTR32, TPTR64, TCHAN, TARRAY: 1342 tp = &t.Type 1343 continue 1344 1345 case TMAP: 1346 substAny(&t.Down, types) 1347 tp = &t.Type 1348 continue 1349 1350 case TFUNC: 1351 substAny(&t.Type, types) 1352 substAny(&t.Type.Down.Down, types) 1353 substAny(&t.Type.Down, types) 1354 1355 case TSTRUCT: 1356 for t = t.Type; t != nil; t = t.Down { 1357 substAny(&t.Type, types) 1358 } 1359 } 1360 return 1361 } 1362 } 1363 1364 // Is this a 64-bit type? 1365 func Is64(t *Type) bool { 1366 if t == nil { 1367 return false 1368 } 1369 switch Simtype[t.Etype] { 1370 case TINT64, TUINT64, TPTR64: 1371 return true 1372 } 1373 1374 return false 1375 } 1376 1377 // Is a conversion between t1 and t2 a no-op? 1378 func Noconv(t1 *Type, t2 *Type) bool { 1379 e1 := Simtype[t1.Etype] 1380 e2 := Simtype[t2.Etype] 1381 1382 switch e1 { 1383 case TINT8, TUINT8: 1384 return e2 == TINT8 || e2 == TUINT8 1385 1386 case TINT16, TUINT16: 1387 return e2 == TINT16 || e2 == TUINT16 1388 1389 case TINT32, TUINT32, TPTR32: 1390 return e2 == TINT32 || e2 == TUINT32 || e2 == TPTR32 1391 1392 case TINT64, TUINT64, TPTR64: 1393 return e2 == TINT64 || e2 == TUINT64 || e2 == TPTR64 1394 1395 case TFLOAT32: 1396 return e2 == TFLOAT32 1397 1398 case TFLOAT64: 1399 return e2 == TFLOAT64 1400 } 1401 1402 return false 1403 } 1404 1405 func shallow(t *Type) *Type { 1406 if t == nil { 1407 return nil 1408 } 1409 nt := typ(0) 1410 *nt = *t 1411 if t.Orig == t { 1412 nt.Orig = nt 1413 } 1414 return nt 1415 } 1416 1417 func deep(t *Type) *Type { 1418 if t == nil { 1419 return nil 1420 } 1421 1422 var nt *Type 1423 switch t.Etype { 1424 default: 1425 nt = t // share from here down 1426 1427 case TANY: 1428 nt = shallow(t) 1429 nt.Copyany = true 1430 1431 case TPTR32, TPTR64, TCHAN, TARRAY: 1432 nt = shallow(t) 1433 nt.Type = deep(t.Type) 1434 1435 case TMAP: 1436 nt = shallow(t) 1437 nt.Down = deep(t.Down) 1438 nt.Type = deep(t.Type) 1439 1440 case TFUNC: 1441 nt = shallow(t) 1442 nt.Type = deep(t.Type) 1443 nt.Type.Down = deep(t.Type.Down) 1444 nt.Type.Down.Down = deep(t.Type.Down.Down) 1445 1446 case TSTRUCT: 1447 nt = shallow(t) 1448 nt.Type = shallow(t.Type) 1449 xt := nt.Type 1450 1451 for t = t.Type; t != nil; t = t.Down { 1452 xt.Type = deep(t.Type) 1453 xt.Down = shallow(t.Down) 1454 xt = xt.Down 1455 } 1456 } 1457 1458 return nt 1459 } 1460 1461 func syslook(name string, copy int) *Node { 1462 s := Pkglookup(name, Runtimepkg) 1463 if s == nil || s.Def == nil { 1464 Fatalf("syslook: can't find runtime.%s", name) 1465 } 1466 1467 if copy == 0 { 1468 return s.Def 1469 } 1470 1471 n := Nod(0, nil, nil) 1472 *n = *s.Def 1473 n.Type = deep(s.Def.Type) 1474 1475 return n 1476 } 1477 1478 // compute a hash value for type t. 1479 // if t is a method type, ignore the receiver 1480 // so that the hash can be used in interface checks. 1481 // %T already contains 1482 // all the necessary logic to generate a representation 1483 // of the type that completely describes it. 1484 // using smprint here avoids duplicating that code. 1485 // using md5 here is overkill, but i got tired of 1486 // accidental collisions making the runtime think 1487 // two types are equal when they really aren't. 1488 func typehash(t *Type) uint32 { 1489 var p string 1490 1491 if t.Thistuple != 0 { 1492 // hide method receiver from Tpretty 1493 t.Thistuple = 0 1494 1495 p = Tconv(t, obj.FmtLeft|obj.FmtUnsigned) 1496 t.Thistuple = 1 1497 } else { 1498 p = Tconv(t, obj.FmtLeft|obj.FmtUnsigned) 1499 } 1500 1501 //print("typehash: %s\n", p); 1502 h := md5.Sum([]byte(p)) 1503 return binary.LittleEndian.Uint32(h[:4]) 1504 } 1505 1506 var initPtrtoDone bool 1507 1508 var ( 1509 ptrToUint8 *Type 1510 ptrToAny *Type 1511 ptrToString *Type 1512 ptrToBool *Type 1513 ptrToInt32 *Type 1514 ) 1515 1516 func initPtrto() { 1517 ptrToUint8 = ptrto1(Types[TUINT8]) 1518 ptrToAny = ptrto1(Types[TANY]) 1519 ptrToString = ptrto1(Types[TSTRING]) 1520 ptrToBool = ptrto1(Types[TBOOL]) 1521 ptrToInt32 = ptrto1(Types[TINT32]) 1522 } 1523 1524 func ptrto1(t *Type) *Type { 1525 t1 := typ(Tptr) 1526 t1.Type = t 1527 t1.Width = int64(Widthptr) 1528 t1.Align = uint8(Widthptr) 1529 return t1 1530 } 1531 1532 // Ptrto returns the Type *t. 1533 // The returned struct must not be modified. 1534 func Ptrto(t *Type) *Type { 1535 if Tptr == 0 { 1536 Fatalf("ptrto: no tptr") 1537 } 1538 // Reduce allocations by pre-creating common cases. 1539 if !initPtrtoDone { 1540 initPtrto() 1541 initPtrtoDone = true 1542 } 1543 switch t { 1544 case Types[TUINT8]: 1545 return ptrToUint8 1546 case Types[TINT32]: 1547 return ptrToInt32 1548 case Types[TANY]: 1549 return ptrToAny 1550 case Types[TSTRING]: 1551 return ptrToString 1552 case Types[TBOOL]: 1553 return ptrToBool 1554 } 1555 return ptrto1(t) 1556 } 1557 1558 func frame(context int) { 1559 if context != 0 { 1560 fmt.Printf("--- external frame ---\n") 1561 for _, n := range externdcl { 1562 printframenode(n) 1563 } 1564 return 1565 } 1566 1567 if Curfn != nil { 1568 fmt.Printf("--- %v frame ---\n", Curfn.Func.Nname.Sym) 1569 for l := Curfn.Func.Dcl; l != nil; l = l.Next { 1570 printframenode(l.N) 1571 } 1572 } 1573 } 1574 1575 func printframenode(n *Node) { 1576 w := int64(-1) 1577 if n.Type != nil { 1578 w = n.Type.Width 1579 } 1580 switch n.Op { 1581 case ONAME: 1582 fmt.Printf("%v %v G%d %v width=%d\n", Oconv(int(n.Op), 0), n.Sym, n.Name.Vargen, n.Type, w) 1583 case OTYPE: 1584 fmt.Printf("%v %v width=%d\n", Oconv(int(n.Op), 0), n.Type, w) 1585 } 1586 } 1587 1588 // calculate sethi/ullman number 1589 // roughly how many registers needed to 1590 // compile a node. used to compile the 1591 // hardest side first to minimize registers. 1592 func ullmancalc(n *Node) { 1593 if n == nil { 1594 return 1595 } 1596 1597 var ul int 1598 var ur int 1599 if n.Ninit != nil { 1600 ul = UINF 1601 goto out 1602 } 1603 1604 switch n.Op { 1605 case OREGISTER, OLITERAL, ONAME: 1606 ul = 1 1607 if n.Class == PPARAMREF || (n.Class&PHEAP != 0) { 1608 ul++ 1609 } 1610 goto out 1611 1612 case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OASWB: 1613 ul = UINF 1614 goto out 1615 1616 // hard with instrumented code 1617 case OANDAND, OOROR: 1618 if instrumenting { 1619 ul = UINF 1620 goto out 1621 } 1622 } 1623 1624 ul = 1 1625 if n.Left != nil { 1626 ul = int(n.Left.Ullman) 1627 } 1628 ur = 1 1629 if n.Right != nil { 1630 ur = int(n.Right.Ullman) 1631 } 1632 if ul == ur { 1633 ul += 1 1634 } 1635 if ur > ul { 1636 ul = ur 1637 } 1638 1639 out: 1640 if ul > 200 { 1641 ul = 200 // clamp to uchar with room to grow 1642 } 1643 n.Ullman = uint8(ul) 1644 } 1645 1646 func badtype(op Op, tl *Type, tr *Type) { 1647 fmt_ := "" 1648 if tl != nil { 1649 fmt_ += fmt.Sprintf("\n\t%v", tl) 1650 } 1651 if tr != nil { 1652 fmt_ += fmt.Sprintf("\n\t%v", tr) 1653 } 1654 1655 // common mistake: *struct and *interface. 1656 if tl != nil && tr != nil && Isptr[tl.Etype] && Isptr[tr.Etype] { 1657 if tl.Type.Etype == TSTRUCT && tr.Type.Etype == TINTER { 1658 fmt_ += "\n\t(*struct vs *interface)" 1659 } else if tl.Type.Etype == TINTER && tr.Type.Etype == TSTRUCT { 1660 fmt_ += "\n\t(*interface vs *struct)" 1661 } 1662 } 1663 1664 s := fmt_ 1665 Yyerror("illegal types for operand: %v%s", Oconv(int(op), 0), s) 1666 } 1667 1668 // iterator to walk a structure declaration 1669 func Structfirst(s *Iter, nn **Type) *Type { 1670 var t *Type 1671 1672 n := *nn 1673 if n == nil { 1674 goto bad 1675 } 1676 1677 switch n.Etype { 1678 default: 1679 goto bad 1680 1681 case TSTRUCT, TINTER, TFUNC: 1682 break 1683 } 1684 1685 t = n.Type 1686 if t == nil { 1687 return nil 1688 } 1689 1690 if t.Etype != TFIELD { 1691 Fatalf("structfirst: not field %v", t) 1692 } 1693 1694 s.T = t 1695 return t 1696 1697 bad: 1698 Fatalf("structfirst: not struct %v", n) 1699 1700 return nil 1701 } 1702 1703 func structnext(s *Iter) *Type { 1704 n := s.T 1705 t := n.Down 1706 if t == nil { 1707 return nil 1708 } 1709 1710 if t.Etype != TFIELD { 1711 Fatalf("structnext: not struct %v", n) 1712 1713 return nil 1714 } 1715 1716 s.T = t 1717 return t 1718 } 1719 1720 // iterator to this and inargs in a function 1721 func funcfirst(s *Iter, t *Type) *Type { 1722 var fp *Type 1723 1724 if t == nil { 1725 goto bad 1726 } 1727 1728 if t.Etype != TFUNC { 1729 goto bad 1730 } 1731 1732 s.Tfunc = t 1733 s.Done = 0 1734 fp = Structfirst(s, getthis(t)) 1735 if fp == nil { 1736 s.Done = 1 1737 fp = Structfirst(s, getinarg(t)) 1738 } 1739 1740 return fp 1741 1742 bad: 1743 Fatalf("funcfirst: not func %v", t) 1744 return nil 1745 } 1746 1747 func funcnext(s *Iter) *Type { 1748 fp := structnext(s) 1749 if fp == nil && s.Done == 0 { 1750 s.Done = 1 1751 fp = Structfirst(s, getinarg(s.Tfunc)) 1752 } 1753 1754 return fp 1755 } 1756 1757 func getthis(t *Type) **Type { 1758 if t.Etype != TFUNC { 1759 Fatalf("getthis: not a func %v", t) 1760 } 1761 return &t.Type 1762 } 1763 1764 func Getoutarg(t *Type) **Type { 1765 if t.Etype != TFUNC { 1766 Fatalf("getoutarg: not a func %v", t) 1767 } 1768 return &t.Type.Down 1769 } 1770 1771 func getinarg(t *Type) **Type { 1772 if t.Etype != TFUNC { 1773 Fatalf("getinarg: not a func %v", t) 1774 } 1775 return &t.Type.Down.Down 1776 } 1777 1778 func getthisx(t *Type) *Type { 1779 return *getthis(t) 1780 } 1781 1782 func getoutargx(t *Type) *Type { 1783 return *Getoutarg(t) 1784 } 1785 1786 func getinargx(t *Type) *Type { 1787 return *getinarg(t) 1788 } 1789 1790 // Brcom returns !(op). 1791 // For example, Brcom(==) is !=. 1792 func Brcom(op Op) Op { 1793 switch op { 1794 case OEQ: 1795 return ONE 1796 case ONE: 1797 return OEQ 1798 case OLT: 1799 return OGE 1800 case OGT: 1801 return OLE 1802 case OLE: 1803 return OGT 1804 case OGE: 1805 return OLT 1806 } 1807 Fatalf("brcom: no com for %v\n", Oconv(int(op), 0)) 1808 return op 1809 } 1810 1811 // Brrev returns reverse(op). 1812 // For example, Brrev(<) is >. 1813 func Brrev(op Op) Op { 1814 switch op { 1815 case OEQ: 1816 return OEQ 1817 case ONE: 1818 return ONE 1819 case OLT: 1820 return OGT 1821 case OGT: 1822 return OLT 1823 case OLE: 1824 return OGE 1825 case OGE: 1826 return OLE 1827 } 1828 Fatalf("brrev: no rev for %v\n", Oconv(int(op), 0)) 1829 return op 1830 } 1831 1832 // return side effect-free n, appending side effects to init. 1833 // result is assignable if n is. 1834 func safeexpr(n *Node, init **NodeList) *Node { 1835 if n == nil { 1836 return nil 1837 } 1838 1839 if n.Ninit != nil { 1840 walkstmtlist(n.Ninit) 1841 *init = concat(*init, n.Ninit) 1842 n.Ninit = nil 1843 } 1844 1845 switch n.Op { 1846 case ONAME, OLITERAL: 1847 return n 1848 1849 case ODOT, OLEN, OCAP: 1850 l := safeexpr(n.Left, init) 1851 if l == n.Left { 1852 return n 1853 } 1854 r := Nod(OXXX, nil, nil) 1855 *r = *n 1856 r.Left = l 1857 typecheck(&r, Erv) 1858 walkexpr(&r, init) 1859 return r 1860 1861 case ODOTPTR, OIND: 1862 l := safeexpr(n.Left, init) 1863 if l == n.Left { 1864 return n 1865 } 1866 a := Nod(OXXX, nil, nil) 1867 *a = *n 1868 a.Left = l 1869 walkexpr(&a, init) 1870 return a 1871 1872 case OINDEX, OINDEXMAP: 1873 l := safeexpr(n.Left, init) 1874 r := safeexpr(n.Right, init) 1875 if l == n.Left && r == n.Right { 1876 return n 1877 } 1878 a := Nod(OXXX, nil, nil) 1879 *a = *n 1880 a.Left = l 1881 a.Right = r 1882 walkexpr(&a, init) 1883 return a 1884 } 1885 1886 // make a copy; must not be used as an lvalue 1887 if islvalue(n) { 1888 Fatalf("missing lvalue case in safeexpr: %v", n) 1889 } 1890 return cheapexpr(n, init) 1891 } 1892 1893 func copyexpr(n *Node, t *Type, init **NodeList) *Node { 1894 l := temp(t) 1895 a := Nod(OAS, l, n) 1896 typecheck(&a, Etop) 1897 walkexpr(&a, init) 1898 *init = list(*init, a) 1899 return l 1900 } 1901 1902 // return side-effect free and cheap n, appending side effects to init. 1903 // result may not be assignable. 1904 func cheapexpr(n *Node, init **NodeList) *Node { 1905 switch n.Op { 1906 case ONAME, OLITERAL: 1907 return n 1908 } 1909 1910 return copyexpr(n, n.Type, init) 1911 } 1912 1913 func Setmaxarg(t *Type, extra int32) { 1914 dowidth(t) 1915 w := t.Argwid 1916 if w >= Thearch.MAXWIDTH { 1917 Fatalf("bad argwid %v", t) 1918 } 1919 w += int64(extra) 1920 if w >= Thearch.MAXWIDTH { 1921 Fatalf("bad argwid %d + %v", extra, t) 1922 } 1923 if w > Maxarg { 1924 Maxarg = w 1925 } 1926 } 1927 1928 // unicode-aware case-insensitive strcmp 1929 1930 // code to resolve elided DOTs 1931 // in embedded types 1932 1933 // search depth 0 -- 1934 // return count of fields+methods 1935 // found with a given name 1936 func lookdot0(s *Sym, t *Type, save **Type, ignorecase int) int { 1937 u := t 1938 if Isptr[u.Etype] { 1939 u = u.Type 1940 } 1941 1942 c := 0 1943 if u.Etype == TSTRUCT || u.Etype == TINTER { 1944 for f := u.Type; f != nil; f = f.Down { 1945 if f.Sym == s || (ignorecase != 0 && f.Type.Etype == TFUNC && f.Type.Thistuple > 0 && strings.EqualFold(f.Sym.Name, s.Name)) { 1946 if save != nil { 1947 *save = f 1948 } 1949 c++ 1950 } 1951 } 1952 } 1953 1954 u = methtype(t, 0) 1955 if u != nil { 1956 for f := u.Method; f != nil; f = f.Down { 1957 if f.Embedded == 0 && (f.Sym == s || (ignorecase != 0 && strings.EqualFold(f.Sym.Name, s.Name))) { 1958 if save != nil { 1959 *save = f 1960 } 1961 c++ 1962 } 1963 } 1964 } 1965 1966 return c 1967 } 1968 1969 // search depth d for field/method s -- 1970 // return count of fields+methods 1971 // found at search depth. 1972 // answer is in dotlist array and 1973 // count of number of ways is returned. 1974 func adddot1(s *Sym, t *Type, d int, save **Type, ignorecase int) int { 1975 if t.Trecur != 0 { 1976 return 0 1977 } 1978 t.Trecur = 1 1979 1980 var c int 1981 var u *Type 1982 var a int 1983 if d == 0 { 1984 c = lookdot0(s, t, save, ignorecase) 1985 goto out 1986 } 1987 1988 c = 0 1989 u = t 1990 if Isptr[u.Etype] { 1991 u = u.Type 1992 } 1993 if u.Etype != TSTRUCT && u.Etype != TINTER { 1994 goto out 1995 } 1996 1997 d-- 1998 for f := u.Type; f != nil; f = f.Down { 1999 if f.Embedded == 0 { 2000 continue 2001 } 2002 if f.Sym == nil { 2003 continue 2004 } 2005 a = adddot1(s, f.Type, d, save, ignorecase) 2006 if a != 0 && c == 0 { 2007 dotlist[d].field = f 2008 } 2009 c += a 2010 } 2011 2012 out: 2013 t.Trecur = 0 2014 return c 2015 } 2016 2017 // in T.field 2018 // find missing fields that 2019 // will give shortest unique addressing. 2020 // modify the tree with missing type names. 2021 func adddot(n *Node) *Node { 2022 typecheck(&n.Left, Etype|Erv) 2023 n.Diag |= n.Left.Diag 2024 t := n.Left.Type 2025 if t == nil { 2026 return n 2027 } 2028 2029 if n.Left.Op == OTYPE { 2030 return n 2031 } 2032 2033 if n.Right.Op != ONAME { 2034 return n 2035 } 2036 s := n.Right.Sym 2037 if s == nil { 2038 return n 2039 } 2040 2041 var c int 2042 for d := 0; d < len(dotlist); d++ { 2043 c = adddot1(s, t, d, nil, 0) 2044 if c > 0 { 2045 if c > 1 { 2046 Yyerror("ambiguous selector %v", n) 2047 n.Left = nil 2048 return n 2049 } 2050 2051 // rebuild elided dots 2052 for c := d - 1; c >= 0; c-- { 2053 n.Left = Nod(ODOT, n.Left, newname(dotlist[c].field.Sym)) 2054 n.Left.Implicit = true 2055 } 2056 2057 return n 2058 } 2059 } 2060 2061 return n 2062 } 2063 2064 // code to help generate trampoline 2065 // functions for methods on embedded 2066 // subtypes. 2067 // these are approx the same as 2068 // the corresponding adddot routines 2069 // except that they expect to be called 2070 // with unique tasks and they return 2071 // the actual methods. 2072 type Symlink struct { 2073 field *Type 2074 link *Symlink 2075 good bool 2076 followptr bool 2077 } 2078 2079 var slist *Symlink 2080 2081 func expand0(t *Type, followptr bool) { 2082 u := t 2083 if Isptr[u.Etype] { 2084 followptr = true 2085 u = u.Type 2086 } 2087 2088 if u.Etype == TINTER { 2089 var sl *Symlink 2090 for f := u.Type; f != nil; f = f.Down { 2091 if f.Sym.Flags&SymUniq != 0 { 2092 continue 2093 } 2094 f.Sym.Flags |= SymUniq 2095 sl = new(Symlink) 2096 sl.field = f 2097 sl.link = slist 2098 sl.followptr = followptr 2099 slist = sl 2100 } 2101 2102 return 2103 } 2104 2105 u = methtype(t, 0) 2106 if u != nil { 2107 var sl *Symlink 2108 for f := u.Method; f != nil; f = f.Down { 2109 if f.Sym.Flags&SymUniq != 0 { 2110 continue 2111 } 2112 f.Sym.Flags |= SymUniq 2113 sl = new(Symlink) 2114 sl.field = f 2115 sl.link = slist 2116 sl.followptr = followptr 2117 slist = sl 2118 } 2119 } 2120 } 2121 2122 func expand1(t *Type, d int, followptr bool) { 2123 if t.Trecur != 0 { 2124 return 2125 } 2126 if d == 0 { 2127 return 2128 } 2129 t.Trecur = 1 2130 2131 if d != len(dotlist)-1 { 2132 expand0(t, followptr) 2133 } 2134 2135 u := t 2136 if Isptr[u.Etype] { 2137 followptr = true 2138 u = u.Type 2139 } 2140 2141 if u.Etype != TSTRUCT && u.Etype != TINTER { 2142 goto out 2143 } 2144 2145 for f := u.Type; f != nil; f = f.Down { 2146 if f.Embedded == 0 { 2147 continue 2148 } 2149 if f.Sym == nil { 2150 continue 2151 } 2152 expand1(f.Type, d-1, followptr) 2153 } 2154 2155 out: 2156 t.Trecur = 0 2157 } 2158 2159 func expandmeth(t *Type) { 2160 if t == nil || t.Xmethod != nil { 2161 return 2162 } 2163 2164 // mark top-level method symbols 2165 // so that expand1 doesn't consider them. 2166 var f *Type 2167 for f = t.Method; f != nil; f = f.Down { 2168 f.Sym.Flags |= SymUniq 2169 } 2170 2171 // generate all reachable methods 2172 slist = nil 2173 2174 expand1(t, len(dotlist)-1, false) 2175 2176 // check each method to be uniquely reachable 2177 var c int 2178 var d int 2179 for sl := slist; sl != nil; sl = sl.link { 2180 sl.field.Sym.Flags &^= SymUniq 2181 for d = 0; d < len(dotlist); d++ { 2182 c = adddot1(sl.field.Sym, t, d, &f, 0) 2183 if c == 0 { 2184 continue 2185 } 2186 if c == 1 { 2187 // addot1 may have dug out arbitrary fields, we only want methods. 2188 if f.Type.Etype == TFUNC && f.Type.Thistuple > 0 { 2189 sl.good = true 2190 sl.field = f 2191 } 2192 } 2193 2194 break 2195 } 2196 } 2197 2198 for f = t.Method; f != nil; f = f.Down { 2199 f.Sym.Flags &^= SymUniq 2200 } 2201 2202 t.Xmethod = t.Method 2203 for sl := slist; sl != nil; sl = sl.link { 2204 if sl.good { 2205 // add it to the base type method list 2206 f = typ(TFIELD) 2207 2208 *f = *sl.field 2209 f.Embedded = 1 // needs a trampoline 2210 if sl.followptr { 2211 f.Embedded = 2 2212 } 2213 f.Down = t.Xmethod 2214 t.Xmethod = f 2215 } 2216 } 2217 } 2218 2219 // Given funarg struct list, return list of ODCLFIELD Node fn args. 2220 func structargs(tl **Type, mustname int) *NodeList { 2221 var savet Iter 2222 var a *Node 2223 var n *Node 2224 var buf string 2225 2226 var args *NodeList 2227 gen := 0 2228 for t := Structfirst(&savet, tl); t != nil; t = structnext(&savet) { 2229 n = nil 2230 if mustname != 0 && (t.Sym == nil || t.Sym.Name == "_") { 2231 // invent a name so that we can refer to it in the trampoline 2232 buf = fmt.Sprintf(".anon%d", gen) 2233 gen++ 2234 2235 n = newname(Lookup(buf)) 2236 } else if t.Sym != nil { 2237 n = newname(t.Sym) 2238 } 2239 a = Nod(ODCLFIELD, n, typenod(t.Type)) 2240 a.Isddd = t.Isddd 2241 if n != nil { 2242 n.Isddd = t.Isddd 2243 } 2244 args = list(args, a) 2245 } 2246 2247 return args 2248 } 2249 2250 // Generate a wrapper function to convert from 2251 // a receiver of type T to a receiver of type U. 2252 // That is, 2253 // 2254 // func (t T) M() { 2255 // ... 2256 // } 2257 // 2258 // already exists; this function generates 2259 // 2260 // func (u U) M() { 2261 // u.M() 2262 // } 2263 // 2264 // where the types T and U are such that u.M() is valid 2265 // and calls the T.M method. 2266 // The resulting function is for use in method tables. 2267 // 2268 // rcvr - U 2269 // method - M func (t T)(), a TFIELD type struct 2270 // newnam - the eventual mangled name of this function 2271 2272 var genwrapper_linehistdone int = 0 2273 2274 func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { 2275 if false && Debug['r'] != 0 { 2276 fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam) 2277 } 2278 2279 lexlineno++ 2280 lineno = lexlineno 2281 if genwrapper_linehistdone == 0 { 2282 // All the wrappers can share the same linehist entry. 2283 linehistpush("<autogenerated>") 2284 2285 genwrapper_linehistdone = 1 2286 } 2287 2288 dclcontext = PEXTERN 2289 markdcl() 2290 2291 this := Nod(ODCLFIELD, newname(Lookup(".this")), typenod(rcvr)) 2292 this.Left.Name.Param.Ntype = this.Right 2293 in := structargs(getinarg(method.Type), 1) 2294 out := structargs(Getoutarg(method.Type), 0) 2295 2296 t := Nod(OTFUNC, nil, nil) 2297 l := list1(this) 2298 if iface != 0 && rcvr.Width < Types[Tptr].Width { 2299 // Building method for interface table and receiver 2300 // is smaller than the single pointer-sized word 2301 // that the interface call will pass in. 2302 // Add a dummy padding argument after the 2303 // receiver to make up the difference. 2304 tpad := typ(TARRAY) 2305 2306 tpad.Type = Types[TUINT8] 2307 tpad.Bound = Types[Tptr].Width - rcvr.Width 2308 pad := Nod(ODCLFIELD, newname(Lookup(".pad")), typenod(tpad)) 2309 l = list(l, pad) 2310 } 2311 2312 t.List = concat(l, in) 2313 t.Rlist = out 2314 2315 fn := Nod(ODCLFUNC, nil, nil) 2316 fn.Func.Nname = newname(newnam) 2317 fn.Func.Nname.Name.Defn = fn 2318 fn.Func.Nname.Name.Param.Ntype = t 2319 declare(fn.Func.Nname, PFUNC) 2320 funchdr(fn) 2321 2322 // arg list 2323 var args *NodeList 2324 2325 isddd := false 2326 for l := in; l != nil; l = l.Next { 2327 args = list(args, l.N.Left) 2328 isddd = l.N.Left.Isddd 2329 } 2330 2331 methodrcvr := getthisx(method.Type).Type.Type 2332 2333 // generate nil pointer check for better error 2334 if Isptr[rcvr.Etype] && rcvr.Type == methodrcvr { 2335 // generating wrapper from *T to T. 2336 n := Nod(OIF, nil, nil) 2337 2338 n.Left = Nod(OEQ, this.Left, nodnil()) 2339 2340 // these strings are already in the reflect tables, 2341 // so no space cost to use them here. 2342 var l *NodeList 2343 2344 var v Val 2345 v.U = rcvr.Type.Sym.Pkg.Name // package name 2346 l = list(l, nodlit(v)) 2347 v.U = rcvr.Type.Sym.Name // type name 2348 l = list(l, nodlit(v)) 2349 v.U = method.Sym.Name 2350 l = list(l, nodlit(v)) // method name 2351 call := Nod(OCALL, syslook("panicwrap", 0), nil) 2352 call.List = l 2353 n.Nbody = list1(call) 2354 fn.Nbody = list(fn.Nbody, n) 2355 } 2356 2357 dot := adddot(Nod(OXDOT, this.Left, newname(method.Sym))) 2358 2359 // generate call 2360 if !instrumenting && Isptr[rcvr.Etype] && Isptr[methodrcvr.Etype] && method.Embedded != 0 && !isifacemethod(method.Type) { 2361 // generate tail call: adjust pointer receiver and jump to embedded method. 2362 dot = dot.Left // skip final .M 2363 if !Isptr[dotlist[0].field.Type.Etype] { 2364 dot = Nod(OADDR, dot, nil) 2365 } 2366 as := Nod(OAS, this.Left, Nod(OCONVNOP, dot, nil)) 2367 as.Right.Type = rcvr 2368 fn.Nbody = list(fn.Nbody, as) 2369 n := Nod(ORETJMP, nil, nil) 2370 n.Left = newname(methodsym(method.Sym, methodrcvr, 0)) 2371 fn.Nbody = list(fn.Nbody, n) 2372 } else { 2373 fn.Func.Wrapper = true // ignore frame for panic+recover matching 2374 call := Nod(OCALL, dot, nil) 2375 call.List = args 2376 call.Isddd = isddd 2377 if method.Type.Outtuple > 0 { 2378 n := Nod(ORETURN, nil, nil) 2379 n.List = list1(call) 2380 call = n 2381 } 2382 2383 fn.Nbody = list(fn.Nbody, call) 2384 } 2385 2386 if false && Debug['r'] != 0 { 2387 dumplist("genwrapper body", fn.Nbody) 2388 } 2389 2390 funcbody(fn) 2391 Curfn = fn 2392 2393 // wrappers where T is anonymous (struct or interface) can be duplicated. 2394 if rcvr.Etype == TSTRUCT || rcvr.Etype == TINTER || Isptr[rcvr.Etype] && rcvr.Type.Etype == TSTRUCT { 2395 fn.Func.Dupok = true 2396 } 2397 typecheck(&fn, Etop) 2398 typechecklist(fn.Nbody, Etop) 2399 2400 inlcalls(fn) 2401 escAnalyze([]*Node{fn}, false) 2402 2403 Curfn = nil 2404 funccompile(fn) 2405 } 2406 2407 func hashmem(t *Type) *Node { 2408 sym := Pkglookup("memhash", Runtimepkg) 2409 2410 n := newname(sym) 2411 n.Class = PFUNC 2412 tfn := Nod(OTFUNC, nil, nil) 2413 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t)))) 2414 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2415 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2416 tfn.Rlist = list(tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2417 typecheck(&tfn, Etype) 2418 n.Type = tfn.Type 2419 return n 2420 } 2421 2422 func hashfor(t *Type) *Node { 2423 var sym *Sym 2424 2425 a := algtype1(t, nil) 2426 switch a { 2427 case AMEM: 2428 Fatalf("hashfor with AMEM type") 2429 2430 case AINTER: 2431 sym = Pkglookup("interhash", Runtimepkg) 2432 2433 case ANILINTER: 2434 sym = Pkglookup("nilinterhash", Runtimepkg) 2435 2436 case ASTRING: 2437 sym = Pkglookup("strhash", Runtimepkg) 2438 2439 case AFLOAT32: 2440 sym = Pkglookup("f32hash", Runtimepkg) 2441 2442 case AFLOAT64: 2443 sym = Pkglookup("f64hash", Runtimepkg) 2444 2445 case ACPLX64: 2446 sym = Pkglookup("c64hash", Runtimepkg) 2447 2448 case ACPLX128: 2449 sym = Pkglookup("c128hash", Runtimepkg) 2450 2451 default: 2452 sym = typesymprefix(".hash", t) 2453 } 2454 2455 n := newname(sym) 2456 n.Class = PFUNC 2457 tfn := Nod(OTFUNC, nil, nil) 2458 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t)))) 2459 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2460 tfn.Rlist = list(tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2461 typecheck(&tfn, Etype) 2462 n.Type = tfn.Type 2463 return n 2464 } 2465 2466 // Generate a helper function to compute the hash of a value of type t. 2467 func genhash(sym *Sym, t *Type) { 2468 if Debug['r'] != 0 { 2469 fmt.Printf("genhash %v %v\n", sym, t) 2470 } 2471 2472 lineno = 1 // less confusing than end of input 2473 dclcontext = PEXTERN 2474 markdcl() 2475 2476 // func sym(p *T, h uintptr) uintptr 2477 fn := Nod(ODCLFUNC, nil, nil) 2478 2479 fn.Func.Nname = newname(sym) 2480 fn.Func.Nname.Class = PFUNC 2481 tfn := Nod(OTFUNC, nil, nil) 2482 fn.Func.Nname.Name.Param.Ntype = tfn 2483 2484 n := Nod(ODCLFIELD, newname(Lookup("p")), typenod(Ptrto(t))) 2485 tfn.List = list(tfn.List, n) 2486 np := n.Left 2487 n = Nod(ODCLFIELD, newname(Lookup("h")), typenod(Types[TUINTPTR])) 2488 tfn.List = list(tfn.List, n) 2489 nh := n.Left 2490 n = Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])) // return value 2491 tfn.Rlist = list(tfn.Rlist, n) 2492 2493 funchdr(fn) 2494 typecheck(&fn.Func.Nname.Name.Param.Ntype, Etype) 2495 2496 // genhash is only called for types that have equality but 2497 // cannot be handled by the standard algorithms, 2498 // so t must be either an array or a struct. 2499 switch t.Etype { 2500 default: 2501 Fatalf("genhash %v", t) 2502 2503 case TARRAY: 2504 if Isslice(t) { 2505 Fatalf("genhash %v", t) 2506 } 2507 2508 // An array of pure memory would be handled by the 2509 // standard algorithm, so the element type must not be 2510 // pure memory. 2511 hashel := hashfor(t.Type) 2512 2513 n := Nod(ORANGE, nil, Nod(OIND, np, nil)) 2514 ni := newname(Lookup("i")) 2515 ni.Type = Types[TINT] 2516 n.List = list1(ni) 2517 n.Colas = true 2518 colasdefn(n.List, n) 2519 ni = n.List.N 2520 2521 // h = hashel(&p[i], h) 2522 call := Nod(OCALL, hashel, nil) 2523 2524 nx := Nod(OINDEX, np, ni) 2525 nx.Bounded = true 2526 na := Nod(OADDR, nx, nil) 2527 na.Etype = 1 // no escape to heap 2528 call.List = list(call.List, na) 2529 call.List = list(call.List, nh) 2530 n.Nbody = list(n.Nbody, Nod(OAS, nh, call)) 2531 2532 fn.Nbody = list(fn.Nbody, n) 2533 2534 // Walk the struct using memhash for runs of AMEM 2535 // and calling specific hash functions for the others. 2536 case TSTRUCT: 2537 var first *Type 2538 2539 offend := int64(0) 2540 var size int64 2541 var call *Node 2542 var nx *Node 2543 var na *Node 2544 var hashel *Node 2545 for t1 := t.Type; ; t1 = t1.Down { 2546 if t1 != nil && algtype1(t1.Type, nil) == AMEM && !isblanksym(t1.Sym) { 2547 offend = t1.Width + t1.Type.Width 2548 if first == nil { 2549 first = t1 2550 } 2551 2552 // If it's a memory field but it's padded, stop here. 2553 if ispaddedfield(t1, t.Width) { 2554 t1 = t1.Down 2555 } else { 2556 continue 2557 } 2558 } 2559 2560 // Run memhash for fields up to this one. 2561 if first != nil { 2562 size = offend - first.Width // first->width is offset 2563 hashel = hashmem(first.Type) 2564 2565 // h = hashel(&p.first, size, h) 2566 call = Nod(OCALL, hashel, nil) 2567 2568 nx = Nod(OXDOT, np, newname(first.Sym)) // TODO: fields from other packages? 2569 na = Nod(OADDR, nx, nil) 2570 na.Etype = 1 // no escape to heap 2571 call.List = list(call.List, na) 2572 call.List = list(call.List, nh) 2573 call.List = list(call.List, Nodintconst(size)) 2574 fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call)) 2575 2576 first = nil 2577 } 2578 2579 if t1 == nil { 2580 break 2581 } 2582 if isblanksym(t1.Sym) { 2583 continue 2584 } 2585 2586 // Run hash for this field. 2587 if algtype1(t1.Type, nil) == AMEM { 2588 hashel = hashmem(t1.Type) 2589 2590 // h = memhash(&p.t1, h, size) 2591 call = Nod(OCALL, hashel, nil) 2592 2593 nx = Nod(OXDOT, np, newname(t1.Sym)) // TODO: fields from other packages? 2594 na = Nod(OADDR, nx, nil) 2595 na.Etype = 1 // no escape to heap 2596 call.List = list(call.List, na) 2597 call.List = list(call.List, nh) 2598 call.List = list(call.List, Nodintconst(t1.Type.Width)) 2599 fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call)) 2600 } else { 2601 hashel = hashfor(t1.Type) 2602 2603 // h = hashel(&p.t1, h) 2604 call = Nod(OCALL, hashel, nil) 2605 2606 nx = Nod(OXDOT, np, newname(t1.Sym)) // TODO: fields from other packages? 2607 na = Nod(OADDR, nx, nil) 2608 na.Etype = 1 // no escape to heap 2609 call.List = list(call.List, na) 2610 call.List = list(call.List, nh) 2611 fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call)) 2612 } 2613 } 2614 } 2615 2616 r := Nod(ORETURN, nil, nil) 2617 r.List = list(r.List, nh) 2618 fn.Nbody = list(fn.Nbody, r) 2619 2620 if Debug['r'] != 0 { 2621 dumplist("genhash body", fn.Nbody) 2622 } 2623 2624 funcbody(fn) 2625 Curfn = fn 2626 fn.Func.Dupok = true 2627 typecheck(&fn, Etop) 2628 typechecklist(fn.Nbody, Etop) 2629 Curfn = nil 2630 2631 // Disable safemode while compiling this code: the code we 2632 // generate internally can refer to unsafe.Pointer. 2633 // In this case it can happen if we need to generate an == 2634 // for a struct containing a reflect.Value, which itself has 2635 // an unexported field of type unsafe.Pointer. 2636 old_safemode := safemode 2637 2638 safemode = 0 2639 funccompile(fn) 2640 safemode = old_safemode 2641 } 2642 2643 // Return node for 2644 // if p.field != q.field { return false } 2645 func eqfield(p *Node, q *Node, field *Node) *Node { 2646 nx := Nod(OXDOT, p, field) 2647 ny := Nod(OXDOT, q, field) 2648 nif := Nod(OIF, nil, nil) 2649 nif.Left = Nod(ONE, nx, ny) 2650 r := Nod(ORETURN, nil, nil) 2651 r.List = list(r.List, Nodbool(false)) 2652 nif.Nbody = list(nif.Nbody, r) 2653 return nif 2654 } 2655 2656 func eqmemfunc(size int64, type_ *Type, needsize *int) *Node { 2657 var fn *Node 2658 2659 switch size { 2660 default: 2661 fn = syslook("memequal", 1) 2662 *needsize = 1 2663 2664 case 1, 2, 4, 8, 16: 2665 buf := fmt.Sprintf("memequal%d", int(size)*8) 2666 fn = syslook(buf, 1) 2667 *needsize = 0 2668 } 2669 2670 substArgTypes(fn, type_, type_) 2671 return fn 2672 } 2673 2674 // Return node for 2675 // if !memequal(&p.field, &q.field [, size]) { return false } 2676 func eqmem(p *Node, q *Node, field *Node, size int64) *Node { 2677 var needsize int 2678 2679 nx := Nod(OADDR, Nod(OXDOT, p, field), nil) 2680 nx.Etype = 1 // does not escape 2681 ny := Nod(OADDR, Nod(OXDOT, q, field), nil) 2682 ny.Etype = 1 // does not escape 2683 typecheck(&nx, Erv) 2684 typecheck(&ny, Erv) 2685 2686 call := Nod(OCALL, eqmemfunc(size, nx.Type.Type, &needsize), nil) 2687 call.List = list(call.List, nx) 2688 call.List = list(call.List, ny) 2689 if needsize != 0 { 2690 call.List = list(call.List, Nodintconst(size)) 2691 } 2692 2693 nif := Nod(OIF, nil, nil) 2694 nif.Left = Nod(ONOT, call, nil) 2695 r := Nod(ORETURN, nil, nil) 2696 r.List = list(r.List, Nodbool(false)) 2697 nif.Nbody = list(nif.Nbody, r) 2698 return nif 2699 } 2700 2701 // Generate a helper function to check equality of two values of type t. 2702 func geneq(sym *Sym, t *Type) { 2703 if Debug['r'] != 0 { 2704 fmt.Printf("geneq %v %v\n", sym, t) 2705 } 2706 2707 lineno = 1 // less confusing than end of input 2708 dclcontext = PEXTERN 2709 markdcl() 2710 2711 // func sym(p, q *T) bool 2712 fn := Nod(ODCLFUNC, nil, nil) 2713 2714 fn.Func.Nname = newname(sym) 2715 fn.Func.Nname.Class = PFUNC 2716 tfn := Nod(OTFUNC, nil, nil) 2717 fn.Func.Nname.Name.Param.Ntype = tfn 2718 2719 n := Nod(ODCLFIELD, newname(Lookup("p")), typenod(Ptrto(t))) 2720 tfn.List = list(tfn.List, n) 2721 np := n.Left 2722 n = Nod(ODCLFIELD, newname(Lookup("q")), typenod(Ptrto(t))) 2723 tfn.List = list(tfn.List, n) 2724 nq := n.Left 2725 n = Nod(ODCLFIELD, nil, typenod(Types[TBOOL])) 2726 tfn.Rlist = list(tfn.Rlist, n) 2727 2728 funchdr(fn) 2729 2730 // geneq is only called for types that have equality but 2731 // cannot be handled by the standard algorithms, 2732 // so t must be either an array or a struct. 2733 switch t.Etype { 2734 default: 2735 Fatalf("geneq %v", t) 2736 2737 case TARRAY: 2738 if Isslice(t) { 2739 Fatalf("geneq %v", t) 2740 } 2741 2742 // An array of pure memory would be handled by the 2743 // standard memequal, so the element type must not be 2744 // pure memory. Even if we unrolled the range loop, 2745 // each iteration would be a function call, so don't bother 2746 // unrolling. 2747 nrange := Nod(ORANGE, nil, Nod(OIND, np, nil)) 2748 2749 ni := newname(Lookup("i")) 2750 ni.Type = Types[TINT] 2751 nrange.List = list1(ni) 2752 nrange.Colas = true 2753 colasdefn(nrange.List, nrange) 2754 ni = nrange.List.N 2755 2756 // if p[i] != q[i] { return false } 2757 nx := Nod(OINDEX, np, ni) 2758 2759 nx.Bounded = true 2760 ny := Nod(OINDEX, nq, ni) 2761 ny.Bounded = true 2762 2763 nif := Nod(OIF, nil, nil) 2764 nif.Left = Nod(ONE, nx, ny) 2765 r := Nod(ORETURN, nil, nil) 2766 r.List = list(r.List, Nodbool(false)) 2767 nif.Nbody = list(nif.Nbody, r) 2768 nrange.Nbody = list(nrange.Nbody, nif) 2769 fn.Nbody = list(fn.Nbody, nrange) 2770 2771 // Walk the struct using memequal for runs of AMEM 2772 // and calling specific equality tests for the others. 2773 // Skip blank-named fields. 2774 case TSTRUCT: 2775 var first *Type 2776 2777 offend := int64(0) 2778 var size int64 2779 for t1 := t.Type; ; t1 = t1.Down { 2780 if t1 != nil && algtype1(t1.Type, nil) == AMEM && !isblanksym(t1.Sym) { 2781 offend = t1.Width + t1.Type.Width 2782 if first == nil { 2783 first = t1 2784 } 2785 2786 // If it's a memory field but it's padded, stop here. 2787 if ispaddedfield(t1, t.Width) { 2788 t1 = t1.Down 2789 } else { 2790 continue 2791 } 2792 } 2793 2794 // Run memequal for fields up to this one. 2795 // TODO(rsc): All the calls to newname are wrong for 2796 // cross-package unexported fields. 2797 if first != nil { 2798 if first.Down == t1 { 2799 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym))) 2800 } else if first.Down.Down == t1 { 2801 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym))) 2802 first = first.Down 2803 if !isblanksym(first.Sym) { 2804 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym))) 2805 } 2806 } else { 2807 // More than two fields: use memequal. 2808 size = offend - first.Width // first->width is offset 2809 fn.Nbody = list(fn.Nbody, eqmem(np, nq, newname(first.Sym), size)) 2810 } 2811 2812 first = nil 2813 } 2814 2815 if t1 == nil { 2816 break 2817 } 2818 if isblanksym(t1.Sym) { 2819 continue 2820 } 2821 2822 // Check this field, which is not just memory. 2823 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(t1.Sym))) 2824 } 2825 } 2826 2827 // return true 2828 r := Nod(ORETURN, nil, nil) 2829 2830 r.List = list(r.List, Nodbool(true)) 2831 fn.Nbody = list(fn.Nbody, r) 2832 2833 if Debug['r'] != 0 { 2834 dumplist("geneq body", fn.Nbody) 2835 } 2836 2837 funcbody(fn) 2838 Curfn = fn 2839 fn.Func.Dupok = true 2840 typecheck(&fn, Etop) 2841 typechecklist(fn.Nbody, Etop) 2842 Curfn = nil 2843 2844 // Disable safemode while compiling this code: the code we 2845 // generate internally can refer to unsafe.Pointer. 2846 // In this case it can happen if we need to generate an == 2847 // for a struct containing a reflect.Value, which itself has 2848 // an unexported field of type unsafe.Pointer. 2849 old_safemode := safemode 2850 2851 safemode = 0 2852 funccompile(fn) 2853 safemode = old_safemode 2854 } 2855 2856 func ifacelookdot(s *Sym, t *Type, followptr *bool, ignorecase int) *Type { 2857 *followptr = false 2858 2859 if t == nil { 2860 return nil 2861 } 2862 2863 var m *Type 2864 var i int 2865 var c int 2866 for d := 0; d < len(dotlist); d++ { 2867 c = adddot1(s, t, d, &m, ignorecase) 2868 if c > 1 { 2869 Yyerror("%v.%v is ambiguous", t, s) 2870 return nil 2871 } 2872 2873 if c == 1 { 2874 for i = 0; i < d; i++ { 2875 if Isptr[dotlist[i].field.Type.Etype] { 2876 *followptr = true 2877 break 2878 } 2879 } 2880 2881 if m.Type.Etype != TFUNC || m.Type.Thistuple == 0 { 2882 Yyerror("%v.%v is a field, not a method", t, s) 2883 return nil 2884 } 2885 2886 return m 2887 } 2888 } 2889 2890 return nil 2891 } 2892 2893 func implements(t *Type, iface *Type, m **Type, samename **Type, ptr *int) bool { 2894 t0 := t 2895 if t == nil { 2896 return false 2897 } 2898 2899 // if this is too slow, 2900 // could sort these first 2901 // and then do one loop. 2902 2903 if t.Etype == TINTER { 2904 var tm *Type 2905 for im := iface.Type; im != nil; im = im.Down { 2906 for tm = t.Type; tm != nil; tm = tm.Down { 2907 if tm.Sym == im.Sym { 2908 if Eqtype(tm.Type, im.Type) { 2909 goto found 2910 } 2911 *m = im 2912 *samename = tm 2913 *ptr = 0 2914 return false 2915 } 2916 } 2917 2918 *m = im 2919 *samename = nil 2920 *ptr = 0 2921 return false 2922 found: 2923 } 2924 2925 return true 2926 } 2927 2928 t = methtype(t, 0) 2929 if t != nil { 2930 expandmeth(t) 2931 } 2932 var tm *Type 2933 var imtype *Type 2934 var followptr bool 2935 var rcvr *Type 2936 for im := iface.Type; im != nil; im = im.Down { 2937 if im.Broke { 2938 continue 2939 } 2940 imtype = methodfunc(im.Type, nil) 2941 tm = ifacelookdot(im.Sym, t, &followptr, 0) 2942 if tm == nil || tm.Nointerface || !Eqtype(methodfunc(tm.Type, nil), imtype) { 2943 if tm == nil { 2944 tm = ifacelookdot(im.Sym, t, &followptr, 1) 2945 } 2946 *m = im 2947 *samename = tm 2948 *ptr = 0 2949 return false 2950 } 2951 2952 // if pointer receiver in method, 2953 // the method does not exist for value types. 2954 rcvr = getthisx(tm.Type).Type.Type 2955 2956 if Isptr[rcvr.Etype] && !Isptr[t0.Etype] && !followptr && !isifacemethod(tm.Type) { 2957 if false && Debug['r'] != 0 { 2958 Yyerror("interface pointer mismatch") 2959 } 2960 2961 *m = im 2962 *samename = nil 2963 *ptr = 1 2964 return false 2965 } 2966 } 2967 2968 return true 2969 } 2970 2971 // even simpler simtype; get rid of ptr, bool. 2972 // assuming that the front end has rejected 2973 // all the invalid conversions (like ptr -> bool) 2974 func Simsimtype(t *Type) EType { 2975 if t == nil { 2976 return 0 2977 } 2978 2979 et := Simtype[t.Etype] 2980 switch et { 2981 case TPTR32: 2982 et = TUINT32 2983 2984 case TPTR64: 2985 et = TUINT64 2986 2987 case TBOOL: 2988 et = TUINT8 2989 } 2990 2991 return et 2992 } 2993 2994 func listtreecopy(l *NodeList, lineno int32) *NodeList { 2995 var out *NodeList 2996 for ; l != nil; l = l.Next { 2997 out = list(out, treecopy(l.N, lineno)) 2998 } 2999 return out 3000 } 3001 3002 func liststmt(l *NodeList) *Node { 3003 n := Nod(OBLOCK, nil, nil) 3004 n.List = l 3005 if l != nil { 3006 n.Lineno = l.N.Lineno 3007 } 3008 return n 3009 } 3010 3011 // return nelem of list 3012 func structcount(t *Type) int { 3013 var s Iter 3014 3015 v := 0 3016 for t = Structfirst(&s, &t); t != nil; t = structnext(&s) { 3017 v++ 3018 } 3019 return v 3020 } 3021 3022 // return power of 2 of the constant 3023 // operand. -1 if it is not a power of 2. 3024 // 1000+ if it is a -(power of 2) 3025 func powtwo(n *Node) int { 3026 if n == nil || n.Op != OLITERAL || n.Type == nil { 3027 return -1 3028 } 3029 if !Isint[n.Type.Etype] { 3030 return -1 3031 } 3032 3033 v := uint64(Mpgetfix(n.Val().U.(*Mpint))) 3034 b := uint64(1) 3035 for i := 0; i < 64; i++ { 3036 if b == v { 3037 return i 3038 } 3039 b = b << 1 3040 } 3041 3042 if !Issigned[n.Type.Etype] { 3043 return -1 3044 } 3045 3046 v = -v 3047 b = 1 3048 for i := 0; i < 64; i++ { 3049 if b == v { 3050 return i + 1000 3051 } 3052 b = b << 1 3053 } 3054 3055 return -1 3056 } 3057 3058 // return the unsigned type for 3059 // a signed integer type. 3060 // returns T if input is not a 3061 // signed integer type. 3062 func tounsigned(t *Type) *Type { 3063 // this is types[et+1], but not sure 3064 // that this relation is immutable 3065 switch t.Etype { 3066 default: 3067 fmt.Printf("tounsigned: unknown type %v\n", t) 3068 t = nil 3069 3070 case TINT: 3071 t = Types[TUINT] 3072 3073 case TINT8: 3074 t = Types[TUINT8] 3075 3076 case TINT16: 3077 t = Types[TUINT16] 3078 3079 case TINT32: 3080 t = Types[TUINT32] 3081 3082 case TINT64: 3083 t = Types[TUINT64] 3084 } 3085 3086 return t 3087 } 3088 3089 // magic number for signed division 3090 // see hacker's delight chapter 10 3091 func Smagic(m *Magic) { 3092 var mask uint64 3093 3094 m.Bad = 0 3095 switch m.W { 3096 default: 3097 m.Bad = 1 3098 return 3099 3100 case 8: 3101 mask = 0xff 3102 3103 case 16: 3104 mask = 0xffff 3105 3106 case 32: 3107 mask = 0xffffffff 3108 3109 case 64: 3110 mask = 0xffffffffffffffff 3111 } 3112 3113 two31 := mask ^ (mask >> 1) 3114 3115 p := m.W - 1 3116 ad := uint64(m.Sd) 3117 if m.Sd < 0 { 3118 ad = -uint64(m.Sd) 3119 } 3120 3121 // bad denominators 3122 if ad == 0 || ad == 1 || ad == two31 { 3123 m.Bad = 1 3124 return 3125 } 3126 3127 t := two31 3128 ad &= mask 3129 3130 anc := t - 1 - t%ad 3131 anc &= mask 3132 3133 q1 := two31 / anc 3134 r1 := two31 - q1*anc 3135 q1 &= mask 3136 r1 &= mask 3137 3138 q2 := two31 / ad 3139 r2 := two31 - q2*ad 3140 q2 &= mask 3141 r2 &= mask 3142 3143 var delta uint64 3144 for { 3145 p++ 3146 q1 <<= 1 3147 r1 <<= 1 3148 q1 &= mask 3149 r1 &= mask 3150 if r1 >= anc { 3151 q1++ 3152 r1 -= anc 3153 q1 &= mask 3154 r1 &= mask 3155 } 3156 3157 q2 <<= 1 3158 r2 <<= 1 3159 q2 &= mask 3160 r2 &= mask 3161 if r2 >= ad { 3162 q2++ 3163 r2 -= ad 3164 q2 &= mask 3165 r2 &= mask 3166 } 3167 3168 delta = ad - r2 3169 delta &= mask 3170 if q1 < delta || (q1 == delta && r1 == 0) { 3171 continue 3172 } 3173 3174 break 3175 } 3176 3177 m.Sm = int64(q2 + 1) 3178 if uint64(m.Sm)&two31 != 0 { 3179 m.Sm |= ^int64(mask) 3180 } 3181 m.S = p - m.W 3182 } 3183 3184 // magic number for unsigned division 3185 // see hacker's delight chapter 10 3186 func Umagic(m *Magic) { 3187 var mask uint64 3188 3189 m.Bad = 0 3190 m.Ua = 0 3191 3192 switch m.W { 3193 default: 3194 m.Bad = 1 3195 return 3196 3197 case 8: 3198 mask = 0xff 3199 3200 case 16: 3201 mask = 0xffff 3202 3203 case 32: 3204 mask = 0xffffffff 3205 3206 case 64: 3207 mask = 0xffffffffffffffff 3208 } 3209 3210 two31 := mask ^ (mask >> 1) 3211 3212 m.Ud &= mask 3213 if m.Ud == 0 || m.Ud == two31 { 3214 m.Bad = 1 3215 return 3216 } 3217 3218 nc := mask - (-m.Ud&mask)%m.Ud 3219 p := m.W - 1 3220 3221 q1 := two31 / nc 3222 r1 := two31 - q1*nc 3223 q1 &= mask 3224 r1 &= mask 3225 3226 q2 := (two31 - 1) / m.Ud 3227 r2 := (two31 - 1) - q2*m.Ud 3228 q2 &= mask 3229 r2 &= mask 3230 3231 var delta uint64 3232 for { 3233 p++ 3234 if r1 >= nc-r1 { 3235 q1 <<= 1 3236 q1++ 3237 r1 <<= 1 3238 r1 -= nc 3239 } else { 3240 q1 <<= 1 3241 r1 <<= 1 3242 } 3243 3244 q1 &= mask 3245 r1 &= mask 3246 if r2+1 >= m.Ud-r2 { 3247 if q2 >= two31-1 { 3248 m.Ua = 1 3249 } 3250 3251 q2 <<= 1 3252 q2++ 3253 r2 <<= 1 3254 r2++ 3255 r2 -= m.Ud 3256 } else { 3257 if q2 >= two31 { 3258 m.Ua = 1 3259 } 3260 3261 q2 <<= 1 3262 r2 <<= 1 3263 r2++ 3264 } 3265 3266 q2 &= mask 3267 r2 &= mask 3268 3269 delta = m.Ud - 1 - r2 3270 delta &= mask 3271 3272 if p < m.W+m.W { 3273 if q1 < delta || (q1 == delta && r1 == 0) { 3274 continue 3275 } 3276 } 3277 3278 break 3279 } 3280 3281 m.Um = q2 + 1 3282 m.S = p - m.W 3283 } 3284 3285 func ngotype(n *Node) *Sym { 3286 if n.Type != nil { 3287 return typenamesym(n.Type) 3288 } 3289 return nil 3290 } 3291 3292 // Convert raw string to the prefix that will be used in the symbol 3293 // table. All control characters, space, '%' and '"', as well as 3294 // non-7-bit clean bytes turn into %xx. The period needs escaping 3295 // only in the last segment of the path, and it makes for happier 3296 // users if we escape that as little as possible. 3297 // 3298 // If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too. 3299 func pathtoprefix(s string) string { 3300 slash := strings.LastIndex(s, "/") 3301 for i := 0; i < len(s); i++ { 3302 c := s[i] 3303 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 3304 var buf bytes.Buffer 3305 for i := 0; i < len(s); i++ { 3306 c := s[i] 3307 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 3308 fmt.Fprintf(&buf, "%%%02x", c) 3309 continue 3310 } 3311 buf.WriteByte(c) 3312 } 3313 return buf.String() 3314 } 3315 } 3316 return s 3317 } 3318 3319 var pkgMap = make(map[string]*Pkg) 3320 var pkgs []*Pkg 3321 3322 func mkpkg(path string) *Pkg { 3323 if p := pkgMap[path]; p != nil { 3324 return p 3325 } 3326 3327 p := new(Pkg) 3328 p.Path = path 3329 p.Prefix = pathtoprefix(path) 3330 p.Syms = make(map[string]*Sym) 3331 pkgMap[path] = p 3332 pkgs = append(pkgs, p) 3333 return p 3334 } 3335 3336 func addinit(np **Node, init *NodeList) { 3337 if init == nil { 3338 return 3339 } 3340 3341 n := *np 3342 switch n.Op { 3343 // There may be multiple refs to this node; 3344 // introduce OCONVNOP to hold init list. 3345 case ONAME, OLITERAL: 3346 n = Nod(OCONVNOP, n, nil) 3347 3348 n.Type = n.Left.Type 3349 n.Typecheck = 1 3350 *np = n 3351 } 3352 3353 n.Ninit = concat(init, n.Ninit) 3354 n.Ullman = UINF 3355 } 3356 3357 var reservedimports = []string{ 3358 "go", 3359 "type", 3360 } 3361 3362 func isbadimport(path string) bool { 3363 if strings.Contains(path, "\x00") { 3364 Yyerror("import path contains NUL") 3365 return true 3366 } 3367 3368 for _, ri := range reservedimports { 3369 if path == ri { 3370 Yyerror("import path %q is reserved and cannot be used", path) 3371 return true 3372 } 3373 } 3374 3375 for _, r := range path { 3376 if r == utf8.RuneError { 3377 Yyerror("import path contains invalid UTF-8 sequence: %q", path) 3378 return true 3379 } 3380 3381 if r < 0x20 || r == 0x7f { 3382 Yyerror("import path contains control character: %q", path) 3383 return true 3384 } 3385 3386 if r == '\\' { 3387 Yyerror("import path contains backslash; use slash: %q", path) 3388 return true 3389 } 3390 3391 if unicode.IsSpace(rune(r)) { 3392 Yyerror("import path contains space character: %q", path) 3393 return true 3394 } 3395 3396 if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) { 3397 Yyerror("import path contains invalid character '%c': %q", r, path) 3398 return true 3399 } 3400 } 3401 3402 return false 3403 } 3404 3405 func checknil(x *Node, init **NodeList) { 3406 if Isinter(x.Type) { 3407 x = Nod(OITAB, x, nil) 3408 typecheck(&x, Erv) 3409 } 3410 3411 n := Nod(OCHECKNIL, x, nil) 3412 n.Typecheck = 1 3413 *init = list(*init, n) 3414 } 3415 3416 // Can this type be stored directly in an interface word? 3417 // Yes, if the representation is a single pointer. 3418 func isdirectiface(t *Type) bool { 3419 switch t.Etype { 3420 case TPTR32, 3421 TPTR64, 3422 TCHAN, 3423 TMAP, 3424 TFUNC, 3425 TUNSAFEPTR: 3426 return true 3427 3428 // Array of 1 direct iface type can be direct. 3429 case TARRAY: 3430 return t.Bound == 1 && isdirectiface(t.Type) 3431 3432 // Struct with 1 field of direct iface type can be direct. 3433 case TSTRUCT: 3434 return t.Type != nil && t.Type.Down == nil && isdirectiface(t.Type.Type) 3435 } 3436 3437 return false 3438 } 3439 3440 // type2IET returns "T" if t is a concrete type, 3441 // "I" if t is an interface type, and "E" if t is an empty interface type. 3442 // It is used to build calls to the conv* and assert* runtime routines. 3443 func type2IET(t *Type) string { 3444 if isnilinter(t) { 3445 return "E" 3446 } 3447 if Isinter(t) { 3448 return "I" 3449 } 3450 return "T" 3451 }