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