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