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